diff --git a/.github/workflows/cargo-audit.yml b/.github/workflows/cargo-audit.yml index 1934dcaeb..14e2d9449 100644 --- a/.github/workflows/cargo-audit.yml +++ b/.github/workflows/cargo-audit.yml @@ -5,6 +5,7 @@ on: - labeled - unlabeled - synchronize + - opened concurrency: group: cargo-audit-${{ github.ref }} cancel-in-progress: true @@ -24,10 +25,19 @@ jobs: sudo apt-get install -y clang curl libssl-dev llvm libudev-dev protobuf-compiler - name: Install cargo-audit - run: cargo install --version 0.20.1 --force cargo-audit + run: cargo install --force cargo-audit - name: Display cargo-audit --version run: cargo audit --version - name: cargo audit - run: cargo audit --ignore RUSTSEC-2024-0336 # rustls issue; wait for upstream to resolve this + run: | + cargo audit --ignore RUSTSEC-2024-0336 \ + --ignore RUSTSEC-2021-0127 \ + --ignore RUSTSEC-2024-0370 \ + --ignore RUSTSEC-2022-0080 \ + --ignore RUSTSEC-2022-0061 \ + --ignore RUSTSEC-2020-0168 \ + --ignore RUSTSEC-2024-0384 \ + --ignore RUSTSEC-2024-0388 \ + --ignore RUSTSEC-2024-0421 diff --git a/.github/workflows/check-devnet.yml b/.github/workflows/check-devnet.yml index c7f39082e..13ebf89cc 100644 --- a/.github/workflows/check-devnet.yml +++ b/.github/workflows/check-devnet.yml @@ -3,7 +3,7 @@ name: Devnet Deploy Check on: pull_request: branches: [devnet, devnet-ready] - types: [labeled, unlabeled, synchronize] + types: [labeled, unlabeled, synchronize, opened] env: CARGO_TERM_COLOR: always diff --git a/.github/workflows/check-finney.yml b/.github/workflows/check-finney.yml index 292bae7ee..98f90fc8e 100644 --- a/.github/workflows/check-finney.yml +++ b/.github/workflows/check-finney.yml @@ -3,7 +3,7 @@ name: Finney Deploy Check on: pull_request: branches: [finney, main] - types: [labeled, unlabeled, synchronize] + types: [labeled, unlabeled, synchronize, opened] env: CARGO_TERM_COLOR: always diff --git a/.github/workflows/check-testnet.yml b/.github/workflows/check-testnet.yml index 03c7e8f8a..7c8532ec5 100644 --- a/.github/workflows/check-testnet.yml +++ b/.github/workflows/check-testnet.yml @@ -3,7 +3,7 @@ name: Testnet Deploy Check on: pull_request: branches: [testnet, testnet-ready] - types: [labeled, unlabeled, synchronize] + types: [labeled, unlabeled, synchronize, opened] env: CARGO_TERM_COLOR: always diff --git a/.github/workflows/label-triggers.yml b/.github/workflows/label-triggers.yml index d32396e07..f3c330f85 100644 --- a/.github/workflows/label-triggers.yml +++ b/.github/workflows/label-triggers.yml @@ -3,6 +3,9 @@ on: pull_request: types: - labeled + - unlabeled + - synchronize + - opened permissions: issues: write diff --git a/Cargo.lock b/Cargo.lock index 1d5fad7da..62cb7a7a7 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,23 +1062,17 @@ checksum = "eee4243f1f26fc7a42710e7439c149e2b10b05472f88090acce52632f231a73a" dependencies = [ "camino", "cargo-platform", - "semver 1.0.23", + "semver 1.0.25", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", ] -[[package]] -name = "case" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -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 +1145,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 +1217,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 +1227,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 +1240,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 +1263,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 +1284,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 +1310,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 +1342,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 +1401,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 +1532,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 +1560,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 +1646,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 +1729,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -1730,7 +1740,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -1748,15 +1758,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 +1774,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 +1849,7 @@ checksum = "d65d7ce8132b7c0e54497a4d9a55a1c2a0912a0d786cf894472ba818fba45762" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -1852,7 +1862,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 +1971,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 +1995,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.90", + "syn 2.0.96", "termcolor", "toml 0.8.19", "walkdir", @@ -1991,9 +2021,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 +2031,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 +2132,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 +2157,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 +2207,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 +2223,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 +2256,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 +2272,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 +2283,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 +2305,7 @@ dependencies = [ "evm-runtime", "log", "parity-scale-codec", - "primitive-types", + "primitive-types 0.12.2", "rlp", "scale-info", "serde", @@ -2289,7 +2319,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 +2333,7 @@ dependencies = [ "environmental", "evm-core", "evm-runtime", - "primitive-types", + "primitive-types 0.12.2", ] [[package]] @@ -2315,7 +2345,7 @@ dependencies = [ "auto_impl", "environmental", "evm-core", - "primitive-types", + "primitive-types 0.12.2", "sha3", ] @@ -2337,10 +2367,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 +2387,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 +2416,7 @@ dependencies = [ "sp-block-builder", "sp-consensus", "sp-runtime", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -2492,7 +2522,7 @@ dependencies = [ "sp-storage 21.0.0", "sp-timestamp", "substrate-prometheus-endpoint", - "thiserror", + "thiserror 1.0.69", "tokio", ] @@ -2535,7 +2565,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e182f7dbc2ef73d9ef67351c5fbbea084729c48362d3ce9dd44c28e32e277fe5" dependencies = [ "libc", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -2648,9 +2678,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 +2721,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8835f84f38484cc86f110a805655697908257fb9a7af005234060891557198e9" dependencies = [ "nonempty", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -2700,7 +2730,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", @@ -2724,16 +2754,6 @@ dependencies = [ "sp-runtime", ] -[[package]] -name = "fp-dynamic-fee" -version = "1.0.0" -source = "git+https://github.com/opentensor/frontier?rev=635bdac882#635bdac882333afed827053f31ef56ab739f7a2e" -dependencies = [ - "async-trait", - "sp-core", - "sp-inherents", -] - [[package]] name = "fp-ethereum" version = "1.0.0-dev" @@ -2874,7 +2894,7 @@ dependencies = [ "sp-storage 21.0.0", "sp-trie", "sp-wasm-interface 21.0.1", - "thiserror", + "thiserror 1.0.69", "thousands", ] @@ -2981,7 +3001,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]] @@ -2994,7 +3014,7 @@ dependencies = [ "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -3006,7 +3026,7 @@ dependencies = [ "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -3017,7 +3037,7 @@ checksum = "68672b9ec6fe72d259d3879dc212c5e42e977588cdac830c76f54d9f492aeb58" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -3027,7 +3047,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]] @@ -3112,9 +3132,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ "futures-channel", "futures-core", @@ -3137,9 +3157,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", @@ -3147,15 +3167,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" dependencies = [ "futures-core", "futures-task", @@ -3176,15 +3196,15 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +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", @@ -3192,13 +3212,13 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -3213,15 +3233,15 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-timer" @@ -3231,9 +3251,9 @@ checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-channel", "futures-core", @@ -3294,7 +3314,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]] @@ -3340,15 +3372,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" @@ -3393,7 +3425,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.6.0", + "indexmap 2.7.1", "slab", "tokio", "tokio-util", @@ -3402,17 +3434,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", @@ -3436,7 +3468,7 @@ dependencies = [ "pest_derive", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -3484,9 +3516,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.0" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" dependencies = [ "allocator-api2", "equivalent", @@ -3504,11 +3536,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]] @@ -3597,11 +3629,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]] @@ -3628,9 +3660,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", @@ -3655,7 +3687,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http 1.1.0", + "http 1.2.0", ] [[package]] @@ -3666,16 +3698,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" @@ -3691,9 +3723,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", @@ -3706,7 +3738,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.5.7", + "socket2 0.5.8", "tokio", "tower-service", "tracing", @@ -3715,15 +3747,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", @@ -3741,7 +3773,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", @@ -3757,9 +3789,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", @@ -3788,6 +3820,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" @@ -3817,12 +3967,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]] @@ -3837,9 +3998,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", @@ -3848,6 +4009,10 @@ dependencies = [ "if-addrs", "ipnet", "log", + "netlink-packet-core", + "netlink-packet-route", + "netlink-proto", + "netlink-sys", "rtnetlink", "system-configuration", "tokio", @@ -3865,7 +4030,7 @@ dependencies = [ "bytes", "futures", "http 0.2.12", - "hyper 0.14.30", + "hyper 0.14.32", "log", "rand", "tokio", @@ -3882,6 +4047,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" @@ -3900,15 +4085,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]] @@ -3943,12 +4137,12 @@ 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.0", + "hashbrown 0.15.2", ] [[package]] @@ -4001,7 +4195,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", @@ -4009,19 +4203,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]] @@ -4059,9 +4253,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" @@ -4074,18 +4268,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", @@ -4097,51 +4292,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", @@ -4150,7 +4345,7 @@ dependencies = [ "serde", "serde_json", "soketto", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-stream", "tokio-util", @@ -4160,14 +4355,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]] @@ -4246,15 +4441,15 @@ 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", @@ -4262,9 +4457,9 @@ dependencies = [ [[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" @@ -4276,7 +4471,7 @@ dependencies = [ "either", "futures", "futures-timer", - "getrandom", + "getrandom 0.2.15", "instant", "libp2p-allow-block-list", "libp2p-connection-limits", @@ -4300,7 +4495,7 @@ dependencies = [ "multiaddr 0.18.2", "pin-project", "rw-stream-sink", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -4341,7 +4536,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", @@ -4350,7 +4545,7 @@ dependencies = [ "rand", "rw-stream-sink", "smallvec", - "thiserror", + "thiserror 1.0.69", "unsigned-varint 0.7.2", "void", ] @@ -4390,24 +4585,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", ] @@ -4435,8 +4630,8 @@ dependencies = [ "rand", "sha2 0.10.8", "smallvec", - "thiserror", - "uint", + "thiserror 1.0.69", + "uint 0.9.5", "unsigned-varint 0.7.2", "void", ] @@ -4456,7 +4651,7 @@ dependencies = [ "log", "rand", "smallvec", - "socket2 0.5.7", + "socket2 0.5.8", "tokio", "trust-dns-proto 0.22.0", "void", @@ -4492,14 +4687,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", ] @@ -4541,8 +4736,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", ] @@ -4597,7 +4792,7 @@ dependencies = [ "proc-macro-warning 0.4.2", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -4613,7 +4808,7 @@ dependencies = [ "libp2p-core", "libp2p-identity", "log", - "socket2 0.5.7", + "socket2 0.5.8", "tokio", ] @@ -4631,7 +4826,7 @@ dependencies = [ "ring 0.16.20", "rustls 0.21.12", "rustls-webpki", - "thiserror", + "thiserror 1.0.69", "x509-parser 0.15.1", "yasna", ] @@ -4682,7 +4877,7 @@ dependencies = [ "pin-project-lite", "rw-stream-sink", "soketto", - "thiserror", + "thiserror 1.0.69", "url", "webpki-roots", ] @@ -4696,7 +4891,7 @@ dependencies = [ "futures", "libp2p-core", "log", - "thiserror", + "thiserror 1.0.69", "yamux", ] @@ -4706,9 +4901,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]] @@ -4787,9 +4982,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", @@ -4813,18 +5008,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", ] @@ -4837,9 +5032,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" @@ -4853,6 +5048,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" @@ -4867,7 +5068,7 @@ dependencies = [ "futures", "futures-timer", "hex-literal", - "indexmap 2.6.0", + "indexmap 2.7.1", "libc", "mockall 0.12.1", "multiaddr 0.17.1", @@ -4888,17 +5089,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", @@ -4920,9 +5121,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" @@ -4939,7 +5140,7 @@ version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" dependencies = [ - "hashbrown 0.15.0", + "hashbrown 0.15.2", ] [[package]] @@ -4953,9 +5154,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", ] @@ -4988,7 +5189,7 @@ dependencies = [ "macro_magic_core", "macro_magic_macros", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -5002,7 +5203,7 @@ dependencies = [ "macro_magic_core_macros", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -5013,7 +5214,7 @@ checksum = "b02abfe41815b5bd98dbd4260173db2c116dda171dc0fe7838cb206333b83308" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -5024,7 +5225,7 @@ checksum = "73ea28ee64b88876bf45277ed9a5817c1817df061a74f2b988971a12570e5869" dependencies = [ "macro_magic_core", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -5070,7 +5271,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]] @@ -5143,22 +5344,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", ] @@ -5183,7 +5383,7 @@ dependencies = [ "rand_chacha", "rand_distr", "subtle 2.6.1", - "thiserror", + "thiserror 1.0.69", "zeroize", ] @@ -5213,7 +5413,7 @@ dependencies = [ "fragile", "lazy_static", "mockall_derive 0.12.1", - "predicates 3.1.2", + "predicates 3.1.3", "predicates-tree", ] @@ -5238,7 +5438,7 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -5271,7 +5471,7 @@ dependencies = [ "data-encoding", "libp2p-identity", "multibase", - "multihash 0.19.2", + "multihash 0.19.3", "percent-encoding", "serde", "static_assertions", @@ -5326,9 +5526,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", @@ -5354,6 +5554,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" @@ -5370,13 +5576,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", @@ -5384,17 +5589,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" @@ -5406,9 +5600,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", @@ -5436,21 +5630,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", @@ -5469,29 +5662,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", @@ -5508,15 +5700,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", @@ -5543,7 +5735,6 @@ dependencies = [ "fc-rpc-core", "fc-storage", "fp-consensus", - "fp-dynamic-fee", "fp-rpc", "frame-benchmarking", "frame-benchmarking-cli", @@ -5608,7 +5799,7 @@ dependencies = [ "substrate-prometheus-endpoint", "subtensor-custom-rpc", "subtensor-custom-rpc-runtime-api", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -5630,7 +5821,7 @@ dependencies = [ "frame-system-benchmarking", "frame-system-rpc-runtime-api", "frame-try-runtime", - "getrandom", + "getrandom 0.2.15", "hex", "log", "pallet-admin-utils", @@ -5640,7 +5831,6 @@ dependencies = [ "pallet-collective", "pallet-commitments", "pallet-drand", - "pallet-dynamic-fee", "pallet-ethereum", "pallet-evm", "pallet-evm-chain-id", @@ -5664,7 +5854,6 @@ dependencies = [ "pallet-transaction-payment-rpc-runtime-api", "pallet-utility", "parity-scale-codec", - "precompile-utils", "rand_chacha", "scale-info", "serde_json", @@ -5854,7 +6043,7 @@ dependencies = [ "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -5880,9 +6069,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", ] @@ -5907,12 +6096,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" @@ -5928,11 +6114,11 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "openssl" -version = "0.10.68" +version = "0.10.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" +checksum = "61cfb4e166a8bb8c9b55c500bc2308550148ece889be90f609377e58140f42c6" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.8.0", "cfg-if", "foreign-types", "libc", @@ -5949,29 +6135,29 @@ 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", ] [[package]] name = "openssl-sys" -version = "0.9.104" +version = "0.9.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" +checksum = "8b22d5b84be05a8d6947c7cb71f7c849aa0f112acd4bf51c2a7c1c988ac0a9dc" dependencies = [ "cc", "libc", @@ -6146,21 +6332,6 @@ dependencies = [ "w3f-bls", ] -[[package]] -name = "pallet-dynamic-fee" -version = "4.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=635bdac882#635bdac882333afed827053f31ef56ab739f7a2e" -dependencies = [ - "fp-dynamic-fee", - "fp-evm", - "frame-support", - "frame-system", - "parity-scale-codec", - "scale-info", - "sp-core", - "sp-inherents", -] - [[package]] name = "pallet-ethereum" version = "4.0.0-dev" @@ -6643,7 +6814,7 @@ dependencies = [ "lru 0.8.1", "parity-util-mem-derive", "parking_lot 0.12.3", - "primitive-types", + "primitive-types 0.12.2", "smallvec", "winapi", ] @@ -6714,7 +6885,7 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.7", + "redox_syscall 0.5.8", "smallvec", "windows-targets 0.52.6", ] @@ -6775,20 +6946,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", @@ -6796,22 +6967,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", @@ -6825,34 +6996,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" @@ -6885,7 +7056,7 @@ dependencies = [ "libc", "log", "polkavm-assembler", - "polkavm-common", + "polkavm-common 0.9.0", "polkavm-linux-raw", ] @@ -6907,25 +7078,52 @@ dependencies = [ "log", ] +[[package]] +name = "polkavm-common" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31ff33982a807d8567645d4784b9b5d7ab87bcb494f534a57cadd9012688e102" + [[package]] name = "polkavm-derive" version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae8c4bea6f3e11cd89bb18bcdddac10bd9a24015399bd1c485ad68a985a19606" dependencies = [ - "polkavm-derive-impl-macro", + "polkavm-derive-impl-macro 0.9.0", +] + +[[package]] +name = "polkavm-derive" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2eb703f3b6404c13228402e98a5eae063fd16b8f58afe334073ec105ee4117e" +dependencies = [ + "polkavm-derive-impl-macro 0.18.0", +] + +[[package]] +name = "polkavm-derive-impl" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c4fdfc49717fb9a196e74a5d28e0bc764eb394a2c803eb11133a31ac996c60c" +dependencies = [ + "polkavm-common 0.9.0", + "proc-macro2", + "quote", + "syn 2.0.96", ] [[package]] name = "polkavm-derive-impl" -version = "0.9.0" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c4fdfc49717fb9a196e74a5d28e0bc764eb394a2c803eb11133a31ac996c60c" +checksum = "2f2116a92e6e96220a398930f4c8a6cda1264206f3e2034fc9982bfd93f261f7" dependencies = [ - "polkavm-common", + "polkavm-common 0.18.0", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -6934,8 +7132,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]] @@ -6948,7 +7156,7 @@ dependencies = [ "hashbrown 0.14.5", "log", "object 0.32.2", - "polkavm-common", + "polkavm-common 0.9.0", "regalloc2 0.9.3", "rustc-demangle", ] @@ -6961,15 +7169,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", ] @@ -6999,9 +7207,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" @@ -7018,44 +7226,6 @@ dependencies = [ "zerocopy", ] -[[package]] -name = "precompile-utils" -version = "0.1.0" -source = "git+https://github.com/opentensor/frontier?rev=635bdac882#635bdac882333afed827053f31ef56ab739f7a2e" -dependencies = [ - "environmental", - "evm", - "fp-evm", - "frame-support", - "frame-system", - "hex", - "impl-trait-for-tuples", - "log", - "num_enum", - "pallet-evm", - "parity-scale-codec", - "precompile-utils-macro", - "sp-core", - "sp-io", - "sp-runtime", - "sp-weights", - "staging-xcm", -] - -[[package]] -name = "precompile-utils-macro" -version = "0.1.0" -source = "git+https://github.com/opentensor/frontier?rev=635bdac882#635bdac882333afed827053f31ef56ab739f7a2e" -dependencies = [ - "case", - "num_enum", - "prettyplease 0.2.22", - "proc-macro2", - "quote", - "sp-crypto-hashing 0.1.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-stable2409)", - "syn 1.0.109", -] - [[package]] name = "predicates" version = "2.1.5" @@ -7072,9 +7242,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", @@ -7082,15 +7252,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", @@ -7108,12 +7278,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]] @@ -7123,11 +7293,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]] @@ -7136,7 +7318,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", ] @@ -7181,7 +7363,7 @@ checksum = "3d1eaa7fa0aa1929ffdf7eeb6eac234dde6268914a14ad44d23521ab6a9b258e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -7192,14 +7374,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", ] @@ -7220,7 +7402,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]] @@ -7234,7 +7416,7 @@ dependencies = [ "lazy_static", "memchr", "parking_lot 0.12.3", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -7257,7 +7439,7 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -7291,7 +7473,7 @@ dependencies = [ "itertools 0.10.5", "lazy_static", "log", - "multimap", + "multimap 0.8.3", "petgraph", "prettyplease 0.1.25", "prost 0.11.9", @@ -7312,14 +7494,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", ] @@ -7346,7 +7528,7 @@ dependencies = [ "itertools 0.12.1", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -7369,24 +7551,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", ] @@ -7415,7 +7597,7 @@ dependencies = [ "asynchronous-codec", "bytes", "quick-protobuf", - "thiserror", + "thiserror 1.0.69", "unsigned-varint 0.7.2", ] @@ -7431,7 +7613,7 @@ dependencies = [ "quinn-udp 0.3.2", "rustc-hash 1.1.0", "rustls 0.20.9", - "thiserror", + "thiserror 1.0.69", "tokio", "tracing", "webpki", @@ -7450,7 +7632,7 @@ dependencies = [ "quinn-udp 0.4.1", "rustc-hash 1.1.0", "rustls 0.21.12", - "thiserror", + "thiserror 1.0.69", "tokio", "tracing", ] @@ -7467,7 +7649,7 @@ dependencies = [ "rustc-hash 1.1.0", "rustls 0.20.9", "slab", - "thiserror", + "thiserror 1.0.69", "tinyvec", "tracing", "webpki", @@ -7485,7 +7667,7 @@ dependencies = [ "rustc-hash 1.1.0", "rustls 0.21.12", "slab", - "thiserror", + "thiserror 1.0.69", "tinyvec", "tracing", ] @@ -7511,16 +7693,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", ] @@ -7558,7 +7740,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom", + "getrandom 0.2.15", ] [[package]] @@ -7582,11 +7764,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]] @@ -7638,11 +7820,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]] @@ -7651,9 +7833,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]] @@ -7673,7 +7855,7 @@ checksum = "bcc303e793d3734489387d205e9b186fac9c6cfacedd98cbb2e8a5943595f3e6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -7703,13 +7885,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", ] @@ -7724,9 +7906,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", @@ -7788,7 +7970,7 @@ checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", "cfg-if", - "getrandom", + "getrandom 0.2.15", "libc", "spin 0.9.8", "untrusted 0.9.0", @@ -7855,16 +8037,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", ] @@ -7892,9 +8077,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" @@ -7917,7 +8102,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]] @@ -7945,15 +8130,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]] @@ -8012,9 +8197,9 @@ dependencies = [ [[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" @@ -8029,9 +8214,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" @@ -8053,9 +8238,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", ] @@ -8077,7 +8262,7 @@ dependencies = [ "log", "sp-core", "sp-wasm-interface 21.0.1", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -8152,7 +8337,7 @@ dependencies = [ "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -8192,7 +8377,7 @@ dependencies = [ "sp-panic-handler", "sp-runtime", "sp-version", - "thiserror", + "thiserror 1.0.69", "tokio", ] @@ -8270,7 +8455,7 @@ dependencies = [ "sp-runtime", "sp-state-machine", "substrate-prometheus-endpoint", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -8299,7 +8484,7 @@ dependencies = [ "sp-keystore", "sp-runtime", "substrate-prometheus-endpoint", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -8335,7 +8520,7 @@ dependencies = [ "sp-keystore", "sp-runtime", "substrate-prometheus-endpoint", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -8392,7 +8577,7 @@ dependencies = [ "sp-keystore", "sp-runtime", "substrate-prometheus-endpoint", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -8412,7 +8597,7 @@ dependencies = [ "sp-blockchain", "sp-core", "sp-runtime", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -8447,7 +8632,7 @@ dependencies = [ "sp-runtime", "sp-timestamp", "substrate-prometheus-endpoint", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -8505,7 +8690,7 @@ dependencies = [ "sc-allocator", "sp-maybe-compressed-blob", "sp-wasm-interface 21.0.1", - "thiserror", + "thiserror 1.0.69", "wasm-instrument", ] @@ -8566,7 +8751,7 @@ dependencies = [ "sp-application-crypto", "sp-core", "sp-keystore", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -8595,7 +8780,7 @@ dependencies = [ "sp-keystore", "sp-mixnet", "sp-runtime", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -8640,7 +8825,7 @@ dependencies = [ "sp-core", "sp-runtime", "substrate-prometheus-endpoint", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-stream", "unsigned-varint 0.7.2", @@ -8704,7 +8889,7 @@ dependencies = [ "sp-blockchain", "sp-core", "sp-runtime", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -8739,7 +8924,7 @@ dependencies = [ "sp-core", "sp-runtime", "substrate-prometheus-endpoint", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-stream", ] @@ -8774,9 +8959,9 @@ dependencies = [ "litep2p", "log", "multiaddr 0.18.2", - "multihash 0.19.2", + "multihash 0.19.3", "rand", - "thiserror", + "thiserror 1.0.69", "zeroize", ] @@ -8790,7 +8975,7 @@ dependencies = [ "fnv", "futures", "futures-timer", - "hyper 0.14.30", + "hyper 0.14.32", "hyper-rustls", "log", "num_cpus", @@ -8872,7 +9057,7 @@ dependencies = [ "sp-rpc", "sp-runtime", "sp-version", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -8884,9 +9069,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", @@ -8926,7 +9111,7 @@ dependencies = [ "sp-rpc", "sp-runtime", "sp-version", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-stream", ] @@ -8989,7 +9174,7 @@ dependencies = [ "static_init", "substrate-prometheus-endpoint", "tempfile", - "thiserror", + "thiserror 1.0.69", "tokio", "tracing", "tracing-futures", @@ -9011,7 +9196,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", @@ -9043,7 +9228,7 @@ dependencies = [ "sc-utils", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "wasm-timer", ] @@ -9070,10 +9255,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]] @@ -9084,7 +9269,7 @@ dependencies = [ "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -9111,7 +9296,7 @@ dependencies = [ "sp-tracing 17.0.1", "sp-transaction-pool", "substrate-prometheus-endpoint", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -9127,7 +9312,7 @@ dependencies = [ "sp-blockchain", "sp-core", "sp-runtime", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -9161,7 +9346,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", @@ -9170,13 +9355,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", @@ -9184,14 +9369,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]] @@ -9202,18 +9387,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", @@ -9273,7 +9458,7 @@ dependencies = [ "log", "rand", "slab", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -9324,7 +9509,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", @@ -9333,9 +9518,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", @@ -9361,9 +9546,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", ] @@ -9382,9 +9567,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", ] @@ -9419,20 +9604,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", @@ -9486,7 +9671,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -9610,9 +9795,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", @@ -9627,7 +9812,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]] @@ -9698,9 +9883,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", @@ -9708,14 +9893,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", @@ -9741,7 +9926,7 @@ dependencies = [ "sp-state-machine", "sp-trie", "sp-version", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -9755,7 +9940,7 @@ dependencies = [ "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -9818,7 +10003,7 @@ dependencies = [ "sp-database", "sp-runtime", "sp-state-machine", - "thiserror", + "thiserror 1.0.69", "tracing", ] @@ -9834,7 +10019,7 @@ dependencies = [ "sp-inherents", "sp-runtime", "sp-state-machine", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -9914,7 +10099,7 @@ dependencies = [ "futures", "hash-db", "hash256-std-hasher", - "impl-serde", + "impl-serde 0.4.0", "itertools 0.11.0", "k256", "libsecp256k1", @@ -9924,7 +10109,7 @@ dependencies = [ "parity-scale-codec", "parking_lot 0.12.3", "paste", - "primitive-types", + "primitive-types 0.12.2", "rand", "scale-info", "schnorrkel", @@ -9939,7 +10124,7 @@ dependencies = [ "sp-storage 21.0.0", "ss58-registry", "substrate-bip39", - "thiserror", + "thiserror 1.0.69", "tracing", "w3f-bls", "zeroize", @@ -9948,7 +10133,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", @@ -10019,7 +10204,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]] @@ -10038,23 +10223,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", @@ -10093,7 +10278,7 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-runtime", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -10107,7 +10292,7 @@ dependencies = [ "libsecp256k1", "log", "parity-scale-codec", - "polkavm-derive", + "polkavm-derive 0.9.1", "rustversion", "secp256k1", "sp-core", @@ -10148,7 +10333,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", ] @@ -10232,13 +10417,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)", @@ -10256,8 +10441,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)", @@ -10270,14 +10455,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]] @@ -10290,7 +10475,7 @@ dependencies = [ "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -10335,7 +10520,7 @@ dependencies = [ "sp-externalities 0.29.0", "sp-panic-handler", "sp-trie", - "thiserror", + "thiserror 1.0.69", "tracing", "trie-db", ] @@ -10360,7 +10545,7 @@ dependencies = [ "sp-externalities 0.29.0", "sp-runtime", "sp-runtime-interface 28.0.0", - "thiserror", + "thiserror 1.0.69", "x25519-dalek", ] @@ -10372,14 +10557,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", @@ -10391,7 +10576,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", @@ -10407,18 +10592,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]] @@ -10429,7 +10614,7 @@ dependencies = [ "parity-scale-codec", "tracing", "tracing-core", - "tracing-subscriber 0.3.18", + "tracing-subscriber 0.3.19", ] [[package]] @@ -10472,7 +10657,7 @@ dependencies = [ "schnellru", "sp-core", "sp-externalities 0.29.0", - "thiserror", + "thiserror 1.0.69", "tracing", "trie-db", "trie-root", @@ -10483,7 +10668,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", @@ -10492,7 +10677,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]] @@ -10503,13 +10688,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", @@ -10577,21 +10762,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", @@ -10600,37 +10775,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", @@ -10639,22 +10808,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", @@ -10668,7 +10837,7 @@ dependencies = [ "sha2 0.10.8", "sqlx-core", "sqlx-sqlite", - "syn 2.0.90", + "syn 2.0.96", "tempfile", "tokio", "url", @@ -10676,9 +10845,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", @@ -10699,9 +10868,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", @@ -10760,9 +10929,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", @@ -10787,7 +10956,7 @@ dependencies = [ "sctp-proto", "serde", "sha-1", - "thiserror", + "thiserror 1.0.69", "tracing", ] @@ -10835,7 +11004,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -10892,11 +11061,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", ] @@ -10939,7 +11108,7 @@ dependencies = [ "quote", "rayon", "subtensor-linting", - "syn 2.0.90", + "syn 2.0.96", "walkdir", ] @@ -10975,7 +11144,7 @@ dependencies = [ "proc-macro2", "procedural-fork", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -10985,7 +11154,7 @@ dependencies = [ "ahash 0.8.11", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -10994,7 +11163,7 @@ version = "0.1.0" dependencies = [ "anyhow", "clap", - "semver 1.0.23", + "semver 1.0.25", "toml_edit", ] @@ -11023,9 +11192,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", @@ -11052,25 +11221,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", @@ -11090,14 +11259,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", ] @@ -11112,38 +11282,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]] @@ -11183,9 +11373,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", @@ -11204,9 +11394,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", @@ -11221,11 +11411,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", ] @@ -11266,9 +11466,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", @@ -11277,20 +11477,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]] @@ -11305,9 +11505,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", @@ -11332,9 +11532,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", @@ -11380,7 +11580,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", @@ -11408,9 +11608,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", @@ -11432,9 +11632,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", @@ -11444,20 +11644,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", @@ -11495,9 +11695,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", @@ -11553,7 +11753,7 @@ dependencies = [ "rand", "smallvec", "socket2 0.4.10", - "thiserror", + "thiserror 1.0.69", "tinyvec", "tokio", "tracing", @@ -11578,7 +11778,7 @@ dependencies = [ "once_cell", "rand", "smallvec", - "thiserror", + "thiserror 1.0.69", "tinyvec", "tokio", "tracing", @@ -11600,7 +11800,7 @@ dependencies = [ "rand", "resolv-conf", "smallvec", - "thiserror", + "thiserror 1.0.69", "tokio", "tracing", "trust-dns-proto 0.23.2", @@ -11633,7 +11833,7 @@ dependencies = [ "rand", "rustls 0.21.12", "sha1", - "thiserror", + "thiserror 1.0.69", "url", "utf-8", ] @@ -11683,17 +11883,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" @@ -11711,16 +11923,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" @@ -11768,12 +11980,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", ] @@ -11783,6 +11995,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" @@ -11791,9 +12015,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" @@ -11833,7 +12057,7 @@ dependencies = [ "rand_core", "sha2 0.10.8", "sha3", - "thiserror", + "thiserror 1.0.69", "zeroize", ] @@ -11862,49 +12086,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", @@ -11912,22 +12146,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" @@ -11949,7 +12186,7 @@ dependencies = [ "strum 0.24.1", "strum_macros 0.24.3", "tempfile", - "thiserror", + "thiserror 1.0.69", "wasm-opt-cxx-sys", "wasm-opt-sys", ] @@ -12076,7 +12313,7 @@ dependencies = [ "log", "object 0.30.4", "target-lexicon", - "thiserror", + "thiserror 1.0.69", "wasmparser", "wasmtime-cranelift-shared", "wasmtime-environ", @@ -12111,7 +12348,7 @@ dependencies = [ "object 0.30.4", "serde", "target-lexicon", - "thiserror", + "thiserror 1.0.69", "wasmparser", "wasmtime-types", ] @@ -12194,15 +12431,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", @@ -12233,14 +12470,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", @@ -12285,28 +12522,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", ] @@ -12542,9 +12789,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", ] @@ -12559,6 +12806,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" @@ -12593,7 +12861,7 @@ dependencies = [ "nom", "oid-registry 0.6.1", "rusticata-macros", - "thiserror", + "thiserror 1.0.69", "time", ] @@ -12610,7 +12878,7 @@ dependencies = [ "nom", "oid-registry 0.7.1", "rusticata-macros", - "thiserror", + "thiserror 1.0.69", "time", ] @@ -12622,14 +12890,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" @@ -12664,6 +12932,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" @@ -12682,7 +12974,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]] @@ -12702,7 +13015,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/node/Cargo.toml b/node/Cargo.toml index 888a76c81..9599e1905 100644 --- a/node/Cargo.toml +++ b/node/Cargo.toml @@ -95,7 +95,6 @@ substrate-prometheus-endpoint = { workspace = true } fc-storage = { workspace = true } fc-db = { workspace = true } fc-consensus = { workspace = true } -fp-dynamic-fee = { workspace = true } fc-api = { workspace = true } fc-rpc = { workspace = true } fc-rpc-core = { workspace = true } diff --git a/node/src/ethereum.rs b/node/src/ethereum.rs index 073635387..44ab48926 100644 --- a/node/src/ethereum.rs +++ b/node/src/ethereum.rs @@ -56,10 +56,6 @@ pub struct EthConfiguration { #[arg(long)] pub enable_dev_signer: bool, - /// The dynamic-fee pallet target gas price set by block author - #[arg(long, default_value = "1")] - pub target_gas_price: u64, - /// Maximum allowed gas limit will be `block.gas_limit * execute_gas_limit_multiplier` /// when using eth_call/eth_estimateGas. #[arg(long, default_value = "10")] diff --git a/node/src/service.rs b/node/src/service.rs index 7b14015bf..9f0f240dc 100644 --- a/node/src/service.rs +++ b/node/src/service.rs @@ -19,7 +19,6 @@ use sp_api::ProvideRuntimeApi; use sp_block_builder::BlockBuilder as BlockBuilderApi; use sp_consensus::Error as ConsensusError; use sp_consensus_aura::sr25519::AuthorityPair as AuraPair; -use sp_core::U256; use sp_runtime::traits::{Block as BlockT, Header, NumberFor}; use std::{cell::RefCell, path::Path}; use std::{marker::PhantomData, sync::Arc, time::Duration}; @@ -279,7 +278,7 @@ where pub fn build_aura_grandpa_import_queue( client: Arc, config: &Configuration, - eth_config: &EthConfiguration, + _eth_config: &EthConfiguration, task_manager: &TaskManager, telemetry: Option, grandpa_block_import: GrandpaBlockImport, @@ -294,7 +293,6 @@ where ); let slot_duration = sc_consensus_aura::slot_duration(&*client)?; - let target_gas_price = eth_config.target_gas_price; let create_inherent_data_providers = move |_, ()| async move { let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); let slot = @@ -302,8 +300,7 @@ where *timestamp, slot_duration, ); - let dynamic_fee = fp_dynamic_fee::InherentDataProvider(U256::from(target_gas_price)); - Ok((slot, timestamp, dynamic_fee)) + Ok((slot, timestamp)) }; let import_queue = sc_consensus_aura::import_queue::( @@ -521,7 +518,6 @@ where )); let slot_duration = sc_consensus_aura::slot_duration(&*client)?; - let target_gas_price = eth_config.target_gas_price; let pending_create_inherent_data_providers = move |_, ()| async move { let current = sp_timestamp::InherentDataProvider::from_system_time(); let next_slot = current @@ -533,8 +529,7 @@ where *timestamp, slot_duration, ); - let dynamic_fee = fp_dynamic_fee::InherentDataProvider(U256::from(target_gas_price)); - Ok((slot, timestamp, dynamic_fee)) + Ok((slot, timestamp)) }; Box::new(move |subscription_task_executor| { @@ -613,7 +608,6 @@ where // manual-seal authorship if let Some(sealing) = sealing { run_manual_seal_authorship( - ð_config, sealing, client, transaction_pool, @@ -639,15 +633,13 @@ where ); let slot_duration = sc_consensus_aura::slot_duration(&*client)?; - let target_gas_price = eth_config.target_gas_price; let create_inherent_data_providers = move |_, ()| async move { let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); let slot = sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration( *timestamp, slot_duration, ); - let dynamic_fee = fp_dynamic_fee::InherentDataProvider(U256::from(target_gas_price)); - Ok((slot, timestamp, dynamic_fee)) + Ok((slot, timestamp)) }; let aura = sc_consensus_aura::start_aura::( @@ -770,7 +762,6 @@ pub fn new_chain_ops( #[allow(clippy::too_many_arguments)] fn run_manual_seal_authorship( - eth_config: &EthConfiguration, sealing: Sealing, client: Arc, transaction_pool: Arc>, @@ -820,12 +811,8 @@ fn run_manual_seal_authorship( } } - let target_gas_price = eth_config.target_gas_price; - let create_inherent_data_providers = move |_, ()| async move { - let timestamp = MockTimestampInherentDataProvider; - let dynamic_fee = fp_dynamic_fee::InherentDataProvider(U256::from(target_gas_price)); - Ok((timestamp, dynamic_fee)) - }; + let create_inherent_data_providers = + move |_, ()| async move { Ok(MockTimestampInherentDataProvider) }; let manual_seal = match sealing { Sealing::Manual => future::Either::Left(sc_consensus_manual_seal::run_manual_seal( diff --git a/pallets/admin-utils/src/lib.rs b/pallets/admin-utils/src/lib.rs index 7de39aa38..90e0c1292 100644 --- a/pallets/admin-utils/src/lib.rs +++ b/pallets/admin-utils/src/lib.rs @@ -554,7 +554,7 @@ pub mod pallet { } /// The extrinsic sets the minimum burn for a subnet. - /// It is only callable by the root account or subnet owner. + /// It is only callable by the root account. /// The extrinsic will call the Subtensor pallet to set the minimum burn. #[pallet::call_index(22)] #[pallet::weight(::WeightInfo::sudo_set_min_burn())] @@ -563,7 +563,7 @@ pub mod pallet { netuid: u16, min_burn: u64, ) -> DispatchResult { - pallet_subtensor::Pallet::::ensure_subnet_owner_or_root(origin, netuid)?; + ensure_root(origin)?; ensure!( pallet_subtensor::Pallet::::if_subnet_exist(netuid), diff --git a/pallets/subtensor/runtime-api/src/lib.rs b/pallets/subtensor/runtime-api/src/lib.rs index cdcd6ed39..31f351aeb 100644 --- a/pallets/subtensor/runtime-api/src/lib.rs +++ b/pallets/subtensor/runtime-api/src/lib.rs @@ -34,6 +34,7 @@ sp_api::decl_runtime_apis! { pub trait StakeInfoRuntimeApi { fn get_stake_info_for_coldkey( coldkey_account_vec: Vec ) -> Vec; fn get_stake_info_for_coldkeys( coldkey_account_vecs: Vec> ) -> Vec; + fn get_stake_info_for_hotkey_coldkey_netuid( hotkey_account_vec: Vec, coldkey_account_vec: Vec, netuid: u16 ) -> Vec; } pub trait SubnetRegistrationRuntimeApi { diff --git a/pallets/subtensor/src/coinbase/run_coinbase.rs b/pallets/subtensor/src/coinbase/run_coinbase.rs index 7516857b4..b57a08503 100644 --- a/pallets/subtensor/src/coinbase/run_coinbase.rs +++ b/pallets/subtensor/src/coinbase/run_coinbase.rs @@ -122,20 +122,26 @@ impl Pallet { netuid, subnet_proportion ); - // 3.7: Calculate subnet's TAO emission: E_s = P_s * E_m - let tao_in: u64 = mech_emission - .checked_mul(subnet_proportion) - .unwrap_or(I96F32::saturating_from_num(0)) - .saturating_to_num::(); - log::debug!( - "Subnet TAO emission (E_s) for netuid {:?}: {:?}", - netuid, - tao_in - ); - // 3.8: Store the subnet TAO emission. - *tao_in_map.entry(*netuid).or_insert(0) = tao_in; - // 3.9: Store the block emission for this subnet for chain storage. - EmissionValues::::insert(*netuid, tao_in); + + // Only emit TAO if the subnetwork allows registration. + if Self::get_network_registration_allowed(*netuid) + || Self::get_network_pow_registration_allowed(*netuid) + { + // 3.7: Calculate subnet's TAO emission: E_s = P_s * E_m + let tao_in: u64 = mech_emission + .checked_mul(subnet_proportion) + .unwrap_or(I96F32::saturating_from_num(0)) + .saturating_to_num::(); + log::debug!( + "Subnet TAO emission (E_s) for netuid {:?}: {:?}", + netuid, + tao_in + ); + // 3.8: Store the subnet TAO emission. + *tao_in_map.entry(*netuid).or_insert(0) = tao_in; + // 3.9: Store the block emission for this subnet for chain storage. + EmissionValues::::insert(*netuid, tao_in); + } } // == We'll save the owner cuts for each subnet. diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index 3fd67e0d8..064bb5c6e 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -82,7 +82,7 @@ pub mod pallet { use sp_std::collections::vec_deque::VecDeque; use sp_std::vec; use sp_std::vec::Vec; - use substrate_fixed::types::U64F64; + use substrate_fixed::types::{I96F32, U64F64}; use subtensor_macros::freeze_struct; #[cfg(not(feature = "std"))] @@ -234,6 +234,11 @@ pub mod pallet { } #[pallet::type_value] /// Default value for zero. + pub fn DefaultZeroU128() -> u128 { + 0 + } + #[pallet::type_value] + /// Default value for zero. pub fn DefaultZeroU16() -> u16 { 0 } @@ -733,6 +738,12 @@ pub mod pallet { U64F64::saturating_from_num(0) } + #[pallet::type_value] + /// Default value for minimum liquidity in pool + pub fn DefaultMinimumPoolLiquidity() -> I96F32 { + I96F32::saturating_from_num(1_000_000_000) + } + #[pallet::storage] pub type ColdkeySwapScheduleDuration = StorageValue<_, BlockNumberFor, ValueQuery, DefaultColdkeySwapScheduleDuration>; @@ -901,7 +912,7 @@ pub mod pallet { pub type DynamicBlock = StorageValue<_, u64, ValueQuery>; #[pallet::storage] // --- MAP ( netuid ) --> total_volume | The total amount of TAO bought and sold since the start of the network. pub type SubnetVolume = - StorageMap<_, Identity, u16, u64, ValueQuery, DefaultZeroU64>; + StorageMap<_, Identity, u16, u128, ValueQuery, DefaultZeroU128>; #[pallet::storage] // --- MAP ( netuid ) --> tao_in_subnet | Returns the amount of TAO in the subnet. pub type SubnetTAO = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultZeroU64>; @@ -1562,6 +1573,8 @@ pub enum CustomTransactionError { HotkeyAccountDoesntExist, NotEnoughStakeToWithdraw, RateLimitExceeded, + InsufficientLiquidity, + SlippageTooHigh, BadRequest, } @@ -1575,6 +1588,8 @@ impl From for u8 { CustomTransactionError::HotkeyAccountDoesntExist => 4, CustomTransactionError::NotEnoughStakeToWithdraw => 5, CustomTransactionError::RateLimitExceeded => 6, + CustomTransactionError::InsufficientLiquidity => 7, + CustomTransactionError::SlippageTooHigh => 8, CustomTransactionError::BadRequest => 255, } } @@ -1642,6 +1657,14 @@ where CustomTransactionError::NotEnoughStakeToWithdraw.into(), ) .into()), + Error::::InsufficientLiquidity => Err(InvalidTransaction::Custom( + CustomTransactionError::InsufficientLiquidity.into(), + ) + .into()), + Error::::SlippageTooHigh => Err(InvalidTransaction::Custom( + CustomTransactionError::SlippageTooHigh.into(), + ) + .into()), _ => Err( InvalidTransaction::Custom(CustomTransactionError::BadRequest.into()).into(), ), @@ -1765,7 +1788,7 @@ where } Some(Call::commit_crv3_weights { netuid, .. }) => { if Self::check_weights_min_stake(who, *netuid) { - let priority: u64 = Self::get_priority_set_weights(who, *netuid); + let priority: u64 = Pallet::::get_priority_set_weights(who, *netuid); Ok(ValidTransaction { priority, longevity: 1, @@ -1789,6 +1812,28 @@ where hotkey, *netuid, *amount_staked, + *amount_staked, + false, + )) + } + Some(Call::add_stake_limit { + hotkey, + netuid, + amount_staked, + limit_price, + allow_partial, + }) => { + // Calcaulate the maximum amount that can be executed with price limit + let max_amount = Pallet::::get_max_amount_add(*netuid, *limit_price); + + // Fully validate the user input + Self::result_to_validity(Pallet::::validate_add_stake( + who, + hotkey, + *netuid, + *amount_staked, + max_amount, + *allow_partial, )) } Some(Call::remove_stake { @@ -1802,6 +1847,28 @@ where hotkey, *netuid, *amount_unstaked, + *amount_unstaked, + false, + )) + } + Some(Call::remove_stake_limit { + hotkey, + netuid, + amount_unstaked, + limit_price, + allow_partial, + }) => { + // Calcaulate the maximum amount that can be executed with price limit + let max_amount = Pallet::::get_max_amount_remove(*netuid, *limit_price); + + // Fully validate the user input + Self::result_to_validity(Pallet::::validate_remove_stake( + who, + hotkey, + *netuid, + *amount_unstaked, + max_amount, + *allow_partial, )) } Some(Call::move_stake { @@ -1820,6 +1887,8 @@ where *origin_netuid, *destination_netuid, *alpha_amount, + *alpha_amount, + None, )) } Some(Call::transfer_stake { @@ -1838,6 +1907,8 @@ where *origin_netuid, *destination_netuid, *alpha_amount, + *alpha_amount, + None, )) } Some(Call::swap_stake { @@ -1855,6 +1926,36 @@ where *origin_netuid, *destination_netuid, *alpha_amount, + *alpha_amount, + None, + )) + } + Some(Call::swap_stake_limit { + hotkey, + origin_netuid, + destination_netuid, + alpha_amount, + limit_price, + allow_partial, + }) => { + // Get the max amount possible to exchange + let max_amount = Pallet::::get_max_amount_move( + *origin_netuid, + *destination_netuid, + *limit_price, + ); + + // Fully validate the user input + Self::result_to_validity(Pallet::::validate_stake_transition( + who, + who, + hotkey, + hotkey, + *origin_netuid, + *destination_netuid, + *alpha_amount, + max_amount, + Some(*allow_partial), )) } Some(Call::register { netuid, .. } | Call::burned_register { netuid, .. }) => { diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index d9eafffa7..2735b6bb7 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -1688,5 +1688,175 @@ mod dispatches { alpha_amount, ) } + + /// --- Adds stake to a hotkey on a subnet with a price limit. + /// This extrinsic allows to specify the limit price for alpha token + /// at which or better (lower) the staking should execute. + /// + /// In case if slippage occurs and the price shall move beyond the limit + /// price, the staking order may execute only partially or not execute + /// at all. + /// + /// # Args: + /// * 'origin': (Origin): + /// - The signature of the caller's coldkey. + /// + /// * 'hotkey' (T::AccountId): + /// - The associated hotkey account. + /// + /// * 'amount_staked' (u64): + /// - The amount of stake to be added to the hotkey staking account. + /// + /// * 'limit_price' (u64): + /// - The limit price expressed in units of RAO per one Alpha. + /// + /// * 'allow_partial' (bool): + /// - Allows partial execution of the amount. If set to false, this becomes + /// fill or kill type or order. + /// + /// # Event: + /// * StakeAdded; + /// - On the successfully adding stake to a global account. + /// + /// # Raises: + /// * 'NotEnoughBalanceToStake': + /// - Not enough balance on the coldkey to add onto the global account. + /// + /// * 'NonAssociatedColdKey': + /// - The calling coldkey is not associated with this hotkey. + /// + /// * 'BalanceWithdrawalError': + /// - Errors stemming from transaction pallet. + /// + #[pallet::call_index(88)] + #[pallet::weight((Weight::from_parts(124_000_000, 0) + .saturating_add(T::DbWeight::get().reads(10)) + .saturating_add(T::DbWeight::get().writes(7)), DispatchClass::Normal, Pays::No))] + pub fn add_stake_limit( + origin: OriginFor, + hotkey: T::AccountId, + netuid: u16, + amount_staked: u64, + limit_price: u64, + allow_partial: bool, + ) -> DispatchResult { + Self::do_add_stake_limit( + origin, + hotkey, + netuid, + amount_staked, + limit_price, + allow_partial, + ) + } + + /// --- Removes stake from a hotkey on a subnet with a price limit. + /// This extrinsic allows to specify the limit price for alpha token + /// at which or better (higher) the staking should execute. + /// + /// In case if slippage occurs and the price shall move beyond the limit + /// price, the staking order may execute only partially or not execute + /// at all. + /// + /// # Args: + /// * 'origin': (Origin): + /// - The signature of the caller's coldkey. + /// + /// * 'hotkey' (T::AccountId): + /// - The associated hotkey account. + /// + /// * 'amount_unstaked' (u64): + /// - The amount of stake to be added to the hotkey staking account. + /// + /// * 'limit_price' (u64): + /// - The limit price expressed in units of RAO per one Alpha. + /// + /// * 'allow_partial' (bool): + /// - Allows partial execution of the amount. If set to false, this becomes + /// fill or kill type or order. + /// + /// # Event: + /// * StakeRemoved; + /// - On the successfully removing stake from the hotkey account. + /// + /// # Raises: + /// * 'NotRegistered': + /// - Thrown if the account we are attempting to unstake from is non existent. + /// + /// * 'NonAssociatedColdKey': + /// - Thrown if the coldkey does not own the hotkey we are unstaking from. + /// + /// * 'NotEnoughStakeToWithdraw': + /// - Thrown if there is not enough stake on the hotkey to withdwraw this amount. + /// + #[pallet::call_index(89)] + #[pallet::weight((Weight::from_parts(111_000_000, 0) + .saturating_add(Weight::from_parts(0, 43991)) + .saturating_add(T::DbWeight::get().reads(10)) + .saturating_add(T::DbWeight::get().writes(7)), DispatchClass::Normal, Pays::No))] + pub fn remove_stake_limit( + origin: OriginFor, + hotkey: T::AccountId, + netuid: u16, + amount_unstaked: u64, + limit_price: u64, + allow_partial: bool, + ) -> DispatchResult { + Self::do_remove_stake_limit( + origin, + hotkey, + netuid, + amount_unstaked, + limit_price, + allow_partial, + ) + } + + /// Swaps a specified amount of stake from one subnet to another, while keeping the same coldkey and hotkey. + /// + /// # Arguments + /// * `origin` - The origin of the transaction, which must be signed by the coldkey that owns the `hotkey`. + /// * `hotkey` - The hotkey whose stake is being swapped. + /// * `origin_netuid` - The network/subnet ID from which stake is removed. + /// * `destination_netuid` - The network/subnet ID to which stake is added. + /// * `alpha_amount` - The amount of stake to swap. + /// * `limit_price` - The limit price expressed in units of RAO per one Alpha. + /// * `allow_partial` - Allows partial execution of the amount. If set to false, this becomes fill or kill type or order. + /// + /// # Errors + /// Returns an error if: + /// * The transaction is not signed by the correct coldkey (i.e., `coldkey_owns_hotkey` fails). + /// * Either `origin_netuid` or `destination_netuid` does not exist. + /// * The hotkey does not exist. + /// * There is insufficient stake on `(coldkey, hotkey, origin_netuid)`. + /// * The swap amount is below the minimum stake requirement. + /// + /// # Events + /// May emit a `StakeSwapped` event on success. + #[pallet::call_index(90)] + #[pallet::weight(( + Weight::from_parts(3_000_000, 0).saturating_add(T::DbWeight::get().writes(1)), + DispatchClass::Operational, + Pays::No + ))] + pub fn swap_stake_limit( + origin: T::RuntimeOrigin, + hotkey: T::AccountId, + origin_netuid: u16, + destination_netuid: u16, + alpha_amount: u64, + limit_price: u64, + allow_partial: bool, + ) -> DispatchResult { + Self::do_swap_stake_limit( + origin, + hotkey, + origin_netuid, + destination_netuid, + alpha_amount, + limit_price, + allow_partial, + ) + } } } diff --git a/pallets/subtensor/src/macros/errors.rs b/pallets/subtensor/src/macros/errors.rs index dd5e97b78..926aead58 100644 --- a/pallets/subtensor/src/macros/errors.rs +++ b/pallets/subtensor/src/macros/errors.rs @@ -185,5 +185,9 @@ mod errors { CommittingWeightsTooFast, /// Stake amount is too low. AmountTooLow, + /// Not enough liquidity. + InsufficientLiquidity, + /// Slippage is too high for the transaction. + SlippageTooHigh, } } diff --git a/pallets/subtensor/src/macros/hooks.rs b/pallets/subtensor/src/macros/hooks.rs index 2a43238ab..19f7d317b 100644 --- a/pallets/subtensor/src/macros/hooks.rs +++ b/pallets/subtensor/src/macros/hooks.rs @@ -76,13 +76,16 @@ mod hooks { // Migrate to RAO .saturating_add(migrations::migrate_rao::migrate_rao::()) // Fix the IsNetworkMember map to be consistent with other storage maps - .saturating_add(migrations::migrate_fix_is_network_member::migrate_fix_is_network_member::()); + .saturating_add(migrations::migrate_fix_is_network_member::migrate_fix_is_network_member::()) + .saturating_add(migrations::migrate_subnet_volume::migrate_subnet_volume::()); weight } #[cfg(feature = "try-runtime")] fn try_state(_n: BlockNumberFor) -> Result<(), sp_runtime::TryRuntimeError> { - Self::check_accounting_invariants()?; + Self::check_total_issuance()?; + // Disabled: https://github.com/opentensor/subtensor/pull/1166 + // Self::check_total_stake()?; Ok(()) } } diff --git a/pallets/subtensor/src/migrations/migrate_init_total_issuance.rs b/pallets/subtensor/src/migrations/migrate_init_total_issuance.rs index a488771c5..ba9d85bad 100644 --- a/pallets/subtensor/src/migrations/migrate_init_total_issuance.rs +++ b/pallets/subtensor/src/migrations/migrate_init_total_issuance.rs @@ -1,6 +1,6 @@ use super::*; -use frame_support::pallet_prelude::OptionQuery; -use frame_support::{pallet_prelude::Identity, storage_alias}; +use frame_support::pallet_prelude::{Identity, OptionQuery, Weight}; +use frame_support::storage_alias; use sp_std::vec::Vec; // TODO: Implement comprehensive tests for this migration @@ -14,10 +14,46 @@ pub mod deprecated_loaded_emission_format { StorageMap, Identity, u16, Vec<(AccountIdOf, u64)>, OptionQuery>; } +pub(crate) fn migrate_init_total_issuance() -> Weight { + // Calculate the total locked tokens across all subnets + let subnets_len = crate::SubnetLocked::::iter().count() as u64; + let total_subnet_locked: u64 = + crate::SubnetLocked::::iter().fold(0, |acc, (_, v)| acc.saturating_add(v)); + + // Retrieve the total balance of all accounts + let total_account_balances = <::Currency as fungible::Inspect< + ::AccountId, + >>::total_issuance(); + + // Get the total stake from the system + let total_stake = crate::TotalStake::::get(); + + // Retrieve the previous total issuance for logging purposes + let prev_total_issuance = crate::TotalIssuance::::get(); + + // Calculate the new total issuance + let new_total_issuance = total_account_balances + .saturating_add(total_stake) + .saturating_add(total_subnet_locked); + + // Update the total issuance in storage + crate::TotalIssuance::::put(new_total_issuance); + + // Log the change in total issuance + log::info!( + "Subtensor Pallet Total Issuance Updated: previous: {:?}, new: {:?}", + prev_total_issuance, + new_total_issuance + ); + + // Return the weight of the operation + // We performed subnets_len + 5 reads and 1 write + ::DbWeight::get().reads_writes(subnets_len.saturating_add(5), 1) +} + pub mod initialise_total_issuance { use frame_support::pallet_prelude::Weight; - use frame_support::traits::{fungible, OnRuntimeUpgrade}; - use sp_core::Get; + use frame_support::traits::OnRuntimeUpgrade; use crate::*; @@ -33,41 +69,7 @@ pub mod initialise_total_issuance { /// /// Returns the weight of the migration operation. fn on_runtime_upgrade() -> Weight { - // Calculate the total locked tokens across all subnets - let subnets_len = crate::SubnetLocked::::iter().count() as u64; - let total_subnet_locked: u64 = - crate::SubnetLocked::::iter().fold(0, |acc, (_, v)| acc.saturating_add(v)); - - // Retrieve the total balance of all accounts - let total_account_balances = <::Currency as fungible::Inspect< - ::AccountId, - >>::total_issuance(); - - // Get the total stake from the system - let total_stake = crate::TotalStake::::get(); - - // Retrieve the previous total issuance for logging purposes - let prev_total_issuance = crate::TotalIssuance::::get(); - - // Calculate the new total issuance - let new_total_issuance = total_account_balances - .saturating_add(total_stake) - .saturating_add(total_subnet_locked); - - // Update the total issuance in storage - crate::TotalIssuance::::put(new_total_issuance); - - // Log the change in total issuance - log::info!( - "Subtensor Pallet Total Issuance Updated: previous: {:?}, new: {:?}", - prev_total_issuance, - new_total_issuance - ); - - // Return the weight of the operation - // We performed subnets_len + 5 reads and 1 write - ::DbWeight::get() - .reads_writes(subnets_len.saturating_add(5), 1) + super::migrate_init_total_issuance::() } /// Performs post-upgrade checks to ensure the migration was successful. @@ -76,7 +78,7 @@ pub mod initialise_total_issuance { #[cfg(feature = "try-runtime")] fn post_upgrade(_state: Vec) -> Result<(), sp_runtime::TryRuntimeError> { // Verify that all accounting invariants are satisfied after the migration - crate::Pallet::::check_accounting_invariants()?; + crate::Pallet::::check_total_issuance()?; Ok(()) } } diff --git a/pallets/subtensor/src/migrations/migrate_rao.rs b/pallets/subtensor/src/migrations/migrate_rao.rs index 3c034b7da..136bd4c59 100644 --- a/pallets/subtensor/src/migrations/migrate_rao.rs +++ b/pallets/subtensor/src/migrations/migrate_rao.rs @@ -1,11 +1,13 @@ -use super::*; use alloc::string::String; + use frame_support::IterableStorageMap; use frame_support::{traits::Get, weights::Weight}; -use log; use sp_runtime::format; use substrate_fixed::types::U64F64; +use super::*; +use crate::subnets::subnet::POOL_INITIAL_TAO; + pub fn migrate_rao() -> Weight { let migration_name = b"migrate_rao".to_vec(); @@ -69,12 +71,12 @@ pub fn migrate_rao() -> Weight { TokenSymbol::::insert(netuid, Pallet::::get_symbol_for_subnet(0)); continue; } - let owner: T::AccountId = SubnetOwner::::get(netuid); - let lock: u64 = SubnetLocked::::get(netuid); + let owner = SubnetOwner::::get(netuid); + let lock = SubnetLocked::::get(netuid); // Put initial TAO from lock into subnet TAO and produce numerically equal amount of Alpha // The initial TAO is the locked amount, with a minimum of 1 RAO and a cap of 100 TAO. - let pool_initial_tao = 100_000_000_000.min(lock.max(1)); + let pool_initial_tao = POOL_INITIAL_TAO.min(lock.max(1)); let remaining_lock = lock.saturating_sub(pool_initial_tao); // Refund the owner for the remaining lock. @@ -127,6 +129,10 @@ pub fn migrate_rao() -> Weight { // TargetStakesPerInterval::::put(10); (DEPRECATED) } + // update `TotalIssuance`, because currency issuance (`T::Currency`) has changed due to lock + // refunds above + weight = weight.saturating_add(migrate_init_total_issuance::migrate_init_total_issuance::()); + // Mark the migration as completed HasMigrationRun::::insert(&migration_name, true); weight = weight.saturating_add(T::DbWeight::get().writes(1)); diff --git a/pallets/subtensor/src/migrations/migrate_subnet_volume.rs b/pallets/subtensor/src/migrations/migrate_subnet_volume.rs new file mode 100644 index 000000000..46835877d --- /dev/null +++ b/pallets/subtensor/src/migrations/migrate_subnet_volume.rs @@ -0,0 +1,33 @@ +use super::*; +use alloc::string::String; +use frame_support::{traits::Get, weights::Weight}; + +pub fn migrate_subnet_volume() -> Weight { + let migration_name = b"migrate_subnet_volume".to_vec(); + + // Initialize the weight with one read operation. + let weight = T::DbWeight::get().reads(1); + + // Check if the migration has already run + 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) + ); + + let mut migrated = 0u64; + + SubnetVolume::::translate::(|_key, old_value| { + migrated = migrated.saturating_add(1); + Some(old_value as u128) // Convert and store as u128 + }); + + log::info!("Migrated {} entries in SubnetVolume", migrated); + weight.saturating_add(T::DbWeight::get().reads_writes(migrated, migrated)) +} diff --git a/pallets/subtensor/src/migrations/mod.rs b/pallets/subtensor/src/migrations/mod.rs index 6cf358c4d..5d9aff969 100644 --- a/pallets/subtensor/src/migrations/mod.rs +++ b/pallets/subtensor/src/migrations/mod.rs @@ -11,6 +11,7 @@ pub mod migrate_populate_owned_hotkeys; pub mod migrate_populate_staking_hotkeys; pub mod migrate_rao; pub mod migrate_stake_threshold; +pub mod migrate_subnet_volume; pub mod migrate_to_v1_separate_emission; pub mod migrate_to_v2_fixed_total_stake; pub mod migrate_total_issuance; diff --git a/pallets/subtensor/src/rpc_info/dynamic_info.rs b/pallets/subtensor/src/rpc_info/dynamic_info.rs index a8ffd8549..27d10dc2d 100644 --- a/pallets/subtensor/src/rpc_info/dynamic_info.rs +++ b/pallets/subtensor/src/rpc_info/dynamic_info.rs @@ -4,7 +4,7 @@ use codec::Compact; use frame_support::pallet_prelude::{Decode, Encode}; use subtensor_macros::freeze_struct; -#[freeze_struct("44fd17b240416875")] +#[freeze_struct("a5cdc80d655398e9")] #[derive(Decode, Encode, PartialEq, Eq, Clone, Debug)] pub struct DynamicInfo { netuid: Compact, @@ -24,6 +24,7 @@ pub struct DynamicInfo { tao_in_emission: Compact, pending_alpha_emission: Compact, pending_root_emission: Compact, + subnet_volume: Compact, network_registered_at: Compact, subnet_identity: Option, } @@ -60,6 +61,7 @@ impl Pallet { tao_in_emission: SubnetTaoInEmission::::get(netuid).into(), pending_alpha_emission: PendingEmission::::get(netuid).into(), pending_root_emission: PendingRootDivs::::get(netuid).into(), + subnet_volume: SubnetVolume::::get(netuid).into(), network_registered_at: NetworkRegisteredAt::::get(netuid).into(), subnet_identity: SubnetIdentities::::get(netuid), }) diff --git a/pallets/subtensor/src/rpc_info/metagraph.rs b/pallets/subtensor/src/rpc_info/metagraph.rs index 1e77e5fe6..267af1d05 100644 --- a/pallets/subtensor/src/rpc_info/metagraph.rs +++ b/pallets/subtensor/src/rpc_info/metagraph.rs @@ -6,7 +6,7 @@ use frame_support::pallet_prelude::{Decode, Encode}; use substrate_fixed::types::I64F64; use subtensor_macros::freeze_struct; -#[freeze_struct("bce2310daa502e48")] +#[freeze_struct("7c5fe907490c5d5e")] #[derive(Decode, Encode, PartialEq, Eq, Clone, Debug)] pub struct Metagraph { // Subnet index @@ -38,6 +38,7 @@ pub struct Metagraph { tao_in_emission: Compact, // amount of tao injected per block pending_alpha_emission: Compact, // pending alpha to be distributed pending_root_emission: Compact, // panding tao for root divs to be distributed + subnet_volume: Compact, // volume of the subnet in TAO // Hparams for epoch rho: Compact, // subnet rho param @@ -141,6 +142,8 @@ impl Pallet { Vec, Vec, ) = Self::get_stake_weights_for_network(netuid); + + let subnet_volume = SubnetVolume::::get(netuid); Some(Metagraph { // Subnet index netuid: netuid.into(), // subnet index. @@ -177,6 +180,7 @@ impl Pallet { tao_in_emission: SubnetTaoInEmission::::get(netuid).into(), // amount of tao injected per block pending_alpha_emission: PendingEmission::::get(netuid).into(), // pending alpha to be distributed pending_root_emission: PendingRootDivs::::get(netuid).into(), // panding tao for root divs to be distributed + subnet_volume: subnet_volume.into(), // Hparams for epoch rho: Self::get_rho(netuid).into(), // subnet rho param diff --git a/pallets/subtensor/src/rpc_info/stake_info.rs b/pallets/subtensor/src/rpc_info/stake_info.rs index 97afd5aa2..0422bc33b 100644 --- a/pallets/subtensor/src/rpc_info/stake_info.rs +++ b/pallets/subtensor/src/rpc_info/stake_info.rs @@ -99,4 +99,42 @@ impl Pallet { first.1.clone() } } + + pub fn get_stake_info_for_hotkey_coldkey_netuid( + hotkey_account_vec: Vec, + coldkey_account_vec: Vec, + netuid: u16, + ) -> Option> { + if coldkey_account_vec.len() != 32 { + return None; // Invalid coldkey + } + + let Ok(coldkey) = T::AccountId::decode(&mut coldkey_account_vec.as_bytes_ref()) else { + return None; + }; + + if hotkey_account_vec.len() != 32 { + return None; // Invalid hotkey + } + + let Ok(hotkey) = T::AccountId::decode(&mut hotkey_account_vec.as_bytes_ref()) else { + return None; + }; + + let alpha: u64 = + Self::get_stake_for_hotkey_and_coldkey_on_subnet(&hotkey, &coldkey, netuid); + let emission: u64 = AlphaDividendsPerSubnet::::get(netuid, &hotkey); + let is_registered: bool = Self::is_hotkey_registered_on_network(netuid, &hotkey); + + Some(StakeInfo { + hotkey: hotkey.clone(), + coldkey: coldkey.clone(), + netuid: (netuid).into(), + stake: alpha.into(), + locked: 0.into(), + emission: emission.into(), + drain: 0.into(), + is_registered, + }) + } } diff --git a/pallets/subtensor/src/staking/add_stake.rs b/pallets/subtensor/src/staking/add_stake.rs index 326eca1dc..2291de748 100644 --- a/pallets/subtensor/src/staking/add_stake.rs +++ b/pallets/subtensor/src/staking/add_stake.rs @@ -48,7 +48,14 @@ impl Pallet { ); // 2. Validate user input - Self::validate_add_stake(&coldkey, &hotkey, netuid, stake_to_be_added)?; + Self::validate_add_stake( + &coldkey, + &hotkey, + netuid, + stake_to_be_added, + stake_to_be_added, + false, + )?; // 3. Ensure the remove operation from the coldkey is a success. let tao_staked: u64 = @@ -62,4 +69,142 @@ impl Pallet { // Ok and return. Ok(()) } + + /// ---- The implementation for the extrinsic add_stake_limit: Adds stake to a hotkey + /// account on a subnet with price limit. + /// + /// # Args: + /// * 'origin': (RuntimeOrigin): + /// - The signature of the caller's coldkey. + /// + /// * 'hotkey' (T::AccountId): + /// - The associated hotkey account. + /// + /// * 'stake_to_be_added' (u64): + /// - The amount of stake to be added to the hotkey staking account. + /// + /// * 'limit_price' (u64): + /// - The limit price expressed in units of RAO per one Alpha. + /// + /// * 'allow_partial' (bool): + /// - Allows partial execution of the amount. If set to false, this becomes + /// fill or kill type or order. + /// + /// # Event: + /// * StakeAdded; + /// - On the successfully adding stake to a global account. + /// + /// # Raises: + /// * 'NotEnoughBalanceToStake': + /// - Not enough balance on the coldkey to add onto the global account. + /// + /// * 'NonAssociatedColdKey': + /// - The calling coldkey is not associated with this hotkey. + /// + /// * 'BalanceWithdrawalError': + /// - Errors stemming from transaction pallet. + /// + /// * 'TxRateLimitExceeded': + /// - Thrown if key has hit transaction rate limit + /// + pub fn do_add_stake_limit( + origin: T::RuntimeOrigin, + hotkey: T::AccountId, + netuid: u16, + stake_to_be_added: u64, + limit_price: u64, + allow_partial: bool, + ) -> dispatch::DispatchResult { + // 1. We check that the transaction is signed by the caller and retrieve the T::AccountId coldkey information. + let coldkey = ensure_signed(origin)?; + log::debug!( + "do_add_stake( origin:{:?} hotkey:{:?}, netuid:{:?}, stake_to_be_added:{:?} )", + coldkey, + hotkey, + netuid, + stake_to_be_added + ); + + // 2. Calcaulate the maximum amount that can be executed with price limit + let max_amount = Self::get_max_amount_add(netuid, limit_price); + let mut possible_stake = stake_to_be_added; + if possible_stake > max_amount { + possible_stake = max_amount; + } + + // 3. Validate user input + Self::validate_add_stake( + &coldkey, + &hotkey, + netuid, + stake_to_be_added, + max_amount, + allow_partial, + )?; + + // 4. Ensure the remove operation from the coldkey is a success. + let tao_staked: u64 = Self::remove_balance_from_coldkey_account(&coldkey, possible_stake)?; + + // 5. 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); + + // Ok and return. + Ok(()) + } + + // Returns the maximum amount of RAO that can be executed with price limit + pub fn get_max_amount_add(netuid: u16, limit_price: u64) -> u64 { + // Corner case: root and stao + // There's no slippage for root or stable subnets, so if limit price is 1e9 rao or + // higher, then max_amount equals u64::MAX, otherwise it is 0. + if (netuid == Self::get_root_netuid()) || (SubnetMechanism::::get(netuid)) == 0 { + if limit_price >= 1_000_000_000 { + return u64::MAX; + } else { + return 0; + } + } + + // Corner case: SubnetAlphaIn is zero. Staking can't happen, so max amount is zero. + let alpha_in = SubnetAlphaIn::::get(netuid); + if alpha_in == 0 { + return 0; + } + let alpha_in_u128 = alpha_in as u128; + + // Corner case: SubnetTAO is zero. Staking can't happen, so max amount is zero. + let tao_reserve = SubnetTAO::::get(netuid); + if tao_reserve == 0 { + return 0; + } + let tao_reserve_u128 = tao_reserve as u128; + + // Corner case: limit_price < current_price (price cannot decrease with staking) + let tao = 1_000_000_000_u128; + let limit_price_u128 = limit_price as u128; + if (limit_price_u128 + < Self::get_alpha_price(netuid) + .saturating_to_num::() + .saturating_mul(tao)) + || (limit_price == 0u64) + { + return 0; + } + + // Main case: return limit_price * SubnetAlphaIn - SubnetTAO + // Non overflowing calculation: limit_price * alpha_in <= u64::MAX * u64::MAX <= u128::MAX + // May overflow result, then it will be capped at u64::MAX, which is OK because that matches balance u64 size. + let result = limit_price_u128 + .saturating_mul(alpha_in_u128) + .checked_div(tao) + .unwrap_or(0) + .saturating_sub(tao_reserve_u128); + if result < u64::MAX as u128 { + result as u64 + } else { + u64::MAX + } + } } diff --git a/pallets/subtensor/src/staking/move_stake.rs b/pallets/subtensor/src/staking/move_stake.rs index 75f933135..a60191de8 100644 --- a/pallets/subtensor/src/staking/move_stake.rs +++ b/pallets/subtensor/src/staking/move_stake.rs @@ -1,6 +1,7 @@ use super::*; use safe_math::*; use sp_core::Get; +use substrate_fixed::types::U64F64; impl Pallet { /// Moves stake from one hotkey to another across subnets. @@ -44,6 +45,8 @@ impl Pallet { origin_netuid, destination_netuid, alpha_amount, + None, + None, )?; // Log the event. @@ -113,6 +116,8 @@ impl Pallet { origin_netuid, destination_netuid, alpha_amount, + None, + None, )?; // 9. Emit an event for logging/monitoring. @@ -180,6 +185,8 @@ impl Pallet { origin_netuid, destination_netuid, alpha_amount, + None, + None, )?; // Emit an event for logging. @@ -203,6 +210,79 @@ impl Pallet { Ok(()) } + /// Swaps a specified amount of stake for the same `(coldkey, hotkey)` pair from one subnet + /// (`origin_netuid`) to another (`destination_netuid`). + /// + /// # Arguments + /// * `origin` - The origin of the transaction, which must be signed by the coldkey that owns the hotkey. + /// * `hotkey` - The hotkey whose stake is being swapped. + /// * `origin_netuid` - The subnet ID from which stake is removed. + /// * `destination_netuid` - The subnet ID to which stake is added. + /// * `alpha_amount` - The amount of stake to swap. + /// * `limit_price` - The limit price. + /// * `allow_partial` - Allow partial execution + /// + /// # Returns + /// * `DispatchResult` - Indicates success or failure. + /// + /// # Errors + /// This function returns an error if: + /// * The origin is not signed by the correct coldkey (i.e., not associated with `hotkey`). + /// * Either the `origin_netuid` or the `destination_netuid` does not exist. + /// * The specified `hotkey` does not exist. + /// * The `(coldkey, hotkey, origin_netuid)` does not have enough stake (`alpha_amount`). + /// * The unstaked amount is below `DefaultMinStake`. + /// + /// # Events + /// Emits a `StakeSwapped` event upon successful completion. + pub fn do_swap_stake_limit( + origin: T::RuntimeOrigin, + hotkey: T::AccountId, + origin_netuid: u16, + destination_netuid: u16, + alpha_amount: u64, + limit_price: u64, + allow_partial: bool, + ) -> dispatch::DispatchResult { + // Ensure the extrinsic is signed by the coldkey. + let coldkey = ensure_signed(origin)?; + + // Validate input and move stake + let tao_moved = Self::transition_stake_internal( + &coldkey, + &coldkey, + &hotkey, + &hotkey, + origin_netuid, + destination_netuid, + alpha_amount, + Some(limit_price), + Some(allow_partial), + )?; + + // Emit an event for logging. + log::info!( + "StakeSwapped(coldkey: {:?}, hotkey: {:?}, origin_netuid: {:?}, destination_netuid: {:?}, amount: {:?})", + coldkey, + hotkey, + origin_netuid, + destination_netuid, + tao_moved + ); + Self::deposit_event(Event::StakeSwapped( + coldkey, + hotkey, + origin_netuid, + destination_netuid, + tao_moved, + )); + + // 6. Return success. + Ok(()) + } + + // If limit_price is None, this is a regular operation, otherwise, it is slippage-protected + // by setting limit price between origin_netuid and destination_netuid token fn transition_stake_internal( origin_coldkey: &T::AccountId, destination_coldkey: &T::AccountId, @@ -211,7 +291,16 @@ impl Pallet { origin_netuid: u16, destination_netuid: u16, alpha_amount: u64, + maybe_limit_price: Option, + maybe_allow_partial: Option, ) -> Result> { + // Calculate the maximum amount that can be executed + let max_amount = if let Some(limit_price) = maybe_limit_price { + Self::get_max_amount_move(origin_netuid, destination_netuid, limit_price) + } else { + alpha_amount + }; + // Validate user input Self::validate_stake_transition( origin_coldkey, @@ -221,6 +310,8 @@ impl Pallet { origin_netuid, destination_netuid, alpha_amount, + max_amount, + maybe_allow_partial, )?; // Unstake from the origin subnet, returning TAO (or a 1:1 equivalent). @@ -248,4 +339,126 @@ impl Pallet { Ok(tao_unstaked.saturating_sub(fee)) } + + /// Returns the maximum amount of origin netuid Alpha that can be executed before we cross + /// limit_price. + /// + /// ```ignore + /// The TAO we get from unstaking is + /// unstaked_tao = subnet_tao(1) - alpha_in(1) * subnet_tao(1) / (alpha_in(1) + unstaked_alpha) + /// + /// The Alpha we get from staking is + /// moved_alpha = alpha_in(2) - alpha_in(2) * subnet_tao(2) / (subnet_tao(2) + unstaked_tao) + /// + /// The resulting swap price that shall be compared to limit_price is moved_alpha / unstaked_alpha + /// + /// With a known limit_price parameter x = unstaked_alpha can be found using the formula: + /// + /// alpha_in(2) * subnet_tao(1) - limit_price * alpha_in(1) * subnet_tao(2) + /// x = ----------------------------------------------------------------------- + /// limit_price * (subnet_tao(1) + subnet_tao(2)) + /// ``` + /// + /// In the corner case when SubnetTAO(2) == SubnetTAO(1), no slippage is going to occur. + /// + pub fn get_max_amount_move( + origin_netuid: u16, + destination_netuid: u16, + limit_price: u64, + ) -> u64 { + let tao: U64F64 = U64F64::saturating_from_num(1_000_000_000); + + // Corner case: both subnet IDs are root or stao + // There's no slippage for root or stable subnets, so slippage is always 0. + // The price always stays at 1.0, return 0 if price is expected to raise. + if ((origin_netuid == Self::get_root_netuid()) + || (SubnetMechanism::::get(origin_netuid)) == 0) + && ((destination_netuid == Self::get_root_netuid()) + || (SubnetMechanism::::get(destination_netuid)) == 0) + { + if limit_price > tao.saturating_to_num::() { + return 0; + } else { + return u64::MAX; + } + } + + // Corner case: Origin is root or stable, destination is dynamic + // Same as adding stake with limit price + if ((origin_netuid == Self::get_root_netuid()) + || (SubnetMechanism::::get(origin_netuid)) == 0) + && ((SubnetMechanism::::get(destination_netuid)) == 1) + { + if limit_price == 0 { + return u64::MAX; + } else { + // The destination price is reverted because the limit_price is origin_price / destination_price + let destination_subnet_price = tao + .safe_div(U64F64::saturating_from_num(limit_price)) + .saturating_mul(tao) + .saturating_to_num::(); + return Self::get_max_amount_add(destination_netuid, destination_subnet_price); + } + } + + // Corner case: Origin is dynamic, destination is root or stable + // Same as removing stake with limit price + if ((destination_netuid == Self::get_root_netuid()) + || (SubnetMechanism::::get(destination_netuid)) == 0) + && ((SubnetMechanism::::get(origin_netuid)) == 1) + { + return Self::get_max_amount_remove(origin_netuid, limit_price); + } + + // Corner case: SubnetTAO for any of two subnets is zero + let subnet_tao_1 = SubnetTAO::::get(origin_netuid); + let subnet_tao_2 = SubnetTAO::::get(destination_netuid); + if (subnet_tao_1 == 0) || (subnet_tao_2 == 0) { + return 0; + } + let subnet_tao_1_float: U64F64 = U64F64::saturating_from_num(subnet_tao_1); + let subnet_tao_2_float: U64F64 = U64F64::saturating_from_num(subnet_tao_2); + + // Corner case: SubnetAlphaIn for any of two subnets is zero + let alpha_in_1 = SubnetAlphaIn::::get(origin_netuid); + let alpha_in_2 = SubnetAlphaIn::::get(destination_netuid); + if (alpha_in_1 == 0) || (alpha_in_2 == 0) { + return 0; + } + let alpha_in_1_float: U64F64 = U64F64::saturating_from_num(alpha_in_1); + let alpha_in_2_float: U64F64 = U64F64::saturating_from_num(alpha_in_2); + + // Corner case: limit_price > current_price (price of origin (as a base) relative + // to destination (as a quote) cannot increase with moving) + // The alpha price is never zero at this point because of the checks above. + // Excluding this corner case guarantees that main case nominator is non-negative + let limit_price_float: U64F64 = U64F64::saturating_from_num(limit_price) + .checked_div(U64F64::saturating_from_num(1_000_000_000)) + .unwrap_or(U64F64::saturating_from_num(0)); + let current_price = Self::get_alpha_price(origin_netuid) + .safe_div(Self::get_alpha_price(destination_netuid)); + if limit_price_float > current_price { + return 0; + } + + // Corner case: limit_price is zero + if limit_price == 0 { + return u64::MAX; + } + + // Main case + // Nominator is positive + // Denominator is positive + // Perform calculation in a non-overflowing order + let tao_sum: U64F64 = + U64F64::saturating_from_num(subnet_tao_2_float.saturating_add(subnet_tao_1_float)); + let t1_over_sum: U64F64 = subnet_tao_1_float.safe_div(tao_sum); + let t2_over_sum: U64F64 = subnet_tao_2_float.safe_div(tao_sum); + + alpha_in_2_float + .saturating_mul(t1_over_sum) + .safe_div(limit_price_float) + .saturating_sub(alpha_in_1_float.saturating_mul(t2_over_sum)) + .saturating_to_num::() + } } diff --git a/pallets/subtensor/src/staking/remove_stake.rs b/pallets/subtensor/src/staking/remove_stake.rs index bab8c9a29..c1db7012c 100644 --- a/pallets/subtensor/src/staking/remove_stake.rs +++ b/pallets/subtensor/src/staking/remove_stake.rs @@ -48,7 +48,14 @@ impl Pallet { ); // 2. Validate the user input - Self::validate_remove_stake(&coldkey, &hotkey, netuid, alpha_unstaked)?; + Self::validate_remove_stake( + &coldkey, + &hotkey, + netuid, + alpha_unstaked, + alpha_unstaked, + false, + )?; // 3. Swap the alpba to tao and update counters for this subnet. let fee = DefaultStakingFee::::get(); @@ -220,4 +227,162 @@ impl Pallet { // 5. Done and ok. Ok(()) } + + /// ---- The implementation for the extrinsic remove_stake_limit: Removes stake from + /// a hotkey on a subnet with a price limit. + /// + /// In case if slippage occurs and the price shall move beyond the limit + /// price, the staking order may execute only partially or not execute + /// at all. + /// + /// # Args: + /// * 'origin': (Origin): + /// - The signature of the caller's coldkey. + /// + /// * 'hotkey' (T::AccountId): + /// - The associated hotkey account. + /// + /// * 'amount_unstaked' (u64): + /// - The amount of stake to be added to the hotkey staking account. + /// + /// * 'limit_price' (u64): + /// - The limit price expressed in units of RAO per one Alpha. + /// + /// * 'allow_partial' (bool): + /// - Allows partial execution of the amount. If set to false, this becomes + /// fill or kill type or order. + /// + /// # Event: + /// * StakeRemoved; + /// - On the successfully removing stake from the hotkey account. + /// + /// # Raises: + /// * 'NotRegistered': + /// - Thrown if the account we are attempting to unstake from is non existent. + /// + /// * 'NonAssociatedColdKey': + /// - Thrown if the coldkey does not own the hotkey we are unstaking from. + /// + /// * 'NotEnoughStakeToWithdraw': + /// - Thrown if there is not enough stake on the hotkey to withdwraw this amount. + /// + pub fn do_remove_stake_limit( + origin: T::RuntimeOrigin, + hotkey: T::AccountId, + netuid: u16, + alpha_unstaked: u64, + limit_price: u64, + allow_partial: bool, + ) -> dispatch::DispatchResult { + // 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_remove_stake( origin:{:?} hotkey:{:?}, netuid: {:?}, alpha_unstaked:{:?} )", + coldkey, + hotkey, + netuid, + alpha_unstaked + ); + + // 2. Calcaulate the maximum amount that can be executed with price limit + let max_amount = Self::get_max_amount_remove(netuid, limit_price); + let mut possible_alpha = alpha_unstaked; + if possible_alpha > max_amount { + possible_alpha = max_amount; + } + + // 3. Validate the user input + Self::validate_remove_stake( + &coldkey, + &hotkey, + netuid, + alpha_unstaked, + max_amount, + allow_partial, + )?; + + // 4. Swap the alpha to tao and update counters for this subnet. + let fee = DefaultStakingFee::::get(); + let tao_unstaked: u64 = + 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. + Self::add_balance_to_coldkey_account(&coldkey, tao_unstaked); + + // 6. If the stake is below the minimum, we clear the nomination from storage. + Self::clear_small_nomination_if_required(&hotkey, &coldkey, netuid); + + // 7. Check if stake lowered below MinStake and remove Pending children if it did + if Self::get_total_stake_for_hotkey(&hotkey) < StakeThreshold::::get() { + Self::get_all_subnet_netuids().iter().for_each(|netuid| { + PendingChildKeys::::remove(netuid, &hotkey); + }) + } + + // Done and ok. + Ok(()) + } + + // Returns the maximum amount of RAO that can be executed with price limit + pub fn get_max_amount_remove(netuid: u16, limit_price: u64) -> u64 { + // Corner case: root and stao + // There's no slippage for root or stable subnets, so if limit price is 1e9 rao or + // higher, then max_amount equals u64::MAX, otherwise it is 0. + if (netuid == Self::get_root_netuid()) || (SubnetMechanism::::get(netuid)) == 0 { + if limit_price <= 1_000_000_000 { + return u64::MAX; + } else { + return 0; + } + } + + // Corner case: SubnetAlphaIn is zero. Staking can't happen, so max amount is zero. + let alpha_in = SubnetAlphaIn::::get(netuid); + if alpha_in == 0 { + return 0; + } + let alpha_in_u128 = alpha_in as u128; + + // Corner case: SubnetTAO is zero. Staking can't happen, so max amount is zero. + let tao_reserve = SubnetTAO::::get(netuid); + if tao_reserve == 0 { + return 0; + } + let tao_reserve_u128 = tao_reserve as u128; + + // Corner case: limit_price == 0 (because there's division by limit price) + // => can sell all + if limit_price == 0 { + return u64::MAX; + } + + // Corner case: limit_price >= current_price (price cannot increase with unstaking) + // No overflows: alpha_price * tao <= u64::MAX * u64::MAX + // Alpha price is U96F32 size, but it is calculated as u64/u64, so it never uses all 96 bits. + let limit_price_u128 = limit_price as u128; + let tao = 1_000_000_000_u128; + if limit_price_u128 + >= tao_reserve_u128 + .saturating_mul(tao) + .checked_div(alpha_in_u128) + .unwrap_or(0) + { + return 0; + } + + // Main case: SubnetTAO / limit_price - SubnetAlphaIn + // Non overflowing calculation: tao_reserve * tao <= u64::MAX * u64::MAX <= u128::MAX + // May overflow result, then it will be capped at u64::MAX, which is OK because that matches Alpha u64 size. + let result = tao_reserve_u128 + .saturating_mul(tao) + .checked_div(limit_price_u128) + .unwrap_or(0) + .saturating_sub(alpha_in_u128); + + if result < u64::MAX as u128 { + result as u64 + } else { + u64::MAX + } + } } diff --git a/pallets/subtensor/src/staking/stake_utils.rs b/pallets/subtensor/src/staking/stake_utils.rs index 1bd6aa1af..b4b650804 100644 --- a/pallets/subtensor/src/staking/stake_utils.rs +++ b/pallets/subtensor/src/staking/stake_utils.rs @@ -2,7 +2,7 @@ use super::*; use safe_math::*; use share_pool::{SharePool, SharePoolDataOperations}; use sp_std::ops::Neg; -use substrate_fixed::types::{I64F64, I96F32, U64F64}; +use substrate_fixed::types::{I110F18, I64F64, I96F32, U64F64}; impl Pallet { /// Retrieves the total alpha issuance for a given subnet. @@ -457,155 +457,147 @@ impl Pallet { } } - /// Swaps TAO for the alpha token on the subnet. + /// Calculates Some(Alpha) returned from pool by staking operation + /// if liquidity allows that. If not, returns None. /// - /// Updates TaoIn, AlphaIn, and AlphaOut - pub fn sim_swap_tao_for_alpha(netuid: u16, tao: u64) -> u64 { + /// If new alpha_reserve is about to drop below DefaultMinimumPoolLiquidity, + /// then don't do it. + /// + pub fn sim_swap_tao_for_alpha(netuid: u16, tao: u64) -> Option { // Step 1: Get the mechanism type for the subnet (0 for Stable, 1 for Dynamic) let mechanism_id: u16 = SubnetMechanism::::get(netuid); // Step 2: Initialized vars. - let alpha: I96F32 = if mechanism_id == 1 { + if mechanism_id == 1 { // Step 3.a.1: Dynamic mechanism calculations - let tao_reserves: I96F32 = I96F32::saturating_from_num(SubnetTAO::::get(netuid)); - let alpha_reserves: I96F32 = - I96F32::saturating_from_num(SubnetAlphaIn::::get(netuid)); + let tao_reserves: I110F18 = I110F18::saturating_from_num(SubnetTAO::::get(netuid)); + let alpha_reserves: I110F18 = + I110F18::saturating_from_num(SubnetAlphaIn::::get(netuid)); // Step 3.a.2: Compute constant product k = alpha * tao - let k: I96F32 = alpha_reserves.saturating_mul(tao_reserves); + let k: I110F18 = alpha_reserves.saturating_mul(tao_reserves); + + // Calculate new alpha reserve + let new_alpha_reserves: I110F18 = + k.safe_div(tao_reserves.saturating_add(I110F18::saturating_from_num(tao))); + // Step 3.a.3: Calculate alpha staked using the constant product formula // alpha_stake_recieved = current_alpha - (k / (current_tao + new_tao)) - alpha_reserves.saturating_sub( - k.checked_div(tao_reserves.saturating_add(I96F32::saturating_from_num(tao))) - .unwrap_or(I96F32::saturating_from_num(0)), - ) + if new_alpha_reserves >= DefaultMinimumPoolLiquidity::::get() { + Some( + alpha_reserves + .saturating_sub(new_alpha_reserves) + .saturating_to_num::(), + ) + } else { + None + } } else { // Step 3.b.1: Stable mechanism, just return the value 1:1 - I96F32::saturating_from_num(tao) - }; - // Return simulated amount. - alpha.saturating_to_num::() + Some(tao) + } } - /// Swaps a subnet's Alpba token for TAO. + /// Calculates Some(Tao) returned from pool by unstaking operation + /// if liquidity allows that. If not, returns None. /// - /// Updates TaoIn, AlphaIn, and AlphaOut - pub fn sim_swap_alpha_for_tao(netuid: u16, alpha: u64) -> u64 { + /// If new tao_reserve is about to drop below DefaultMinimumPoolLiquidity, + /// then don't do it. + /// + pub fn sim_swap_alpha_for_tao(netuid: u16, alpha: u64) -> Option { // Step 1: Get the mechanism type for the subnet (0 for Stable, 1 for Dynamic) let mechanism_id: u16 = SubnetMechanism::::get(netuid); // Step 2: Swap alpha and attain tao - let tao: I96F32 = if mechanism_id == 1 { + if mechanism_id == 1 { // Step 3.a.1: Dynamic mechanism calculations - let tao_reserves: I96F32 = I96F32::saturating_from_num(SubnetTAO::::get(netuid)); - let alpha_reserves: I96F32 = - I96F32::saturating_from_num(SubnetAlphaIn::::get(netuid)); + let tao_reserves: I110F18 = I110F18::saturating_from_num(SubnetTAO::::get(netuid)); + let alpha_reserves: I110F18 = + I110F18::saturating_from_num(SubnetAlphaIn::::get(netuid)); // Step 3.a.2: Compute constant product k = alpha * tao - let k: I96F32 = alpha_reserves.saturating_mul(tao_reserves); + let k: I110F18 = alpha_reserves.saturating_mul(tao_reserves); + + // Calculate new tao reserve + let new_tao_reserves: I110F18 = k + .checked_div(alpha_reserves.saturating_add(I110F18::saturating_from_num(alpha))) + .unwrap_or(I110F18::saturating_from_num(0)); + // Step 3.a.3: Calculate alpha staked using the constant product formula // tao_recieved = tao_reserves - (k / (alpha_reserves + new_tao)) - tao_reserves.saturating_sub( - k.checked_div(alpha_reserves.saturating_add(I96F32::saturating_from_num(alpha))) - .unwrap_or(I96F32::saturating_from_num(0)), - ) + if new_tao_reserves >= DefaultMinimumPoolLiquidity::::get() { + Some( + tao_reserves + .saturating_sub(new_tao_reserves) + .saturating_to_num::(), + ) + } else { + None + } } else { // Step 3.b.1: Stable mechanism, just return the value 1:1 - I96F32::saturating_from_num(alpha) - }; - tao.saturating_to_num::() + Some(alpha) + } } /// Swaps TAO for the alpha token on the subnet. /// /// Updates TaoIn, AlphaIn, and AlphaOut pub fn swap_tao_for_alpha(netuid: u16, tao: u64) -> u64 { - // Step 1: Get the mechanism type for the subnet (0 for Stable, 1 for Dynamic) - let mechanism_id: u16 = SubnetMechanism::::get(netuid); - // Step 2: Initialized vars. - let alpha: I96F32 = if mechanism_id == 1 { - // Step 3.a.1: Dynamic mechanism calculations - let tao_reserves: I96F32 = I96F32::saturating_from_num(SubnetTAO::::get(netuid)); - let alpha_reserves: I96F32 = - I96F32::saturating_from_num(SubnetAlphaIn::::get(netuid)); - // Step 3.a.2: Compute constant product k = alpha * tao - let k: I96F32 = alpha_reserves.saturating_mul(tao_reserves); - // Step 3.a.3: Calculate alpha staked using the constant product formula - // alpha_stake_recieved = current_alpha - (k / (current_tao + new_tao)) - alpha_reserves.saturating_sub( - k.checked_div(tao_reserves.saturating_add(I96F32::saturating_from_num(tao))) - .unwrap_or(I96F32::saturating_from_num(0)), - ) + if let Some(alpha) = Self::sim_swap_tao_for_alpha(netuid, tao) { + // Step 4. Decrease Alpha reserves. + SubnetAlphaIn::::mutate(netuid, |total| { + *total = total.saturating_sub(alpha); + }); + // Step 5: Increase Alpha outstanding. + SubnetAlphaOut::::mutate(netuid, |total| { + *total = total.saturating_add(alpha); + }); + // Step 6: Increase Tao reserves. + SubnetTAO::::mutate(netuid, |total| { + *total = total.saturating_add(tao); + }); + // Step 7: Increase Total Tao reserves. + TotalStake::::mutate(|total| { + *total = total.saturating_add(tao); + }); + // Step 8. Increase total subnet TAO volume. + SubnetVolume::::mutate(netuid, |total| { + *total = total.saturating_add(tao.into()); + }); + // Step 9. Return the alpha received. + alpha } else { - // Step 3.b.1: Stable mechanism, just return the value 1:1 - I96F32::saturating_from_num(tao) - }; - // Step 4. Decrease Alpha reserves. - SubnetAlphaIn::::mutate(netuid, |total| { - *total = total.saturating_sub(alpha.saturating_to_num::()); - }); - // Step 5: Increase Alpha outstanding. - SubnetAlphaOut::::mutate(netuid, |total| { - *total = total.saturating_add(alpha.saturating_to_num::()); - }); - // Step 6: Increase Tao reserves. - SubnetTAO::::mutate(netuid, |total| { - *total = total.saturating_add(tao); - }); - // Step 7: Increase Total Tao reserves. - TotalStake::::mutate(|total| { - *total = total.saturating_add(tao); - }); - // Step 8. Decrease Alpha reserves. - SubnetVolume::::mutate(netuid, |total| { - *total = total.saturating_sub(tao); - }); - // Step 9. Return the alpha received. - alpha.saturating_to_num::() + 0 + } } /// Swaps a subnet's Alpba token for TAO. /// /// Updates TaoIn, AlphaIn, and AlphaOut pub fn swap_alpha_for_tao(netuid: u16, alpha: u64) -> u64 { - // Step 1: Get the mechanism type for the subnet (0 for Stable, 1 for Dynamic) - let mechanism_id: u16 = SubnetMechanism::::get(netuid); - // Step 2: Swap alpha and attain tao - let tao: I96F32 = if mechanism_id == 1 { - // Step 3.a.1: Dynamic mechanism calculations - let tao_reserves: I96F32 = I96F32::saturating_from_num(SubnetTAO::::get(netuid)); - let alpha_reserves: I96F32 = - I96F32::saturating_from_num(SubnetAlphaIn::::get(netuid)); - // Step 3.a.2: Compute constant product k = alpha * tao - let k: I96F32 = alpha_reserves.saturating_mul(tao_reserves); - // Step 3.a.3: Calculate alpha staked using the constant product formula - // tao_recieved = tao_reserves - (k / (alpha_reserves + new_tao)) - tao_reserves.saturating_sub( - k.checked_div(alpha_reserves.saturating_add(I96F32::saturating_from_num(alpha))) - .unwrap_or(I96F32::saturating_from_num(0)), - ) + if let Some(tao) = Self::sim_swap_alpha_for_tao(netuid, alpha) { + // Step 4: Increase Alpha reserves. + SubnetAlphaIn::::mutate(netuid, |total| { + *total = total.saturating_add(alpha); + }); + // Step 5: Decrease Alpha outstanding. + SubnetAlphaOut::::mutate(netuid, |total| { + *total = total.saturating_sub(alpha); + }); + // Step 6: Decrease tao reserves. + SubnetTAO::::mutate(netuid, |total| { + *total = total.saturating_sub(tao); + }); + // Step 7: Reduce total TAO reserves. + TotalStake::::mutate(|total| { + *total = total.saturating_sub(tao); + }); + // Step 8. Increase total subnet TAO volume. + SubnetVolume::::mutate(netuid, |total| { + *total = total.saturating_add(tao.into()); + }); + // Step 9. Return the tao received. + tao } else { - // Step 3.b.1: Stable mechanism, just return the value 1:1 - I96F32::saturating_from_num(alpha) - }; - // Step 4: Increase Alpha reserves. - SubnetAlphaIn::::mutate(netuid, |total| { - *total = total.saturating_add(alpha); - }); - // Step 5: Decrease Alpha outstanding. - SubnetAlphaOut::::mutate(netuid, |total| { - *total = total.saturating_sub(alpha); - }); - // Step 6: Decrease tao reserves. - SubnetTAO::::mutate(netuid, |total| { - *total = total.saturating_sub(tao.saturating_to_num::()); - }); - // Step 7: Reduce total TAO reserves. - TotalStake::::mutate(|total| { - *total = total.saturating_sub(tao.saturating_to_num::()); - }); - // Step 8. Decrease Alpha reserves. - SubnetVolume::::mutate(netuid, |total| { - *total = total.saturating_sub(tao.saturating_to_num::()); - }); - // Step 9. Return the tao received. - tao.saturating_to_num::() + 0 + } } /// Unstakes alpha from a subnet for a given hotkey and coldkey pair. @@ -737,6 +729,8 @@ impl Pallet { hotkey: &T::AccountId, netuid: u16, stake_to_be_added: u64, + max_amount: u64, + allow_partial: bool, ) -> Result<(), Error> { // Ensure that the subnet exists. ensure!(Self::if_subnet_exist(netuid), Error::::SubnetNotExists); @@ -747,6 +741,12 @@ impl Pallet { // Ensure that the stake_to_be_added is at least the min_amount ensure!(stake_to_be_added >= min_amount, Error::::AmountTooLow); + // Ensure that if partial execution is not allowed, the amount will not cause + // slippage over desired + if !allow_partial { + ensure!(stake_to_be_added <= max_amount, Error::::SlippageTooHigh); + } + // Ensure the callers coldkey has enough stake to perform the transaction. ensure!( Self::can_remove_balance_from_coldkey_account(coldkey, stake_to_be_added), @@ -759,6 +759,12 @@ impl Pallet { Error::::HotKeyAccountNotExists ); + // Ensure that we have adequate liquidity + ensure!( + Self::sim_swap_tao_for_alpha(netuid, stake_to_be_added).is_some(), + Error::::InsufficientLiquidity + ); + Ok(()) } @@ -769,16 +775,27 @@ impl Pallet { hotkey: &T::AccountId, netuid: u16, alpha_unstaked: u64, + max_amount: u64, + allow_partial: bool, ) -> Result<(), Error> { // Ensure that the subnet exists. ensure!(Self::if_subnet_exist(netuid), Error::::SubnetNotExists); // Ensure that the stake amount to be removed is above the minimum in tao equivalent. - let tao_equivalent = Self::sim_swap_alpha_for_tao(netuid, alpha_unstaked); - ensure!( - tao_equivalent > DefaultMinStake::::get(), - Error::::AmountTooLow - ); + if let Some(tao_equivalent) = Self::sim_swap_alpha_for_tao(netuid, alpha_unstaked) { + ensure!( + tao_equivalent > DefaultMinStake::::get(), + Error::::AmountTooLow + ); + } else { + return Err(Error::::InsufficientLiquidity); + }; + + // Ensure that if partial execution is not allowed, the amount will not cause + // slippage over desired + if !allow_partial { + ensure!(alpha_unstaked <= max_amount, Error::::SlippageTooHigh); + } // Ensure that the hotkey account exists this is only possible through registration. ensure!( @@ -806,6 +823,8 @@ impl Pallet { origin_netuid: u16, destination_netuid: u16, alpha_amount: u64, + max_amount: u64, + maybe_allow_partial: Option, ) -> Result<(), Error> { // Ensure that both subnets exist. ensure!( @@ -843,11 +862,22 @@ impl Pallet { ); // Ensure that the stake amount to be removed is above the minimum in tao equivalent. - let tao_equivalent = Self::sim_swap_alpha_for_tao(origin_netuid, alpha_amount); - ensure!( - tao_equivalent > DefaultMinStake::::get(), - Error::::AmountTooLow - ); + if let Some(tao_equivalent) = Self::sim_swap_alpha_for_tao(origin_netuid, alpha_amount) { + ensure!( + tao_equivalent > DefaultMinStake::::get(), + Error::::AmountTooLow + ); + } else { + return Err(Error::::InsufficientLiquidity); + } + + // Ensure that if partial execution is not allowed, the amount will not cause + // slippage over desired + if let Some(allow_partial) = maybe_allow_partial { + if !allow_partial { + ensure!(alpha_amount <= max_amount, Error::::SlippageTooHigh); + } + } Ok(()) } diff --git a/pallets/subtensor/src/subnets/subnet.rs b/pallets/subtensor/src/subnets/subnet.rs index 942f6fe8b..ee713cacf 100644 --- a/pallets/subtensor/src/subnets/subnet.rs +++ b/pallets/subtensor/src/subnets/subnet.rs @@ -2,6 +2,8 @@ use super::*; use frame_support::IterableStorageMap; use sp_core::Get; +pub(crate) const POOL_INITIAL_TAO: u64 = 100_000_000_000; + impl Pallet { /// Retrieves the unique identifier (UID) for the root network. /// @@ -235,7 +237,7 @@ impl Pallet { // Put initial TAO from lock into subnet TAO and produce numerically equal amount of Alpha // The initial TAO is the locked amount, with a minimum of 1 RAO and a cap of 100 TAO. - let pool_initial_tao = 100_000_000_000.min(actual_tao_lock_amount.max(1)); + let pool_initial_tao = POOL_INITIAL_TAO.min(actual_tao_lock_amount.max(1)); let actual_tao_lock_amount_less_pool_tao = actual_tao_lock_amount.saturating_sub(pool_initial_tao); diff --git a/pallets/subtensor/src/tests/coinbase.rs b/pallets/subtensor/src/tests/coinbase.rs index ff4908172..fb7a927be 100644 --- a/pallets/subtensor/src/tests/coinbase.rs +++ b/pallets/subtensor/src/tests/coinbase.rs @@ -389,3 +389,189 @@ fn test_total_issuance_after_coinbase() { ); }); } + +// Verifies that the total issuance after the coinbase is not changed when registration is disabled. +// Includes TAO weight. +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::coinbase::test_registration_disabled_total_issuance_same --exact --show-output --nocapture +#[test] +fn test_registration_disabled_total_issuance_same() { + new_test_ext(1).execute_with(|| { + let netuid: u16 = 1; + add_network(netuid, 1, 0); + // Set TAO weight to 18% + SubtensorModule::set_tao_weight(I96F32::from_num(0.18).saturating_to_num::()); + // Set owner cut to ~11.11% + SubtensorModule::set_subnet_owner_cut(u16::MAX / 9); + let total_coinbase_emission: I96F32 = I96F32::from_num(1_123_456_789); + let epsilon: u64 = 100; + + // Define hotkeys and coldkeys + let hotkey_a: U256 = U256::from(1); + let hotkey_b: U256 = U256::from(2); + let hotkey_c: U256 = U256::from(3); + let coldkey_a: U256 = U256::from(100); + let coldkey_b: U256 = U256::from(101); + let coldkey_c: U256 = U256::from(102); + + // Register neurons with decreasing stakes + register_ok_neuron(netuid, hotkey_a, coldkey_a, 0); + register_ok_neuron(netuid, hotkey_b, coldkey_b, 0); + register_ok_neuron(netuid, hotkey_c, coldkey_c, 0); + + // Add initial stakes + SubtensorModule::add_balance_to_coldkey_account(&coldkey_a, 1_000); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_b, 1_000); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_c, 1_000); + + // Swap to alpha + let total_tao: I96F32 = I96F32::from_num(300_000 + 100_000 + 50_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_b, + netuid, + (total_alpha * I96F32::from_num(100_000) / total_tao).saturating_to_num::(), + ); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &hotkey_c, + &coldkey_c, + netuid, + (total_alpha * I96F32::from_num(50_000) / total_tao).saturating_to_num::(), + ); + + // Stake some to root + let stake_to_root: u64 = 10_000_000; + SubtensorModule::add_balance_to_coldkey_account(&coldkey_a, stake_to_root); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &hotkey_a, + &coldkey_a, + netuid, + stake_to_root, + ); + + let alpha_price = SubtensorModule::get_alpha_price(netuid); + log::info!("alpha_price: {:?}", alpha_price); + + // Get the total issuance + let mut total_issuance_before = TotalIssuance::::get(); + log::info!("total_issuance_before: {:?}", total_issuance_before); + + // Disable registration on the network + SubtensorModule::set_network_registration_allowed(netuid, false); + SubtensorModule::set_network_pow_registration_allowed(netuid, false); + + // Run the coinbase + SubtensorModule::run_coinbase(total_coinbase_emission); + + // Should be the same + let total_issuance_after = TotalIssuance::::get(); + assert_abs_diff_eq!( + total_issuance_after, + total_issuance_before, + epsilon = epsilon + ); + }); +} + +// Verifies that the TAO-in after the coinbase is not changed when registration is disabled. +// Includes TAO weight. +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::coinbase::test_registration_disabled_tao_in_same --exact --show-output --nocapture +#[test] +fn test_registration_disabled_tao_in_same() { + new_test_ext(1).execute_with(|| { + let netuid: u16 = 1; + add_network(netuid, 1, 0); + // Set TAO weight to 18% + SubtensorModule::set_tao_weight(I96F32::from_num(0.18).saturating_to_num::()); + // Set owner cut to ~11.11% + SubtensorModule::set_subnet_owner_cut(u16::MAX / 9); + let total_coinbase_emission: I96F32 = I96F32::from_num(1_123_456_789); + let epsilon: u64 = 100; + + // Define hotkeys and coldkeys + let hotkey_a: U256 = U256::from(1); + let hotkey_b: U256 = U256::from(2); + let hotkey_c: U256 = U256::from(3); + let coldkey_a: U256 = U256::from(100); + let coldkey_b: U256 = U256::from(101); + let coldkey_c: U256 = U256::from(102); + + // Register neurons with decreasing stakes + register_ok_neuron(netuid, hotkey_a, coldkey_a, 0); + register_ok_neuron(netuid, hotkey_b, coldkey_b, 0); + register_ok_neuron(netuid, hotkey_c, coldkey_c, 0); + + // Add initial stakes + SubtensorModule::add_balance_to_coldkey_account(&coldkey_a, 1_000); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_b, 1_000); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_c, 1_000); + + // Swap to alpha + let total_tao: I96F32 = I96F32::from_num(300_000 + 100_000 + 50_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_b, + netuid, + (total_alpha * I96F32::from_num(100_000) / total_tao).saturating_to_num::(), + ); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &hotkey_c, + &coldkey_c, + netuid, + (total_alpha * I96F32::from_num(50_000) / total_tao).saturating_to_num::(), + ); + + // Stake some to root + let stake_to_root: u64 = 10_000_000; + SubtensorModule::add_balance_to_coldkey_account(&coldkey_a, stake_to_root); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &hotkey_a, + &coldkey_a, + netuid, + stake_to_root, + ); + + let alpha_price = SubtensorModule::get_alpha_price(netuid); + log::info!("alpha_price: {:?}", alpha_price); + + // Get the total issuance + let mut tao_in_before = SubnetTAO::::get(netuid); + log::info!("tao_in_before: {:?}", tao_in_before); + + // Disable registration on the network + SubtensorModule::set_network_registration_allowed(netuid, false); + SubtensorModule::set_network_pow_registration_allowed(netuid, false); + + // Run the coinbase + SubtensorModule::run_coinbase(total_coinbase_emission); + + // Should be the same + let tao_in_after = SubnetTAO::::get(netuid); + assert_abs_diff_eq!(tao_in_after, tao_in_before, epsilon = epsilon); + }); +} diff --git a/pallets/subtensor/src/tests/migration.rs b/pallets/subtensor/src/tests/migration.rs index 793908336..f321267fb 100644 --- a/pallets/subtensor/src/tests/migration.rs +++ b/pallets/subtensor/src/tests/migration.rs @@ -5,7 +5,7 @@ use crate::*; use codec::{Decode, Encode}; use frame_support::{ assert_ok, - storage::unhashed::{get_raw, put_raw}, + storage::unhashed::{get, get_raw, put, put_raw}, traits::{StorageInstance, StoredMap}, weights::Weight, StorageHasher, Twox64Concat, @@ -711,3 +711,42 @@ fn test_migrate_rao() { ); }); } + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::migration::test_migrate_subnet_volume --exact --show-output +#[test] +fn test_migrate_subnet_volume() { + new_test_ext(1).execute_with(|| { + // Setup initial state + let netuid_1: u16 = 1; + add_network(netuid_1, 1, 0); + + // SubnetValue for netuid 1 key + let old_key: [u8; 34] = hex_literal::hex!( + "658faa385070e074c85bf6b568cf05553c3226e141696000b4b239c65bc2b2b40100" + ); + + // Old value in u64 format + let old_value: u64 = 123_456_789_000_u64; + put::(&old_key, &old_value); // Store as u64 + + // Ensure it is stored as `u64` + assert_eq!(get::(&old_key), Some(old_value)); + + // Run migration + crate::migrations::migrate_subnet_volume::migrate_subnet_volume::(); + + // Verify the value is now stored as `u128` + let new_value: Option = get(&old_key); + let new_value_as_subnet_volume = SubnetVolume::::get(netuid_1); + assert_eq!(new_value, Some(old_value as u128)); + assert_eq!(new_value_as_subnet_volume, old_value as u128); + + // Ensure migration does not break when running twice + let weight_second_run = + crate::migrations::migrate_subnet_volume::migrate_subnet_volume::(); + + // Verify the value is still stored as `u128` + let new_value: Option = get(&old_key); + assert_eq!(new_value, Some(old_value as u128)); + }); +} diff --git a/pallets/subtensor/src/tests/move_stake.rs b/pallets/subtensor/src/tests/move_stake.rs index f299832ed..f0a35f91a 100644 --- a/pallets/subtensor/src/tests/move_stake.rs +++ b/pallets/subtensor/src/tests/move_stake.rs @@ -724,7 +724,7 @@ fn test_do_move_storage_updates() { // 18. test_do_move_max_values // Description: Test moving the maximum possible stake values to check for overflows -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test move -- test_do_move_max_values --exact --nocapture +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::move_stake::test_do_move_max_values --exact --show-output #[test] fn test_do_move_max_values() { new_test_ext(1).execute_with(|| { @@ -740,6 +740,11 @@ fn test_do_move_max_values() { // Set up initial stake with maximum value SubtensorModule::create_account_if_non_existent(&coldkey, &origin_hotkey); SubtensorModule::create_account_if_non_existent(&coldkey, &destination_hotkey); + + // Add lots of liquidity to bypass low liquidity check + SubnetTAO::::insert(netuid, u64::MAX / 1000); + SubnetAlphaIn::::insert(netuid, u64::MAX / 1000); + SubtensorModule::stake_into_subnet(&origin_hotkey, &coldkey, netuid, max_stake, fee); let alpha = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( &origin_hotkey, @@ -773,7 +778,7 @@ fn test_do_move_max_values() { netuid ), alpha, - epsilon = 5 + epsilon = alpha / 1_000_000 ); }); } @@ -1480,3 +1485,57 @@ fn test_do_swap_multiple_times() { assert_eq!(final_stake_netuid2, 0); }); } + +// cargo test --package pallet-subtensor --lib -- tests::move_stake::test_swap_stake_limit_validate --exact --show-output +#[test] +fn test_swap_stake_limit_validate() { + // Testing the signed extension validate function + // correctly filters the `add_stake` transaction. + + new_test_ext(0).execute_with(|| { + let subnet_owner_coldkey = U256::from(1001); + let subnet_owner_hotkey = U256::from(1002); + let origin_netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); + let destination_netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); + + let coldkey = U256::from(1); + let hotkey = U256::from(2); + let stake_amount = 100_000_000_000; + + SubtensorModule::create_account_if_non_existent(&coldkey, &hotkey); + let unstake_amount = + SubtensorModule::stake_into_subnet(&hotkey, &coldkey, origin_netuid, stake_amount, 0); + + // Setup limit price so that it doesn't allow much slippage at all + let limit_price = ((SubtensorModule::get_alpha_price(origin_netuid) + / SubtensorModule::get_alpha_price(destination_netuid)) + * I96F32::from_num(1_000_000_000)) + .to_num::() + - 1_u64; + + // Swap stake limit call + let call = RuntimeCall::SubtensorModule(SubtensorCall::swap_stake_limit { + hotkey, + origin_netuid, + destination_netuid, + alpha_amount: unstake_amount, + limit_price, + allow_partial: false, + }); + + let info: crate::DispatchInfo = + crate::DispatchInfoOf::<::RuntimeCall>::default(); + + let extension = crate::SubtensorSignedExtension::::new(); + // Submit to the signed extension validate function + let result_no_stake = extension.validate(&coldkey, &call.clone(), &info, 10); + + // Should fail due to slippage + assert_err!( + result_no_stake, + crate::TransactionValidityError::Invalid(crate::InvalidTransaction::Custom( + CustomTransactionError::SlippageTooHigh.into() + )) + ); + }); +} diff --git a/pallets/subtensor/src/tests/staking.rs b/pallets/subtensor/src/tests/staking.rs index 54413fdc0..5282c9941 100644 --- a/pallets/subtensor/src/tests/staking.rs +++ b/pallets/subtensor/src/tests/staking.rs @@ -10,6 +10,7 @@ use approx::assert_abs_diff_eq; use frame_support::dispatch::{DispatchClass, DispatchInfo, GetDispatchInfo, Pays}; use frame_support::sp_runtime::DispatchError; use sp_core::{Get, H256, U256}; +use substrate_fixed::types::{I96F32, U96F32}; /*********************************************************** staking::add_stake() tests @@ -144,7 +145,7 @@ fn test_add_stake_err_signature() { let netuid = 1; assert_err!( - SubtensorModule::add_stake(RawOrigin::None.into(), hotkey_account_id, netuid, amount,), + SubtensorModule::add_stake(RawOrigin::None.into(), hotkey_account_id, netuid, amount), DispatchError::BadOrigin ); }); @@ -556,6 +557,78 @@ fn test_remove_stake_total_balance_no_change() { }); } +#[test] +fn test_add_stake_insufficient_liquidity() { + 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 amount_staked = DefaultMinStake::::get() * 10 + DefaultStakingFee::::get(); + + let netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); + SubtensorModule::create_account_if_non_existent(&coldkey, &hotkey); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, amount_staked); + + // Set the liquidity at lowest possible value so that all staking requests fail + SubnetTAO::::insert( + netuid, + DefaultMinimumPoolLiquidity::::get().to_num::(), + ); + SubnetAlphaIn::::insert( + netuid, + DefaultMinimumPoolLiquidity::::get().to_num::(), + ); + + // Check the error + assert_noop!( + SubtensorModule::add_stake( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + amount_staked + ), + Error::::InsufficientLiquidity + ); + }); +} + +#[test] +fn test_remove_stake_insufficient_liquidity() { + 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 amount_staked = DefaultMinStake::::get() * 10 + DefaultStakingFee::::get(); + + let netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); + SubtensorModule::create_account_if_non_existent(&coldkey, &hotkey); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, amount_staked); + + // Simulate stake for hotkey + SubnetTAO::::insert(netuid, u64::MAX / 1000); + SubnetAlphaIn::::insert(netuid, u64::MAX / 1000); + let alpha = SubtensorModule::stake_into_subnet(&hotkey, &coldkey, netuid, amount_staked, 0); + + // Set the liquidity at lowest possible value so that all staking requests fail + SubnetTAO::::insert( + netuid, + DefaultMinimumPoolLiquidity::::get().to_num::(), + ); + SubnetAlphaIn::::insert( + netuid, + DefaultMinimumPoolLiquidity::::get().to_num::(), + ); + + // Check the error + assert_noop!( + SubtensorModule::remove_stake(RuntimeOrigin::signed(coldkey), hotkey, netuid, alpha), + Error::::InsufficientLiquidity + ); + }); +} + #[test] fn test_remove_stake_total_issuance_no_change() { // When we remove stake, the total issuance of the balances pallet should not change @@ -2132,3 +2205,1293 @@ fn test_stake_below_min_validate() { assert_ok!(result_min_stake); }); } + +// cargo test --package pallet-subtensor --lib -- tests::staking::test_add_stake_limit_validate --exact --show-output +#[test] +fn test_add_stake_limit_validate() { + // Testing the signed extension validate function + // correctly filters the `add_stake` transaction. + + new_test_ext(0).execute_with(|| { + let hotkey = U256::from(533453); + let coldkey = U256::from(55453); + let amount = 900_000_000_000; + + // add network + let netuid: u16 = add_dynamic_network(&hotkey, &coldkey); + + // Force-set alpha in and tao reserve to make price equal 1.5 + 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(netuid, tao_reserve.to_num::()); + SubnetAlphaIn::::insert(netuid, alpha_in.to_num::()); + let current_price: U96F32 = U96F32::from_num(SubtensorModule::get_alpha_price(netuid)); + assert_eq!(current_price, U96F32::from_num(1.5)); + + // Give it some $$$ in his coldkey balance + SubtensorModule::add_balance_to_coldkey_account(&coldkey, amount); + + // Setup limit price so that it doesn't peak above 4x of current price + // The amount that can be executed at this price is 450 TAO only + let limit_price = 6_000_000_000; + + // Add stake limit call + let call = RuntimeCall::SubtensorModule(SubtensorCall::add_stake_limit { + hotkey, + netuid, + amount_staked: amount, + limit_price, + allow_partial: false, + }); + + let info: crate::DispatchInfo = + crate::DispatchInfoOf::<::RuntimeCall>::default(); + + let extension = crate::SubtensorSignedExtension::::new(); + // Submit to the signed extension validate function + let result_no_stake = extension.validate(&coldkey, &call.clone(), &info, 10); + + // Should fail due to slippage + assert_err!( + result_no_stake, + crate::TransactionValidityError::Invalid(crate::InvalidTransaction::Custom( + CustomTransactionError::SlippageTooHigh.into() + )) + ); + }); +} + +// cargo test --package pallet-subtensor --lib -- tests::staking::test_remove_stake_limit_validate --exact --show-output +#[test] +fn test_remove_stake_limit_validate() { + // Testing the signed extension validate function + // correctly filters the `add_stake` transaction. + + new_test_ext(0).execute_with(|| { + let hotkey = U256::from(533453); + let coldkey = U256::from(55453); + let stake_amount = 300_000_000_000; + let unstake_amount = 150_000_000_000; + + // add network + let netuid: u16 = add_dynamic_network(&hotkey, &coldkey); + + // Give the neuron some stake to remove + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &hotkey, + &coldkey, + netuid, + stake_amount, + ); + + // Forse-set alpha in and tao reserve to make price equal 1.5 + 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(netuid, tao_reserve.to_num::()); + SubnetAlphaIn::::insert(netuid, alpha_in.to_num::()); + let current_price: U96F32 = U96F32::from_num(SubtensorModule::get_alpha_price(netuid)); + assert_eq!(current_price, U96F32::from_num(1.5)); + + // Setup limit price so that it doesn't drop by more than 10% from current price + let limit_price = 1_350_000_000; + + // Remove stake limit call + let call = RuntimeCall::SubtensorModule(SubtensorCall::remove_stake_limit { + hotkey, + netuid, + amount_unstaked: unstake_amount, + limit_price, + allow_partial: false, + }); + + let info: crate::DispatchInfo = + crate::DispatchInfoOf::<::RuntimeCall>::default(); + + let extension = crate::SubtensorSignedExtension::::new(); + // Submit to the signed extension validate function + let result_no_stake = extension.validate(&coldkey, &call.clone(), &info, 10); + + // Should fail due to slippage + assert_err!( + result_no_stake, + crate::TransactionValidityError::Invalid(crate::InvalidTransaction::Custom( + CustomTransactionError::SlippageTooHigh.into() + )) + ); + }); +} + +#[test] +fn test_stake_overflow() { + new_test_ext(1).execute_with(|| { + let subnet_owner_coldkey = U256::from(1001); + let subnet_owner_hotkey = U256::from(1002); + let coldkey_account_id = U256::from(435445); + let hotkey_account_id = U256::from(54544); + let netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); + let amount = 21_000_000_000_000_000; // Max TAO supply + let fee = DefaultStakingFee::::get(); + register_ok_neuron(netuid, hotkey_account_id, coldkey_account_id, 192213123); + + // Give it some $$$ in his coldkey balance + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount); + + // Setup liquidity with 21M TAO values + SubnetTAO::::insert(netuid, amount); + SubnetAlphaIn::::insert(netuid, amount); + + // Stake and check if the result is ok + assert_ok!(SubtensorModule::add_stake( + RuntimeOrigin::signed(coldkey_account_id), + hotkey_account_id, + netuid, + amount + )); + + // Check if stake has increased properly (staking 1:1 to SubnetTAO results in SubnetTAO/2 alpha) + assert_abs_diff_eq!( + SubtensorModule::get_stake_for_hotkey_on_subnet(&hotkey_account_id, netuid), + (amount - fee) / 2, + epsilon = amount / 1_000_000, + ); + + // Check if total stake has increased accordingly. + assert_abs_diff_eq!(SubtensorModule::get_total_stake(), amount, epsilon = 10); + }); +} + +#[test] +fn test_stake_low_liquidity_validate() { + // Testing the signed extension validate function + // correctly filters the `add_stake` transaction. + + new_test_ext(0).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 amount_staked = DefaultMinStake::::get() * 10 + DefaultStakingFee::::get(); + + let netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); + SubtensorModule::create_account_if_non_existent(&coldkey, &hotkey); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, amount_staked); + + // Set the liquidity at lowest possible value so that all staking requests fail + SubnetTAO::::insert( + netuid, + DefaultMinimumPoolLiquidity::::get().to_num::(), + ); + SubnetAlphaIn::::insert( + netuid, + DefaultMinimumPoolLiquidity::::get().to_num::(), + ); + + // Add stake call + let call = RuntimeCall::SubtensorModule(SubtensorCall::add_stake { + hotkey, + netuid, + amount_staked, + }); + + let info: crate::DispatchInfo = + crate::DispatchInfoOf::<::RuntimeCall>::default(); + + let extension = crate::SubtensorSignedExtension::::new(); + // Submit to the signed extension validate function + let result_no_stake = extension.validate(&coldkey, &call.clone(), &info, 10); + + // Should fail due to insufficient stake + assert_err!( + result_no_stake, + crate::TransactionValidityError::Invalid(crate::InvalidTransaction::Custom( + CustomTransactionError::InsufficientLiquidity.into() + )) + ); + }); +} + +#[test] +fn test_unstake_low_liquidity_validate() { + // Testing the signed extension validate function + // correctly filters the `add_stake` transaction. + + new_test_ext(0).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 amount_staked = DefaultMinStake::::get() * 10 + DefaultStakingFee::::get(); + + let netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); + SubtensorModule::create_account_if_non_existent(&coldkey, &hotkey); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, amount_staked); + + // Simulate stake for hotkey + SubnetTAO::::insert(netuid, u64::MAX / 1000); + SubnetAlphaIn::::insert(netuid, u64::MAX / 1000); + let alpha = SubtensorModule::stake_into_subnet(&hotkey, &coldkey, netuid, amount_staked, 0); + + // Set the liquidity at lowest possible value so that all staking requests fail + SubnetTAO::::insert( + netuid, + DefaultMinimumPoolLiquidity::::get().to_num::(), + ); + SubnetAlphaIn::::insert( + netuid, + DefaultMinimumPoolLiquidity::::get().to_num::(), + ); + + // Remove stake call + let call = RuntimeCall::SubtensorModule(SubtensorCall::remove_stake { + hotkey, + netuid, + amount_unstaked: alpha, + }); + + let info: crate::DispatchInfo = + crate::DispatchInfoOf::<::RuntimeCall>::default(); + + let extension = crate::SubtensorSignedExtension::::new(); + // Submit to the signed extension validate function + let result_no_stake = extension.validate(&coldkey, &call.clone(), &info, 10); + + // Should fail due to insufficient stake + assert_err!( + result_no_stake, + crate::TransactionValidityError::Invalid(crate::InvalidTransaction::Custom( + CustomTransactionError::InsufficientLiquidity.into() + )) + ); + }); +} + +#[test] +fn test_max_amount_add_root() { + new_test_ext(0).execute_with(|| { + // 0 price on root => max is 0 + assert_eq!(SubtensorModule::get_max_amount_add(0, 0), 0); + + // 0.999999... price on root => max is 0 + assert_eq!(SubtensorModule::get_max_amount_add(0, 999_999_999), 0); + + // 1.0 price on root => max is u64::MAX + assert_eq!( + SubtensorModule::get_max_amount_add(0, 1_000_000_000), + u64::MAX + ); + + // 1.000...001 price on root => max is u64::MAX + assert_eq!( + SubtensorModule::get_max_amount_add(0, 1_000_000_001), + u64::MAX + ); + + // 2.0 price on root => max is u64::MAX + assert_eq!( + SubtensorModule::get_max_amount_add(0, 2_000_000_000), + u64::MAX + ); + }); +} + +#[test] +fn test_max_amount_add_stable() { + new_test_ext(0).execute_with(|| { + let netuid: u16 = 1; + add_network(netuid, 1, 0); + + // 0 price => max is 0 + assert_eq!(SubtensorModule::get_max_amount_add(netuid, 0), 0); + + // 0.999999... price => max is 0 + assert_eq!(SubtensorModule::get_max_amount_add(netuid, 999_999_999), 0); + + // 1.0 price => max is u64::MAX + assert_eq!( + SubtensorModule::get_max_amount_add(netuid, 1_000_000_000), + u64::MAX + ); + + // 1.000...001 price => max is u64::MAX + assert_eq!( + SubtensorModule::get_max_amount_add(netuid, 1_000_000_001), + u64::MAX + ); + + // 2.0 price => max is u64::MAX + assert_eq!( + SubtensorModule::get_max_amount_add(netuid, 2_000_000_000), + u64::MAX + ); + }); +} + +// cargo test --package pallet-subtensor --lib -- tests::staking::test_max_amount_add_dynamic --exact --show-output +#[test] +fn test_max_amount_add_dynamic() { + new_test_ext(0).execute_with(|| { + let subnet_owner_coldkey = U256::from(1001); + let subnet_owner_hotkey = U256::from(1002); + let netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); + + // Test cases are generated with help with this limit-staking calculator: + // https://docs.google.com/spreadsheets/d/1pfU-PVycd3I4DbJIc0GjtPohy4CbhdV6CWqgiy__jKE + // This is for reference only; verify before use. + // + // CSV backup for this spreadhsheet: + // + // SubnetTAO,AlphaIn,initial price,limit price,max swappable + // 100,100,=A2/B2,4,=B8*D8-A8 + // + // tao_in, alpha_in, limit_price, expected_max_swappable + [ + // Zero handling (no panics) + (0, 1_000_000_000, 100, 0), + (1_000_000_000, 0, 100, 0), + (1_000_000_000, 1_000_000_000, 0, 0), + // Low bounds + (1, 1, 0, 0), + (1, 1, 1, 0), + (1, 1, 2, 0), + (1, 1, 50_000_000_000, 49), + // Basic math + (1_000, 1_000, 2_000_000_000, 1_000), + (1_000, 1_000, 4_000_000_000, 3_000), + (1_000, 1_000, 16_000_000_000, 15_000), + ( + 1_000_000_000_000, + 1_000_000_000_000, + 16_000_000_000, + 15_000_000_000_000, + ), + // Normal range values with edge cases + (150_000_000_000, 100_000_000_000, 0, 0), + (150_000_000_000, 100_000_000_000, 100_000_000, 0), + (150_000_000_000, 100_000_000_000, 500_000_000, 0), + (150_000_000_000, 100_000_000_000, 1_499_999_999, 0), + (150_000_000_000, 100_000_000_000, 1_500_000_000, 0), + (150_000_000_000, 100_000_000_000, 1_500_000_001, 100), + ( + 150_000_000_000, + 100_000_000_000, + 3_000_000_000, + 150_000_000_000, + ), + // Miscellaneous overflows and underflows + (150_000_000_000, 100_000_000_000, u64::MAX, u64::MAX), + (150_000_000_000, 100_000_000_000, u64::MAX / 2, u64::MAX), + (1_000_000, 1_000_000_000_000_000_000_u64, 1, 999_000_000), + (1_000_000, 1_000_000_000_000_000_000_u64, 2, 1_999_000_000), + ( + 1_000_000, + 1_000_000_000_000_000_000_u64, + 10_000, + 9_999_999_000_000, + ), + ( + 1_000_000, + 1_000_000_000_000_000_000_u64, + 100_000, + 99_999_999_000_000, + ), + ( + 1_000_000, + 1_000_000_000_000_000_000_u64, + 1_000_000, + 999_999_999_000_000, + ), + ( + 1_000_000, + 1_000_000_000_000_000_000_u64, + 1_000_000_000, + 999_999_999_999_000_000, + ), + ( + 21_000_000_000_000_000, + 10_000_000, + 4_200_000_000_000_000_000, + 21_000_000_000_000_000, + ), + ( + 21_000_000_000_000_000, + 1_000_000_000_000_000_000_u64, + u64::MAX, + u64::MAX, + ), + ( + 21_000_000_000_000_000, + 1_000_000_000_000_000_000_u64, + 42_000_000, + 21_000_000_000_000_000, + ), + ] + .iter() + .for_each(|&(tao_in, alpha_in, limit_price, expected_max_swappable)| { + // Forse-set alpha in and tao reserve to achieve relative price of subnets + SubnetTAO::::insert(netuid, tao_in); + SubnetAlphaIn::::insert(netuid, alpha_in); + + if alpha_in != 0 { + let expected_price = I96F32::from_num(tao_in) / I96F32::from_num(alpha_in); + assert_eq!(SubtensorModule::get_alpha_price(netuid), expected_price); + } + + assert_eq!( + SubtensorModule::get_max_amount_add(netuid, limit_price), + expected_max_swappable, + ); + }); + }); +} + +#[test] +fn test_max_amount_remove_root() { + new_test_ext(0).execute_with(|| { + // 0 price on root => max is u64::MAX + assert_eq!(SubtensorModule::get_max_amount_remove(0, 0), u64::MAX); + + // 0.5 price on root => max is u64::MAX + assert_eq!( + SubtensorModule::get_max_amount_remove(0, 500_000_000), + u64::MAX + ); + + // 0.999999... price on root => max is u64::MAX + assert_eq!( + SubtensorModule::get_max_amount_remove(0, 999_999_999), + u64::MAX + ); + + // 1.0 price on root => max is u64::MAX + assert_eq!( + SubtensorModule::get_max_amount_remove(0, 1_000_000_000), + u64::MAX + ); + + // 1.000...001 price on root => max is 0 + assert_eq!(SubtensorModule::get_max_amount_remove(0, 1_000_000_001), 0); + + // 2.0 price on root => max is 0 + assert_eq!(SubtensorModule::get_max_amount_remove(0, 2_000_000_000), 0); + }); +} + +#[test] +fn test_max_amount_remove_stable() { + new_test_ext(0).execute_with(|| { + let netuid: u16 = 1; + add_network(netuid, 1, 0); + + // 0 price => max is u64::MAX + assert_eq!(SubtensorModule::get_max_amount_remove(netuid, 0), u64::MAX); + + // 0.999999... price => max is u64::MAX + assert_eq!( + SubtensorModule::get_max_amount_remove(netuid, 999_999_999), + u64::MAX + ); + + // 1.0 price => max is u64::MAX + assert_eq!( + SubtensorModule::get_max_amount_remove(netuid, 1_000_000_000), + u64::MAX + ); + + // 1.000...001 price => max is 0 + assert_eq!( + SubtensorModule::get_max_amount_remove(netuid, 1_000_000_001), + 0 + ); + + // 2.0 price => max is 0 + assert_eq!( + SubtensorModule::get_max_amount_remove(netuid, 2_000_000_000), + 0 + ); + }); +} + +// cargo test --package pallet-subtensor --lib -- tests::staking::test_max_amount_remove_dynamic --exact --show-output +#[test] +fn test_max_amount_remove_dynamic() { + new_test_ext(0).execute_with(|| { + let subnet_owner_coldkey = U256::from(1001); + let subnet_owner_hotkey = U256::from(1002); + let netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); + + // Test cases are generated with help with this limit-staking calculator: + // https://docs.google.com/spreadsheets/d/1pfU-PVycd3I4DbJIc0GjtPohy4CbhdV6CWqgiy__jKE + // This is for reference only; verify before use. + // + // CSV backup for this spreadhsheet: + // + // SubnetTAO,AlphaIn,initial price,limit price,max swappable + // 100,100,=A2/B2,4,=A2/D2-B2 + // + // tao_in, alpha_in, limit_price, expected_max_swappable + [ + // Zero handling (no panics) + (0, 1_000_000_000, 100, 0), + (1_000_000_000, 0, 100, 0), + (1_000_000_000, 1_000_000_000, 0, u64::MAX), + // Low bounds + (1, 1, 0, u64::MAX), + (1, 1, 1, 999_999_999), + (1, 1, 2, 499_999_999), + (1, 1, 250_000_000, 3), + // Basic math + (1_000, 1_000, 250_000_000, 3_000), + (1_000, 1_000, 62_500_000, 15_000), + ( + 1_000_000_000_000, + 1_000_000_000_000, + 62_500_000, + 15_000_000_000_000, + ), + // Normal range values with edge cases + (200_000_000_000, 100_000_000_000, 0, u64::MAX), + ( + 200_000_000_000, + 100_000_000_000, + 1_000_000_000, + 100_000_000_000, + ), + ( + 200_000_000_000, + 100_000_000_000, + 500_000_000, + 300_000_000_000, + ), + (200_000_000_000, 100_000_000_000, 2_000_000_000, 0), + (200_000_000_000, 100_000_000_000, 2_000_000_001, 0), + (200_000_000_000, 100_000_000_000, 1_999_999_999, 50), + (200_000_000_000, 100_000_000_000, 1_999_999_990, 500), + // Miscellaneous overflows and underflows + (2_000_000_000_000, 100_000_000_000, u64::MAX, 0), + (200_000_000_000, 100_000_000_000, u64::MAX / 2, 0), + (1_000_000, 1_000_000_000_000_000_000_u64, 1, 0), + (1_000_000, 1_000_000_000_000_000_000_u64, 10, 0), + (1_000_000, 1_000_000_000_000_000_000_u64, 100, 0), + (1_000_000, 1_000_000_000_000_000_000_u64, 1_000, 0), + (1_000_000, 1_000_000_000_000_000_000_u64, u64::MAX, 0), + ( + 21_000_000_000_000_000, + 1_000_000, + 21_000_000_000_000_000, + 999_000_000, + ), + (21_000_000_000_000_000, 1_000_000, u64::MAX, 138_412), + ( + 21_000_000_000_000_000, + 1_000_000_000_000_000_000_u64, + u64::MAX, + 0, + ), + ( + 21_000_000_000_000_000, + 1_000_000_000_000_000_000_u64, + 20_000_000, + 50_000_000_000_000_000, + ), + ] + .iter() + .for_each(|&(tao_in, alpha_in, limit_price, expected_max_swappable)| { + // Forse-set alpha in and tao reserve to achieve relative price of subnets + SubnetTAO::::insert(netuid, tao_in); + SubnetAlphaIn::::insert(netuid, alpha_in); + + if alpha_in != 0 { + let expected_price = I96F32::from_num(tao_in) / I96F32::from_num(alpha_in); + assert_eq!(SubtensorModule::get_alpha_price(netuid), expected_price); + } + + assert_eq!( + SubtensorModule::get_max_amount_remove(netuid, limit_price), + expected_max_swappable, + ); + }); + }); +} + +// cargo test --package pallet-subtensor --lib -- tests::staking::test_max_amount_move_root_root --exact --show-output +#[test] +fn test_max_amount_move_root_root() { + new_test_ext(0).execute_with(|| { + // 0 price on (root, root) exchange => max is u64::MAX + assert_eq!(SubtensorModule::get_max_amount_move(0, 0, 0), u64::MAX); + + // 0.5 price on (root, root) => max is u64::MAX + assert_eq!( + SubtensorModule::get_max_amount_move(0, 0, 500_000_000), + u64::MAX + ); + + // 0.999999... price on (root, root) => max is u64::MAX + assert_eq!( + SubtensorModule::get_max_amount_move(0, 0, 999_999_999), + u64::MAX + ); + + // 1.0 price on (root, root) => max is u64::MAX + assert_eq!( + SubtensorModule::get_max_amount_move(0, 0, 1_000_000_000), + u64::MAX + ); + + // 1.000...001 price on (root, root) => max is 0 + assert_eq!(SubtensorModule::get_max_amount_move(0, 0, 1_000_000_001), 0); + + // 2.0 price on (root, root) => max is 0 + assert_eq!(SubtensorModule::get_max_amount_move(0, 0, 2_000_000_000), 0); + }); +} + +// cargo test --package pallet-subtensor --lib -- tests::staking::test_max_amount_move_root_stable --exact --show-output +#[test] +fn test_max_amount_move_root_stable() { + new_test_ext(0).execute_with(|| { + let netuid: u16 = 1; + add_network(netuid, 1, 0); + + // 0 price on (root, stable) exchange => max is u64::MAX + assert_eq!(SubtensorModule::get_max_amount_move(0, netuid, 0), u64::MAX); + + // 0.5 price on (root, stable) => max is u64::MAX + assert_eq!( + SubtensorModule::get_max_amount_move(0, netuid, 500_000_000), + u64::MAX + ); + + // 0.999999... price on (root, stable) => max is u64::MAX + assert_eq!( + SubtensorModule::get_max_amount_move(0, netuid, 999_999_999), + u64::MAX + ); + + // 1.0 price on (root, stable) => max is u64::MAX + assert_eq!( + SubtensorModule::get_max_amount_move(0, netuid, 1_000_000_000), + u64::MAX + ); + + // 1.000...001 price on (root, stable) => max is 0 + assert_eq!( + SubtensorModule::get_max_amount_move(0, netuid, 1_000_000_001), + 0 + ); + + // 2.0 price on (root, stable) => max is 0 + assert_eq!( + SubtensorModule::get_max_amount_move(0, netuid, 2_000_000_000), + 0 + ); + }); +} + +// cargo test --package pallet-subtensor --lib -- tests::staking::test_max_amount_move_stable_dynamic --exact --show-output +#[test] +fn test_max_amount_move_stable_dynamic() { + new_test_ext(0).execute_with(|| { + // Add stable subnet + let stable_netuid: u16 = 1; + add_network(stable_netuid, 1, 0); + + // Add dynamic subnet + let subnet_owner_coldkey = U256::from(1001); + let subnet_owner_hotkey = U256::from(1002); + let dynamic_netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); + + // Forse-set alpha in and tao reserve to make price equal 0.5 + let tao_reserve: U96F32 = U96F32::from_num(50_000_000_000_u64); + let alpha_in: U96F32 = U96F32::from_num(100_000_000_000_u64); + SubnetTAO::::insert(dynamic_netuid, tao_reserve.to_num::()); + SubnetAlphaIn::::insert(dynamic_netuid, alpha_in.to_num::()); + let current_price: U96F32 = + U96F32::from_num(SubtensorModule::get_alpha_price(dynamic_netuid)); + assert_eq!(current_price, U96F32::from_num(0.5)); + + // The tests below just mimic the add_stake_limit tests for reverted price + + // 0 price => max is u64::MAX + assert_eq!( + SubtensorModule::get_max_amount_move(stable_netuid, dynamic_netuid, 0), + u64::MAX + ); + + // 2.0 price => max is 0 + assert_eq!( + SubtensorModule::get_max_amount_move(stable_netuid, dynamic_netuid, 2_000_000_000), + 0 + ); + + // 3.0 price => max is 0 + assert_eq!( + SubtensorModule::get_max_amount_move(stable_netuid, dynamic_netuid, 3_000_000_000), + 0 + ); + + // 2x price => max is 1x TAO + assert_abs_diff_eq!( + SubtensorModule::get_max_amount_move(stable_netuid, dynamic_netuid, 1_000_000_000), + 50_000_000_000, + epsilon = 10_000, + ); + + // Precision test: + // 1.99999..9000 price => max > 0 + assert!( + SubtensorModule::get_max_amount_move(stable_netuid, dynamic_netuid, 1_999_999_000) > 0 + ); + + // Max price doesn't panic and returns something meaningful + assert_eq!( + SubtensorModule::get_max_amount_move(stable_netuid, dynamic_netuid, u64::MAX), + 0 + ); + assert_eq!( + SubtensorModule::get_max_amount_move(stable_netuid, dynamic_netuid, u64::MAX - 1), + 0 + ); + assert_eq!( + SubtensorModule::get_max_amount_move(stable_netuid, dynamic_netuid, u64::MAX / 2), + 0 + ); + }); +} + +// cargo test --package pallet-subtensor --lib -- tests::staking::test_max_amount_move_dynamic_stable --exact --show-output +#[test] +fn test_max_amount_move_dynamic_stable() { + new_test_ext(0).execute_with(|| { + // Add stable subnet + let stable_netuid: u16 = 1; + add_network(stable_netuid, 1, 0); + + // Add dynamic subnet + let subnet_owner_coldkey = U256::from(1001); + let subnet_owner_hotkey = U256::from(1002); + let dynamic_netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); + + // Forse-set alpha in and tao reserve to make price equal 1.5 + 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(dynamic_netuid, tao_reserve.to_num::()); + SubnetAlphaIn::::insert(dynamic_netuid, alpha_in.to_num::()); + let current_price: U96F32 = + U96F32::from_num(SubtensorModule::get_alpha_price(dynamic_netuid)); + assert_eq!(current_price, U96F32::from_num(1.5)); + + // The tests below just mimic the remove_stake_limit tests + + // 0 price => max is u64::MAX + assert_eq!( + SubtensorModule::get_max_amount_move(dynamic_netuid, stable_netuid, 0), + u64::MAX + ); + + // Low price values don't blow things up + assert!(SubtensorModule::get_max_amount_move(dynamic_netuid, stable_netuid, 1) > 0); + assert!(SubtensorModule::get_max_amount_move(dynamic_netuid, stable_netuid, 2) > 0); + assert!(SubtensorModule::get_max_amount_move(dynamic_netuid, stable_netuid, 3) > 0); + + // 1.5000...1 price => max is 0 + assert_eq!( + SubtensorModule::get_max_amount_move(dynamic_netuid, stable_netuid, 1_500_000_001), + 0 + ); + + // 1.5 price => max is 0 because of non-zero slippage + assert_abs_diff_eq!( + SubtensorModule::get_max_amount_move(dynamic_netuid, stable_netuid, 1_500_000_000), + 0, + epsilon = 10_000 + ); + + // 1/2 price => max is 1x Alpha + assert_abs_diff_eq!( + SubtensorModule::get_max_amount_move(dynamic_netuid, stable_netuid, 750_000_000), + 100_000_000_000, + epsilon = 10_000, + ); + + // Precision test: + // 1.499999.. price => max > 0 + assert!( + SubtensorModule::get_max_amount_move(dynamic_netuid, stable_netuid, 1_499_999_999) > 0 + ); + + // Max price doesn't panic and returns something meaningful + assert!( + SubtensorModule::get_max_amount_move(dynamic_netuid, stable_netuid, u64::MAX) + < 21_000_000_000_000_000 + ); + assert!( + SubtensorModule::get_max_amount_move(dynamic_netuid, stable_netuid, u64::MAX - 1) + < 21_000_000_000_000_000 + ); + assert!( + SubtensorModule::get_max_amount_move(dynamic_netuid, stable_netuid, u64::MAX / 2) + < 21_000_000_000_000_000 + ); + }); +} + +// cargo test --package pallet-subtensor --lib -- tests::staking::test_max_amount_move_dynamic_dynamic --exact --show-output +#[test] +fn test_max_amount_move_dynamic_dynamic() { + new_test_ext(0).execute_with(|| { + // Add two dynamic subnets + let subnet_owner_coldkey = U256::from(1001); + let subnet_owner_hotkey = U256::from(1002); + let origin_netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); + let destination_netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); + + // Test cases are generated with help with this limit-staking calculator: + // https://docs.google.com/spreadsheets/d/1pfU-PVycd3I4DbJIc0GjtPohy4CbhdV6CWqgiy__jKE + // This is for reference only; verify before use. + // + // CSV backup for this spreadhsheet: + // + // SubnetTAO 1,AlphaIn 1,SubnetTAO 2,AlphaIn 2,,initial price,limit price,max swappable + // 150,100,100,100,,=(A2/B2)/(C2/D2),0.1,=(D2*A2-B2*C2*G2)/(G2*(A2+C2)) + // + // tao_in_1, alpha_in_1, tao_in_2, alpha_in_2, limit_price, expected_max_swappable, precision + [ + // Zero handling (no panics) + (0, 1_000_000_000, 1_000_000_000, 1_000_000_000, 100, 0, 1), + (1_000_000_000, 0, 1_000_000_000, 1_000_000_000, 100, 0, 1), + (1_000_000_000, 1_000_000_000, 0, 1_000_000_000, 100, 0, 1), + (1_000_000_000, 1_000_000_000, 1_000_000_000, 0, 100, 0, 1), + // Low bounds + (1, 1, 1, 1, 0, u64::MAX, 1), + (1, 1, 1, 1, 1, 500_000_000, 1), + (1, 1, 1, 1, 2, 250_000_000, 1), + (1, 1, 1, 1, 3, 166_666_666, 1), + (1, 1, 1, 1, 4, 125_000_000, 1), + (1, 1, 1, 1, 1_000, 500_000, 1), + // Basic math + (1_000, 1_000, 1_000, 1_000, 500_000_000, 500, 1), + (1_000, 1_000, 1_000, 1_000, 100_000_000, 4_500, 1), + // Normal range values edge cases + ( + 150_000_000_000, + 100_000_000_000, + 100_000_000_000, + 100_000_000_000, + 100_000_000, + 560_000_000_000, + 1_000_000, + ), + ( + 150_000_000_000, + 100_000_000_000, + 100_000_000_000, + 100_000_000_000, + 500_000_000, + 80_000_000_000, + 1_000_000, + ), + ( + 150_000_000_000, + 100_000_000_000, + 100_000_000_000, + 100_000_000_000, + 750_000_000, + 40_000_000_000, + 1_000_000, + ), + ( + 150_000_000_000, + 100_000_000_000, + 100_000_000_000, + 100_000_000_000, + 1_000_000_000, + 20_000_000_000, + 1_000, + ), + ( + 150_000_000_000, + 100_000_000_000, + 100_000_000_000, + 100_000_000_000, + 1_250_000_000, + 8_000_000_000, + 1_000, + ), + ( + 150_000_000_000, + 100_000_000_000, + 100_000_000_000, + 100_000_000_000, + 1_499_999_999, + 27, + 1, + ), + ( + 150_000_000_000, + 100_000_000_000, + 100_000_000_000, + 100_000_000_000, + 1_500_000_000, + 0, + 1, + ), + ( + 150_000_000_000, + 100_000_000_000, + 100_000_000_000, + 100_000_000_000, + 1_500_000_001, + 0, + 1, + ), + ( + 150_000_000_000, + 100_000_000_000, + 100_000_000_000, + 100_000_000_000, + 1_500_001_000, + 0, + 1, + ), + ( + 150_000_000_000, + 100_000_000_000, + 100_000_000_000, + 100_000_000_000, + 2_000_000_000, + 0, + 1, + ), + ( + 150_000_000_000, + 100_000_000_000, + 100_000_000_000, + 100_000_000_000, + u64::MAX, + 0, + 1, + ), + ( + 100_000_000_000, + 200_000_000_000, + 300_000_000_000, + 400_000_000_000, + 500_000_000, + 50_000_000_000, + 1_000, + ), + // Miscellaneous overflows + ( + 1_000_000_000, + 1_000_000_000, + 1_000_000_000, + 1_000_000_000, + 1, + 499_999_999_500_000_000, + 100_000_000, + ), + ( + 1_000_000, + 1_000_000, + 21_000_000_000_000_000, + 1_000_000_000_000_000_000_u64, + 1, + 48_000_000_000_000_000, + 1_000_000_000_000_000, + ), + ( + 150_000_000_000, + 100_000_000_000, + 100_000_000_000, + 100_000_000_000, + u64::MAX, + 0, + 1, + ), + ( + 1_000_000, + 1_000_000, + 21_000_000_000_000_000, + 1_000_000_000_000_000_000_u64, + u64::MAX, + 0, + 1, + ), + ] + .iter() + .for_each( + |&( + tao_in_1, + alpha_in_1, + tao_in_2, + alpha_in_2, + limit_price, + expected_max_swappable, + precision, + )| { + // Forse-set alpha in and tao reserve to achieve relative price of subnets + SubnetTAO::::insert(origin_netuid, tao_in_1); + SubnetAlphaIn::::insert(origin_netuid, alpha_in_1); + SubnetTAO::::insert(destination_netuid, tao_in_2); + SubnetAlphaIn::::insert(destination_netuid, alpha_in_2); + + if (alpha_in_1 != 0) && (alpha_in_2 != 0) { + let origin_price = I96F32::from_num(tao_in_1) / I96F32::from_num(alpha_in_1); + let dest_price = I96F32::from_num(tao_in_2) / I96F32::from_num(alpha_in_2); + if dest_price != 0 { + let expected_price = origin_price / dest_price; + assert_eq!( + SubtensorModule::get_alpha_price(origin_netuid) + / SubtensorModule::get_alpha_price(destination_netuid), + expected_price + ); + } + } + + assert_abs_diff_eq!( + SubtensorModule::get_max_amount_move( + origin_netuid, + destination_netuid, + limit_price + ), + expected_max_swappable, + epsilon = precision + ); + }, + ); + }); +} + +#[test] +fn test_add_stake_limit_ok() { + new_test_ext(1).execute_with(|| { + let hotkey_account_id = U256::from(533453); + let coldkey_account_id = U256::from(55453); + let amount = 900_000_000_000; // over the maximum + let fee = DefaultStakingFee::::get(); + + // add network + let netuid: u16 = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); + + // Forse-set alpha in and tao reserve to make price equal 1.5 + 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(netuid, tao_reserve.to_num::()); + SubnetAlphaIn::::insert(netuid, alpha_in.to_num::()); + let current_price: U96F32 = U96F32::from_num(SubtensorModule::get_alpha_price(netuid)); + assert_eq!(current_price, U96F32::from_num(1.5)); + + // Give it some $$$ in his coldkey balance + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount); + + // Setup limit price so that it doesn't peak above 4x of current price + // The amount that can be executed at this price is 450 TAO only + // Alpha produced will be equal to 75 = 450*100/(450+150) + let limit_price = 6_000_000_000; + let expected_executed_stake = 75_000_000_000; + + // Add stake with slippage safety and check if the result is ok + assert_ok!(SubtensorModule::add_stake_limit( + RuntimeOrigin::signed(coldkey_account_id), + hotkey_account_id, + netuid, + amount, + limit_price, + true + )); + + // Check if stake has increased only by 75 Alpha + assert_abs_diff_eq!( + SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( + &hotkey_account_id, + &coldkey_account_id, + netuid + ), + expected_executed_stake - fee, + epsilon = expected_executed_stake / 1000, + ); + + // Check that 450 TAO balance still remains free on coldkey + assert_abs_diff_eq!( + SubtensorModule::get_coldkey_balance(&coldkey_account_id), + 450_000_000_000, + epsilon = 10_000 + ); + + // Check that price has updated to ~24 = (150+450) / (100 - 75) + let exp_price = U96F32::from_num(24.0); + let current_price: U96F32 = U96F32::from_num(SubtensorModule::get_alpha_price(netuid)); + assert!(exp_price.saturating_sub(current_price) < 0.0001); + assert!(current_price.saturating_sub(exp_price) < 0.0001); + }); +} + +#[test] +fn test_add_stake_limit_fill_or_kill() { + new_test_ext(1).execute_with(|| { + let hotkey_account_id = U256::from(533453); + let coldkey_account_id = U256::from(55453); + let amount = 900_000_000_000; // over the maximum + + // add network + let netuid: u16 = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); + + // Force-set alpha in and tao reserve to make price equal 1.5 + 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(netuid, tao_reserve.to_num::()); + SubnetAlphaIn::::insert(netuid, alpha_in.to_num::()); + let current_price: U96F32 = U96F32::from_num(SubtensorModule::get_alpha_price(netuid)); + assert_eq!(current_price, U96F32::from_num(1.5)); + + // Give it some $$$ in his coldkey balance + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount); + + // Setup limit price so that it doesn't peak above 4x of current price + // The amount that can be executed at this price is 450 TAO only + // Alpha produced will be equal to 25 = 100 - 450*100/(150+450) + let limit_price = 6_000_000_000; + + // Add stake with slippage safety and check if it fails + assert_noop!( + SubtensorModule::add_stake_limit( + RuntimeOrigin::signed(coldkey_account_id), + hotkey_account_id, + netuid, + amount, + limit_price, + false + ), + Error::::SlippageTooHigh + ); + + // Lower the amount and it should succeed now + let amount_ok = 450_000_000_000; // fits the maximum + assert_ok!(SubtensorModule::add_stake_limit( + RuntimeOrigin::signed(coldkey_account_id), + hotkey_account_id, + netuid, + amount_ok, + limit_price, + false + )); + }); +} + +#[test] +fn test_remove_stake_limit_ok() { + new_test_ext(1).execute_with(|| { + let hotkey_account_id = U256::from(533453); + let coldkey_account_id = U256::from(55453); + let stake_amount = 300_000_000_000; + let unstake_amount = 150_000_000_000; + let fee = DefaultStakingFee::::get(); + + // add network + let netuid: u16 = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); + + // Give the neuron some stake to remove + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &hotkey_account_id, + &coldkey_account_id, + netuid, + stake_amount, + ); + let alpha_before = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( + &hotkey_account_id, + &coldkey_account_id, + netuid, + ); + + // Forse-set alpha in and tao reserve to make price equal 1.5 + 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(netuid, tao_reserve.to_num::()); + SubnetAlphaIn::::insert(netuid, alpha_in.to_num::()); + let current_price: U96F32 = U96F32::from_num(SubtensorModule::get_alpha_price(netuid)); + assert_eq!(current_price, U96F32::from_num(1.5)); + + // Setup limit price so resulting average price doesn't drop by more than 10% from current price + let limit_price = 1_350_000_000; + + // Alpha unstaked = 150 / 1.35 - 100 ~ 11.1 + let expected_alpha_reduction = 11_111_111_111; + + // Remove stake with slippage safety + assert_ok!(SubtensorModule::remove_stake_limit( + RuntimeOrigin::signed(coldkey_account_id), + hotkey_account_id, + netuid, + unstake_amount, + limit_price, + true + )); + + // Check if stake has decreased only by + assert_abs_diff_eq!( + SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( + &hotkey_account_id, + &coldkey_account_id, + netuid + ), + alpha_before - expected_alpha_reduction - fee, + epsilon = expected_alpha_reduction / 1_000, + ); + }); +} + +#[test] +fn test_remove_stake_limit_fill_or_kill() { + new_test_ext(1).execute_with(|| { + let hotkey_account_id = U256::from(533453); + let coldkey_account_id = U256::from(55453); + let stake_amount = 300_000_000_000; + let unstake_amount = 150_000_000_000; + + // add network + let netuid: u16 = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); + + // Give the neuron some stake to remove + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &hotkey_account_id, + &coldkey_account_id, + netuid, + stake_amount, + ); + + // Forse-set alpha in and tao reserve to make price equal 1.5 + 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(netuid, tao_reserve.to_num::()); + SubnetAlphaIn::::insert(netuid, alpha_in.to_num::()); + let current_price: U96F32 = U96F32::from_num(SubtensorModule::get_alpha_price(netuid)); + assert_eq!(current_price, U96F32::from_num(1.5)); + + // Setup limit price so that it doesn't drop by more than 10% from current price + let limit_price = 1_350_000_000; + + // Remove stake with slippage safety - fails + assert_noop!( + SubtensorModule::remove_stake_limit( + RuntimeOrigin::signed(coldkey_account_id), + hotkey_account_id, + netuid, + unstake_amount, + limit_price, + false + ), + Error::::SlippageTooHigh + ); + + // Lower the amount: Should succeed + assert_ok!(SubtensorModule::remove_stake_limit( + RuntimeOrigin::signed(coldkey_account_id), + hotkey_account_id, + netuid, + unstake_amount / 100, + limit_price, + false + ),); + }); +} diff --git a/pallets/subtensor/src/tests/staking2.rs b/pallets/subtensor/src/tests/staking2.rs index bb71c8594..2abff8faf 100644 --- a/pallets/subtensor/src/tests/staking2.rs +++ b/pallets/subtensor/src/tests/staking2.rs @@ -15,7 +15,7 @@ fn test_stake_base_case() { // Initialize subnet with some existing TAO and Alpha let initial_subnet_tao = 10_000_000_000; // 10 TAO - let initial_subnet_alpha = 5_000_000; // 5 Alpha + let initial_subnet_alpha = 5_000_000_000; // 5 Alpha SubnetTAO::::insert(netuid, initial_subnet_tao); SubnetAlphaIn::::insert(netuid, initial_subnet_alpha); SubnetAlphaOut::::insert(netuid, initial_subnet_alpha); diff --git a/pallets/subtensor/src/utils/mod.rs b/pallets/subtensor/src/utils/mod.rs index a42c91119..909ad8959 100644 --- a/pallets/subtensor/src/utils/mod.rs +++ b/pallets/subtensor/src/utils/mod.rs @@ -2,4 +2,5 @@ use super::*; pub mod identity; pub mod misc; pub mod rate_limiting; +#[cfg(feature = "try-runtime")] pub mod try_state; diff --git a/pallets/subtensor/src/utils/try_state.rs b/pallets/subtensor/src/utils/try_state.rs index 385a21bdd..db7e4352e 100644 --- a/pallets/subtensor/src/utils/try_state.rs +++ b/pallets/subtensor/src/utils/try_state.rs @@ -1,59 +1,72 @@ +use frame_support::traits::fungible::Inspect; + use super::*; +use crate::subnets::subnet::POOL_INITIAL_TAO; impl Pallet { - /// Checks if the accounting invariants for [`TotalStake`], [`TotalSubnetLocked`], and [`TotalIssuance`] are correct. - /// - /// This function verifies that: - /// 1. The sum of all stakes matches the [`TotalStake`]. - /// 2. The [`TotalSubnetLocked`] is correctly calculated. - /// 3. The [`TotalIssuance`] equals the sum of currency issuance, total stake, and total subnet locked. - /// - /// # Returns - /// - /// Returns `Ok(())` if all invariants are correct, otherwise returns an error. - #[cfg(feature = "try-runtime")] - pub fn check_accounting_invariants() -> Result<(), sp_runtime::TryRuntimeError> { - use frame_support::traits::fungible::Inspect; - - // Calculate the total staked amount - let mut total_staked: u64 = 0; - for (_hotkey, _coldkey, stake) in Stake::::iter() { - total_staked = total_staked.saturating_add(stake); - } - - // Verify that the calculated total stake matches the stored TotalStake - ensure!( - total_staked == TotalStake::::get(), - "TotalStake does not match total staked", - ); - + /// Checks [`TotalIssuance`] equals the sum of currency issuance, total stake, and total subnet + /// locked. + pub(crate) fn check_total_issuance() -> Result<(), sp_runtime::TryRuntimeError> { // Get the total subnet locked amount - let total_subnet_locked: u64 = Self::get_total_subnet_locked(); + let total_subnet_locked = Self::get_total_subnet_locked(); // Get the total currency issuance - let currency_issuance: u64 = T::Currency::total_issuance(); + let currency_issuance = T::Currency::total_issuance(); // Calculate the expected total issuance - let expected_total_issuance: u64 = currency_issuance - .saturating_add(total_staked) + let expected_total_issuance = currency_issuance + .saturating_add(TotalStake::::get()) .saturating_add(total_subnet_locked); // Verify the diff between calculated TI and actual TI is less than delta // // These values can be off slightly due to float rounding errors. // They are corrected every runtime upgrade. - const DELTA: u64 = 1000; - let diff = if TotalIssuance::::get() > expected_total_issuance { - TotalIssuance::::get().checked_sub(expected_total_issuance) + let delta = 1000; + let total_issuance = TotalIssuance::::get(); + + let diff = if total_issuance > expected_total_issuance { + total_issuance.checked_sub(expected_total_issuance) } else { - expected_total_issuance.checked_sub(TotalIssuance::::get()) + expected_total_issuance.checked_sub(total_issuance) } .expect("LHS > RHS"); + ensure!( - diff <= DELTA, + diff <= delta, "TotalIssuance diff greater than allowable delta", ); Ok(()) } + + /// Checks the sum of all stakes matches the [`TotalStake`]. + #[allow(dead_code)] + pub(crate) fn check_total_stake() -> Result<(), sp_runtime::TryRuntimeError> { + // Calculate the total staked amount + let total_staked = SubnetTAO::::iter().fold(0u64, |acc, (netuid, stake)| { + let acc = acc.saturating_add(stake); + + if netuid == Self::get_root_netuid() { + // root network doesn't have initial pool TAO + acc + } else { + acc.saturating_sub(POOL_INITIAL_TAO) + } + }); + + log::warn!( + "total_staked: {}, TotalStake: {}", + total_staked, + TotalStake::::get() + ); + + // Verify that the calculated total stake matches the stored TotalStake + ensure!( + total_staked == TotalStake::::get(), + "TotalStake does not match total staked", + ); + + Ok(()) + } } diff --git a/primitives/safe-math/src/lib.rs b/primitives/safe-math/src/lib.rs index 83c27b07c..e73aeb003 100644 --- a/primitives/safe-math/src/lib.rs +++ b/primitives/safe-math/src/lib.rs @@ -1,7 +1,12 @@ #![cfg_attr(not(feature = "std"), no_std)] #![allow(clippy::result_unit_err)] +#![cfg_attr(test, allow(clippy::arithmetic_side_effects))] +#![cfg_attr(test, allow(clippy::unwrap_used))] -use substrate_fixed::types::{I110F18, I32F32, I64F64, I96F32, U64F64}; +use substrate_fixed::{ + traits::Fixed, + types::{I110F18, I32F32, I64F64, I96F32, U110F18, U64F64, U96F32}, +}; /// Safe division trait pub trait SafeDiv { @@ -45,27 +50,131 @@ macro_rules! impl_safe_div_for_fixed { )* }; } -impl_safe_div_for_fixed!(I96F32, I32F32, I64F64, I110F18, U64F64); - -// /// Trait for safe conversion to primitive type P -// pub trait SafeToNum { -// /// Safe conversion to primitive type P -// fn safe_to_num

(self) -> P -// where -// P: num_traits::Bounded + substrate_fixed::prelude::ToFixed + substrate_fixed::prelude::FromFixed; -// } - -// impl SafeToNum for T -// where -// T: substrate_fixed::traits::Fixed, -// { -// fn safe_to_num

(self) -> P -// where -// P: num_traits::Bounded + substrate_fixed::prelude::ToFixed + substrate_fixed::prelude::FromFixed -// { -// match self.try_into() { -// Ok(value) => value, -// Err(_) => P::max_value(), -// } -// } -// } +impl_safe_div_for_fixed!(I96F32, I32F32, I64F64, I110F18, U110F18, U64F64, U96F32); + +fn abs_diff(a: T, b: T) -> T { + if a < b { + b.saturating_sub(a) + } else { + a.saturating_sub(b) + } +} + +/// Safe sqrt with good precision +pub fn checked_sqrt(value: T, epsilon: T) -> Option { + let zero: T = T::saturating_from_num(0); + let two: T = T::saturating_from_num(2); + + if value < zero { + return None; + } + + let mut high: T = value; + let mut low: T = zero; + let mut middle: T = high.saturating_add(low).safe_div(two); + + let mut iteration: i32 = 0; + let max_iterations = 128; + let mut check_val: T = value.safe_div(middle); + + // Iterative approximation using bisection + while abs_diff(check_val, middle) > epsilon { + if check_val < middle { + high = middle; + } else { + low = middle; + } + + middle = high.saturating_add(low).safe_div(two); + check_val = value.safe_div(middle); + + iteration = iteration.saturating_add(1); + if iteration > max_iterations { + break; + } + } + + Some(middle) +} + +#[cfg(test)] +mod tests { + use super::*; + use substrate_fixed::types::U110F18; // Assuming U110F18 is properly imported + + // Helper function for absolute difference + fn abs_diff(a: U110F18, b: U110F18) -> U110F18 { + if a > b { + a - b + } else { + b - a + } + } + + #[test] + fn test_checked_sqrt_positive_values() { + let value: U110F18 = U110F18::from_num(4.0); + let epsilon: U110F18 = U110F18::from_num(0.0001); + + let result: Option = checked_sqrt(value, epsilon); + assert!(result.is_some()); + let sqrt_result: U110F18 = result.unwrap(); + let precise_sqrt: U110F18 = U110F18::from_num(4.0_f64.sqrt()); + assert!(abs_diff(sqrt_result, precise_sqrt) <= epsilon); + } + + #[test] + fn test_checked_sqrt_large_value() { + let value: U110F18 = U110F18::from_num(1_000_000_000_000_000_000.0); + let epsilon: U110F18 = U110F18::from_num(0.0001); + + let result: Option = checked_sqrt(value, epsilon); + assert!(result.is_some()); + let sqrt_result: U110F18 = result.unwrap(); + let precise_sqrt: U110F18 = U110F18::from_num(1_000_000_000_000_000_000.0_f64.sqrt()); + assert!(abs_diff(sqrt_result, precise_sqrt) <= epsilon); + } + + #[test] + fn test_checked_sqrt_21m_tao_value() { + let value: U110F18 = U110F18::from_num(441_000_000_000_000_000_000_000_000_000_000.0); + let epsilon: U110F18 = U110F18::from_num(1000); + + let result: Option = checked_sqrt(value, epsilon); + assert!(result.is_some()); + let sqrt_result: U110F18 = result.unwrap(); + let precise_sqrt: U110F18 = + U110F18::from_num(441_000_000_000_000_000_000_000_000_000_000.0_f64.sqrt()); + assert!(abs_diff(sqrt_result, precise_sqrt) <= epsilon); + } + + #[test] + fn test_checked_sqrt_zero() { + let value: U110F18 = U110F18::from_num(0.0); + let epsilon: U110F18 = U110F18::from_num(0.0001); + + let result: Option = checked_sqrt(value, epsilon); + assert!(result.is_some()); + assert_eq!(result.unwrap(), U110F18::from_num(0.0)); + } + + #[test] + fn test_checked_sqrt_precision() { + let value: U110F18 = U110F18::from_num(2.0); + let epsilon: U110F18 = U110F18::from_num(0.0001); + + let result: Option = checked_sqrt(value, epsilon); + assert!(result.is_some()); + let sqrt_result: U110F18 = result.unwrap(); + let precise_sqrt: U110F18 = U110F18::from_num(2.0_f64.sqrt()); + assert!(abs_diff(sqrt_result, precise_sqrt) <= epsilon); + } + + #[test] + fn test_checked_sqrt_max_iterations() { + let value: U110F18 = U110F18::from_num(2.0); + let epsilon: U110F18 = U110F18::from_num(1e-30); // Very high precision + let result: Option = checked_sqrt(value, epsilon); + assert!(result.is_some()); // Check that it doesn't break, but may not be highly accurate + } +} diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index 0d44e0907..2e6eda522 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -20,7 +20,9 @@ name = "spec_version" path = "src/spec_version.rs" [dependencies] -ed25519-dalek = { workspace = true, default-features = false, features = ["alloc"] } +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 } smallvec = { workspace = true } @@ -98,11 +100,9 @@ pallet-commitments = { default-features = false, path = "../pallets/commitments" fp-evm = { workspace = true } fp-rpc = { workspace = true } fp-self-contained = { workspace = true } -precompile-utils = { workspace = true } # Frontier FRAME pallet-base-fee = { workspace = true } -pallet-dynamic-fee = { workspace = true } pallet-ethereum = { workspace = true } pallet-evm = { workspace = true } pallet-evm-chain-id = { workspace = true } @@ -133,9 +133,7 @@ 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"] std = [ "frame-try-runtime?/std", "frame-system-benchmarking?/std", @@ -192,10 +190,8 @@ std = [ "fp-evm/std", "fp-rpc/std", "fp-self-contained/std", - "precompile-utils/std", # Frontier FRAME "pallet-base-fee/std", - "pallet-dynamic-fee/std", "pallet-ethereum/std", "pallet-evm/std", "pallet-evm-chain-id/std", @@ -211,7 +207,7 @@ std = [ "hex/std", "rand_chacha/std", "sha2/std", - "w3f-bls/std" + "w3f-bls/std", ] runtime-benchmarks = [ "frame-benchmarking/runtime-benchmarks", @@ -240,7 +236,7 @@ runtime-benchmarks = [ "pallet-ethereum/runtime-benchmarks", "pallet-evm/runtime-benchmarks", "pallet-hotfix-sufficients/runtime-benchmarks", - "pallet-drand/runtime-benchmarks" + "pallet-drand/runtime-benchmarks", ] try-runtime = [ "frame-try-runtime/try-runtime", @@ -272,10 +268,9 @@ try-runtime = [ # EVM + Frontier "fp-self-contained/try-runtime", "pallet-base-fee/try-runtime", - "pallet-dynamic-fee/try-runtime", "pallet-ethereum/try-runtime", "pallet-evm/try-runtime", "pallet-evm-chain-id/try-runtime", - "pallet-drand/try-runtime" + "pallet-drand/try-runtime", ] metadata-hash = ["substrate-wasm-builder/metadata-hash"] diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 372c9a981..63a03c1ad 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -220,7 +220,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // `spec_version`, and `authoring_version` are the same between Wasm and native. // This value is set to 100 to notify Polkadot-JS App (https://polkadot.js.org/apps) to use // the compatible custom types. - spec_version: 224, + spec_version: 225, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1, @@ -1289,10 +1289,6 @@ parameter_types! { pub BoundDivision: U256 = U256::from(1024); } -impl pallet_dynamic_fee::Config for Runtime { - type MinGasPriceBoundDivisor = BoundDivision; -} - parameter_types! { pub DefaultBaseFeePerGas: U256 = U256::from(20_000_000_000_u128); pub DefaultElasticity: Permill = Permill::from_parts(125_000); @@ -1427,7 +1423,7 @@ construct_runtime!( Ethereum: pallet_ethereum = 21, EVM: pallet_evm = 22, EVMChainId: pallet_evm_chain_id = 23, - DynamicFee: pallet_dynamic_fee = 24, + // pallet_dynamic_fee was 24 BaseFee: pallet_base_fee = 25, Drand: pallet_drand = 26, @@ -2157,6 +2153,11 @@ impl_runtime_apis! { let result = SubtensorModule::get_stake_info_for_coldkeys( coldkey_account_vecs ); result.encode() } + + fn get_stake_info_for_hotkey_coldkey_netuid( hotkey_account_vec: Vec, coldkey_account_vec: Vec, netuid: u16 ) -> Vec { + let result = SubtensorModule::get_stake_info_for_hotkey_coldkey_netuid( hotkey_account_vec, coldkey_account_vec, netuid ); + result.encode() + } } impl subtensor_custom_rpc_runtime_api::SubnetRegistrationRuntimeApi for Runtime { diff --git a/runtime/src/precompiles/balance_transfer.rs b/runtime/src/precompiles/balance_transfer.rs index 03c4be8a6..6154cf8a5 100644 --- a/runtime/src/precompiles/balance_transfer.rs +++ b/runtime/src/precompiles/balance_transfer.rs @@ -1,19 +1,15 @@ -use frame_system::RawOrigin; use pallet_evm::{ - BalanceConverter, ExitError, ExitSucceed, PrecompileFailure, PrecompileHandle, - PrecompileOutput, PrecompileResult, + BalanceConverter, ExitError, ExitSucceed, PrecompileHandle, PrecompileOutput, PrecompileResult, }; -use precompile_utils::prelude::RuntimeHelper; -use sp_core::U256; use sp_runtime::traits::UniqueSaturatedInto; use sp_std::vec; -use crate::precompiles::{bytes_to_account_id, get_method_id, get_slice}; -use crate::{Runtime, RuntimeCall}; +use crate::precompiles::{ + contract_to_origin, get_method_id, get_pubkey, get_slice, try_dispatch_runtime_call, +}; +use crate::Runtime; pub const BALANCE_TRANSFER_INDEX: u64 = 2048; - -// This is a hardcoded hashed address mapping of 0x0000000000000000000000000000000000000800 to an // ss58 public key i.e., the contract sends funds it received to the destination address from the // method parameter. const CONTRACT_ADDRESS_SS58: [u8; 32] = [ @@ -37,7 +33,7 @@ impl BalanceTransferPrecompile { } // Forward all received value to the destination address - let amount: U256 = handle.context().apparent_value; + let amount = handle.context().apparent_value; // Use BalanceConverter to convert EVM amount to Substrate balance let amount_sub = @@ -52,26 +48,13 @@ impl BalanceTransferPrecompile { } let address_bytes_dst = get_slice(txdata, 4, 36)?; - let account_id_src = bytes_to_account_id(&CONTRACT_ADDRESS_SS58)?; - let account_id_dst = bytes_to_account_id(address_bytes_dst)?; + let (account_id_dst, _) = get_pubkey(address_bytes_dst)?; - let call = RuntimeCall::Balances(pallet_balances::Call::::transfer_allow_death { + let call = pallet_balances::Call::::transfer_allow_death { dest: account_id_dst.into(), value: amount_sub.unique_saturated_into(), - }); + }; - // Dispatch the call - RuntimeHelper::::try_dispatch( - handle, - RawOrigin::Signed(account_id_src).into(), - call, - ) - .map(|_| PrecompileOutput { - exit_status: ExitSucceed::Returned, - output: vec![], - }) - .map_err(|_| PrecompileFailure::Error { - exit_status: ExitError::OutOfFund, - }) + try_dispatch_runtime_call(handle, call, contract_to_origin(&CONTRACT_ADDRESS_SS58)?) } } diff --git a/runtime/src/precompiles/mod.rs b/runtime/src/precompiles/mod.rs index e13516e95..3857affb7 100644 --- a/runtime/src/precompiles/mod.rs +++ b/runtime/src/precompiles/mod.rs @@ -1,28 +1,39 @@ +extern crate alloc; + +use alloc::format; use core::marker::PhantomData; -use sp_core::{hashing::keccak_256, H160}; -use sp_runtime::AccountId32; + +use crate::{Runtime, RuntimeCall}; use pallet_evm::{ - ExitError, IsPrecompileResult, Precompile, PrecompileFailure, PrecompileHandle, - PrecompileResult, PrecompileSet, + ExitError, ExitSucceed, GasWeightMapping, IsPrecompileResult, Precompile, PrecompileFailure, + PrecompileHandle, PrecompileOutput, 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 frame_support::dispatch::{GetDispatchInfo, Pays}; +use frame_system::RawOrigin; +use sp_core::{hashing::keccak_256, H160}; +use sp_runtime::{traits::Dispatchable, AccountId32}; +use sp_std::vec; + // 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, @@ -39,7 +50,7 @@ where pub fn new() -> Self { Self(Default::default()) } - pub fn used_addresses() -> [H160; 11] { + pub fn used_addresses() -> [H160; 13] { [ hash(1), hash(2), @@ -51,7 +62,9 @@ where hash(EDVERIFY_PRECOMPILE_INDEX), hash(BALANCE_TRANSFER_INDEX), hash(STAKING_PRECOMPILE_INDEX), + hash(SUBNET_PRECOMPILE_INDEX), hash(METAGRAPH_PRECOMPILE_INDEX), + hash(NEURON_PRECOMPILE_INDEX), ] } } @@ -76,9 +89,11 @@ where Some(BalanceTransferPrecompile::execute(handle)) } a if a == hash(STAKING_PRECOMPILE_INDEX) => Some(StakingPrecompile::execute(handle)), + a if a == hash(SUBNET_PRECOMPILE_INDEX) => Some(SubnetPrecompile::execute(handle)), a if a == hash(METAGRAPH_PRECOMPILE_INDEX) => { Some(MetagraphPrecompile::execute(handle)) } + a if a == hash(NEURON_PRECOMPILE_INDEX) => Some(NeuronPrecompile::execute(handle)), _ => None, } @@ -106,18 +121,6 @@ pub fn get_method_id(method_signature: &str) -> [u8; 4] { [hash[0], hash[1], hash[2], hash[3]] } -/// Convert bytes to AccountId32 with PrecompileFailure as Error -/// which consumes all gas -/// -pub fn bytes_to_account_id(account_id_bytes: &[u8]) -> Result { - AccountId32::try_from(account_id_bytes).map_err(|_| { - log::info!("Error parsing account id bytes {:?}", account_id_bytes); - PrecompileFailure::Error { - exit_status: ExitError::InvalidRange, - } - }) -} - /// Takes a slice from bytes with PrecompileFailure as Error /// pub fn get_slice(data: &[u8], from: usize, to: usize) -> Result<&[u8], PrecompileFailure> { @@ -125,8 +128,111 @@ pub fn get_slice(data: &[u8], from: usize, to: usize) -> Result<&[u8], Precompil 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, }) } } + +pub fn get_pubkey(data: &[u8]) -> Result<(AccountId32, vec::Vec), PrecompileFailure> { + let mut pubkey = [0u8; 32]; + pubkey.copy_from_slice(get_slice(data, 0, 32)?); + + Ok(( + pubkey.into(), + data.get(4..) + .map_or_else(vec::Vec::new, |slice| slice.to_vec()), + )) +} + +fn parse_netuid(data: &[u8], offset: usize) -> Result { + if data.len() < offset + 2 { + return Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }); + } + + let mut netuid_bytes = [0u8; 2]; + netuid_bytes.copy_from_slice(get_slice(data, offset, offset + 2)?); + let netuid: u16 = netuid_bytes[1] as u16 | ((netuid_bytes[0] as u16) << 8u16); + + Ok(netuid) +} + +fn contract_to_origin(contract: &[u8; 32]) -> Result, PrecompileFailure> { + let (account_id, _) = get_pubkey(contract)?; + Ok(RawOrigin::Signed(account_id)) +} + +/// Dispatches a runtime call, but also checks and records the gas costs. +fn try_dispatch_runtime_call( + handle: &mut impl PrecompileHandle, + call: impl Into, + origin: RawOrigin, +) -> PrecompileResult { + let call = Into::::into(call); + let info = call.get_dispatch_info(); + + let target_gas = handle.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, + }); + } + } + + handle.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); + handle.record_cost(cost)?; + + handle.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(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: Default::default(), + }) + } + 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(), + ), + }) + } + } +} diff --git a/runtime/src/precompiles/neuron.rs b/runtime/src/precompiles/neuron.rs new file mode 100644 index 000000000..317f99242 --- /dev/null +++ b/runtime/src/precompiles/neuron.rs @@ -0,0 +1,415 @@ +use pallet_evm::{ + AddressMapping, ExitError, HashedAddressMapping, PrecompileFailure, PrecompileHandle, + PrecompileResult, +}; + +use crate::precompiles::{ + get_method_id, get_pubkey, get_slice, parse_netuid, try_dispatch_runtime_call, +}; +use crate::{Runtime, RuntimeCall}; +use frame_system::RawOrigin; +use sp_core::H256; +use sp_runtime::traits::BlakeTwo256; +use sp_runtime::AccountId32; +use sp_std::vec; +use sp_std::vec::Vec; + +pub const NEURON_PRECOMPILE_INDEX: u64 = 2052; +// max paramter lenght 4K +pub const MAX_PARAMETER_SIZE: usize = 4 * 1024; +// ss58 public key i.e., the contract sends funds it received to the destination address from the +// method parameter. +#[allow(dead_code)] +const CONTRACT_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, +]; +pub struct NeuronPrecompile; + +impl NeuronPrecompile { + pub fn execute(handle: &mut impl PrecompileHandle) -> PrecompileResult { + let txdata = handle.input(); + let method_id = get_slice(txdata, 0, 4)?; + let method_input = txdata + .get(4..) + .map_or_else(vec::Vec::new, |slice| slice.to_vec()); // Avoiding borrowing conflicts + + if method_input.len() > MAX_PARAMETER_SIZE { + log::error!( + "method parameter data length as {} is too long", + method_input.len() + ); + return Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }); + } + + match method_id { + id if id == get_method_id("setWeights(uint16,uint16[],uint16[],uint64)") => { + Self::set_weights(handle, &method_input) + } + id if id == get_method_id("commitWeights(uint16,uint256)") => { + Self::commit_weights(handle, &method_input) + } + id if id + == get_method_id("revealWeights(uint16,uint16[],uint16[],uint16[],uint64)") => + { + Self::reveal_weights(handle, &method_input) + } + + id if id == get_method_id("burnedRegister(uint16,bytes32)") => { + Self::burned_register(handle, &method_input) + } + + _ => Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }), + } + } + + pub fn set_weights(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { + let (netuid, dests, weights, version_key) = Self::parse_netuid_dests_weights(data)?; + let call = RuntimeCall::SubtensorModule(pallet_subtensor::Call::::set_weights { + netuid, + dests, + weights, + version_key, + }); + let account_id = + as AddressMapping>::into_account_id( + handle.context().caller, + ); + + try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id)) + } + + pub fn commit_weights(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { + let (netuid, commit_hash) = Self::parse_netuid_commit_hash(data)?; + + let call = + RuntimeCall::SubtensorModule(pallet_subtensor::Call::::commit_weights { + netuid, + commit_hash, + }); + let account_id = + as AddressMapping>::into_account_id( + handle.context().caller, + ); + try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id)) + } + + pub fn reveal_weights(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { + let (netuid, uids, values, salt, version_key) = + Self::parse_netuid_dests_weights_salt(data)?; + let call = + RuntimeCall::SubtensorModule(pallet_subtensor::Call::::reveal_weights { + netuid, + uids, + values, + salt, + version_key, + }); + let account_id = + as AddressMapping>::into_account_id( + handle.context().caller, + ); + try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id)) + } + + pub fn burned_register(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { + let (netuid, hotkey) = Self::parse_netuid_hotkey_parameter(data)?; + let call = + RuntimeCall::SubtensorModule(pallet_subtensor::Call::::burned_register { + netuid, + hotkey, + }); + + let account_id = + as AddressMapping>::into_account_id( + handle.context().caller, + ); + try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id)) + } + + fn parse_netuid_hotkey_parameter(data: &[u8]) -> Result<(u16, AccountId32), PrecompileFailure> { + if data.len() < 64 { + return Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }); + } + + let netuid = parse_netuid(data, 30)?; + + let (hotkey, _) = get_pubkey(get_slice(data, 32, 64)?)?; + + Ok((netuid, hotkey)) + } + + fn parse_netuid_dests_weights( + data: &[u8], + ) -> Result<(u16, Vec, Vec, u64), PrecompileFailure> { + let data_len = data.len(); + if data_len < 4 * 32 { + return Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }); + } + let mut netuid_vec = [0u8; 2]; + netuid_vec.copy_from_slice(get_slice(data, 30, 32)?); + let netuid = u16::from_be_bytes(netuid_vec); + + // get the neuron amount in sebnet + let subnet_size = pallet_subtensor::Pallet::::get_subnetwork_n(netuid) as usize; + + let mut first_position_vec = [0u8; 2]; + first_position_vec.copy_from_slice(get_slice(data, 62, 64)?); + let first_position = u16::from_be_bytes(first_position_vec) as usize; + + if first_position > data_len { + log::error!("position for uids data as {} is too large", first_position); + return Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }); + } + + let mut second_position_vec = [0u8; 2]; + second_position_vec.copy_from_slice(get_slice(data, 94, 96)?); + let second_position = u16::from_be_bytes(second_position_vec) as usize; + + if second_position > data_len { + log::error!("position for uids data as {} is too large", first_position); + return Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }); + } + + let mut version_key_vec = [0u8; 8]; + version_key_vec.copy_from_slice(get_slice(data, 120, 128)?); + let version_key = u64::from_be_bytes(version_key_vec); + + let mut dests = vec![]; + let mut weights = vec![]; + + let mut dests_len_vec = [0u8; 2]; + dests_len_vec.copy_from_slice(get_slice(data, first_position + 30, first_position + 32)?); + let dests_len = u16::from_be_bytes(dests_len_vec) as usize; + + if dests_len > subnet_size { + log::error!( + "uids len as {} in set weight is more than neurons {} in subnet {}", + dests_len, + subnet_size, + netuid + ); + return Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }); + } + + for i in 0..dests_len { + let mut tmp_vec = [0u8; 2]; + let from = first_position + .saturating_add(62) + .saturating_add(i.saturating_mul(32)); + let to = from.saturating_add(2); + tmp_vec.copy_from_slice(get_slice(data, from, to)?); + let dest = u16::from_be_bytes(tmp_vec); + dests.push(dest); + } + + let mut weights_len_vec = [0u8; 2]; + weights_len_vec.copy_from_slice(get_slice( + data, + second_position + 30, + second_position + 32, + )?); + let weights_len = u16::from_be_bytes(weights_len_vec) as usize; + + if weights_len > subnet_size { + log::error!( + "weights len as {} in set weight is more than neurons {} in subnet {}", + weights_len, + subnet_size, + netuid + ); + return Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }); + } + + for i in 0..weights_len { + let mut tmp_vec = [0u8; 2]; + let from = second_position + .saturating_add(62) + .saturating_add(i.saturating_mul(32)); + let to = from.saturating_add(2); + tmp_vec.copy_from_slice(get_slice(data, from, to)?); + let weight = u16::from_be_bytes(tmp_vec); + weights.push(weight); + } + + Ok((netuid, dests, weights, version_key)) + } + + fn parse_netuid_commit_hash(data: &[u8]) -> Result<(u16, H256), PrecompileFailure> { + if data.len() < 2 * 32 { + return Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }); + } + + let mut netuid_vec = [0u8; 2]; + netuid_vec.copy_from_slice(get_slice(data, 30, 32)?); + let netuid = u16::from_be_bytes(netuid_vec); + let commit_hash = H256::from_slice(get_slice(data, 32, 64)?); + + Ok((netuid, commit_hash)) + } + + fn parse_netuid_dests_weights_salt( + data: &[u8], + ) -> Result<(u16, Vec, Vec, Vec, u64), PrecompileFailure> { + let data_len = data.len(); + if data_len < 5 * 32 { + return Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }); + } + + let netuid = parse_netuid(data, 30)?; + + // get the neuron amount in sebnet + let subnet_size = pallet_subtensor::Pallet::::get_subnetwork_n(netuid) as usize; + + let mut first_position_vec = [0u8; 2]; + first_position_vec.copy_from_slice(get_slice(data, 62, 64)?); + let first_position = u16::from_be_bytes(first_position_vec) as usize; + + if first_position > data_len { + log::error!("position for uids data as {} is too large", first_position); + return Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }); + } + + let mut second_position_vec = [0u8; 2]; + second_position_vec.copy_from_slice(get_slice(data, 94, 96)?); + let second_position = u16::from_be_bytes(second_position_vec) as usize; + + if second_position > data_len { + log::error!( + "position for values data as {} is too large", + first_position + ); + return Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }); + } + + let mut third_position_vec = [0u8; 2]; + third_position_vec.copy_from_slice(get_slice(data, 126, 128)?); + let third_position = u16::from_be_bytes(third_position_vec) as usize; + + if third_position > data_len { + log::error!("position for salt data as {} is too large", first_position); + return Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }); + } + + let mut version_key_vec = [0u8; 8]; + version_key_vec.copy_from_slice(get_slice(data, 152, 160)?); + let version_key = u64::from_be_bytes(version_key_vec); + + let mut uids = vec![]; + let mut values = vec![]; + let mut salt = vec![]; + + let mut uids_len_vec = [0u8; 2]; + uids_len_vec.copy_from_slice(get_slice(data, first_position + 30, first_position + 32)?); + let uids_len = u16::from_be_bytes(uids_len_vec) as usize; + + if uids_len > subnet_size { + log::error!( + "uids len as {} in reveal weight is more than neurons {} in subnet {}", + uids_len, + subnet_size, + netuid + ); + return Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }); + } + + for i in 0..uids_len { + let mut tmp_vec = [0u8; 2]; + let from = first_position + .saturating_add(62) + .saturating_add(i.saturating_mul(32)); + let to = from.saturating_add(2); + tmp_vec.copy_from_slice(get_slice(data, from, to)?); + let uid = u16::from_be_bytes(tmp_vec); + uids.push(uid); + } + + let mut values_len_vec = [0u8; 2]; + values_len_vec.copy_from_slice(get_slice( + data, + second_position + 30, + second_position + 32, + )?); + let values_len = u16::from_be_bytes(values_len_vec) as usize; + + if values_len > subnet_size { + log::error!( + "values len as {} in reveal weight is more than neurons {} in subnet {}", + values_len, + subnet_size, + netuid + ); + return Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }); + } + + for i in 0..values_len { + let mut tmp_vec = [0u8; 2]; + let from = second_position + .saturating_add(62) + .saturating_add(i.saturating_mul(32)); + let to = from.saturating_add(2); + tmp_vec.copy_from_slice(get_slice(data, from, to)?); + let value = u16::from_be_bytes(tmp_vec); + values.push(value); + } + + let mut salt_len_vec = [0u8; 2]; + salt_len_vec.copy_from_slice(get_slice(data, third_position + 30, third_position + 32)?); + let salt_len = u16::from_be_bytes(salt_len_vec) as usize; + + if salt_len > subnet_size { + log::error!( + "salt len as {} in reveal weight is more than neurons {} in subnet {}", + salt_len, + subnet_size, + netuid + ); + return Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }); + } + + for i in 0..salt_len { + let mut tmp_vec = [0u8; 2]; + let from = third_position + .saturating_add(62) + .saturating_add(i.saturating_mul(32)); + let to = from.saturating_add(2); + tmp_vec.copy_from_slice(get_slice(data, from, to)?); + let value = u16::from_be_bytes(tmp_vec); + salt.push(value); + } + + Ok((netuid, uids, values, salt, version_key)) + } +} diff --git a/runtime/src/precompiles/solidity/neuron.abi b/runtime/src/precompiles/solidity/neuron.abi new file mode 100644 index 000000000..804c9e8f1 --- /dev/null +++ b/runtime/src/precompiles/solidity/neuron.abi @@ -0,0 +1,100 @@ + +[ + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "bytes32", + "name": "hotkey", + "type": "bytes32" + } + ], + "name": "burnedRegister", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "uint256", + "name": "commitHash", + "type": "uint256" + } + ], + "name": "commitWeights", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "uint16[]", + "name": "uids", + "type": "uint16[]" + }, + { + "internalType": "uint16[]", + "name": "values", + "type": "uint16[]" + }, + { + "internalType": "uint16[]", + "name": "salt", + "type": "uint16[]" + }, + { + "internalType": "uint64", + "name": "versionKey", + "type": "uint64" + } + ], + "name": "revealWeights", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "uint16[]", + "name": "dests", + "type": "uint16[]" + }, + { + "internalType": "uint16[]", + "name": "weights", + "type": "uint16[]" + }, + { + "internalType": "uint64", + "name": "versionKey", + "type": "uint64" + } + ], + "name": "setWeights", + "outputs": [], + "stateMutability": "payable", + "type": "function" + } +] \ No newline at end of file diff --git a/runtime/src/precompiles/solidity/neuron.sol b/runtime/src/precompiles/solidity/neuron.sol new file mode 100644 index 000000000..ae002c47a --- /dev/null +++ b/runtime/src/precompiles/solidity/neuron.sol @@ -0,0 +1,54 @@ +pragma solidity ^0.8.0; + +address constant INeuron_ADDRESS = 0x0000000000000000000000000000000000000804; + +interface INeuron { + /** + * @dev Registers a neuron by calling `do_burned_registration` internally with the origin set to the ss58 mirror of the H160 address. + * This allows the H160 to further call neuron-related methods and receive emissions. + * + * @param netuid The subnet to register the neuron to (uint16). + * @param hotkey The hotkey public key (32 bytes). + */ + function burnedRegister(uint16 netuid, bytes32 hotkey) external payable; + + /** + * @dev Sets the weights for a neuron. + * + * @param netuid The subnet to set the weights for (uint16). + * @param dests The destinations of the weights (uint16[]). + * @param weights The weights to set (uint16[]). + * @param versionKey The version key for the weights (uint64). + */ + function setWeights( + uint16 netuid, + uint16[] memory dests, + uint16[] memory weights, + uint64 versionKey + ) external payable; + + /** + * @dev Commits the weights for a neuron. + * + * @param netuid The subnet to commit the weights for (uint16). + * @param commitHash The commit hash for the weights (uint256). + */ + function commitWeights(uint16 netuid, uint256 commitHash) external payable; + + /** + * @dev Reveals the weights for a neuron. + * + * @param netuid The subnet to reveal the weights for (uint16). + * @param uids The unique identifiers for the weights (uint16[]). + * @param values The values of the weights (uint16[]). + * @param salt The salt values for the weights (uint16[]). + * @param versionKey The version key for the weights (uint64). + */ + function revealWeights( + uint16 netuid, + uint16[] memory uids, + uint16[] memory values, + uint16[] memory salt, + uint64 versionKey + ) external payable; +} diff --git a/runtime/src/precompiles/solidity/staking.sol b/runtime/src/precompiles/solidity/staking.sol index 9d4eab471..19d51d047 100644 --- a/runtime/src/precompiles/solidity/staking.sol +++ b/runtime/src/precompiles/solidity/staking.sol @@ -3,69 +3,77 @@ pragma solidity ^0.8.0; address constant ISTAKING_ADDRESS = 0x0000000000000000000000000000000000000801; interface IStaking { - /** - * @dev Adds a subtensor stake corresponding to the value sent with the transaction, 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 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 netuid) external payable; + /** + * @dev Adds a subtensor stake corresponding to the value sent with the transaction, 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 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 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 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. - * - The existing stake amount must be not lower than specified amount - */ - function removeStake(bytes32 hotkey, uint256 amount, uint256 netuid) external; + /** + * @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 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. + * - The existing stake amount must be not lower than specified amount + */ + function removeStake( + bytes32 hotkey, + uint256 amount, + 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 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; + /** + * @dev Removes staking proxy account. + * + * @param delegate The public key (32 bytes) of the delegate. + */ + function removeProxy(bytes32 delegate) external; - /** - * @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 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); } diff --git a/runtime/src/precompiles/solidity/subnet.abi b/runtime/src/precompiles/solidity/subnet.abi new file mode 100644 index 000000000..a11879241 --- /dev/null +++ b/runtime/src/precompiles/solidity/subnet.abi @@ -0,0 +1,43 @@ +[ + { + "inputs": [ + { + "internalType": "bytes32", + "name": "hotkey", + "type": "bytes32" + } + ], + "name": "registerNetwork", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "hotkey", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "subnetName", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "githubRepo", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "subnetContact", + "type": "bytes" + } + ], + "name": "registerNetwork", + "outputs": [], + "stateMutability": "payable", + "type": "function" + } +] \ No newline at end of file diff --git a/runtime/src/precompiles/solidity/subnet.sol b/runtime/src/precompiles/solidity/subnet.sol new file mode 100644 index 000000000..c6639891a --- /dev/null +++ b/runtime/src/precompiles/solidity/subnet.sol @@ -0,0 +1,15 @@ +pragma solidity ^0.8.0; + +address constant ISUBNET_ADDRESS = 0x0000000000000000000000000000000000000803; + +interface ISubnet { + /// Registers a new network without specifying details. + function registerNetwork(bytes32 hotkey) external payable; + /// Registers a new network with specified subnet name, GitHub repository, and contact information. + function registerNetwork( + bytes32 hotkey, + bytes memory subnetName, + bytes memory githubRepo, + bytes memory subnetContact + ) external payable; +} diff --git a/runtime/src/precompiles/staking.rs b/runtime/src/precompiles/staking.rs index f8534927b..8cc1c879a 100644 --- a/runtime/src/precompiles/staking.rs +++ b/runtime/src/precompiles/staking.rs @@ -25,25 +25,29 @@ // - Precompile checks the result of do_remove_stake and, in case of a failure, reverts the transaction. // +use crate::precompiles::{ + get_method_id, get_pubkey, get_slice, parse_netuid, try_dispatch_runtime_call, +}; +use crate::{ProxyType, Runtime, RuntimeCall}; use frame_system::RawOrigin; use pallet_evm::{ AddressMapping, BalanceConverter, ExitError, ExitSucceed, HashedAddressMapping, PrecompileFailure, PrecompileHandle, PrecompileOutput, PrecompileResult, }; -use precompile_utils::prelude::RuntimeHelper; -use sp_core::crypto::Ss58Codec; use sp_core::U256; use sp_runtime::traits::{BlakeTwo256, Dispatchable, StaticLookup, UniqueSaturatedInto}; use sp_runtime::AccountId32; use sp_std::vec; -use crate::{ - precompiles::{get_method_id, get_slice}, - ProxyType, Runtime, RuntimeCall, -}; - pub const STAKING_PRECOMPILE_INDEX: u64 = 2049; +// ss58 public key i.e., the contract sends funds it received to the destination address from the +// method parameter. +const CONTRACT_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, +]; + pub struct StakingPrecompile; impl StakingPrecompile { @@ -72,27 +76,39 @@ impl StakingPrecompile { } fn add_stake(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { - let hotkey = Self::parse_pub_key(data)?.into(); + let account_id = + as AddressMapping>::into_account_id( + handle.context().caller, + ); + + let (hotkey, _) = get_pubkey(data)?; let amount: U256 = handle.context().apparent_value; - let netuid = Self::parse_netuid(data, 0x3E)?; + let netuid = parse_netuid(data, 0x3E)?; + + if !amount.is_zero() { + Self::transfer_back_to_caller(&account_id, amount)?; + } let amount_sub = ::BalanceConverter::into_substrate_balance(amount) .ok_or(ExitError::OutOfFund)?; - // Create the add_stake call let call = RuntimeCall::SubtensorModule(pallet_subtensor::Call::::add_stake { hotkey, netuid, amount_staked: amount_sub.unique_saturated_into(), }); - // Dispatch the add_stake call - Self::dispatch(handle, call) + + try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id)) } fn remove_stake(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { - let hotkey = Self::parse_pub_key(data)?.into(); - let netuid = Self::parse_netuid(data, 0x5E)?; + let account_id = + as AddressMapping>::into_account_id( + handle.context().caller, + ); + let (hotkey, _) = get_pubkey(data)?; + let netuid = parse_netuid(data, 0x5E)?; // We have to treat this as uint256 (because of Solidity ABI encoding rules, it pads uint64), // but this will never exceed 8 bytes, se we will ignore higher bytes and will only use lower @@ -110,11 +126,15 @@ impl StakingPrecompile { netuid, amount_unstaked: amount_sub.unique_saturated_into(), }); - Self::dispatch(handle, call) + try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id)) } fn add_proxy(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { - let delegate = AccountId32::from(Self::parse_pub_key(data)?); + let account_id = + as AddressMapping>::into_account_id( + handle.context().caller, + ); + let (delegate, _) = get_pubkey(data)?; let delegate = ::Lookup::unlookup(delegate); let call = RuntimeCall::Proxy(pallet_proxy::Call::::add_proxy { delegate, @@ -122,11 +142,15 @@ impl StakingPrecompile { delay: 0, }); - Self::dispatch(handle, call) + try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id)) } fn remove_proxy(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { - let delegate = AccountId32::from(Self::parse_pub_key(data)?); + let account_id = + as AddressMapping>::into_account_id( + handle.context().caller, + ); + let (delegate, _) = get_pubkey(data)?; let delegate = ::Lookup::unlookup(delegate); let call = RuntimeCall::Proxy(pallet_proxy::Call::::remove_proxy { delegate, @@ -134,17 +158,16 @@ impl StakingPrecompile { delay: 0, }); - Self::dispatch(handle, call) + try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id)) } fn get_stake(data: &[u8]) -> PrecompileResult { - let (hotkey, coldkey) = Self::parse_hotkey_coldkey(data)?; - let netuid = Self::parse_netuid(data, 0x5E)?; + let (hotkey, left_data) = get_pubkey(data)?; + let (coldkey, _) = get_pubkey(&left_data)?; + let netuid = parse_netuid(data, 0x5E)?; let stake = pallet_subtensor::Pallet::::get_stake_for_hotkey_and_coldkey_on_subnet( - &hotkey.into(), - &coldkey.into(), - netuid, + &hotkey, &coldkey, netuid, ); // Convert to EVM decimals @@ -163,95 +186,12 @@ impl StakingPrecompile { }) } - fn parse_hotkey_coldkey(data: &[u8]) -> Result<([u8; 32], [u8; 32]), PrecompileFailure> { - if data.len() < 64 { - return Err(PrecompileFailure::Error { - exit_status: ExitError::InvalidRange, - }); - } - let mut hotkey = [0u8; 32]; - hotkey.copy_from_slice(get_slice(data, 0, 32)?); - let mut coldkey = [0u8; 32]; - coldkey.copy_from_slice(get_slice(data, 32, 64)?); - Ok((hotkey, coldkey)) - } - - fn parse_pub_key(data: &[u8]) -> Result<[u8; 32], PrecompileFailure> { - if data.len() < 32 { - return Err(PrecompileFailure::Error { - exit_status: ExitError::InvalidRange, - }); - } - let mut pubkey = [0u8; 32]; - pubkey.copy_from_slice(get_slice(data, 0, 32)?); - Ok(pubkey) - } - - fn parse_netuid(data: &[u8], offset: usize) -> Result { - if data.len() < offset + 2 { - return Err(PrecompileFailure::Error { - exit_status: ExitError::InvalidRange, - }); - } - - let mut netuid_bytes = [0u8; 2]; - netuid_bytes.copy_from_slice(get_slice(data, offset, offset + 2)?); - let netuid: u16 = netuid_bytes[1] as u16 | ((netuid_bytes[0] as u16) << 8u16); - - Ok(netuid) - } - - fn dispatch(handle: &mut impl PrecompileHandle, call: RuntimeCall) -> PrecompileResult { - let account_id = - as AddressMapping>::into_account_id( - handle.context().caller, - ); - - // Transfer the amount back to the caller before executing the staking operation - let amount = handle.context().apparent_value; - - if !amount.is_zero() { - Self::transfer_back_to_caller(&account_id, amount)?; - } - - match RuntimeHelper::::try_dispatch( - handle, - RawOrigin::Signed(account_id.clone()).into(), - call, - ) { - Ok(post_info) => { - log::info!("Dispatch succeeded. Post info: {:?}", post_info); - - Ok(PrecompileOutput { - exit_status: ExitSucceed::Returned, - output: vec![], - }) - } - - Err(dispatch_error) => { - log::error!("Dispatch failed. Error: {:?}", dispatch_error); - log::warn!("Returning error PrecompileFailure::Error"); - Err(PrecompileFailure::Error { - exit_status: ExitError::Other("Subtensor call failed".into()), - }) - } - } - } - fn transfer_back_to_caller( account_id: &AccountId32, amount: U256, ) -> Result<(), PrecompileFailure> { - // this is staking smart contract's(0x0000000000000000000000000000000000000801) sr25519 address - let smart_contract_account_id = - match AccountId32::from_ss58check("5CwnBK9Ack1mhznmCnwiibCNQc174pYQVktYW3ayRpLm4K2X") { - Ok(addr) => addr, - Err(_) => { - return Err(PrecompileFailure::Error { - exit_status: ExitError::Other("Invalid SS58 address".into()), - }); - } - }; + let smart_contract_account_id: AccountId32 = CONTRACT_ADDRESS_SS58.into(); + let amount_sub = ::BalanceConverter::into_substrate_balance(amount) .ok_or(ExitError::OutOfFund)?; diff --git a/runtime/src/precompiles/subnet.rs b/runtime/src/precompiles/subnet.rs new file mode 100644 index 000000000..9944572c5 --- /dev/null +++ b/runtime/src/precompiles/subnet.rs @@ -0,0 +1,215 @@ +use crate::precompiles::{get_method_id, get_pubkey, get_slice, try_dispatch_runtime_call}; +use crate::{Runtime, RuntimeCall}; +use frame_system::RawOrigin; +use pallet_evm::{ + AddressMapping, ExitError, HashedAddressMapping, PrecompileFailure, PrecompileHandle, + PrecompileResult, +}; +use sp_runtime::traits::BlakeTwo256; +use sp_runtime::AccountId32; +use sp_std::vec; +pub const SUBNET_PRECOMPILE_INDEX: u64 = 2051; +// bytes with max lenght 1K +pub const MAX_SINGLE_PARAMETER_SIZE: usize = 1024; +// three bytes with max lenght 1K +pub const MAX_PARAMETER_SIZE: usize = 3 * MAX_SINGLE_PARAMETER_SIZE; + +// ss58 public key i.e., the contract sends funds it received to the destination address from the +// method parameter. +#[allow(dead_code)] +const CONTRACT_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, +]; +pub struct SubnetPrecompile; + +impl SubnetPrecompile { + pub fn execute(handle: &mut impl PrecompileHandle) -> PrecompileResult { + let txdata = handle.input(); + if txdata.len() > MAX_PARAMETER_SIZE { + log::error!("the length of subnet call is {} ", txdata.len()); + return Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }); + } + let method_id = get_slice(txdata, 0, 4)?; + let method_input = txdata + .get(4..) + .map_or_else(vec::Vec::new, |slice| slice.to_vec()); // Avoiding borrowing conflicts + + match method_id { + id if id == get_method_id("registerNetwork(bytes32,bytes,bytes,bytes)") => { + Self::register_network(handle, &method_input) + } + id if id == get_method_id("registerNetwork(bytes32)") => { + Self::register_network(handle, &method_input) + } + _ => Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }), + } + } + + fn register_network(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { + let call = match data.len() { + 32 => { + let (hotkey, _) = get_pubkey(data)?; + RuntimeCall::SubtensorModule( + pallet_subtensor::Call::::register_network_with_identity { + hotkey, + identity: None, + }, + ) + } + 33.. => { + let (hotkey, subnet_name, github_repo, subnet_contact) = + Self::parse_register_network_parameters(data)?; + + let identity: pallet_subtensor::SubnetIdentityOf = + pallet_subtensor::SubnetIdentityOf { + subnet_name, + github_repo, + subnet_contact, + }; + + // Create the register_network callcle + RuntimeCall::SubtensorModule( + pallet_subtensor::Call::::register_network_with_identity { + hotkey, + identity: Some(identity), + }, + ) + } + _ => { + return Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }); + } + }; + + let account_id = + as AddressMapping>::into_account_id( + handle.context().caller, + ); + + // Dispatch the register_network call + try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id)) + } + + fn parse_register_network_parameters( + data: &[u8], + ) -> Result<(AccountId32, vec::Vec, vec::Vec, vec::Vec), PrecompileFailure> { + let (pubkey, dynamic_params) = get_pubkey(data)?; + let dynamic_data_len = dynamic_params.len(); + + let mut buf = [0_u8; 4]; + // get all start point for three data items: name, repo and contact + buf.copy_from_slice(get_slice(data, 60, 64)?); + let subnet_name_start: usize = u32::from_be_bytes(buf) as usize; + if subnet_name_start > dynamic_data_len { + log::error!( + "the start position of subnet name as {} is too big ", + subnet_name_start + ); + return Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }); + } + + buf.copy_from_slice(get_slice(data, 92, 96)?); + let github_repo_start: usize = u32::from_be_bytes(buf) as usize; + if github_repo_start > dynamic_data_len { + log::error!( + "the start position of github repo as {} is too big ", + github_repo_start + ); + return Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }); + } + + buf.copy_from_slice(get_slice(data, 124, 128)?); + let subnet_contact_start: usize = u32::from_be_bytes(buf) as usize; + if subnet_contact_start > dynamic_data_len { + log::error!( + "the start position of subnet contact as {} is too big ", + subnet_contact_start + ); + return Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }); + } + + // get name + buf.copy_from_slice(get_slice( + data, + subnet_name_start + 28, + subnet_name_start + 32, + )?); + let subnet_name_len: usize = u32::from_be_bytes(buf) as usize; + + if subnet_name_len > MAX_SINGLE_PARAMETER_SIZE { + log::error!("the length of subnet nae as {} is too big", subnet_name_len); + return Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }); + } + + let mut name_vec = vec![0; subnet_name_len]; + name_vec.copy_from_slice(get_slice( + data, + subnet_name_start + 32, + subnet_name_start + subnet_name_len + 32, + )?); + + // get repo data + buf.copy_from_slice(get_slice( + data, + github_repo_start + 28, + github_repo_start + 32, + )?); + let github_repo_len: usize = u32::from_be_bytes(buf) as usize; + if github_repo_len > MAX_SINGLE_PARAMETER_SIZE { + log::error!( + "the length of github repo as {} is too big", + github_repo_len + ); + return Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }); + } + + let mut repo_vec = vec![0; github_repo_len]; + repo_vec.copy_from_slice(get_slice( + data, + github_repo_start + 32, + github_repo_start + github_repo_len + 32, + )?); + + // get contact data + buf.copy_from_slice(get_slice( + data, + subnet_contact_start + 28, + subnet_contact_start + 32, + )?); + let subnet_contact_len: usize = u32::from_be_bytes(buf) as usize; + if subnet_contact_len > MAX_SINGLE_PARAMETER_SIZE { + log::error!( + "the length of subnet contact as {} is too big", + subnet_contact_len + ); + return Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }); + } + + let mut contact_vec = vec![0; subnet_contact_len]; + contact_vec.copy_from_slice(get_slice( + data, + subnet_contact_start + 32, + subnet_contact_start + subnet_contact_len + 32, + )?); + + Ok((pubkey, name_vec, repo_vec, contact_vec)) + } +} diff --git a/scripts/try-runtime-upgrade.sh b/scripts/try-runtime-upgrade.sh new file mode 100755 index 000000000..9523656b6 --- /dev/null +++ b/scripts/try-runtime-upgrade.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash + +# Tries runtime upgrade (via try-runtime). +# +# Usage: +# try-runtime-upgrade.sh [-p ] [-u ] [-s ] +# +# Dependencies: +# - rust toolchain +# - try-runtime-cli + +set -eou pipefail + +runtime_wasm_path="./target/release/wbuild/node-subtensor-runtime/node_subtensor_runtime.compact.wasm" +live_chain_url="wss://dev.chain.opentensor.ai" +snapshot_path="" + +parse_args() { + u_provided=false + + while getopts "r:u:s:" opt; do + case "${opt}" in + r) runtime_wasm_path="${OPTARG}" ;; + u) + live_chain_url="${OPTARG}" + u_provided=true + ;; + s) snapshot_path="${OPTARG}" ;; + *) echo "Usage: $(basename "$0") [-r ] [-u ] [-s ]" && exit 1 ;; + esac + done + + # Prevent specifying URI if snapshot is specified + if [ -n "$snapshot_path" ] && [ "$u_provided" = true ]; then + echo "Error: Either live URI or snapshot path should be specified, but not both." + exit 1 + fi +} + +build_runtime() { + cargo build -p node-subtensor-runtime --release --features "metadata-hash,try-runtime" +} + +do_try_runtime() { + if [ -n "$snapshot_path" ]; then + chain_state="snap --path $snapshot_path" + else + chain_state="live --uri $live_chain_url" + fi + + eval "try-runtime --runtime $runtime_wasm_path on-runtime-upgrade \ + --no-weight-warnings --disable-spec-version-check --disable-idempotency-checks --checks=all \ + --blocktime 12000 \ + $chain_state" +} + +parse_args "$@" +build_runtime +do_try_runtime