diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml deleted file mode 100644 index 65fb5fed57..0000000000 --- a/.github/workflows/e2e.yml +++ /dev/null @@ -1,4 +0,0 @@ -name: E2E Tests - -on: - workflow_dispatch: \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index f936e40cf6..0b2a387c2b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1056,7 +1056,7 @@ checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" [[package]] name = "assets-common" version = "0.22.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "cumulus-primitives-core", "ethereum-standards", @@ -1435,7 +1435,7 @@ checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" [[package]] name = "binary-merkle-tree" version = "16.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "hash-db", "log", @@ -1704,7 +1704,7 @@ dependencies = [ [[package]] name = "bp-header-chain" version = "0.21.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "bp-runtime", "finality-grandpa", @@ -1721,7 +1721,7 @@ dependencies = [ [[package]] name = "bp-messages" version = "0.21.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "bp-header-chain", "bp-runtime", @@ -1737,7 +1737,7 @@ dependencies = [ [[package]] name = "bp-parachains" version = "0.21.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "bp-header-chain", "bp-polkadot-core", @@ -1754,7 +1754,7 @@ dependencies = [ [[package]] name = "bp-polkadot-core" version = "0.21.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "bp-messages", "bp-runtime", @@ -1770,7 +1770,7 @@ dependencies = [ [[package]] name = "bp-relayers" version = "0.21.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "bp-header-chain", "bp-messages", @@ -1788,7 +1788,7 @@ dependencies = [ [[package]] name = "bp-runtime" version = "0.21.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-support", "frame-system", @@ -1811,7 +1811,7 @@ dependencies = [ [[package]] name = "bp-test-utils" version = "0.21.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "bp-header-chain", "bp-parachains", @@ -1831,7 +1831,7 @@ dependencies = [ [[package]] name = "bp-xcm-bridge-hub" version = "0.7.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "bp-messages", "bp-runtime", @@ -1848,7 +1848,7 @@ dependencies = [ [[package]] name = "bp-xcm-bridge-hub-router" version = "0.18.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "parity-scale-codec", "scale-info", @@ -1860,7 +1860,7 @@ dependencies = [ [[package]] name = "bridge-hub-common" version = "0.14.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -1879,7 +1879,7 @@ dependencies = [ [[package]] name = "bridge-runtime-common" version = "0.22.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "bp-header-chain", "bp-messages", @@ -1917,6 +1917,17 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "bstr" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab" +dependencies = [ + "memchr", + "regex-automata 0.4.11", + "serde", +] + [[package]] name = "build-helper" version = "0.1.1" @@ -2711,7 +2722,7 @@ dependencies = [ [[package]] name = "cumulus-client-bootnodes" version = "0.2.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "array-bytes 6.2.3", "async-channel 1.9.0", @@ -2737,7 +2748,7 @@ dependencies = [ [[package]] name = "cumulus-client-cli" version = "0.24.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "clap", "parity-scale-codec", @@ -2754,7 +2765,7 @@ dependencies = [ [[package]] name = "cumulus-client-collator" version = "0.24.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "cumulus-client-consensus-common", "cumulus-client-network", @@ -2777,7 +2788,7 @@ dependencies = [ [[package]] name = "cumulus-client-consensus-aura" version = "0.24.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "async-trait", "cumulus-client-collator", @@ -2824,7 +2835,7 @@ dependencies = [ [[package]] name = "cumulus-client-consensus-common" version = "0.24.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "async-trait", "cumulus-client-pov-recovery", @@ -2856,7 +2867,7 @@ dependencies = [ [[package]] name = "cumulus-client-consensus-proposer" version = "0.20.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "anyhow", "async-trait", @@ -2871,7 +2882,7 @@ dependencies = [ [[package]] name = "cumulus-client-consensus-relay-chain" version = "0.24.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "async-trait", "cumulus-client-consensus-common", @@ -2894,7 +2905,7 @@ dependencies = [ [[package]] name = "cumulus-client-network" version = "0.24.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "async-trait", "cumulus-relay-chain-interface", @@ -2921,7 +2932,7 @@ dependencies = [ [[package]] name = "cumulus-client-parachain-inherent" version = "0.18.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "async-trait", "cumulus-primitives-core", @@ -2931,7 +2942,7 @@ dependencies = [ "parity-scale-codec", "sc-client-api", "sc-consensus-babe", - "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8)", + "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61)", "sp-inherents", "sp-runtime", "sp-state-machine", @@ -2942,7 +2953,7 @@ dependencies = [ [[package]] name = "cumulus-client-pov-recovery" version = "0.24.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "async-trait", "cumulus-primitives-core", @@ -2970,7 +2981,7 @@ dependencies = [ [[package]] name = "cumulus-client-service" version = "0.25.1" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "async-channel 1.9.0", "cumulus-client-cli", @@ -3010,7 +3021,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-aura-ext" version = "0.21.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "cumulus-pallet-parachain-system", "frame-support", @@ -3027,7 +3038,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-dmp-queue" version = "0.21.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "cumulus-primitives-core", "frame-benchmarking", @@ -3044,7 +3055,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-parachain-system" version = "0.21.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "bytes", "cumulus-pallet-parachain-system-proc-macro", @@ -3081,7 +3092,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-parachain-system-proc-macro" version = "0.6.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "proc-macro-crate 3.4.0", "proc-macro2", @@ -3092,7 +3103,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-session-benchmarking" version = "22.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-support", @@ -3105,7 +3116,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-solo-to-para" version = "0.21.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "cumulus-pallet-parachain-system", "frame-support", @@ -3120,7 +3131,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-weight-reclaim" version = "0.3.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "cumulus-primitives-storage-weight-reclaim", "derive-where", @@ -3139,7 +3150,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-xcm" version = "0.20.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -3154,7 +3165,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-xcmp-queue" version = "0.21.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "approx", "bounded-collections 0.2.4", @@ -3179,7 +3190,7 @@ dependencies = [ [[package]] name = "cumulus-ping" version = "0.21.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "cumulus-pallet-xcm", "cumulus-primitives-core", @@ -3194,7 +3205,7 @@ dependencies = [ [[package]] name = "cumulus-primitives-aura" version = "0.18.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "sp-api", "sp-consensus-aura", @@ -3203,7 +3214,7 @@ dependencies = [ [[package]] name = "cumulus-primitives-core" version = "0.19.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "parity-scale-codec", "polkadot-core-primitives", @@ -3220,7 +3231,7 @@ dependencies = [ [[package]] name = "cumulus-primitives-parachain-inherent" version = "0.19.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "async-trait", "cumulus-primitives-core", @@ -3234,7 +3245,7 @@ dependencies = [ [[package]] name = "cumulus-primitives-proof-size-hostfunction" version = "0.13.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "sp-externalities", "sp-runtime-interface", @@ -3244,7 +3255,7 @@ dependencies = [ [[package]] name = "cumulus-primitives-storage-weight-reclaim" version = "12.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "cumulus-primitives-core", "cumulus-primitives-proof-size-hostfunction", @@ -3261,7 +3272,7 @@ dependencies = [ [[package]] name = "cumulus-primitives-utility" version = "0.21.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -3278,7 +3289,7 @@ dependencies = [ [[package]] name = "cumulus-relay-chain-inprocess-interface" version = "0.25.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "async-channel 1.9.0", "async-trait", @@ -3306,7 +3317,7 @@ dependencies = [ [[package]] name = "cumulus-relay-chain-interface" version = "0.24.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "async-trait", "cumulus-primitives-core", @@ -3326,7 +3337,7 @@ dependencies = [ [[package]] name = "cumulus-relay-chain-minimal-node" version = "0.25.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "array-bytes 6.2.3", "async-channel 1.9.0", @@ -3362,7 +3373,7 @@ dependencies = [ [[package]] name = "cumulus-relay-chain-rpc-interface" version = "0.24.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "async-trait", "cumulus-primitives-core", @@ -3403,7 +3414,7 @@ dependencies = [ [[package]] name = "cumulus-relay-chain-streams" version = "0.2.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "cumulus-relay-chain-interface", "futures", @@ -3417,7 +3428,7 @@ dependencies = [ [[package]] name = "cumulus-test-relay-sproof-builder" version = "0.20.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "cumulus-primitives-core", "parity-scale-codec", @@ -3760,6 +3771,7 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.106", + "unicode-xid", ] [[package]] @@ -4198,7 +4210,7 @@ dependencies = [ [[package]] name = "ethereum-standards" version = "0.1.1" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "alloy-core", ] @@ -4415,7 +4427,7 @@ dependencies = [ [[package]] name = "fc-api" version = "1.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=f12a1274f91442a564bb722a2b9547caba487fa0#f12a1274f91442a564bb722a2b9547caba487fa0" +source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" dependencies = [ "async-trait", "fp-storage", @@ -4427,7 +4439,7 @@ dependencies = [ [[package]] name = "fc-aura" version = "1.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=f12a1274f91442a564bb722a2b9547caba487fa0#f12a1274f91442a564bb722a2b9547caba487fa0" +source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" dependencies = [ "fc-rpc", "fp-storage", @@ -4443,7 +4455,7 @@ dependencies = [ [[package]] name = "fc-babe" version = "1.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=f12a1274f91442a564bb722a2b9547caba487fa0#f12a1274f91442a564bb722a2b9547caba487fa0" +source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" dependencies = [ "fc-rpc", "sc-client-api", @@ -4459,7 +4471,7 @@ dependencies = [ [[package]] name = "fc-consensus" version = "2.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=f12a1274f91442a564bb722a2b9547caba487fa0#f12a1274f91442a564bb722a2b9547caba487fa0" +source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" dependencies = [ "async-trait", "fp-consensus", @@ -4475,7 +4487,7 @@ dependencies = [ [[package]] name = "fc-db" version = "2.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=f12a1274f91442a564bb722a2b9547caba487fa0#f12a1274f91442a564bb722a2b9547caba487fa0" +source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" dependencies = [ "async-trait", "ethereum", @@ -4505,7 +4517,7 @@ dependencies = [ [[package]] name = "fc-mapping-sync" version = "2.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=f12a1274f91442a564bb722a2b9547caba487fa0#f12a1274f91442a564bb722a2b9547caba487fa0" +source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" dependencies = [ "fc-db", "fc-storage", @@ -4528,7 +4540,7 @@ dependencies = [ [[package]] name = "fc-rpc" version = "2.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=f12a1274f91442a564bb722a2b9547caba487fa0#f12a1274f91442a564bb722a2b9547caba487fa0" +source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" dependencies = [ "ethereum", "ethereum-types", @@ -4579,7 +4591,7 @@ dependencies = [ [[package]] name = "fc-rpc-core" version = "1.1.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=f12a1274f91442a564bb722a2b9547caba487fa0#f12a1274f91442a564bb722a2b9547caba487fa0" +source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" dependencies = [ "ethereum", "ethereum-types", @@ -4588,13 +4600,13 @@ dependencies = [ "rustc-hex", "serde", "serde_json", - "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8)", + "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61)", ] [[package]] name = "fc-storage" version = "1.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=f12a1274f91442a564bb722a2b9547caba487fa0#f12a1274f91442a564bb722a2b9547caba487fa0" +source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" dependencies = [ "ethereum", "ethereum-types", @@ -4759,7 +4771,7 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "fork-tree" version = "13.0.1" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "parity-scale-codec", ] @@ -4786,7 +4798,7 @@ dependencies = [ [[package]] name = "fp-account" version = "1.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=f12a1274f91442a564bb722a2b9547caba487fa0#f12a1274f91442a564bb722a2b9547caba487fa0" +source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" dependencies = [ "hex", "impl-serde", @@ -4804,7 +4816,7 @@ dependencies = [ [[package]] name = "fp-consensus" version = "2.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=f12a1274f91442a564bb722a2b9547caba487fa0#f12a1274f91442a564bb722a2b9547caba487fa0" +source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" dependencies = [ "ethereum", "parity-scale-codec", @@ -4815,7 +4827,7 @@ dependencies = [ [[package]] name = "fp-ethereum" version = "1.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=f12a1274f91442a564bb722a2b9547caba487fa0#f12a1274f91442a564bb722a2b9547caba487fa0" +source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" dependencies = [ "ethereum", "ethereum-types", @@ -4827,7 +4839,7 @@ dependencies = [ [[package]] name = "fp-evm" version = "3.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=f12a1274f91442a564bb722a2b9547caba487fa0#f12a1274f91442a564bb722a2b9547caba487fa0" +source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" dependencies = [ "environmental", "evm", @@ -4843,7 +4855,7 @@ dependencies = [ [[package]] name = "fp-rpc" version = "3.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=f12a1274f91442a564bb722a2b9547caba487fa0#f12a1274f91442a564bb722a2b9547caba487fa0" +source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" dependencies = [ "ethereum", "ethereum-types", @@ -4859,7 +4871,7 @@ dependencies = [ [[package]] name = "fp-self-contained" version = "1.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=f12a1274f91442a564bb722a2b9547caba487fa0#f12a1274f91442a564bb722a2b9547caba487fa0" +source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" dependencies = [ "frame-support", "parity-scale-codec", @@ -4871,7 +4883,7 @@ dependencies = [ [[package]] name = "fp-storage" version = "2.0.0" -source = "git+https://github.com/opentensor/frontier?rev=f12a1274f91442a564bb722a2b9547caba487fa0#f12a1274f91442a564bb722a2b9547caba487fa0" +source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" dependencies = [ "parity-scale-codec", "serde", @@ -4886,7 +4898,7 @@ checksum = "28dd6caf6059519a65843af8fe2a3ae298b14b80179855aeb4adc2c1934ee619" [[package]] name = "frame-benchmarking" version = "41.0.1" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-support", "frame-support-procedural", @@ -4910,7 +4922,7 @@ dependencies = [ [[package]] name = "frame-benchmarking-cli" version = "49.1.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "Inflector", "array-bytes 6.2.3", @@ -4975,7 +4987,7 @@ dependencies = [ [[package]] name = "frame-benchmarking-pallet-pov" version = "31.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-support", @@ -5003,7 +5015,7 @@ dependencies = [ [[package]] name = "frame-election-provider-solution-type" version = "16.1.1" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "proc-macro-crate 3.4.0", "proc-macro2", @@ -5014,7 +5026,7 @@ dependencies = [ [[package]] name = "frame-election-provider-support" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-election-provider-solution-type", "frame-support", @@ -5031,7 +5043,7 @@ dependencies = [ [[package]] name = "frame-executive" version = "41.0.1" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "aquamarine", "frame-support", @@ -5084,7 +5096,7 @@ dependencies = [ [[package]] name = "frame-metadata-hash-extension" version = "0.9.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "array-bytes 6.2.3", "const-hex", @@ -5100,7 +5112,7 @@ dependencies = [ [[package]] name = "frame-storage-access-test-runtime" version = "0.2.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "cumulus-pallet-parachain-system", "parity-scale-codec", @@ -5114,7 +5126,7 @@ dependencies = [ [[package]] name = "frame-support" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "aquamarine", "array-bytes 6.2.3", @@ -5155,7 +5167,7 @@ dependencies = [ [[package]] name = "frame-support-procedural" version = "34.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "Inflector", "cfg-expr", @@ -5168,7 +5180,7 @@ dependencies = [ "proc-macro-warning", "proc-macro2", "quote", - "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8)", + "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61)", "syn 2.0.106", ] @@ -5188,7 +5200,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools" version = "13.0.1" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-support-procedural-tools-derive 12.0.0", "proc-macro-crate 3.4.0", @@ -5211,7 +5223,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools-derive" version = "12.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "proc-macro2", "quote", @@ -5221,7 +5233,7 @@ dependencies = [ [[package]] name = "frame-system" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "cfg-if", "docify", @@ -5240,7 +5252,7 @@ dependencies = [ [[package]] name = "frame-system-benchmarking" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-support", @@ -5254,7 +5266,7 @@ dependencies = [ [[package]] name = "frame-system-rpc-runtime-api" version = "37.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "docify", "parity-scale-codec", @@ -5264,7 +5276,7 @@ dependencies = [ [[package]] name = "frame-try-runtime" version = "0.47.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-support", "parity-scale-codec", @@ -7821,7 +7833,7 @@ dependencies = [ [[package]] name = "mmr-gadget" version = "46.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "futures", "log", @@ -7840,7 +7852,7 @@ dependencies = [ [[package]] name = "mmr-rpc" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "jsonrpsee", "parity-scale-codec", @@ -8323,7 +8335,7 @@ dependencies = [ "pallet-balances", "pallet-base-fee", "pallet-commitments", - "pallet-contracts 40.1.0", + "pallet-contracts", "pallet-crowdloan", "pallet-drand", "pallet-election-provider-multi-phase", @@ -8789,7 +8801,7 @@ dependencies = [ [[package]] name = "pallet-alliance" version = "40.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "array-bytes 6.2.3", "frame-benchmarking", @@ -8801,7 +8813,7 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-core", - "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8)", + "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61)", "sp-io", "sp-runtime", ] @@ -8809,7 +8821,7 @@ dependencies = [ [[package]] name = "pallet-asset-conversion" version = "23.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-support", @@ -8827,7 +8839,7 @@ dependencies = [ [[package]] name = "pallet-asset-conversion-ops" version = "0.9.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-support", @@ -8845,7 +8857,7 @@ dependencies = [ [[package]] name = "pallet-asset-conversion-tx-payment" version = "23.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-support", @@ -8860,7 +8872,7 @@ dependencies = [ [[package]] name = "pallet-asset-rate" version = "20.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-support", @@ -8874,7 +8886,7 @@ dependencies = [ [[package]] name = "pallet-asset-rewards" version = "0.3.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-support", @@ -8892,7 +8904,7 @@ dependencies = [ [[package]] name = "pallet-asset-tx-payment" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-support", @@ -8908,7 +8920,7 @@ dependencies = [ [[package]] name = "pallet-assets" version = "43.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "ethereum-standards", "frame-benchmarking", @@ -8926,7 +8938,7 @@ dependencies = [ [[package]] name = "pallet-assets-freezer" version = "0.8.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "log", "pallet-assets", @@ -8938,7 +8950,7 @@ dependencies = [ [[package]] name = "pallet-assets-holder" version = "0.3.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-support", @@ -8953,7 +8965,7 @@ dependencies = [ [[package]] name = "pallet-atomic-swap" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "parity-scale-codec", "polkadot-sdk-frame", @@ -8963,7 +8975,7 @@ dependencies = [ [[package]] name = "pallet-aura" version = "40.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-support", "frame-system", @@ -8979,7 +8991,7 @@ dependencies = [ [[package]] name = "pallet-authority-discovery" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-support", "frame-system", @@ -8994,7 +9006,7 @@ dependencies = [ [[package]] name = "pallet-authorship" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-support", "frame-system", @@ -9007,7 +9019,7 @@ dependencies = [ [[package]] name = "pallet-babe" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-support", @@ -9030,7 +9042,7 @@ dependencies = [ [[package]] name = "pallet-bags-list" version = "40.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "aquamarine", "docify", @@ -9051,7 +9063,7 @@ dependencies = [ [[package]] name = "pallet-balances" version = "42.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "docify", "frame-benchmarking", @@ -9067,7 +9079,7 @@ dependencies = [ [[package]] name = "pallet-base-fee" version = "1.0.0" -source = "git+https://github.com/opentensor/frontier?rev=f12a1274f91442a564bb722a2b9547caba487fa0#f12a1274f91442a564bb722a2b9547caba487fa0" +source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" dependencies = [ "fp-evm", "frame-support", @@ -9081,7 +9093,7 @@ dependencies = [ [[package]] name = "pallet-beefy" version = "42.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-support", "frame-system", @@ -9100,7 +9112,7 @@ dependencies = [ [[package]] name = "pallet-beefy-mmr" version = "42.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "array-bytes 6.2.3", "binary-merkle-tree", @@ -9125,7 +9137,7 @@ dependencies = [ [[package]] name = "pallet-bounties" version = "40.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-support", @@ -9142,7 +9154,7 @@ dependencies = [ [[package]] name = "pallet-bridge-grandpa" version = "0.21.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "bp-header-chain", "bp-runtime", @@ -9161,7 +9173,7 @@ dependencies = [ [[package]] name = "pallet-bridge-messages" version = "0.21.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "bp-header-chain", "bp-messages", @@ -9180,7 +9192,7 @@ dependencies = [ [[package]] name = "pallet-bridge-parachains" version = "0.21.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "bp-header-chain", "bp-parachains", @@ -9200,7 +9212,7 @@ dependencies = [ [[package]] name = "pallet-bridge-relayers" version = "0.21.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "bp-header-chain", "bp-messages", @@ -9223,7 +9235,7 @@ dependencies = [ [[package]] name = "pallet-broker" version = "0.20.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "bitvec", "frame-benchmarking", @@ -9241,7 +9253,7 @@ dependencies = [ [[package]] name = "pallet-child-bounties" version = "40.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-support", @@ -9259,7 +9271,7 @@ dependencies = [ [[package]] name = "pallet-collator-selection" version = "22.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-support", @@ -9278,7 +9290,7 @@ dependencies = [ [[package]] name = "pallet-collective" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "docify", "frame-benchmarking", @@ -9295,7 +9307,7 @@ dependencies = [ [[package]] name = "pallet-collective-content" version = "0.19.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-support", @@ -9333,41 +9345,10 @@ dependencies = [ "w3f-bls 0.1.3", ] -[[package]] -name = "pallet-contracts" -version = "40.1.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-stable2503-6#598feddb893f5ad3923a62e41a2f179b6e10c30c" -dependencies = [ - "environmental", - "frame-benchmarking", - "frame-support", - "frame-system", - "impl-trait-for-tuples", - "log", - "pallet-balances", - "pallet-contracts-proc-macro 23.0.3 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-stable2503-6)", - "pallet-contracts-uapi 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-stable2503-6)", - "parity-scale-codec", - "paste", - "rand 0.8.5", - "rand_pcg", - "scale-info", - "serde", - "smallvec", - "sp-api", - "sp-core", - "sp-io", - "sp-runtime", - "staging-xcm", - "staging-xcm-builder", - "wasm-instrument", - "wasmi 0.32.3", -] - [[package]] name = "pallet-contracts" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "environmental", "frame-benchmarking", @@ -9376,8 +9357,8 @@ dependencies = [ "impl-trait-for-tuples", "log", "pallet-balances", - "pallet-contracts-proc-macro 23.0.3 (git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8)", - "pallet-contracts-uapi 14.0.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8)", + "pallet-contracts-proc-macro", + "pallet-contracts-uapi", "parity-scale-codec", "paste", "rand 0.8.5", @@ -9398,14 +9379,14 @@ dependencies = [ [[package]] name = "pallet-contracts-mock-network" version = "18.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-support", "frame-system", "pallet-assets", "pallet-balances", - "pallet-contracts 41.0.0", - "pallet-contracts-uapi 14.0.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8)", + "pallet-contracts", + "pallet-contracts-uapi", "pallet-message-queue", "pallet-timestamp", "pallet-xcm", @@ -9429,38 +9410,17 @@ dependencies = [ [[package]] name = "pallet-contracts-proc-macro" version = "23.0.3" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-stable2503-6#598feddb893f5ad3923a62e41a2f179b6e10c30c" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "proc-macro2", "quote", "syn 2.0.106", ] -[[package]] -name = "pallet-contracts-proc-macro" -version = "23.0.3" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "pallet-contracts-uapi" -version = "14.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-stable2503-6#598feddb893f5ad3923a62e41a2f179b6e10c30c" -dependencies = [ - "bitflags 1.3.2", - "parity-scale-codec", - "paste", - "scale-info", -] - [[package]] name = "pallet-contracts-uapi" version = "14.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "bitflags 1.3.2", "parity-scale-codec", @@ -9471,7 +9431,7 @@ dependencies = [ [[package]] name = "pallet-conviction-voting" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "assert_matches", "frame-benchmarking", @@ -9487,7 +9447,7 @@ dependencies = [ [[package]] name = "pallet-core-fellowship" version = "25.0.1" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-support", @@ -9524,7 +9484,7 @@ dependencies = [ [[package]] name = "pallet-delegated-staking" version = "8.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-support", "frame-system", @@ -9539,7 +9499,7 @@ dependencies = [ [[package]] name = "pallet-democracy" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-support", @@ -9556,7 +9516,7 @@ dependencies = [ [[package]] name = "pallet-dev-mode" version = "23.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-support", "frame-system", @@ -9605,7 +9565,7 @@ dependencies = [ [[package]] name = "pallet-dummy-dim" version = "0.2.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-support", @@ -9623,7 +9583,7 @@ dependencies = [ [[package]] name = "pallet-election-provider-multi-block" version = "0.2.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -9644,7 +9604,7 @@ dependencies = [ [[package]] name = "pallet-election-provider-multi-phase" version = "40.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -9665,7 +9625,7 @@ dependencies = [ [[package]] name = "pallet-election-provider-support-benchmarking" version = "40.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -9678,7 +9638,7 @@ dependencies = [ [[package]] name = "pallet-elections-phragmen" version = "42.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-support", @@ -9696,7 +9656,7 @@ dependencies = [ [[package]] name = "pallet-ethereum" version = "4.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=f12a1274f91442a564bb722a2b9547caba487fa0#f12a1274f91442a564bb722a2b9547caba487fa0" +source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" dependencies = [ "ethereum", "ethereum-types", @@ -9719,7 +9679,7 @@ dependencies = [ [[package]] name = "pallet-evm" version = "6.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=f12a1274f91442a564bb722a2b9547caba487fa0#f12a1274f91442a564bb722a2b9547caba487fa0" +source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" dependencies = [ "cumulus-primitives-storage-weight-reclaim", "environmental", @@ -9744,7 +9704,7 @@ dependencies = [ [[package]] name = "pallet-evm-chain-id" version = "1.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=f12a1274f91442a564bb722a2b9547caba487fa0#f12a1274f91442a564bb722a2b9547caba487fa0" +source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" dependencies = [ "frame-support", "frame-system", @@ -9755,7 +9715,7 @@ dependencies = [ [[package]] name = "pallet-evm-precompile-bn128" version = "2.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=f12a1274f91442a564bb722a2b9547caba487fa0#f12a1274f91442a564bb722a2b9547caba487fa0" +source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" dependencies = [ "fp-evm", "sp-core", @@ -9765,7 +9725,7 @@ dependencies = [ [[package]] name = "pallet-evm-precompile-dispatch" version = "2.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=f12a1274f91442a564bb722a2b9547caba487fa0#f12a1274f91442a564bb722a2b9547caba487fa0" +source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" dependencies = [ "fp-evm", "frame-support", @@ -9777,7 +9737,7 @@ dependencies = [ [[package]] name = "pallet-evm-precompile-modexp" version = "2.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=f12a1274f91442a564bb722a2b9547caba487fa0#f12a1274f91442a564bb722a2b9547caba487fa0" +source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" dependencies = [ "fp-evm", "num", @@ -9786,7 +9746,7 @@ dependencies = [ [[package]] name = "pallet-evm-precompile-sha3fips" version = "2.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=f12a1274f91442a564bb722a2b9547caba487fa0#f12a1274f91442a564bb722a2b9547caba487fa0" +source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" dependencies = [ "fp-evm", "tiny-keccak", @@ -9795,7 +9755,7 @@ dependencies = [ [[package]] name = "pallet-evm-precompile-simple" version = "2.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=f12a1274f91442a564bb722a2b9547caba487fa0#f12a1274f91442a564bb722a2b9547caba487fa0" +source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" dependencies = [ "fp-evm", "ripemd", @@ -9805,7 +9765,7 @@ dependencies = [ [[package]] name = "pallet-fast-unstake" version = "40.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "docify", "frame-benchmarking", @@ -9823,7 +9783,7 @@ dependencies = [ [[package]] name = "pallet-glutton" version = "27.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "blake2 0.10.6", "frame-benchmarking", @@ -9841,7 +9801,7 @@ dependencies = [ [[package]] name = "pallet-grandpa" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-support", @@ -9863,7 +9823,7 @@ dependencies = [ [[package]] name = "pallet-hotfix-sufficients" version = "1.0.0" -source = "git+https://github.com/opentensor/frontier?rev=f12a1274f91442a564bb722a2b9547caba487fa0#f12a1274f91442a564bb722a2b9547caba487fa0" +source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" dependencies = [ "frame-benchmarking", "frame-support", @@ -9878,7 +9838,7 @@ dependencies = [ [[package]] name = "pallet-identity" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "enumflags2", "frame-benchmarking", @@ -9894,7 +9854,7 @@ dependencies = [ [[package]] name = "pallet-im-online" version = "40.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-support", @@ -9913,7 +9873,7 @@ dependencies = [ [[package]] name = "pallet-indices" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-support", @@ -9928,7 +9888,7 @@ dependencies = [ [[package]] name = "pallet-insecure-randomness-collective-flip" version = "29.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "parity-scale-codec", "polkadot-sdk-frame", @@ -9939,7 +9899,7 @@ dependencies = [ [[package]] name = "pallet-lottery" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-support", @@ -9952,7 +9912,7 @@ dependencies = [ [[package]] name = "pallet-membership" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-support", @@ -9968,7 +9928,7 @@ dependencies = [ [[package]] name = "pallet-message-queue" version = "44.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "environmental", "frame-benchmarking", @@ -9987,7 +9947,7 @@ dependencies = [ [[package]] name = "pallet-meta-tx" version = "0.3.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "docify", "frame-benchmarking", @@ -10005,7 +9965,7 @@ dependencies = [ [[package]] name = "pallet-migrations" version = "11.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "docify", "frame-benchmarking", @@ -10024,7 +9984,7 @@ dependencies = [ [[package]] name = "pallet-mixnet" version = "0.17.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "log", "parity-scale-codec", @@ -10038,7 +9998,7 @@ dependencies = [ [[package]] name = "pallet-mmr" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "log", "parity-scale-codec", @@ -10050,7 +10010,7 @@ dependencies = [ [[package]] name = "pallet-multisig" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "log", "parity-scale-codec", @@ -10061,7 +10021,7 @@ dependencies = [ [[package]] name = "pallet-nft-fractionalization" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "log", "pallet-assets", @@ -10074,7 +10034,7 @@ dependencies = [ [[package]] name = "pallet-nfts" version = "35.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "enumflags2", "frame-benchmarking", @@ -10091,7 +10051,7 @@ dependencies = [ [[package]] name = "pallet-nis" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "parity-scale-codec", "polkadot-sdk-frame", @@ -10101,7 +10061,7 @@ dependencies = [ [[package]] name = "pallet-node-authorization" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "log", "parity-scale-codec", @@ -10112,7 +10072,7 @@ dependencies = [ [[package]] name = "pallet-nomination-pools" version = "39.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-support", "frame-system", @@ -10130,7 +10090,7 @@ dependencies = [ [[package]] name = "pallet-nomination-pools-benchmarking" version = "39.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -10150,7 +10110,7 @@ dependencies = [ [[package]] name = "pallet-nomination-pools-runtime-api" version = "37.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "pallet-nomination-pools", "parity-scale-codec", @@ -10160,7 +10120,7 @@ dependencies = [ [[package]] name = "pallet-offences" version = "40.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-support", "frame-system", @@ -10175,7 +10135,7 @@ dependencies = [ [[package]] name = "pallet-offences-benchmarking" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -10198,7 +10158,7 @@ dependencies = [ [[package]] name = "pallet-origin-restriction" version = "0.2.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-support", @@ -10216,7 +10176,7 @@ dependencies = [ [[package]] name = "pallet-paged-list" version = "0.19.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "docify", "parity-scale-codec", @@ -10227,7 +10187,7 @@ dependencies = [ [[package]] name = "pallet-parameters" version = "0.12.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "docify", "frame-benchmarking", @@ -10244,7 +10204,7 @@ dependencies = [ [[package]] name = "pallet-people" version = "0.2.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-support", @@ -10262,7 +10222,7 @@ dependencies = [ [[package]] name = "pallet-preimage" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-support", @@ -10278,7 +10238,7 @@ dependencies = [ [[package]] name = "pallet-proxy" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "parity-scale-codec", "polkadot-sdk-frame", @@ -10288,7 +10248,7 @@ dependencies = [ [[package]] name = "pallet-ranked-collective" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-support", @@ -10306,7 +10266,7 @@ dependencies = [ [[package]] name = "pallet-recovery" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "parity-scale-codec", "polkadot-sdk-frame", @@ -10316,7 +10276,7 @@ dependencies = [ [[package]] name = "pallet-referenda" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "assert_matches", "frame-benchmarking", @@ -10351,7 +10311,7 @@ dependencies = [ [[package]] name = "pallet-remark" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-support", @@ -10366,7 +10326,7 @@ dependencies = [ [[package]] name = "pallet-revive" version = "0.7.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "alloy-core", "derive_more 0.99.20", @@ -10412,7 +10372,7 @@ dependencies = [ [[package]] name = "pallet-revive-fixtures" version = "0.4.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "anyhow", "cargo_metadata", @@ -10426,7 +10386,7 @@ dependencies = [ [[package]] name = "pallet-revive-proc-macro" version = "0.3.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "proc-macro2", "quote", @@ -10436,7 +10396,7 @@ dependencies = [ [[package]] name = "pallet-revive-uapi" version = "0.5.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "bitflags 1.3.2", "pallet-revive-proc-macro", @@ -10448,7 +10408,7 @@ dependencies = [ [[package]] name = "pallet-root-offences" version = "38.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-support", "frame-system", @@ -10464,7 +10424,7 @@ dependencies = [ [[package]] name = "pallet-root-testing" version = "17.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-support", "frame-system", @@ -10477,7 +10437,7 @@ dependencies = [ [[package]] name = "pallet-safe-mode" version = "22.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "docify", "pallet-balances", @@ -10491,7 +10451,7 @@ dependencies = [ [[package]] name = "pallet-salary" version = "26.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "log", "pallet-ranked-collective", @@ -10503,7 +10463,7 @@ dependencies = [ [[package]] name = "pallet-scheduler" version = "42.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "docify", "frame-benchmarking", @@ -10520,7 +10480,7 @@ dependencies = [ [[package]] name = "pallet-scored-pool" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-support", "frame-system", @@ -10533,7 +10493,7 @@ dependencies = [ [[package]] name = "pallet-session" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-support", "frame-system", @@ -10554,7 +10514,7 @@ dependencies = [ [[package]] name = "pallet-session-benchmarking" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-support", @@ -10590,7 +10550,7 @@ dependencies = [ [[package]] name = "pallet-skip-feeless-payment" version = "16.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-support", "frame-system", @@ -10602,7 +10562,7 @@ dependencies = [ [[package]] name = "pallet-society" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-support", @@ -10619,7 +10579,7 @@ dependencies = [ [[package]] name = "pallet-staking" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -10641,7 +10601,7 @@ dependencies = [ [[package]] name = "pallet-staking-async" version = "0.2.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -10664,7 +10624,7 @@ dependencies = [ [[package]] name = "pallet-staking-async-ah-client" version = "0.2.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-support", "frame-system", @@ -10683,7 +10643,7 @@ dependencies = [ [[package]] name = "pallet-staking-async-rc-client" version = "0.2.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-support", "frame-system", @@ -10700,7 +10660,7 @@ dependencies = [ [[package]] name = "pallet-staking-reward-curve" version = "12.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "proc-macro-crate 3.4.0", "proc-macro2", @@ -10711,7 +10671,7 @@ dependencies = [ [[package]] name = "pallet-staking-reward-fn" version = "23.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "log", "sp-arithmetic", @@ -10720,7 +10680,7 @@ dependencies = [ [[package]] name = "pallet-staking-runtime-api" version = "27.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "parity-scale-codec", "sp-api", @@ -10730,7 +10690,7 @@ dependencies = [ [[package]] name = "pallet-state-trie-migration" version = "46.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-support", @@ -10746,7 +10706,7 @@ dependencies = [ [[package]] name = "pallet-statement" version = "23.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-support", "frame-system", @@ -10775,15 +10735,18 @@ dependencies = [ "log", "ndarray", "num-traits", + "pallet-aura", "pallet-balances", "pallet-commitments", "pallet-crowdloan", "pallet-drand", "pallet-preimage", "pallet-scheduler", + "pallet-shield", "pallet-subtensor-proxy", "pallet-subtensor-swap", "pallet-subtensor-utility", + "pallet-timestamp", "pallet-transaction-payment", "parity-scale-codec", "polkadot-runtime-common", @@ -10795,6 +10758,7 @@ dependencies = [ "serde_json", "sha2 0.10.9", "share-pool", + "sp-consensus-aura", "sp-core", "sp-io", "sp-keyring", @@ -10817,6 +10781,8 @@ dependencies = [ name = "pallet-subtensor-proxy" version = "40.1.0" dependencies = [ + "frame-support", + "frame-system", "pallet-balances", "pallet-subtensor-utility", "parity-scale-codec", @@ -10901,7 +10867,7 @@ dependencies = [ [[package]] name = "pallet-sudo" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "docify", "frame-benchmarking", @@ -10916,7 +10882,7 @@ dependencies = [ [[package]] name = "pallet-timestamp" version = "40.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "docify", "frame-benchmarking", @@ -10934,7 +10900,7 @@ dependencies = [ [[package]] name = "pallet-tips" version = "40.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-support", @@ -10952,7 +10918,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-support", @@ -10967,7 +10933,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc" version = "44.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "jsonrpsee", "pallet-transaction-payment-rpc-runtime-api", @@ -10983,7 +10949,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc-runtime-api" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "pallet-transaction-payment", "parity-scale-codec", @@ -10995,7 +10961,7 @@ dependencies = [ [[package]] name = "pallet-transaction-storage" version = "40.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "array-bytes 6.2.3", "frame-benchmarking", @@ -11014,7 +10980,7 @@ dependencies = [ [[package]] name = "pallet-treasury" version = "40.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "docify", "frame-benchmarking", @@ -11033,7 +10999,7 @@ dependencies = [ [[package]] name = "pallet-tx-pause" version = "22.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "docify", "parity-scale-codec", @@ -11044,7 +11010,7 @@ dependencies = [ [[package]] name = "pallet-uniques" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-support", @@ -11058,7 +11024,7 @@ dependencies = [ [[package]] name = "pallet-utility" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-support", @@ -11073,7 +11039,7 @@ dependencies = [ [[package]] name = "pallet-verify-signature" version = "0.4.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-support", @@ -11088,7 +11054,7 @@ dependencies = [ [[package]] name = "pallet-vesting" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-support", @@ -11102,7 +11068,7 @@ dependencies = [ [[package]] name = "pallet-whitelist" version = "40.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "parity-scale-codec", "polkadot-sdk-frame", @@ -11112,7 +11078,7 @@ dependencies = [ [[package]] name = "pallet-xcm" version = "20.1.3" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "bounded-collections 0.2.4", "frame-benchmarking", @@ -11138,7 +11104,7 @@ dependencies = [ [[package]] name = "pallet-xcm-benchmarks" version = "21.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-benchmarking", "frame-support", @@ -11155,7 +11121,7 @@ dependencies = [ [[package]] name = "pallet-xcm-bridge-hub" version = "0.17.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "bp-messages", "bp-runtime", @@ -11177,7 +11143,7 @@ dependencies = [ [[package]] name = "pallet-xcm-bridge-hub-router" version = "0.19.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "bp-xcm-bridge-hub-router", "frame-benchmarking", @@ -11197,7 +11163,7 @@ dependencies = [ [[package]] name = "parachains-common" version = "22.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "cumulus-primitives-core", "cumulus-primitives-utility", @@ -11536,7 +11502,7 @@ checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "polkadot-approval-distribution" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "futures", "futures-timer", @@ -11554,7 +11520,7 @@ dependencies = [ [[package]] name = "polkadot-availability-bitfield-distribution" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "futures", "futures-timer", @@ -11569,7 +11535,7 @@ dependencies = [ [[package]] name = "polkadot-availability-distribution" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "fatality", "futures", @@ -11592,7 +11558,7 @@ dependencies = [ [[package]] name = "polkadot-availability-recovery" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "async-trait", "fatality", @@ -11625,7 +11591,7 @@ dependencies = [ [[package]] name = "polkadot-cli" version = "25.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "clap", "frame-benchmarking-cli", @@ -11649,7 +11615,7 @@ dependencies = [ [[package]] name = "polkadot-collator-protocol" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "bitvec", "fatality", @@ -11672,7 +11638,7 @@ dependencies = [ [[package]] name = "polkadot-core-primitives" version = "18.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "parity-scale-codec", "scale-info", @@ -11683,7 +11649,7 @@ dependencies = [ [[package]] name = "polkadot-dispute-distribution" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "fatality", "futures", @@ -11705,7 +11671,7 @@ dependencies = [ [[package]] name = "polkadot-erasure-coding" version = "20.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "parity-scale-codec", "polkadot-node-primitives", @@ -11719,7 +11685,7 @@ dependencies = [ [[package]] name = "polkadot-gossip-support" version = "24.0.1" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "futures", "futures-timer", @@ -11732,7 +11698,7 @@ dependencies = [ "sc-network", "sp-application-crypto", "sp-core", - "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8)", + "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61)", "sp-keystore", "tracing-gum", ] @@ -11740,7 +11706,7 @@ dependencies = [ [[package]] name = "polkadot-network-bridge" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "always-assert", "async-trait", @@ -11763,7 +11729,7 @@ dependencies = [ [[package]] name = "polkadot-node-collation-generation" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "futures", "parity-scale-codec", @@ -11781,7 +11747,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-approval-voting" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "async-trait", "bitvec", @@ -11813,7 +11779,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-approval-voting-parallel" version = "0.7.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "async-trait", "futures", @@ -11837,7 +11803,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-av-store" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "bitvec", "futures", @@ -11856,7 +11822,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-backing" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "bitvec", "fatality", @@ -11877,7 +11843,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-bitfield-signing" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "futures", "polkadot-node-subsystem", @@ -11892,7 +11858,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-candidate-validation" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "async-trait", "futures", @@ -11914,7 +11880,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-chain-api" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "futures", "polkadot-node-metrics", @@ -11928,7 +11894,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-chain-selection" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "futures", "futures-timer", @@ -11944,7 +11910,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-dispute-coordinator" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "fatality", "futures", @@ -11962,7 +11928,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-parachains-inherent" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "async-trait", "futures", @@ -11979,7 +11945,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-prospective-parachains" version = "23.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "fatality", "futures", @@ -11993,7 +11959,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-provisioner" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "bitvec", "fatality", @@ -12010,7 +11976,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-pvf" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "always-assert", "array-bytes 6.2.3", @@ -12038,7 +12004,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-pvf-checker" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "futures", "polkadot-node-subsystem", @@ -12051,7 +12017,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-pvf-common" version = "20.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "cpu-time", "futures", @@ -12066,7 +12032,7 @@ dependencies = [ "sc-executor-wasmtime", "seccompiler", "sp-core", - "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8)", + "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61)", "sp-externalities", "sp-io", "sp-tracing", @@ -12077,7 +12043,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-runtime-api" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "futures", "polkadot-node-metrics", @@ -12092,7 +12058,7 @@ dependencies = [ [[package]] name = "polkadot-node-metrics" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "bs58", "futures", @@ -12109,7 +12075,7 @@ dependencies = [ [[package]] name = "polkadot-node-network-protocol" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "async-channel 1.9.0", "async-trait", @@ -12134,7 +12100,7 @@ dependencies = [ [[package]] name = "polkadot-node-primitives" version = "20.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "bitvec", "bounded-vec", @@ -12158,7 +12124,7 @@ dependencies = [ [[package]] name = "polkadot-node-subsystem" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "polkadot-node-subsystem-types", "polkadot-overseer", @@ -12167,7 +12133,7 @@ dependencies = [ [[package]] name = "polkadot-node-subsystem-types" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "async-trait", "derive_more 0.99.20", @@ -12195,7 +12161,7 @@ dependencies = [ [[package]] name = "polkadot-node-subsystem-util" version = "24.0.1" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "fatality", "futures", @@ -12226,7 +12192,7 @@ dependencies = [ [[package]] name = "polkadot-omni-node-lib" version = "0.7.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "async-trait", "clap", @@ -12312,7 +12278,7 @@ dependencies = [ [[package]] name = "polkadot-overseer" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "async-trait", "futures", @@ -12332,7 +12298,7 @@ dependencies = [ [[package]] name = "polkadot-parachain-primitives" version = "17.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "bounded-collections 0.2.4", "derive_more 0.99.20", @@ -12348,7 +12314,7 @@ dependencies = [ [[package]] name = "polkadot-primitives" version = "19.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "bitvec", "bounded-collections 0.2.4", @@ -12377,7 +12343,7 @@ dependencies = [ [[package]] name = "polkadot-rpc" version = "25.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "jsonrpsee", "mmr-rpc", @@ -12410,7 +12376,7 @@ dependencies = [ [[package]] name = "polkadot-runtime-common" version = "20.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "bitvec", "frame-benchmarking", @@ -12460,7 +12426,7 @@ dependencies = [ [[package]] name = "polkadot-runtime-metrics" version = "21.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "bs58", "frame-benchmarking", @@ -12472,7 +12438,7 @@ dependencies = [ [[package]] name = "polkadot-runtime-parachains" version = "20.0.2" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "bitflags 1.3.2", "bitvec", @@ -12520,7 +12486,7 @@ dependencies = [ [[package]] name = "polkadot-sdk" version = "2506.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "assets-common", "bridge-hub-common", @@ -12575,7 +12541,7 @@ dependencies = [ "pallet-collator-selection", "pallet-collective", "pallet-collective-content", - "pallet-contracts 41.0.0", + "pallet-contracts", "pallet-contracts-mock-network", "pallet-conviction-voting", "pallet-core-fellowship", @@ -12678,7 +12644,7 @@ dependencies = [ [[package]] name = "polkadot-sdk-frame" version = "0.10.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "docify", "frame-benchmarking", @@ -12713,7 +12679,7 @@ dependencies = [ [[package]] name = "polkadot-service" version = "25.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "async-trait", "frame-benchmarking", @@ -12821,7 +12787,7 @@ dependencies = [ [[package]] name = "polkadot-statement-distribution" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "bitvec", "fatality", @@ -12841,7 +12807,7 @@ dependencies = [ [[package]] name = "polkadot-statement-table" version = "20.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "parity-scale-codec", "polkadot-primitives", @@ -13114,20 +13080,25 @@ dependencies = [ [[package]] name = "precompile-utils" version = "0.1.0" -source = "git+https://github.com/opentensor/frontier?rev=f12a1274f91442a564bb722a2b9547caba487fa0#f12a1274f91442a564bb722a2b9547caba487fa0" +source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" dependencies = [ + "derive_more 1.0.0", "environmental", "evm", "fp-evm", "frame-support", "frame-system", "hex", + "hex-literal", "impl-trait-for-tuples", "log", "num_enum", "pallet-evm", "parity-scale-codec", "precompile-utils-macro", + "scale-info", + "serde", + "similar-asserts", "sp-core", "sp-io", "sp-runtime", @@ -13138,14 +13109,14 @@ dependencies = [ [[package]] name = "precompile-utils-macro" version = "0.1.0" -source = "git+https://github.com/opentensor/frontier?rev=f12a1274f91442a564bb722a2b9547caba487fa0#f12a1274f91442a564bb722a2b9547caba487fa0" +source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" dependencies = [ "case", "num_enum", "prettyplease", "proc-macro2", "quote", - "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8)", + "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61)", "syn 2.0.106", ] @@ -13327,7 +13298,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8)", + "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61)", "syn 2.0.106", ] @@ -13957,7 +13928,7 @@ dependencies = [ [[package]] name = "rococo-runtime" version = "24.0.1" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "binary-merkle-tree", "bitvec", @@ -14055,7 +14026,7 @@ dependencies = [ [[package]] name = "rococo-runtime-constants" version = "21.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-support", "polkadot-primitives", @@ -14451,7 +14422,7 @@ dependencies = [ [[package]] name = "sc-allocator" version = "32.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "log", "sp-core", @@ -14462,7 +14433,7 @@ dependencies = [ [[package]] name = "sc-authority-discovery" version = "0.51.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "async-trait", "futures", @@ -14493,7 +14464,7 @@ dependencies = [ [[package]] name = "sc-basic-authorship" version = "0.50.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "futures", "log", @@ -14514,7 +14485,7 @@ dependencies = [ [[package]] name = "sc-block-builder" version = "0.45.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "parity-scale-codec", "sp-api", @@ -14529,7 +14500,7 @@ dependencies = [ [[package]] name = "sc-chain-spec" version = "44.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "array-bytes 6.2.3", "clap", @@ -14545,7 +14516,7 @@ dependencies = [ "serde_json", "sp-blockchain", "sp-core", - "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8)", + "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61)", "sp-genesis-builder", "sp-io", "sp-runtime", @@ -14556,7 +14527,7 @@ dependencies = [ [[package]] name = "sc-chain-spec-derive" version = "12.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "proc-macro-crate 3.4.0", "proc-macro2", @@ -14567,7 +14538,7 @@ dependencies = [ [[package]] name = "sc-cli" version = "0.53.1" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "array-bytes 6.2.3", "chrono", @@ -14609,7 +14580,7 @@ dependencies = [ [[package]] name = "sc-client-api" version = "40.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "fnv", "futures", @@ -14635,7 +14606,7 @@ dependencies = [ [[package]] name = "sc-client-db" version = "0.47.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "hash-db", "kvdb", @@ -14663,7 +14634,7 @@ dependencies = [ [[package]] name = "sc-consensus" version = "0.50.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "async-trait", "futures", @@ -14686,7 +14657,7 @@ dependencies = [ [[package]] name = "sc-consensus-aura" version = "0.51.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "async-trait", "futures", @@ -14715,7 +14686,7 @@ dependencies = [ [[package]] name = "sc-consensus-babe" version = "0.51.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "async-trait", "fork-tree", @@ -14740,7 +14711,7 @@ dependencies = [ "sp-consensus-babe", "sp-consensus-slots", "sp-core", - "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8)", + "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61)", "sp-inherents", "sp-keystore", "sp-runtime", @@ -14751,7 +14722,7 @@ dependencies = [ [[package]] name = "sc-consensus-babe-rpc" version = "0.51.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "futures", "jsonrpsee", @@ -14773,7 +14744,7 @@ dependencies = [ [[package]] name = "sc-consensus-beefy" version = "30.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "array-bytes 6.2.3", "async-channel 1.9.0", @@ -14807,7 +14778,7 @@ dependencies = [ [[package]] name = "sc-consensus-beefy-rpc" version = "30.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "futures", "jsonrpsee", @@ -14827,7 +14798,7 @@ dependencies = [ [[package]] name = "sc-consensus-epochs" version = "0.50.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "fork-tree", "parity-scale-codec", @@ -14840,7 +14811,7 @@ dependencies = [ [[package]] name = "sc-consensus-grandpa" version = "0.36.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "ahash", "array-bytes 6.2.3", @@ -14874,7 +14845,7 @@ dependencies = [ "sp-consensus", "sp-consensus-grandpa", "sp-core", - "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8)", + "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61)", "sp-keystore", "sp-runtime", "substrate-prometheus-endpoint", @@ -14884,7 +14855,7 @@ dependencies = [ [[package]] name = "sc-consensus-grandpa-rpc" version = "0.36.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "finality-grandpa", "futures", @@ -14904,7 +14875,7 @@ dependencies = [ [[package]] name = "sc-consensus-manual-seal" version = "0.52.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "assert_matches", "async-trait", @@ -14939,7 +14910,7 @@ dependencies = [ [[package]] name = "sc-consensus-slots" version = "0.50.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "async-trait", "futures", @@ -14962,7 +14933,7 @@ dependencies = [ [[package]] name = "sc-executor" version = "0.43.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "parity-scale-codec", "parking_lot 0.12.5", @@ -14985,7 +14956,7 @@ dependencies = [ [[package]] name = "sc-executor-common" version = "0.39.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "polkavm 0.24.0", "sc-allocator", @@ -14998,7 +14969,7 @@ dependencies = [ [[package]] name = "sc-executor-polkavm" version = "0.36.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "log", "polkavm 0.24.0", @@ -15009,7 +14980,7 @@ dependencies = [ [[package]] name = "sc-executor-wasmtime" version = "0.39.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "anyhow", "log", @@ -15025,7 +14996,7 @@ dependencies = [ [[package]] name = "sc-informant" version = "0.50.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "console", "futures", @@ -15041,7 +15012,7 @@ dependencies = [ [[package]] name = "sc-keystore" version = "36.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "array-bytes 6.2.3", "parking_lot 0.12.5", @@ -15055,7 +15026,7 @@ dependencies = [ [[package]] name = "sc-mixnet" version = "0.21.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "array-bytes 6.2.3", "arrayvec 0.7.6", @@ -15083,7 +15054,7 @@ dependencies = [ [[package]] name = "sc-network" version = "0.51.1" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "array-bytes 6.2.3", "async-channel 1.9.0", @@ -15133,7 +15104,7 @@ dependencies = [ [[package]] name = "sc-network-common" version = "0.49.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "bitflags 1.3.2", "parity-scale-codec", @@ -15143,7 +15114,7 @@ dependencies = [ [[package]] name = "sc-network-gossip" version = "0.51.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "ahash", "futures", @@ -15162,7 +15133,7 @@ dependencies = [ [[package]] name = "sc-network-light" version = "0.50.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "array-bytes 6.2.3", "async-channel 1.9.0", @@ -15183,7 +15154,7 @@ dependencies = [ [[package]] name = "sc-network-statement" version = "0.33.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "array-bytes 6.2.3", "async-channel 1.9.0", @@ -15203,7 +15174,7 @@ dependencies = [ [[package]] name = "sc-network-sync" version = "0.50.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "array-bytes 6.2.3", "async-channel 1.9.0", @@ -15238,7 +15209,7 @@ dependencies = [ [[package]] name = "sc-network-transactions" version = "0.50.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "array-bytes 6.2.3", "futures", @@ -15257,7 +15228,7 @@ dependencies = [ [[package]] name = "sc-network-types" version = "0.17.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "bs58", "bytes", @@ -15278,7 +15249,7 @@ dependencies = [ [[package]] name = "sc-offchain" version = "46.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "bytes", "fnv", @@ -15312,7 +15283,7 @@ dependencies = [ [[package]] name = "sc-proposer-metrics" version = "0.20.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "log", "substrate-prometheus-endpoint", @@ -15321,7 +15292,7 @@ dependencies = [ [[package]] name = "sc-rpc" version = "46.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "futures", "jsonrpsee", @@ -15353,7 +15324,7 @@ dependencies = [ [[package]] name = "sc-rpc-api" version = "0.50.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "jsonrpsee", "parity-scale-codec", @@ -15373,7 +15344,7 @@ dependencies = [ [[package]] name = "sc-rpc-server" version = "23.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "dyn-clone", "forwarded-header-value", @@ -15397,7 +15368,7 @@ dependencies = [ [[package]] name = "sc-rpc-spec-v2" version = "0.51.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "array-bytes 6.2.3", "futures", @@ -15430,13 +15401,13 @@ dependencies = [ [[package]] name = "sc-runtime-utilities" version = "0.3.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "parity-scale-codec", "sc-executor", "sc-executor-common", "sp-core", - "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8)", + "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61)", "sp-state-machine", "sp-wasm-interface", "thiserror 1.0.69", @@ -15445,7 +15416,7 @@ dependencies = [ [[package]] name = "sc-service" version = "0.52.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "async-trait", "directories", @@ -15509,7 +15480,7 @@ dependencies = [ [[package]] name = "sc-state-db" version = "0.39.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "log", "parity-scale-codec", @@ -15520,7 +15491,7 @@ dependencies = [ [[package]] name = "sc-statement-store" version = "22.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "log", "parity-db", @@ -15539,7 +15510,7 @@ dependencies = [ [[package]] name = "sc-storage-monitor" version = "0.25.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "clap", "fs4", @@ -15552,7 +15523,7 @@ dependencies = [ [[package]] name = "sc-sync-state-rpc" version = "0.51.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "jsonrpsee", "parity-scale-codec", @@ -15571,7 +15542,7 @@ dependencies = [ [[package]] name = "sc-sysinfo" version = "43.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "derive_more 0.99.20", "futures", @@ -15584,14 +15555,14 @@ dependencies = [ "serde", "serde_json", "sp-core", - "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8)", + "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61)", "sp-io", ] [[package]] name = "sc-telemetry" version = "29.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "chrono", "futures", @@ -15610,7 +15581,7 @@ dependencies = [ [[package]] name = "sc-tracing" version = "40.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "chrono", "console", @@ -15638,7 +15609,7 @@ dependencies = [ [[package]] name = "sc-tracing-proc-macro" version = "11.1.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "proc-macro-crate 3.4.0", "proc-macro2", @@ -15649,7 +15620,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool" version = "40.1.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "async-trait", "futures", @@ -15666,7 +15637,7 @@ dependencies = [ "sp-api", "sp-blockchain", "sp-core", - "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8)", + "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61)", "sp-runtime", "sp-tracing", "sp-transaction-pool", @@ -15680,7 +15651,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool-api" version = "40.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "async-trait", "futures", @@ -15697,7 +15668,7 @@ dependencies = [ [[package]] name = "sc-utils" version = "19.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "async-channel 1.9.0", "futures", @@ -16353,6 +16324,26 @@ dependencies = [ "wide", ] +[[package]] +name = "similar" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" +dependencies = [ + "bstr", + "unicode-segmentation", +] + +[[package]] +name = "similar-asserts" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b441962c817e33508847a22bd82f03a30cff43642dc2fae8b050566121eb9a" +dependencies = [ + "console", + "similar", +] + [[package]] name = "simple-dns" version = "0.9.3" @@ -16395,7 +16386,7 @@ checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" [[package]] name = "slot-range-helper" version = "18.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "enumn", "parity-scale-codec", @@ -16658,7 +16649,7 @@ dependencies = [ [[package]] name = "snowbridge-core" version = "0.14.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "bp-relayers", "frame-support", @@ -16742,7 +16733,7 @@ dependencies = [ [[package]] name = "sp-api" version = "37.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "docify", "hash-db", @@ -16764,7 +16755,7 @@ dependencies = [ [[package]] name = "sp-api-proc-macro" version = "23.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "Inflector", "blake2 0.10.6", @@ -16778,7 +16769,7 @@ dependencies = [ [[package]] name = "sp-application-crypto" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "parity-scale-codec", "scale-info", @@ -16790,7 +16781,7 @@ dependencies = [ [[package]] name = "sp-arithmetic" version = "27.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "docify", "integer-sqrt", @@ -16804,7 +16795,7 @@ dependencies = [ [[package]] name = "sp-authority-discovery" version = "37.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "parity-scale-codec", "scale-info", @@ -16816,7 +16807,7 @@ dependencies = [ [[package]] name = "sp-block-builder" version = "37.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "sp-api", "sp-inherents", @@ -16826,7 +16817,7 @@ dependencies = [ [[package]] name = "sp-blockchain" version = "40.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "futures", "parity-scale-codec", @@ -16845,7 +16836,7 @@ dependencies = [ [[package]] name = "sp-consensus" version = "0.43.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "async-trait", "futures", @@ -16859,7 +16850,7 @@ dependencies = [ [[package]] name = "sp-consensus-aura" version = "0.43.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "async-trait", "parity-scale-codec", @@ -16875,7 +16866,7 @@ dependencies = [ [[package]] name = "sp-consensus-babe" version = "0.43.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "async-trait", "parity-scale-codec", @@ -16893,7 +16884,7 @@ dependencies = [ [[package]] name = "sp-consensus-beefy" version = "25.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "parity-scale-codec", "scale-info", @@ -16901,7 +16892,7 @@ dependencies = [ "sp-api", "sp-application-crypto", "sp-core", - "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8)", + "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61)", "sp-io", "sp-keystore", "sp-mmr-primitives", @@ -16913,7 +16904,7 @@ dependencies = [ [[package]] name = "sp-consensus-grandpa" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "finality-grandpa", "log", @@ -16930,7 +16921,7 @@ dependencies = [ [[package]] name = "sp-consensus-slots" version = "0.43.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "parity-scale-codec", "scale-info", @@ -16941,7 +16932,7 @@ dependencies = [ [[package]] name = "sp-core" version = "37.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "ark-vrf", "array-bytes 6.2.3", @@ -16972,7 +16963,7 @@ dependencies = [ "secrecy 0.8.0", "serde", "sha2 0.10.9", - "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8)", + "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61)", "sp-debug-derive", "sp-externalities", "sp-runtime-interface", @@ -16989,7 +16980,7 @@ dependencies = [ [[package]] name = "sp-crypto-ec-utils" version = "0.16.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "ark-bls12-377", "ark-bls12-377-ext", @@ -17023,7 +17014,7 @@ dependencies = [ [[package]] name = "sp-crypto-hashing" version = "0.1.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "blake2b_simd", "byteorder", @@ -17036,17 +17027,17 @@ dependencies = [ [[package]] name = "sp-crypto-hashing-proc-macro" version = "0.1.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "quote", - "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8)", + "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61)", "syn 2.0.106", ] [[package]] name = "sp-database" version = "10.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "kvdb", "parking_lot 0.12.5", @@ -17055,7 +17046,7 @@ dependencies = [ [[package]] name = "sp-debug-derive" version = "14.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "proc-macro2", "quote", @@ -17065,7 +17056,7 @@ dependencies = [ [[package]] name = "sp-externalities" version = "0.30.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "environmental", "parity-scale-codec", @@ -17075,7 +17066,7 @@ dependencies = [ [[package]] name = "sp-genesis-builder" version = "0.18.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "parity-scale-codec", "scale-info", @@ -17087,7 +17078,7 @@ dependencies = [ [[package]] name = "sp-inherents" version = "37.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "async-trait", "impl-trait-for-tuples", @@ -17100,7 +17091,7 @@ dependencies = [ [[package]] name = "sp-io" version = "41.0.1" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "bytes", "docify", @@ -17112,7 +17103,7 @@ dependencies = [ "rustversion", "secp256k1 0.28.2", "sp-core", - "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8)", + "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61)", "sp-externalities", "sp-keystore", "sp-runtime-interface", @@ -17126,7 +17117,7 @@ dependencies = [ [[package]] name = "sp-keyring" version = "42.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "sp-core", "sp-runtime", @@ -17136,7 +17127,7 @@ dependencies = [ [[package]] name = "sp-keystore" version = "0.43.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "parity-scale-codec", "parking_lot 0.12.5", @@ -17147,7 +17138,7 @@ dependencies = [ [[package]] name = "sp-maybe-compressed-blob" version = "11.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "thiserror 1.0.69", "zstd 0.12.4", @@ -17156,7 +17147,7 @@ dependencies = [ [[package]] name = "sp-metadata-ir" version = "0.11.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-metadata 23.0.0", "parity-scale-codec", @@ -17166,7 +17157,7 @@ dependencies = [ [[package]] name = "sp-mixnet" version = "0.15.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "parity-scale-codec", "scale-info", @@ -17177,7 +17168,7 @@ dependencies = [ [[package]] name = "sp-mmr-primitives" version = "37.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "log", "parity-scale-codec", @@ -17194,7 +17185,7 @@ dependencies = [ [[package]] name = "sp-npos-elections" version = "37.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "parity-scale-codec", "scale-info", @@ -17207,7 +17198,7 @@ dependencies = [ [[package]] name = "sp-offchain" version = "37.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "sp-api", "sp-core", @@ -17217,7 +17208,7 @@ dependencies = [ [[package]] name = "sp-panic-handler" version = "13.0.2" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "backtrace", "regex", @@ -17226,7 +17217,7 @@ dependencies = [ [[package]] name = "sp-rpc" version = "35.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "rustc-hash 1.1.0", "serde", @@ -17236,7 +17227,7 @@ dependencies = [ [[package]] name = "sp-runtime" version = "42.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "binary-merkle-tree", "docify", @@ -17265,7 +17256,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface" version = "30.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "bytes", "impl-trait-for-tuples", @@ -17284,7 +17275,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" version = "19.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "Inflector", "expander", @@ -17297,7 +17288,7 @@ dependencies = [ [[package]] name = "sp-session" version = "39.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "parity-scale-codec", "scale-info", @@ -17311,7 +17302,7 @@ dependencies = [ [[package]] name = "sp-staking" version = "39.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", @@ -17324,7 +17315,7 @@ dependencies = [ [[package]] name = "sp-state-machine" version = "0.46.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "hash-db", "log", @@ -17344,7 +17335,7 @@ dependencies = [ [[package]] name = "sp-statement-store" version = "21.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "aes-gcm", "curve25519-dalek", @@ -17357,7 +17348,7 @@ dependencies = [ "sp-api", "sp-application-crypto", "sp-core", - "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8)", + "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61)", "sp-externalities", "sp-runtime", "sp-runtime-interface", @@ -17368,12 +17359,12 @@ dependencies = [ [[package]] name = "sp-std" version = "14.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" [[package]] name = "sp-storage" version = "22.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "impl-serde", "parity-scale-codec", @@ -17385,7 +17376,7 @@ dependencies = [ [[package]] name = "sp-timestamp" version = "37.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "async-trait", "parity-scale-codec", @@ -17397,7 +17388,7 @@ dependencies = [ [[package]] name = "sp-tracing" version = "17.1.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "parity-scale-codec", "tracing", @@ -17408,7 +17399,7 @@ dependencies = [ [[package]] name = "sp-transaction-pool" version = "37.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "sp-api", "sp-runtime", @@ -17417,7 +17408,7 @@ dependencies = [ [[package]] name = "sp-transaction-storage-proof" version = "37.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "async-trait", "parity-scale-codec", @@ -17431,7 +17422,7 @@ dependencies = [ [[package]] name = "sp-trie" version = "40.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "ahash", "foldhash 0.1.5", @@ -17456,7 +17447,7 @@ dependencies = [ [[package]] name = "sp-version" version = "40.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "impl-serde", "parity-scale-codec", @@ -17473,7 +17464,7 @@ dependencies = [ [[package]] name = "sp-version-proc-macro" version = "15.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "parity-scale-codec", "proc-macro-warning", @@ -17485,7 +17476,7 @@ dependencies = [ [[package]] name = "sp-wasm-interface" version = "22.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "anyhow", "impl-trait-for-tuples", @@ -17497,7 +17488,7 @@ dependencies = [ [[package]] name = "sp-weights" version = "32.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "bounded-collections 0.2.4", "parity-scale-codec", @@ -17671,7 +17662,7 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "staging-chain-spec-builder" version = "12.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "clap", "docify", @@ -17684,7 +17675,7 @@ dependencies = [ [[package]] name = "staging-node-inspect" version = "0.29.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "clap", "parity-scale-codec", @@ -17702,7 +17693,7 @@ dependencies = [ [[package]] name = "staging-parachain-info" version = "0.21.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -17715,7 +17706,7 @@ dependencies = [ [[package]] name = "staging-xcm" version = "17.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "array-bytes 6.2.3", "bounded-collections 0.2.4", @@ -17736,7 +17727,7 @@ dependencies = [ [[package]] name = "staging-xcm-builder" version = "21.1.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "environmental", "frame-support", @@ -17760,7 +17751,7 @@ dependencies = [ [[package]] name = "staging-xcm-executor" version = "20.0.1" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "environmental", "frame-benchmarking", @@ -17872,7 +17863,7 @@ dependencies = [ [[package]] name = "substrate-bip39" version = "0.6.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "hmac 0.12.1", "pbkdf2", @@ -17897,7 +17888,7 @@ dependencies = [ [[package]] name = "substrate-build-script-utils" version = "11.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" [[package]] name = "substrate-fixed" @@ -17913,7 +17904,7 @@ dependencies = [ [[package]] name = "substrate-frame-rpc-system" version = "45.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "docify", "frame-system-rpc-runtime-api", @@ -17933,7 +17924,7 @@ dependencies = [ [[package]] name = "substrate-prometheus-endpoint" version = "0.17.6" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "http-body-util", "hyper 1.7.0", @@ -17947,7 +17938,7 @@ dependencies = [ [[package]] name = "substrate-state-trie-migration-rpc" version = "44.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "jsonrpsee", "parity-scale-codec", @@ -17974,7 +17965,7 @@ dependencies = [ [[package]] name = "substrate-wasm-builder" version = "27.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "array-bytes 6.2.3", "build-helper", @@ -18022,7 +18013,7 @@ dependencies = [ "log", "num_enum", "pallet-balances", - "pallet-contracts 40.1.0", + "pallet-contracts", "pallet-crowdloan", "pallet-drand", "pallet-preimage", @@ -18105,6 +18096,7 @@ dependencies = [ "pallet-evm-precompile-modexp", "pallet-evm-precompile-sha3fips", "pallet-evm-precompile-simple", + "pallet-shield", "pallet-subtensor", "pallet-subtensor-proxy", "pallet-subtensor-swap", @@ -18124,6 +18116,7 @@ name = "subtensor-runtime-common" version = "0.1.0" dependencies = [ "approx", + "environmental", "frame-support", "parity-scale-codec", "polkadot-runtime-common", @@ -19003,7 +18996,7 @@ dependencies = [ [[package]] name = "tracing-gum" version = "20.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "coarsetime", "polkadot-primitives", @@ -19014,7 +19007,7 @@ dependencies = [ [[package]] name = "tracing-gum-proc-macro" version = "5.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "expander", "proc-macro-crate 3.4.0", @@ -19965,7 +19958,7 @@ checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "westend-runtime" version = "24.0.1" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "binary-merkle-tree", "bitvec", @@ -20072,7 +20065,7 @@ dependencies = [ [[package]] name = "westend-runtime-constants" version = "21.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-support", "polkadot-primitives", @@ -20625,7 +20618,7 @@ dependencies = [ [[package]] name = "xcm-procedural" version = "11.0.2" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "Inflector", "proc-macro2", @@ -20636,7 +20629,7 @@ dependencies = [ [[package]] name = "xcm-runtime-apis" version = "0.8.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-support", "parity-scale-codec", @@ -20650,7 +20643,7 @@ dependencies = [ [[package]] name = "xcm-simulator" version = "21.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8#a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" dependencies = [ "frame-support", "frame-system", diff --git a/Cargo.toml b/Cargo.toml index efc22431fa..32bcacf4c3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -118,159 +118,160 @@ ahash = { version = "0.8", default-features = false } regex = { version = "1.11.1", default-features = false } ethereum = { version = "0.18.2", default-features = false } num_enum = { version = "0.7.4", default-features = false } +environmental = { version = "1.1.4", default-features = false } -frame = { package = "polkadot-sdk-frame", git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -frame-benchmarking = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -frame-benchmarking-cli = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -frame-executive = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -frame-metadata-hash-extension = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -frame-support = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -frame-system = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -frame-system-benchmarking = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -frame-system-rpc-runtime-api = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -frame-try-runtime = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } +frame = { package = "polkadot-sdk-frame", git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +frame-benchmarking = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +frame-benchmarking-cli = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +frame-executive = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +frame-metadata-hash-extension = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +frame-support = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +frame-system = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +frame-system-benchmarking = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +frame-system-rpc-runtime-api = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +frame-try-runtime = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } frame-metadata = { version = "23.0.0", default-features = false } pallet-subtensor-proxy = { path = "pallets/proxy", default-features = false } pallet-subtensor-utility = { path = "pallets/utility", default-features = false } -pallet-babe = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -pallet-aura = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -pallet-balances = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -pallet-grandpa = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -pallet-insecure-randomness-collective-flip = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -pallet-multisig = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -pallet-preimage = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -pallet-safe-mode = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -pallet-scheduler = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -pallet-sudo = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -pallet-timestamp = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -pallet-transaction-payment = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -pallet-transaction-payment-rpc = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -pallet-root-testing = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -pallet-contracts = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } +pallet-babe = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +pallet-aura = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +pallet-balances = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +pallet-grandpa = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +pallet-insecure-randomness-collective-flip = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +pallet-multisig = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +pallet-preimage = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +pallet-safe-mode = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +pallet-scheduler = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +pallet-sudo = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +pallet-timestamp = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +pallet-transaction-payment = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +pallet-transaction-payment-rpc = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +pallet-root-testing = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +pallet-contracts = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } # NPoS -frame-election-provider-support = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -pallet-authority-discovery = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -pallet-authorship = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -pallet-bags-list = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -pallet-election-provider-multi-phase = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -pallet-fast-unstake = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -pallet-nomination-pools = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -pallet-nomination-pools-runtime-api = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -pallet-session = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -pallet-staking = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -pallet-staking-runtime-api = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -pallet-staking-reward-fn = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -pallet-staking-reward-curve = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -pallet-offences = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } +frame-election-provider-support = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +pallet-authority-discovery = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +pallet-authorship = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +pallet-bags-list = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +pallet-election-provider-multi-phase = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +pallet-fast-unstake = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +pallet-nomination-pools = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +pallet-nomination-pools-runtime-api = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +pallet-session = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +pallet-staking = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +pallet-staking-runtime-api = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +pallet-staking-reward-fn = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +pallet-staking-reward-curve = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +pallet-offences = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } -sc-basic-authorship = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sc-cli = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sc-client-api = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sc-consensus = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sc-consensus-aura = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sc-consensus-babe = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sc-consensus-babe-rpc = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sc-consensus-grandpa = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sc-consensus-grandpa-rpc = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sc-consensus-epochs = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sc-chain-spec-derive = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sc-chain-spec = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sc-consensus-slots = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sc-executor = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sc-keystore = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sc-network = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sc-offchain = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sc-rpc = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sc-rpc-api = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sc-service = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sc-telemetry = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sc-transaction-pool = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sc-transaction-pool-api = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sc-consensus-manual-seal = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sc-network-sync = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } +sc-basic-authorship = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sc-cli = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sc-client-api = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sc-consensus = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sc-consensus-aura = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sc-consensus-babe = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sc-consensus-babe-rpc = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sc-consensus-grandpa = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sc-consensus-grandpa-rpc = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sc-consensus-epochs = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sc-chain-spec-derive = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sc-chain-spec = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sc-consensus-slots = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sc-executor = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sc-keystore = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sc-network = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sc-offchain = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sc-rpc = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sc-rpc-api = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sc-service = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sc-telemetry = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sc-transaction-pool = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sc-transaction-pool-api = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sc-consensus-manual-seal = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sc-network-sync = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } -sp-api = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sp-authority-discovery = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sp-arithmetic = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sp-block-builder = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sp-blockchain = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sp-staking = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sp-consensus = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sp-consensus-aura = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sp-consensus-babe = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sp-consensus-slots = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sp-npos-elections = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sp-consensus-grandpa = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sp-genesis-builder = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sp-core = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sp-inherents = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sp-io = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sp-keyring = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sp-offchain = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sp-rpc = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sp-runtime = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sp-session = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sp-std = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sp-storage = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sp-timestamp = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sp-tracing = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sp-transaction-pool = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sp-version = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sp-weights = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sp-crypto-hashing = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -sp-application-crypto = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } +sp-api = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sp-authority-discovery = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sp-arithmetic = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sp-block-builder = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sp-blockchain = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sp-staking = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sp-consensus = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sp-consensus-aura = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sp-consensus-babe = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sp-consensus-slots = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sp-npos-elections = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sp-consensus-grandpa = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sp-genesis-builder = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sp-core = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sp-inherents = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sp-io = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sp-keyring = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sp-offchain = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sp-rpc = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sp-runtime = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sp-session = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sp-std = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sp-storage = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sp-timestamp = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sp-tracing = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sp-transaction-pool = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sp-version = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sp-weights = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sp-crypto-hashing = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sp-application-crypto = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } -substrate-build-script-utils = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } +substrate-build-script-utils = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } substrate-fixed = { git = "https://github.com/encointer/substrate-fixed.git", tag = "v0.6.0", default-features = false } -substrate-frame-rpc-system = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -substrate-wasm-builder = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } -substrate-prometheus-endpoint = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } +substrate-frame-rpc-system = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +substrate-wasm-builder = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +substrate-prometheus-endpoint = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } -polkadot-sdk = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } +polkadot-sdk = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } -runtime-common = { package = "polkadot-runtime-common", git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } +runtime-common = { package = "polkadot-runtime-common", git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } # Frontier -fp-evm = { git = "https://github.com/opentensor/frontier", rev = "f12a1274f91442a564bb722a2b9547caba487fa0", default-features = false } -fp-rpc = { git = "https://github.com/opentensor/frontier", rev = "f12a1274f91442a564bb722a2b9547caba487fa0", default-features = false } -fp-self-contained = { git = "https://github.com/opentensor/frontier", rev = "f12a1274f91442a564bb722a2b9547caba487fa0", default-features = false } -fp-account = { git = "https://github.com/opentensor/frontier", rev = "f12a1274f91442a564bb722a2b9547caba487fa0", default-features = false } -fc-storage = { git = "https://github.com/opentensor/frontier", rev = "f12a1274f91442a564bb722a2b9547caba487fa0", default-features = false } -fc-db = { git = "https://github.com/opentensor/frontier", rev = "f12a1274f91442a564bb722a2b9547caba487fa0", default-features = false } -fc-consensus = { git = "https://github.com/opentensor/frontier", rev = "f12a1274f91442a564bb722a2b9547caba487fa0", default-features = false } -fp-consensus = { git = "https://github.com/opentensor/frontier", rev = "f12a1274f91442a564bb722a2b9547caba487fa0", default-features = false } -fp-dynamic-fee = { git = "https://github.com/opentensor/frontier", rev = "f12a1274f91442a564bb722a2b9547caba487fa0", default-features = false } -fc-api = { git = "https://github.com/opentensor/frontier", rev = "f12a1274f91442a564bb722a2b9547caba487fa0", default-features = false } -fc-rpc = { git = "https://github.com/opentensor/frontier", rev = "f12a1274f91442a564bb722a2b9547caba487fa0", default-features = false } -fc-rpc-core = { git = "https://github.com/opentensor/frontier", rev = "f12a1274f91442a564bb722a2b9547caba487fa0", default-features = false } -fc-aura = { git = "https://github.com/opentensor/frontier", rev = "f12a1274f91442a564bb722a2b9547caba487fa0", default-features = false } -fc-babe = { git = "https://github.com/opentensor/frontier", rev = "f12a1274f91442a564bb722a2b9547caba487fa0", default-features = false } -fc-mapping-sync = { git = "https://github.com/opentensor/frontier", rev = "f12a1274f91442a564bb722a2b9547caba487fa0", default-features = false } -precompile-utils = { git = "https://github.com/opentensor/frontier", rev = "f12a1274f91442a564bb722a2b9547caba487fa0", default-features = false } +fp-evm = { git = "https://github.com/opentensor/frontier", rev = "b51a81bb3f2a94eabaafcde40eab6a91accf3f36", default-features = false } +fp-rpc = { git = "https://github.com/opentensor/frontier", rev = "b51a81bb3f2a94eabaafcde40eab6a91accf3f36", default-features = false } +fp-self-contained = { git = "https://github.com/opentensor/frontier", rev = "b51a81bb3f2a94eabaafcde40eab6a91accf3f36", default-features = false } +fp-account = { git = "https://github.com/opentensor/frontier", rev = "b51a81bb3f2a94eabaafcde40eab6a91accf3f36", default-features = false } +fc-storage = { git = "https://github.com/opentensor/frontier", rev = "b51a81bb3f2a94eabaafcde40eab6a91accf3f36", default-features = false } +fc-db = { git = "https://github.com/opentensor/frontier", rev = "b51a81bb3f2a94eabaafcde40eab6a91accf3f36", default-features = false } +fc-consensus = { git = "https://github.com/opentensor/frontier", rev = "b51a81bb3f2a94eabaafcde40eab6a91accf3f36", default-features = false } +fp-consensus = { git = "https://github.com/opentensor/frontier", rev = "b51a81bb3f2a94eabaafcde40eab6a91accf3f36", default-features = false } +fp-dynamic-fee = { git = "https://github.com/opentensor/frontier", rev = "b51a81bb3f2a94eabaafcde40eab6a91accf3f36", default-features = false } +fc-api = { git = "https://github.com/opentensor/frontier", rev = "b51a81bb3f2a94eabaafcde40eab6a91accf3f36", default-features = false } +fc-rpc = { git = "https://github.com/opentensor/frontier", rev = "b51a81bb3f2a94eabaafcde40eab6a91accf3f36", default-features = false } +fc-rpc-core = { git = "https://github.com/opentensor/frontier", rev = "b51a81bb3f2a94eabaafcde40eab6a91accf3f36", default-features = false } +fc-aura = { git = "https://github.com/opentensor/frontier", rev = "b51a81bb3f2a94eabaafcde40eab6a91accf3f36", default-features = false } +fc-babe = { git = "https://github.com/opentensor/frontier", rev = "b51a81bb3f2a94eabaafcde40eab6a91accf3f36", default-features = false } +fc-mapping-sync = { git = "https://github.com/opentensor/frontier", rev = "b51a81bb3f2a94eabaafcde40eab6a91accf3f36", default-features = false } +precompile-utils = { git = "https://github.com/opentensor/frontier", rev = "b51a81bb3f2a94eabaafcde40eab6a91accf3f36", default-features = false } # Frontier FRAME -pallet-base-fee = { git = "https://github.com/opentensor/frontier", rev = "f12a1274f91442a564bb722a2b9547caba487fa0", default-features = false } -pallet-dynamic-fee = { git = "https://github.com/opentensor/frontier", rev = "f12a1274f91442a564bb722a2b9547caba487fa0", default-features = false } -pallet-ethereum = { git = "https://github.com/opentensor/frontier", rev = "f12a1274f91442a564bb722a2b9547caba487fa0", default-features = false } -pallet-evm = { git = "https://github.com/opentensor/frontier", rev = "f12a1274f91442a564bb722a2b9547caba487fa0", default-features = false } -pallet-evm-precompile-dispatch = { git = "https://github.com/opentensor/frontier", rev = "f12a1274f91442a564bb722a2b9547caba487fa0", default-features = false } -pallet-evm-chain-id = { git = "https://github.com/opentensor/frontier", rev = "f12a1274f91442a564bb722a2b9547caba487fa0", default-features = false } -pallet-evm-precompile-modexp = { git = "https://github.com/opentensor/frontier", rev = "f12a1274f91442a564bb722a2b9547caba487fa0", default-features = false } -pallet-evm-precompile-sha3fips = { git = "https://github.com/opentensor/frontier", rev = "f12a1274f91442a564bb722a2b9547caba487fa0", default-features = false } -pallet-evm-precompile-simple = { git = "https://github.com/opentensor/frontier", rev = "f12a1274f91442a564bb722a2b9547caba487fa0", default-features = false } -pallet-evm-precompile-bn128 = { git = "https://github.com/opentensor/frontier", rev = "f12a1274f91442a564bb722a2b9547caba487fa0", default-features = false } -pallet-hotfix-sufficients = { git = "https://github.com/opentensor/frontier", rev = "f12a1274f91442a564bb722a2b9547caba487fa0", default-features = false } +pallet-base-fee = { git = "https://github.com/opentensor/frontier", rev = "b51a81bb3f2a94eabaafcde40eab6a91accf3f36", default-features = false } +pallet-dynamic-fee = { git = "https://github.com/opentensor/frontier", rev = "b51a81bb3f2a94eabaafcde40eab6a91accf3f36", default-features = false } +pallet-ethereum = { git = "https://github.com/opentensor/frontier", rev = "b51a81bb3f2a94eabaafcde40eab6a91accf3f36", default-features = false } +pallet-evm = { git = "https://github.com/opentensor/frontier", rev = "b51a81bb3f2a94eabaafcde40eab6a91accf3f36", default-features = false } +pallet-evm-precompile-dispatch = { git = "https://github.com/opentensor/frontier", rev = "b51a81bb3f2a94eabaafcde40eab6a91accf3f36", default-features = false } +pallet-evm-chain-id = { git = "https://github.com/opentensor/frontier", rev = "b51a81bb3f2a94eabaafcde40eab6a91accf3f36", default-features = false } +pallet-evm-precompile-modexp = { git = "https://github.com/opentensor/frontier", rev = "b51a81bb3f2a94eabaafcde40eab6a91accf3f36", default-features = false } +pallet-evm-precompile-sha3fips = { git = "https://github.com/opentensor/frontier", rev = "b51a81bb3f2a94eabaafcde40eab6a91accf3f36", default-features = false } +pallet-evm-precompile-simple = { git = "https://github.com/opentensor/frontier", rev = "b51a81bb3f2a94eabaafcde40eab6a91accf3f36", default-features = false } +pallet-evm-precompile-bn128 = { git = "https://github.com/opentensor/frontier", rev = "b51a81bb3f2a94eabaafcde40eab6a91accf3f36", default-features = false } +pallet-hotfix-sufficients = { git = "https://github.com/opentensor/frontier", rev = "b51a81bb3f2a94eabaafcde40eab6a91accf3f36", default-features = false } #DRAND pallet-drand = { path = "pallets/drand", default-features = false } -sp-crypto-ec-utils = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } +sp-crypto-ec-utils = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } getrandom = { version = "0.2.15", default-features = false, features = [ "custom", ] } -sp-keystore = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503-6", default-features = false } +sp-keystore = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } w3f-bls = { git = "https://github.com/opentensor/bls", branch = "fix-no-std", default-features = false } ark-crypto-primitives = { version = "0.4.0", default-features = false } ark-scale = { version = "0.0.11", default-features = false } @@ -305,203 +306,4 @@ default = [] pow-faucet = [] [patch.crates-io] -w3f-bls = { git = "https://github.com/opentensor/bls", branch = "fix-no-std" } - -# Patches automatically generated with `diener`: -# `diener patch --target https://github.com/paritytech/polkadot-sdk --point-to-git https://github.com/opentensor/polkadot-sdk.git --point-to-git-commit 81fa2c54e94f824eba7dabe9dffd063481cb2d80 --crates-to-patch ../polkadot-sdk --ignore-unused` -# -# Using latest commit from `polkadot-stable2506-2-otf-patches`. -# -# View code changes here: -# -# -# NOTE: The Diener will patch unnecesarry crates while this is waiting to be merged: . -# You may install diener from `liamaharon:ignore-unused-flag` if you like in the meantime. -[patch."https://github.com/paritytech/polkadot-sdk"] -frame-support = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -binary-merkle-tree = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-core = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-crypto-hashing = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-crypto-hashing-proc-macro = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-debug-derive = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-externalities = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-storage = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-runtime-interface = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-runtime-interface-proc-macro = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-std = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-tracing = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-wasm-interface = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-io = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-keystore = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-state-machine = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-panic-handler = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-trie = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-runtime = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-application-crypto = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-arithmetic = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-weights = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-api = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-api-proc-macro = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-metadata-ir = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-version = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-version-proc-macro = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-block-builder = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-block-builder = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-inherents = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-blockchain = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-consensus = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-database = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-client-api = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -substrate-prometheus-endpoint = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-executor = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-executor-common = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-allocator = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-maybe-compressed-blob = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-executor-polkavm = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-executor-wasmtime = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -substrate-wasm-builder = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-tracing = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-tracing-proc-macro = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-rpc = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -frame-executive = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -frame-system = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -frame-try-runtime = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -pallet-balances = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -frame-benchmarking = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -frame-support-procedural = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -frame-support-procedural-tools = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -frame-support-procedural-tools-derive = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-client-db = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-state-db = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -polkadot-sdk-frame = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -frame-system-benchmarking = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -frame-system-rpc-runtime-api = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-consensus-aura = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-consensus-slots = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-timestamp = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-consensus-grandpa = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-genesis-builder = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-keyring = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-offchain = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-session = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-staking = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-transaction-pool = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -polkadot-sdk = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -cumulus-primitives-core = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -polkadot-core-primitives = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -polkadot-parachain-primitives = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -polkadot-primitives = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-authority-discovery = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -staging-xcm = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -xcm-procedural = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -cumulus-primitives-parachain-inherent = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -cumulus-primitives-proof-size-hostfunction = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -pallet-message-queue = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -polkadot-runtime-parachains = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -pallet-authority-discovery = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -pallet-session = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -pallet-timestamp = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -pallet-authorship = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -pallet-babe = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-consensus-babe = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -frame-election-provider-support = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -frame-election-provider-solution-type = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-npos-elections = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -pallet-offences = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -pallet-staking = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -pallet-bags-list = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -pallet-staking-reward-curve = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -pallet-broker = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -pallet-mmr = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-mmr-primitives = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -polkadot-runtime-metrics = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -staging-xcm-executor = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-keystore = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -staging-xcm-builder = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -pallet-asset-conversion = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -pallet-transaction-payment = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -pallet-grandpa = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -pallet-sudo = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -pallet-vesting = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -polkadot-runtime-common = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -pallet-asset-rate = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -pallet-election-provider-multi-phase = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -pallet-election-provider-support-benchmarking = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -pallet-fast-unstake = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -pallet-identity = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -pallet-staking-reward-fn = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -pallet-treasury = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -pallet-utility = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -pallet-root-testing = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -slot-range-helper = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -cumulus-primitives-storage-weight-reclaim = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -pallet-aura = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -cumulus-test-relay-sproof-builder = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-chain-spec = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-chain-spec-derive = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-network = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-network-common = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-network-types = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-utils = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-telemetry = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-cli = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-mixnet = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-transaction-pool-api = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-mixnet = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-service = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-consensus = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-informant = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-network-sync = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -fork-tree = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-network-light = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-network-transactions = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-rpc = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-rpc-api = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-statement-store = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-transaction-pool = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-rpc-server = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-rpc-spec-v2 = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-sysinfo = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-transaction-storage-proof = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -cumulus-relay-chain-interface = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -polkadot-overseer = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -tracing-gum = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -tracing-gum-proc-macro = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -polkadot-node-metrics = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -polkadot-node-primitives = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -polkadot-node-subsystem-types = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -polkadot-node-network-protocol = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-authority-discovery = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -polkadot-statement-table = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -frame-benchmarking-cli = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -cumulus-client-parachain-inherent = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-runtime-utilities = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -frame-metadata-hash-extension = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -pallet-nomination-pools = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -pallet-membership = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -pallet-multisig = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -pallet-nomination-pools-runtime-api = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -pallet-preimage = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -pallet-proxy = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -pallet-scheduler = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -pallet-staking-runtime-api = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-offchain = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-consensus-babe = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-consensus-epochs = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-consensus-slots = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -pallet-transaction-payment-rpc = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-consensus-babe-rpc = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-network-gossip = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-consensus-grandpa = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-consensus-grandpa-rpc = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -substrate-frame-rpc-system = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-basic-authorship = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-proposer-metrics = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -substrate-build-script-utils = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-consensus-aura = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -pallet-insecure-randomness-collective-flip = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -pallet-safe-mode = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sc-consensus-manual-seal = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -sp-crypto-ec-utils = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } -substrate-bip39 = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "a584a577eeaf31e3f1a65e91b0e0b41f0356f7c8" } +w3f-bls = { git = "https://github.com/opentensor/bls", branch = "fix-no-std" } \ No newline at end of file diff --git a/chain-extensions/src/mock.rs b/chain-extensions/src/mock.rs index 660aa0c77c..45c7811adb 100644 --- a/chain-extensions/src/mock.rs +++ b/chain-extensions/src/mock.rs @@ -25,7 +25,7 @@ use sp_runtime::{ traits::{BlakeTwo256, Convert, IdentityLookup}, }; use sp_std::{cell::RefCell, cmp::Ordering, sync::OnceLock}; -use subtensor_runtime_common::{AlphaCurrency, NetUid, TaoCurrency}; +use subtensor_runtime_common::{AlphaCurrency, AuthorshipInfo, NetUid, TaoCurrency}; type Block = frame_system::mocking::MockBlock; @@ -262,6 +262,14 @@ parameter_types! { pub const AnnouncementDepositFactor: Balance = 1; } +pub struct MockAuthorshipProvider; + +impl AuthorshipInfo for MockAuthorshipProvider { + fn author() -> Option { + Some(U256::from(12345u64)) + } +} + parameter_types! { pub const InitialMinAllowedWeights: u16 = 0; pub const InitialEmissionValue: u16 = 0; @@ -325,9 +333,8 @@ parameter_types! { pub const InitialAlphaLow: u16 = 45875; // Represents 0.7 as per the production default pub const InitialLiquidAlphaOn: bool = false; // Default value for LiquidAlphaOn pub const InitialYuma3On: bool = false; // Default value for Yuma3On - // pub const InitialNetworkMaxStake: u64 = u64::MAX; // (DEPRECATED) - pub const InitialColdkeySwapScheduleDuration: u64 = 5 * 24 * 60 * 60 / 12; // Default as 5 days - pub const InitialColdkeySwapRescheduleDuration: u64 = 24 * 60 * 60 / 12; // Default as 1 day + pub const InitialColdkeySwapAnnouncementDelay: u64 = 50; + pub const InitialColdkeySwapReannouncementDelay: u64 = 10; pub const InitialDissolveNetworkScheduleDuration: u64 = 5 * 24 * 60 * 60 / 12; // Default as 5 days pub const InitialTaoWeight: u64 = 0; // 100% global weight. pub const InitialEmaPriceHalvingPeriod: u64 = 201_600_u64; // 4 weeks @@ -397,8 +404,8 @@ impl pallet_subtensor::Config for Test { type LiquidAlphaOn = InitialLiquidAlphaOn; type Yuma3On = InitialYuma3On; type Preimages = Preimage; - type InitialColdkeySwapScheduleDuration = InitialColdkeySwapScheduleDuration; - type InitialColdkeySwapRescheduleDuration = InitialColdkeySwapRescheduleDuration; + type InitialColdkeySwapAnnouncementDelay = InitialColdkeySwapAnnouncementDelay; + type InitialColdkeySwapReannouncementDelay = InitialColdkeySwapReannouncementDelay; type InitialDissolveNetworkScheduleDuration = InitialDissolveNetworkScheduleDuration; type InitialTaoWeight = InitialTaoWeight; type InitialEmaPriceHalvingPeriod = InitialEmaPriceHalvingPeriod; @@ -412,6 +419,7 @@ impl pallet_subtensor::Config for Test { type MaxImmuneUidsPercentage = MaxImmuneUidsPercentage; type CommitmentsInterface = CommitmentsI; type EvmKeyAssociateRateLimit = EvmKeyAssociateRateLimit; + type AuthorshipProvider = MockAuthorshipProvider; } // Swap-related parameter types diff --git a/common/Cargo.toml b/common/Cargo.toml index 8b9c010238..732b0cc5b1 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -12,6 +12,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { workspace = true, features = ["derive"] } +environmental.workspace = true frame-support.workspace = true scale-info.workspace = true serde.workspace = true @@ -31,6 +32,7 @@ approx = ["dep:approx"] fast-runtime = [] std = [ "codec/std", + "environmental/std", "frame-support/std", "scale-info/std", "serde/std", diff --git a/common/src/evm_context.rs b/common/src/evm_context.rs new file mode 100644 index 0000000000..62ae973866 --- /dev/null +++ b/common/src/evm_context.rs @@ -0,0 +1,47 @@ +environmental::environmental!(IN_EVM: bool); + +/// Returns `true` if the current dispatch originated from an EVM precompile. +pub fn is_in_evm() -> bool { + IN_EVM::with(|v| *v).unwrap_or(false) +} + +/// Executes `f` within an EVM context, making `is_in_evm()` return `true` +/// for the duration of the closure. Uses `using_once` so nested calls +/// reuse the already-set value instead of building a stack. +pub fn with_evm_context(f: impl FnOnce() -> R) -> R { + IN_EVM::using_once(&mut true, f) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn is_in_evm_returns_false_by_default() { + assert!(!is_in_evm()); + } + + #[test] + fn with_evm_context_sets_flag() { + with_evm_context(|| { + assert!(is_in_evm()); + }); + } + + #[test] + fn flag_clears_after_evm_context() { + with_evm_context(|| {}); + assert!(!is_in_evm()); + } + + #[test] + fn nested_evm_context_stays_true() { + with_evm_context(|| { + with_evm_context(|| { + assert!(is_in_evm()); + }); + // Still true after inner context exits thanks to using_once. + assert!(is_in_evm()); + }); + } +} diff --git a/common/src/lib.rs b/common/src/lib.rs index 658f8b2e01..a63b92779a 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -15,8 +15,10 @@ use sp_runtime::{ use subtensor_macros::freeze_struct; pub use currency::*; +pub use evm_context::*; mod currency; +mod evm_context; /// Balance of an account. pub type Balance = u64; @@ -260,6 +262,12 @@ pub trait BalanceOps { ) -> Result; } +/// Allows to query the current block author +pub trait AuthorshipInfo { + /// Return the current block author + fn author() -> Option; +} + pub mod time { use super::*; diff --git a/contract-tests/bittensor/Cargo.toml b/contract-tests/bittensor/Cargo.toml index ff46eb3696..a322f2f99e 100755 --- a/contract-tests/bittensor/Cargo.toml +++ b/contract-tests/bittensor/Cargo.toml @@ -10,7 +10,6 @@ edition = "2021" ink = { version = "5.1.1", default-features = false } parity-scale-codec = { version = "3.0.0", default-features = false } serde = { version = "1.0.228", default-features = false } -subtensor-runtime-common = { path = "../../common", default-features = false } [dev-dependencies] ink_e2e = { version = "5.1.1" } @@ -23,7 +22,6 @@ std = [ "ink/std", "parity-scale-codec/std", "serde/std", - "subtensor-runtime-common/std", ] ink-as-dependency = [] diff --git a/contract-tests/bittensor/lib.rs b/contract-tests/bittensor/lib.rs index 48e8d18aea..8867d017d8 100755 --- a/contract-tests/bittensor/lib.rs +++ b/contract-tests/bittensor/lib.rs @@ -5,7 +5,6 @@ use parity_scale_codec::Compact; #[derive(Debug, Clone)] pub struct CustomEnvironment; -use subtensor_runtime_common::{AlphaCurrency, NetUid, TaoCurrency}; pub enum FunctionId { GetStakeInfoForHotkeyColdkeyNetuidV1 = 0, AddStakeV1 = 1, @@ -39,15 +38,15 @@ pub trait RuntimeReadWrite { #[ink(function = 1)] fn add_stake( hotkey: ::AccountId, - netuid: NetUid, - amount: AlphaCurrency, + netuid: u16, + amount: u64, ); #[ink(function = 2)] fn remove_stake( hotkey: ::AccountId, - netuid: NetUid, - amount: AlphaCurrency, + netuid: u16, + amount: u64, ); #[ink(function = 3)] @@ -60,66 +59,66 @@ pub trait RuntimeReadWrite { fn move_stake( origin_hotkey: ::AccountId, destination_hotkey: ::AccountId, - origin_netuid: NetUid, - destination_netuid: NetUid, - amount: AlphaCurrency, + origin_netuid: u16, + destination_netuid: u16, + amount: u64, ); #[ink(function = 6)] fn transfer_stake( destination_coldkey: ::AccountId, hotkey: ::AccountId, - origin_netuid: NetUid, - destination_netuid: NetUid, - amount: AlphaCurrency, + origin_netuid: u16, + destination_netuid: u16, + amount: u64, ); #[ink(function = 7)] fn swap_stake( hotkey: ::AccountId, - origin_netuid: NetUid, - destination_netuid: NetUid, - amount: AlphaCurrency, + origin_netuid: u16, + destination_netuid: u16, + amount: u64, ); #[ink(function = 8)] fn add_stake_limit( hotkey: ::AccountId, - netuid: NetUid, - amount: TaoCurrency, - limit_price: TaoCurrency, + netuid: u16, + amount: u64, + limit_price: u64, allow_partial: bool, ); #[ink(function = 9)] fn remove_stake_limit( hotkey: ::AccountId, - netuid: NetUid, - amount: TaoCurrency, - limit_price: TaoCurrency, + netuid: u16, + amount: u64, + limit_price: u64, allow_partial: bool, ); #[ink(function = 10)] fn swap_stake_limit( hotkey: ::AccountId, - origin_netuid: NetUid, - destination_netuid: NetUid, - amount: AlphaCurrency, - limit_price: TaoCurrency, + origin_netuid: u16, + destination_netuid: u16, + amount: u64, + limit_price: u64, allow_partial: bool, ); #[ink(function = 11)] fn remove_stake_full_limit( hotkey: ::AccountId, - netuid: NetUid, - limit_price: TaoCurrency, + netuid: u16, + limit_price: u64, ); #[ink(function = 12)] fn set_coldkey_auto_stake_hotkey( - netuid: NetUid, + netuid: u16, hotkey: ::AccountId, ); @@ -130,7 +129,7 @@ pub trait RuntimeReadWrite { fn remove_proxy(delegate: ::AccountId); #[ink(function = 15)] - fn get_alpha_price(netuid: NetUid) -> u64; + fn get_alpha_price(netuid: u16) -> u64; } #[ink::scale_derive(Encode, Decode, TypeInfo)] @@ -166,11 +165,11 @@ impl ink::env::Environment for CustomEnvironment { pub struct StakeInfo { hotkey: AccountId, coldkey: AccountId, - netuid: Compact, - stake: Compact, + netuid: Compact, + stake: Compact, locked: Compact, - emission: Compact, - tao_emission: Compact, + emission: Compact, + tao_emission: Compact, drain: Compact, is_registered: bool, } @@ -220,7 +219,7 @@ mod bittensor { ) -> Result<(), ReadWriteErrorCode> { self.env() .extension() - .add_stake(hotkey.into(), netuid.into(), amount.into()) + .add_stake(hotkey.into(), netuid, amount) .map_err(|_e| ReadWriteErrorCode::WriteFailed) } @@ -233,7 +232,7 @@ mod bittensor { ) -> Result<(), ReadWriteErrorCode> { self.env() .extension() - .remove_stake(hotkey.into(), netuid.into(), amount.into()) + .remove_stake(hotkey.into(), netuid, amount) .map_err(|_e| ReadWriteErrorCode::WriteFailed) } @@ -267,9 +266,9 @@ mod bittensor { .move_stake( origin_hotkey.into(), destination_hotkey.into(), - origin_netuid.into(), - destination_netuid.into(), - amount.into(), + origin_netuid, + destination_netuid, + amount, ) .map_err(|_e| ReadWriteErrorCode::WriteFailed) } @@ -288,9 +287,9 @@ mod bittensor { .transfer_stake( destination_coldkey.into(), hotkey.into(), - origin_netuid.into(), - destination_netuid.into(), - amount.into(), + origin_netuid, + destination_netuid, + amount, ) .map_err(|_e| ReadWriteErrorCode::WriteFailed) } @@ -305,12 +304,7 @@ mod bittensor { ) -> Result<(), ReadWriteErrorCode> { self.env() .extension() - .swap_stake( - hotkey.into(), - origin_netuid.into(), - destination_netuid.into(), - amount.into(), - ) + .swap_stake(hotkey.into(), origin_netuid, destination_netuid, amount) .map_err(|_e| ReadWriteErrorCode::WriteFailed) } @@ -325,13 +319,7 @@ mod bittensor { ) -> Result<(), ReadWriteErrorCode> { self.env() .extension() - .add_stake_limit( - hotkey.into(), - netuid.into(), - amount.into(), - limit_price.into(), - allow_partial, - ) + .add_stake_limit(hotkey.into(), netuid, amount, limit_price, allow_partial) .map_err(|_e| ReadWriteErrorCode::WriteFailed) } @@ -346,9 +334,9 @@ mod bittensor { ) -> Result<(), ReadWriteErrorCode> { self.env().extension().remove_stake_limit( hotkey.into(), - netuid.into(), - amount.into(), - limit_price.into(), + netuid, + amount, + limit_price, allow_partial, ) } @@ -367,10 +355,10 @@ mod bittensor { .extension() .swap_stake_limit( hotkey.into(), - origin_netuid.into(), - destination_netuid.into(), - amount.into(), - limit_price.into(), + origin_netuid, + destination_netuid, + amount, + limit_price, allow_partial, ) .map_err(|_e| ReadWriteErrorCode::WriteFailed) @@ -385,7 +373,7 @@ mod bittensor { ) -> Result<(), ReadWriteErrorCode> { self.env() .extension() - .remove_stake_full_limit(hotkey.into(), netuid.into(), limit_price.into()) + .remove_stake_full_limit(hotkey.into(), netuid, limit_price) .map_err(|_e| ReadWriteErrorCode::WriteFailed) } @@ -397,7 +385,7 @@ mod bittensor { ) -> Result<(), ReadWriteErrorCode> { self.env() .extension() - .set_coldkey_auto_stake_hotkey(netuid.into(), hotkey.into()) + .set_coldkey_auto_stake_hotkey(netuid, hotkey.into()) .map_err(|_e| ReadWriteErrorCode::WriteFailed) } @@ -421,7 +409,7 @@ mod bittensor { pub fn get_alpha_price(&self, netuid: u16) -> Result { self.env() .extension() - .get_alpha_price(netuid.into()) + .get_alpha_price(netuid) .map_err(|_e| ReadWriteErrorCode::ReadFailed) } } diff --git a/contract-tests/package-lock.json b/contract-tests/package-lock.json new file mode 100644 index 0000000000..06c722a6de --- /dev/null +++ b/contract-tests/package-lock.json @@ -0,0 +1,6222 @@ +{ + "name": "contract-tests", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "license": "ISC", + "dependencies": { + "@polkadot-api/descriptors": "file:.papi/descriptors", + "@polkadot-api/ink-contracts": "^0.4.1", + "@polkadot-api/sdk-ink": "^0.5.1", + "@polkadot-labs/hdkd": "^0.0.25", + "@polkadot-labs/hdkd-helpers": "^0.0.25", + "@polkadot/api": "^16.4.6", + "@polkadot/util-crypto": "^14.0.1", + "@types/mocha": "^10.0.10", + "dotenv": "17.2.1", + "ethers": "^6.13.5", + "mocha": "^11.1.0", + "polkadot-api": "^1.22.0", + "rxjs": "^7.8.2", + "scale-ts": "^1.6.1", + "viem": "2.23.4", + "ws": "^8.18.2" + }, + "devDependencies": { + "@types/chai": "^5.0.1", + "@types/node": "^22.18.0", + "assert": "^2.1.0", + "chai": "^6.0.1", + "prettier": "^3.3.3", + "ts-node": "^10.9.2", + "typescript": "^5.7.2" + } + }, + ".papi/descriptors": { + "name": "@polkadot-api/descriptors", + "version": "0.1.0-autogenerated.5063582544821983772", + "peerDependencies": { + "polkadot-api": ">=1.21.0" + } + }, + "node_modules/@adraffy/ens-normalize": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.11.1.tgz", + "integrity": "sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ==", + "license": "MIT" + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@commander-js/extra-typings": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@commander-js/extra-typings/-/extra-typings-14.0.0.tgz", + "integrity": "sha512-hIn0ncNaJRLkZrxBIp5AsW/eXEHNKYQBh0aPdoUqNgD+Io3NIykQqpKFyKcuasZhicGaEZJX/JBSIkZ4e5x8Dg==", + "license": "MIT", + "peerDependencies": { + "commander": "~14.0.0" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@ethereumjs/rlp": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-10.1.0.tgz", + "integrity": "sha512-r67BJbwilammAqYI4B5okA66cNdTlFzeWxPNJOolKV52ZS/flo0tUBf4x4gxWXBgh48OgsdFV1Qp5pRoSe8IhQ==", + "license": "MPL-2.0", + "bin": { + "rlp": "bin/rlp.cjs" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/gen-mapping/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@noble/ciphers": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-1.3.0.tgz", + "integrity": "sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/curves": { + "version": "1.9.7", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.7.tgz", + "integrity": "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.8.0" + }, + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/curves/node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-2.0.1.tgz", + "integrity": "sha512-XlOlEbQcE9fmuXxrVTXCTlG2nlRXa9Rj3rr5Ue/+tX+nmkgbX720YHh0VR3hBF9xDvwnb8D2shVGOwNx+ulArw==", + "license": "MIT", + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@polkadot-api/cli": { + "version": "0.16.3", + "resolved": "https://registry.npmjs.org/@polkadot-api/cli/-/cli-0.16.3.tgz", + "integrity": "sha512-s+p3dFw1vOeyMMqhUbt1RFyqPZdR7vg6joS0v9wBvK3qX5xU+QfOOaMxXJ8fl0mJEbwoJnJsvVl4MzjsABaKCg==", + "license": "MIT", + "dependencies": { + "@commander-js/extra-typings": "^14.0.0", + "@polkadot-api/codegen": "0.20.0", + "@polkadot-api/ink-contracts": "0.4.3", + "@polkadot-api/json-rpc-provider": "0.0.4", + "@polkadot-api/known-chains": "0.9.15", + "@polkadot-api/legacy-provider": "0.3.6", + "@polkadot-api/metadata-compatibility": "0.4.1", + "@polkadot-api/observable-client": "0.17.0", + "@polkadot-api/polkadot-sdk-compat": "2.3.3", + "@polkadot-api/sm-provider": "0.1.14", + "@polkadot-api/smoldot": "0.3.14", + "@polkadot-api/substrate-bindings": "0.16.5", + "@polkadot-api/substrate-client": "0.4.7", + "@polkadot-api/utils": "0.2.0", + "@polkadot-api/wasm-executor": "^0.2.2", + "@polkadot-api/ws-provider": "0.7.4", + "@types/node": "^24.10.1", + "commander": "^14.0.2", + "execa": "^9.6.0", + "fs.promises.exists": "^1.1.4", + "ora": "^9.0.0", + "read-pkg": "^10.0.0", + "rxjs": "^7.8.2", + "tsc-prog": "^2.3.0", + "tsup": "8.5.0", + "typescript": "^5.9.3", + "write-package": "^7.2.0" + }, + "bin": { + "papi": "dist/main.js", + "polkadot-api": "dist/main.js" + } + }, + "node_modules/@polkadot-api/cli/node_modules/@types/node": { + "version": "24.10.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.1.tgz", + "integrity": "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/@polkadot-api/cli/node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "license": "MIT" + }, + "node_modules/@polkadot-api/codegen": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@polkadot-api/codegen/-/codegen-0.20.0.tgz", + "integrity": "sha512-akwPArm35UZcebUFtTKcEkdBLCjYyKweGw3/tT04p/EtM4OsQ1FxhRdXZ51ScBC3JVGCFQTUO2hNsd1E6YXvlw==", + "license": "MIT", + "dependencies": { + "@polkadot-api/ink-contracts": "0.4.3", + "@polkadot-api/metadata-builders": "0.13.7", + "@polkadot-api/metadata-compatibility": "0.4.1", + "@polkadot-api/substrate-bindings": "0.16.5", + "@polkadot-api/utils": "0.2.0" + } + }, + "node_modules/@polkadot-api/common-sdk-utils": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@polkadot-api/common-sdk-utils/-/common-sdk-utils-0.1.0.tgz", + "integrity": "sha512-cgA9fh8dfBai9b46XaaQmj9vwzyHStQjc/xrAvQksgF6SqvZ0yAfxVqLvGrsz/Xi3dsAdKLg09PybC7MUAMv9w==", + "license": "MIT", + "peerDependencies": { + "polkadot-api": "^1.8.1", + "rxjs": ">=7.8.1" + } + }, + "node_modules/@polkadot-api/descriptors": { + "resolved": ".papi/descriptors", + "link": true + }, + "node_modules/@polkadot-api/ink-contracts": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@polkadot-api/ink-contracts/-/ink-contracts-0.4.3.tgz", + "integrity": "sha512-Wl+4Dxjt0GAl+rADZEgrrqEesqX/xygTpX18TmzmspcKhb9QIZf9FJI8A5Sgtq0TKAOwsd1d/hbHVX3LgbXFXg==", + "license": "MIT", + "dependencies": { + "@polkadot-api/metadata-builders": "0.13.7", + "@polkadot-api/substrate-bindings": "0.16.5", + "@polkadot-api/utils": "0.2.0" + } + }, + "node_modules/@polkadot-api/json-rpc-provider": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/@polkadot-api/json-rpc-provider/-/json-rpc-provider-0.0.4.tgz", + "integrity": "sha512-9cDijLIxzHOBuq6yHqpqjJ9jBmXrctjc1OFqU+tQrS96adQze3mTIH6DTgfb/0LMrqxzxffz1HQGrIlEH00WrA==", + "license": "MIT" + }, + "node_modules/@polkadot-api/json-rpc-provider-proxy": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@polkadot-api/json-rpc-provider-proxy/-/json-rpc-provider-proxy-0.2.7.tgz", + "integrity": "sha512-+HM4JQXzO2GPUD2++4GOLsmFL6LO8RoLvig0HgCLuypDgfdZMlwd8KnyGHjRnVEHA5X+kvXbk84TDcAXVxTazQ==", + "license": "MIT" + }, + "node_modules/@polkadot-api/known-chains": { + "version": "0.9.15", + "resolved": "https://registry.npmjs.org/@polkadot-api/known-chains/-/known-chains-0.9.15.tgz", + "integrity": "sha512-VQGu2Anvnx0y0Ltd6sQB3aYzQFGsaQwf2znh+w4Oflaxln5lsjO/+trpXz/rdrdgyi0iafkhpeho/p/EGBwJ+A==", + "license": "MIT" + }, + "node_modules/@polkadot-api/legacy-provider": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@polkadot-api/legacy-provider/-/legacy-provider-0.3.6.tgz", + "integrity": "sha512-JZQg0HVtBowFKxNrZdnMBKXmeSBD4yFlz6egEpvE97RXRvjaBzTaVuFFhBchngq9YmgFQewuWSoX5XSUW6hcEg==", + "license": "MIT", + "dependencies": { + "@polkadot-api/json-rpc-provider": "0.0.4", + "@polkadot-api/raw-client": "0.1.1", + "@polkadot-api/substrate-bindings": "0.16.5", + "@polkadot-api/utils": "0.2.0" + }, + "peerDependencies": { + "rxjs": ">=7.8.0" + } + }, + "node_modules/@polkadot-api/logs-provider": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@polkadot-api/logs-provider/-/logs-provider-0.0.6.tgz", + "integrity": "sha512-4WgHlvy+xee1ADaaVf6+MlK/+jGMtsMgAzvbQOJZnP4PfQuagoTqaeayk8HYKxXGphogLlPbD06tANxcb+nvAg==", + "license": "MIT", + "dependencies": { + "@polkadot-api/json-rpc-provider": "0.0.4" + } + }, + "node_modules/@polkadot-api/merkleize-metadata": { + "version": "1.1.27", + "resolved": "https://registry.npmjs.org/@polkadot-api/merkleize-metadata/-/merkleize-metadata-1.1.27.tgz", + "integrity": "sha512-OdKwOzzrLL0Ju3pQA9LjeQEquMcD+KtLybUAO3fVxwjxD5cyI0RwillGoAIBJvfMaZpNxnxJnD+WzNjRcr7FiQ==", + "license": "MIT", + "dependencies": { + "@polkadot-api/metadata-builders": "0.13.7", + "@polkadot-api/substrate-bindings": "0.16.5", + "@polkadot-api/utils": "0.2.0" + } + }, + "node_modules/@polkadot-api/metadata-builders": { + "version": "0.13.7", + "resolved": "https://registry.npmjs.org/@polkadot-api/metadata-builders/-/metadata-builders-0.13.7.tgz", + "integrity": "sha512-xwggY8F/gtX7qGzz+jzP3DZvWgBWIIFQhk+r2MJ431CR+tNKeTtzGdwNocVrb9NYTK2naC9ckJS14nrNM6LWLw==", + "license": "MIT", + "dependencies": { + "@polkadot-api/substrate-bindings": "0.16.5", + "@polkadot-api/utils": "0.2.0" + } + }, + "node_modules/@polkadot-api/metadata-compatibility": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@polkadot-api/metadata-compatibility/-/metadata-compatibility-0.4.1.tgz", + "integrity": "sha512-mZt4Af6oPXEHAprrckJiSZkWRVf0mqwF+Bm+703rPsezLptQid9AjSzh1hkgIkOrPbg6IhWbmMhbuJVjx9VeQA==", + "license": "MIT", + "dependencies": { + "@polkadot-api/metadata-builders": "0.13.7", + "@polkadot-api/substrate-bindings": "0.16.5" + } + }, + "node_modules/@polkadot-api/observable-client": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@polkadot-api/observable-client/-/observable-client-0.17.0.tgz", + "integrity": "sha512-hilb12Fg1JrlM/0nucMT85//EQltB53fmoh7YNBsZMiNpavn/3qGTO4s0JMlC/LBbddYg0nxA+DMkSVlapo7cQ==", + "license": "MIT", + "dependencies": { + "@polkadot-api/metadata-builders": "0.13.7", + "@polkadot-api/substrate-bindings": "0.16.5", + "@polkadot-api/substrate-client": "0.4.7", + "@polkadot-api/utils": "0.2.0" + }, + "peerDependencies": { + "rxjs": ">=7.8.0" + } + }, + "node_modules/@polkadot-api/pjs-signer": { + "version": "0.6.17", + "resolved": "https://registry.npmjs.org/@polkadot-api/pjs-signer/-/pjs-signer-0.6.17.tgz", + "integrity": "sha512-bxFtyiNOchV0osh6m+1CaN4tkWF7Mo4IT9XPLZBwSybpHZgwmu2wbhgqBkVL98QMyGzud7NHfrJsTCgFU6jHGg==", + "license": "MIT", + "dependencies": { + "@polkadot-api/metadata-builders": "0.13.7", + "@polkadot-api/polkadot-signer": "0.1.6", + "@polkadot-api/signers-common": "0.1.18", + "@polkadot-api/substrate-bindings": "0.16.5", + "@polkadot-api/utils": "0.2.0" + } + }, + "node_modules/@polkadot-api/polkadot-sdk-compat": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/@polkadot-api/polkadot-sdk-compat/-/polkadot-sdk-compat-2.3.3.tgz", + "integrity": "sha512-p30po+iv4trniSJ7UZiIt/rFInvtA9Tzg65EzuRkCaQAnh54a3MPp9w/q+x+SNLEcfzVLvf8LyPnMPOIpKuj5w==", + "license": "MIT", + "dependencies": { + "@polkadot-api/json-rpc-provider": "0.0.4" + } + }, + "node_modules/@polkadot-api/polkadot-signer": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@polkadot-api/polkadot-signer/-/polkadot-signer-0.1.6.tgz", + "integrity": "sha512-X7ghAa4r7doETtjAPTb50IpfGtrBmy3BJM5WCfNKa1saK04VFY9w+vDn+hwEcM4p0PcDHt66Ts74hzvHq54d9A==", + "license": "MIT" + }, + "node_modules/@polkadot-api/raw-client": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@polkadot-api/raw-client/-/raw-client-0.1.1.tgz", + "integrity": "sha512-HxalpNEo8JCYXfxKM5p3TrK8sEasTGMkGjBNLzD4TLye9IK2smdb5oTvp2yfkU1iuVBdmjr69uif4NaukOYo2g==", + "license": "MIT", + "dependencies": { + "@polkadot-api/json-rpc-provider": "0.0.4" + } + }, + "node_modules/@polkadot-api/sdk-ink": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@polkadot-api/sdk-ink/-/sdk-ink-0.5.1.tgz", + "integrity": "sha512-9pRnghjigivvgq7375hzkoazstvPDbc0YB01Jzw1/MYKcX+YJn1p/H8SAQTWbKlz2ohFgi1nwU52a0bsmKqb/Q==", + "license": "MIT", + "dependencies": { + "@ethereumjs/rlp": "^10.0.0", + "@polkadot-api/common-sdk-utils": "0.1.0", + "@polkadot-api/substrate-bindings": "^0.16.3", + "abitype": "^1.1.1", + "viem": "^2.37.9" + }, + "peerDependencies": { + "@polkadot-api/ink-contracts": ">=0.4.0", + "polkadot-api": ">=1.19.0", + "rxjs": ">=7.8.0" + } + }, + "node_modules/@polkadot-api/sdk-ink/node_modules/@noble/curves": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.1.tgz", + "integrity": "sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.8.0" + }, + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@polkadot-api/sdk-ink/node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@polkadot-api/sdk-ink/node_modules/isows": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/isows/-/isows-1.0.7.tgz", + "integrity": "sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/wevm" + } + ], + "license": "MIT", + "peerDependencies": { + "ws": "*" + } + }, + "node_modules/@polkadot-api/sdk-ink/node_modules/ox": { + "version": "0.9.6", + "resolved": "https://registry.npmjs.org/ox/-/ox-0.9.6.tgz", + "integrity": "sha512-8SuCbHPvv2eZLYXrNmC0EC12rdzXQLdhnOMlHDW2wiCPLxBrOOJwX5L5E61by+UjTPOryqQiRSnjIKCI+GykKg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/wevm" + } + ], + "license": "MIT", + "dependencies": { + "@adraffy/ens-normalize": "^1.11.0", + "@noble/ciphers": "^1.3.0", + "@noble/curves": "1.9.1", + "@noble/hashes": "^1.8.0", + "@scure/bip32": "^1.7.0", + "@scure/bip39": "^1.6.0", + "abitype": "^1.0.9", + "eventemitter3": "5.0.1" + }, + "peerDependencies": { + "typescript": ">=5.4.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@polkadot-api/sdk-ink/node_modules/viem": { + "version": "2.41.2", + "resolved": "https://registry.npmjs.org/viem/-/viem-2.41.2.tgz", + "integrity": "sha512-LYliajglBe1FU6+EH9mSWozp+gRA/QcHfxeD9Odf83AdH5fwUS7DroH4gHvlv6Sshqi1uXrYFA2B/EOczxd15g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/wevm" + } + ], + "license": "MIT", + "dependencies": { + "@noble/curves": "1.9.1", + "@noble/hashes": "1.8.0", + "@scure/bip32": "1.7.0", + "@scure/bip39": "1.6.0", + "abitype": "1.1.0", + "isows": "1.0.7", + "ox": "0.9.6", + "ws": "8.18.3" + }, + "peerDependencies": { + "typescript": ">=5.0.4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@polkadot-api/sdk-ink/node_modules/viem/node_modules/abitype": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/abitype/-/abitype-1.1.0.tgz", + "integrity": "sha512-6Vh4HcRxNMLA0puzPjM5GBgT4aAcFGKZzSgAXvuZ27shJP6NEpielTuqbBmZILR5/xd0PizkBGy5hReKz9jl5A==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/wevm" + }, + "peerDependencies": { + "typescript": ">=5.0.4", + "zod": "^3.22.0 || ^4.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + }, + "zod": { + "optional": true + } + } + }, + "node_modules/@polkadot-api/signer": { + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/@polkadot-api/signer/-/signer-0.2.11.tgz", + "integrity": "sha512-32tqbJo6JDfc/lHg+nTveeunFRULonWoTQX9xbs70arr/tAyyZfljupdECRK8CVRx1777es/CQO3QVj8EpWtYg==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "^2.0.1", + "@polkadot-api/merkleize-metadata": "1.1.27", + "@polkadot-api/polkadot-signer": "0.1.6", + "@polkadot-api/signers-common": "0.1.18", + "@polkadot-api/substrate-bindings": "0.16.5", + "@polkadot-api/utils": "0.2.0" + } + }, + "node_modules/@polkadot-api/signers-common": { + "version": "0.1.18", + "resolved": "https://registry.npmjs.org/@polkadot-api/signers-common/-/signers-common-0.1.18.tgz", + "integrity": "sha512-UQXuRZoQ+jMolEpIPF0mVXcoqQ/382fHrSOgfK5sIvjeH0HPf4P+s3IwcnwyAdpHY2gdHXYlHd/SAw7Q1gJ4EA==", + "license": "MIT", + "dependencies": { + "@polkadot-api/metadata-builders": "0.13.7", + "@polkadot-api/polkadot-signer": "0.1.6", + "@polkadot-api/substrate-bindings": "0.16.5", + "@polkadot-api/utils": "0.2.0" + } + }, + "node_modules/@polkadot-api/sm-provider": { + "version": "0.1.14", + "resolved": "https://registry.npmjs.org/@polkadot-api/sm-provider/-/sm-provider-0.1.14.tgz", + "integrity": "sha512-QQvoeBSIwnEm8IUhGA6sBU6LNh2v7SOuVOnF77ZD7P5ELTrdmQH2Tcn0W15qGTmTG45b3Z52XsKpuQbIJ7c7XA==", + "license": "MIT", + "dependencies": { + "@polkadot-api/json-rpc-provider": "0.0.4", + "@polkadot-api/json-rpc-provider-proxy": "0.2.7" + }, + "peerDependencies": { + "@polkadot-api/smoldot": ">=0.3" + } + }, + "node_modules/@polkadot-api/smoldot": { + "version": "0.3.14", + "resolved": "https://registry.npmjs.org/@polkadot-api/smoldot/-/smoldot-0.3.14.tgz", + "integrity": "sha512-eWqO0xFQaKzqY5mRYxYuZcj1IiaLcQP+J38UQyuJgEorm+9yHVEQ/XBWoM83P+Y8TwE5IWTICp1LCVeiFQTGPQ==", + "license": "MIT", + "dependencies": { + "@types/node": "^24.5.2", + "smoldot": "2.0.39" + } + }, + "node_modules/@polkadot-api/smoldot/node_modules/@types/node": { + "version": "24.10.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.1.tgz", + "integrity": "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/@polkadot-api/smoldot/node_modules/smoldot": { + "version": "2.0.39", + "resolved": "https://registry.npmjs.org/smoldot/-/smoldot-2.0.39.tgz", + "integrity": "sha512-yFMSzI6nkqWFTNao99lBA/TguUFU+bR3A5UGTDd/QqqB12jqzvZnmW/No6l2rKmagt8Qx/KybMNowV/E28znhA==", + "license": "GPL-3.0-or-later WITH Classpath-exception-2.0", + "dependencies": { + "ws": "^8.8.1" + } + }, + "node_modules/@polkadot-api/smoldot/node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "license": "MIT" + }, + "node_modules/@polkadot-api/substrate-bindings": { + "version": "0.16.5", + "resolved": "https://registry.npmjs.org/@polkadot-api/substrate-bindings/-/substrate-bindings-0.16.5.tgz", + "integrity": "sha512-QFgNlBmtLtiUGTCTurxcE6UZrbI2DaQ5/gyIiC2FYfEhStL8tl20b09FRYHcSjY+lxN42Rcf9HVX+MCFWLYlpQ==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "^2.0.1", + "@polkadot-api/utils": "0.2.0", + "@scure/base": "^2.0.0", + "scale-ts": "^1.6.1" + } + }, + "node_modules/@polkadot-api/substrate-bindings/node_modules/@scure/base": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-2.0.0.tgz", + "integrity": "sha512-3E1kpuZginKkek01ovG8krQ0Z44E3DHPjc5S2rjJw9lZn3KSQOs8S7wqikF/AH7iRanHypj85uGyxk0XAyC37w==", + "license": "MIT", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@polkadot-api/substrate-client": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/@polkadot-api/substrate-client/-/substrate-client-0.4.7.tgz", + "integrity": "sha512-Mmx9VKincVqfVQmq89gzDk4DN3uKwf8CxoqYvq+EiPUZ1QmMUc7X4QMwG1MXIlYdnm5LSXzn+2Jn8ik8xMgL+w==", + "license": "MIT", + "dependencies": { + "@polkadot-api/json-rpc-provider": "0.0.4", + "@polkadot-api/raw-client": "0.1.1", + "@polkadot-api/utils": "0.2.0" + } + }, + "node_modules/@polkadot-api/utils": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@polkadot-api/utils/-/utils-0.2.0.tgz", + "integrity": "sha512-nY3i5fQJoAxU4n3bD7Fs208/KR2J95SGfVc58kDjbRYN5a84kWaGEqzjBNtP9oqht49POM8Bm9mbIrkvC1Bzuw==", + "license": "MIT" + }, + "node_modules/@polkadot-api/wasm-executor": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@polkadot-api/wasm-executor/-/wasm-executor-0.2.3.tgz", + "integrity": "sha512-B2h1o+Qlo9idpASaHvMSoViB2I5ko5OAfwfhYF8LQDkTADK0B+SeStzNj1Qn+FG34wqTuv7HzBCdjaUgzYINJQ==", + "license": "MIT" + }, + "node_modules/@polkadot-api/ws-provider": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@polkadot-api/ws-provider/-/ws-provider-0.7.4.tgz", + "integrity": "sha512-mkk2p8wPht+ljU1xULCPMsLpNF7NHuGaufuDCIZZgopALaZpfVFJxc3qa9s6Xv8X3hM+TRoC5WknuD1ykRY99A==", + "license": "MIT", + "dependencies": { + "@polkadot-api/json-rpc-provider": "0.0.4", + "@polkadot-api/json-rpc-provider-proxy": "0.2.7", + "@types/ws": "^8.18.1", + "ws": "^8.18.3" + } + }, + "node_modules/@polkadot-labs/hdkd": { + "version": "0.0.25", + "resolved": "https://registry.npmjs.org/@polkadot-labs/hdkd/-/hdkd-0.0.25.tgz", + "integrity": "sha512-+yZJC1TE4ZKdfoILw8nGxu3H/klrYXm9GdVB0kcyQDecq320ThUmM1M4l8d1F/3QD0Nez9NwHi9t5B++OgJU5A==", + "license": "MIT", + "dependencies": { + "@polkadot-labs/hdkd-helpers": "~0.0.26" + } + }, + "node_modules/@polkadot-labs/hdkd-helpers": { + "version": "0.0.25", + "resolved": "https://registry.npmjs.org/@polkadot-labs/hdkd-helpers/-/hdkd-helpers-0.0.25.tgz", + "integrity": "sha512-GwHayBuyHKfzvGD0vG47NbjFeiK6rRQHQAn1syut9nt0mhXMg4yb3tJ//IyM317qWuDU3HbD2OIp5jKDEQz2/A==", + "license": "MIT", + "dependencies": { + "@noble/curves": "^2.0.0", + "@noble/hashes": "^2.0.0", + "@scure/base": "^2.0.0", + "@scure/sr25519": "^0.3.0", + "scale-ts": "^1.6.1" + } + }, + "node_modules/@polkadot-labs/hdkd-helpers/node_modules/@noble/curves": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-2.0.1.tgz", + "integrity": "sha512-vs1Az2OOTBiP4q0pwjW5aF0xp9n4MxVrmkFBxc6EKZc6ddYx5gaZiAsZoq0uRRXWbi3AT/sBqn05eRPtn1JCPw==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "2.0.1" + }, + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@polkadot-labs/hdkd-helpers/node_modules/@scure/base": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-2.0.0.tgz", + "integrity": "sha512-3E1kpuZginKkek01ovG8krQ0Z44E3DHPjc5S2rjJw9lZn3KSQOs8S7wqikF/AH7iRanHypj85uGyxk0XAyC37w==", + "license": "MIT", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@polkadot-labs/hdkd/node_modules/@noble/curves": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-2.0.1.tgz", + "integrity": "sha512-vs1Az2OOTBiP4q0pwjW5aF0xp9n4MxVrmkFBxc6EKZc6ddYx5gaZiAsZoq0uRRXWbi3AT/sBqn05eRPtn1JCPw==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "2.0.1" + }, + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@polkadot-labs/hdkd/node_modules/@polkadot-labs/hdkd-helpers": { + "version": "0.0.26", + "resolved": "https://registry.npmjs.org/@polkadot-labs/hdkd-helpers/-/hdkd-helpers-0.0.26.tgz", + "integrity": "sha512-mp3GCSiOQeh4aPt+DYBQq6UnX/tKgYUH5F75knjW3ATSA90ifEEWWjRan0Bddt4QKYKamaDGadK9GbVREgzQFw==", + "license": "MIT", + "dependencies": { + "@noble/curves": "^2.0.1", + "@noble/hashes": "^2.0.1", + "@scure/base": "^2.0.0", + "@scure/sr25519": "^0.3.0", + "scale-ts": "^1.6.1" + } + }, + "node_modules/@polkadot-labs/hdkd/node_modules/@scure/base": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-2.0.0.tgz", + "integrity": "sha512-3E1kpuZginKkek01ovG8krQ0Z44E3DHPjc5S2rjJw9lZn3KSQOs8S7wqikF/AH7iRanHypj85uGyxk0XAyC37w==", + "license": "MIT", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@polkadot/api": { + "version": "16.5.3", + "resolved": "https://registry.npmjs.org/@polkadot/api/-/api-16.5.3.tgz", + "integrity": "sha512-Ptwo0f5Qonmus7KIklsbFcGTdHtNjbTAwl5GGI8Mp0dmBc7Y/ISJpIJX49UrG6FhW6COMa0ItsU87XIWMRwI/Q==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/api-augment": "16.5.3", + "@polkadot/api-base": "16.5.3", + "@polkadot/api-derive": "16.5.3", + "@polkadot/keyring": "^13.5.9", + "@polkadot/rpc-augment": "16.5.3", + "@polkadot/rpc-core": "16.5.3", + "@polkadot/rpc-provider": "16.5.3", + "@polkadot/types": "16.5.3", + "@polkadot/types-augment": "16.5.3", + "@polkadot/types-codec": "16.5.3", + "@polkadot/types-create": "16.5.3", + "@polkadot/types-known": "16.5.3", + "@polkadot/util": "^13.5.9", + "@polkadot/util-crypto": "^13.5.9", + "eventemitter3": "^5.0.1", + "rxjs": "^7.8.1", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api-augment": { + "version": "16.5.3", + "resolved": "https://registry.npmjs.org/@polkadot/api-augment/-/api-augment-16.5.3.tgz", + "integrity": "sha512-9+8YKSS66x9qpWS+ZQ/FSm9P4mgE+icD53oAmeIykriPW2gcSTAiNufLwAjmAJAkOLcqbTD7LPjFW6xFlmtYsA==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/api-base": "16.5.3", + "@polkadot/rpc-augment": "16.5.3", + "@polkadot/types": "16.5.3", + "@polkadot/types-augment": "16.5.3", + "@polkadot/types-codec": "16.5.3", + "@polkadot/util": "^13.5.9", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api-base": { + "version": "16.5.3", + "resolved": "https://registry.npmjs.org/@polkadot/api-base/-/api-base-16.5.3.tgz", + "integrity": "sha512-M1+pY6OFQ1uOB73VQMt2JAGq/UVISVQJISqyfjiUllUc0qIzaDMkcZxRqE34Lwaib3fD3RuIpG6dXqCL9rdzJQ==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/rpc-core": "16.5.3", + "@polkadot/types": "16.5.3", + "@polkadot/util": "^13.5.9", + "rxjs": "^7.8.1", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api-derive": { + "version": "16.5.3", + "resolved": "https://registry.npmjs.org/@polkadot/api-derive/-/api-derive-16.5.3.tgz", + "integrity": "sha512-nMsnSC/N1SK1kNhgh2FhrrR1S8bTVH+3WsuBHFRzl+txKHq232IeIn9LpebSvgZdd77PaKaYBxbhYcNaA8Ypew==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/api": "16.5.3", + "@polkadot/api-augment": "16.5.3", + "@polkadot/api-base": "16.5.3", + "@polkadot/rpc-core": "16.5.3", + "@polkadot/types": "16.5.3", + "@polkadot/types-codec": "16.5.3", + "@polkadot/util": "^13.5.9", + "@polkadot/util-crypto": "^13.5.9", + "rxjs": "^7.8.1", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api-derive/node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@polkadot/api-derive/node_modules/@polkadot/util-crypto": { + "version": "13.5.9", + "resolved": "https://registry.npmjs.org/@polkadot/util-crypto/-/util-crypto-13.5.9.tgz", + "integrity": "sha512-foUesMhxkTk8CZ0/XEcfvHk6I0O+aICqqVJllhOpyp/ZVnrTBKBf59T6RpsXx2pCtBlMsLRvg/6Mw7RND1HqDg==", + "license": "Apache-2.0", + "dependencies": { + "@noble/curves": "^1.3.0", + "@noble/hashes": "^1.3.3", + "@polkadot/networks": "13.5.9", + "@polkadot/util": "13.5.9", + "@polkadot/wasm-crypto": "^7.5.3", + "@polkadot/wasm-util": "^7.5.3", + "@polkadot/x-bigint": "13.5.9", + "@polkadot/x-randomvalues": "13.5.9", + "@scure/base": "^1.1.7", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@polkadot/util": "13.5.9" + } + }, + "node_modules/@polkadot/api/node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@polkadot/api/node_modules/@polkadot/util-crypto": { + "version": "13.5.9", + "resolved": "https://registry.npmjs.org/@polkadot/util-crypto/-/util-crypto-13.5.9.tgz", + "integrity": "sha512-foUesMhxkTk8CZ0/XEcfvHk6I0O+aICqqVJllhOpyp/ZVnrTBKBf59T6RpsXx2pCtBlMsLRvg/6Mw7RND1HqDg==", + "license": "Apache-2.0", + "dependencies": { + "@noble/curves": "^1.3.0", + "@noble/hashes": "^1.3.3", + "@polkadot/networks": "13.5.9", + "@polkadot/util": "13.5.9", + "@polkadot/wasm-crypto": "^7.5.3", + "@polkadot/wasm-util": "^7.5.3", + "@polkadot/x-bigint": "13.5.9", + "@polkadot/x-randomvalues": "13.5.9", + "@scure/base": "^1.1.7", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@polkadot/util": "13.5.9" + } + }, + "node_modules/@polkadot/keyring": { + "version": "13.5.9", + "resolved": "https://registry.npmjs.org/@polkadot/keyring/-/keyring-13.5.9.tgz", + "integrity": "sha512-bMCpHDN7U8ytxawjBZ89/he5s3AmEZuOdkM/ABcorh/flXNPfyghjFK27Gy4OKoFxX52yJ2sTHR4NxM87GuFXQ==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/util": "13.5.9", + "@polkadot/util-crypto": "13.5.9", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@polkadot/util": "13.5.9", + "@polkadot/util-crypto": "13.5.9" + } + }, + "node_modules/@polkadot/keyring/node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@polkadot/keyring/node_modules/@polkadot/util-crypto": { + "version": "13.5.9", + "resolved": "https://registry.npmjs.org/@polkadot/util-crypto/-/util-crypto-13.5.9.tgz", + "integrity": "sha512-foUesMhxkTk8CZ0/XEcfvHk6I0O+aICqqVJllhOpyp/ZVnrTBKBf59T6RpsXx2pCtBlMsLRvg/6Mw7RND1HqDg==", + "license": "Apache-2.0", + "dependencies": { + "@noble/curves": "^1.3.0", + "@noble/hashes": "^1.3.3", + "@polkadot/networks": "13.5.9", + "@polkadot/util": "13.5.9", + "@polkadot/wasm-crypto": "^7.5.3", + "@polkadot/wasm-util": "^7.5.3", + "@polkadot/x-bigint": "13.5.9", + "@polkadot/x-randomvalues": "13.5.9", + "@scure/base": "^1.1.7", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@polkadot/util": "13.5.9" + } + }, + "node_modules/@polkadot/networks": { + "version": "13.5.9", + "resolved": "https://registry.npmjs.org/@polkadot/networks/-/networks-13.5.9.tgz", + "integrity": "sha512-nmKUKJjiLgcih0MkdlJNMnhEYdwEml2rv/h59ll2+rAvpsVWMTLCb6Cq6q7UC44+8kiWK2UUJMkFU+3PFFxndA==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/util": "13.5.9", + "@substrate/ss58-registry": "^1.51.0", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/rpc-augment": { + "version": "16.5.3", + "resolved": "https://registry.npmjs.org/@polkadot/rpc-augment/-/rpc-augment-16.5.3.tgz", + "integrity": "sha512-q3Y+b0FSwbYe8Qopd4In+9KCL3eH5QmGVvimX7Z8+cvQ9+h+JUA6TP1bfpWBmYJRKlolaljsBQPBWoubchmxSw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/rpc-core": "16.5.3", + "@polkadot/types": "16.5.3", + "@polkadot/types-codec": "16.5.3", + "@polkadot/util": "^13.5.9", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/rpc-core": { + "version": "16.5.3", + "resolved": "https://registry.npmjs.org/@polkadot/rpc-core/-/rpc-core-16.5.3.tgz", + "integrity": "sha512-UYEIRhO/1uTz/rpWLwUN9Re3c4fuTs0I9RR8dHKpKsH3jZTs1M3CtqME3NNzpGqApY1xb9tZemU/0GfHjCpeBQ==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/rpc-augment": "16.5.3", + "@polkadot/rpc-provider": "16.5.3", + "@polkadot/types": "16.5.3", + "@polkadot/util": "^13.5.9", + "rxjs": "^7.8.1", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/rpc-provider": { + "version": "16.5.3", + "resolved": "https://registry.npmjs.org/@polkadot/rpc-provider/-/rpc-provider-16.5.3.tgz", + "integrity": "sha512-O7hD82HwjT4XJ4i/G58B52RSDM7arHXSpzahZKz4/wtb4x6d6b4JVdfZoskInadARFi5RwIWCrftwPtpRH81Fw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/keyring": "^13.5.9", + "@polkadot/types": "16.5.3", + "@polkadot/types-support": "16.5.3", + "@polkadot/util": "^13.5.9", + "@polkadot/util-crypto": "^13.5.9", + "@polkadot/x-fetch": "^13.5.9", + "@polkadot/x-global": "^13.5.9", + "@polkadot/x-ws": "^13.5.9", + "eventemitter3": "^5.0.1", + "mock-socket": "^9.3.1", + "nock": "^13.5.5", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@substrate/connect": "0.8.11" + } + }, + "node_modules/@polkadot/rpc-provider/node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@polkadot/rpc-provider/node_modules/@polkadot/util-crypto": { + "version": "13.5.9", + "resolved": "https://registry.npmjs.org/@polkadot/util-crypto/-/util-crypto-13.5.9.tgz", + "integrity": "sha512-foUesMhxkTk8CZ0/XEcfvHk6I0O+aICqqVJllhOpyp/ZVnrTBKBf59T6RpsXx2pCtBlMsLRvg/6Mw7RND1HqDg==", + "license": "Apache-2.0", + "dependencies": { + "@noble/curves": "^1.3.0", + "@noble/hashes": "^1.3.3", + "@polkadot/networks": "13.5.9", + "@polkadot/util": "13.5.9", + "@polkadot/wasm-crypto": "^7.5.3", + "@polkadot/wasm-util": "^7.5.3", + "@polkadot/x-bigint": "13.5.9", + "@polkadot/x-randomvalues": "13.5.9", + "@scure/base": "^1.1.7", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@polkadot/util": "13.5.9" + } + }, + "node_modules/@polkadot/types": { + "version": "16.5.3", + "resolved": "https://registry.npmjs.org/@polkadot/types/-/types-16.5.3.tgz", + "integrity": "sha512-xy9uv/X4iT7uJ7TNCoqbcMkR8ePHwNW6DgpOU+1y1zc/KSu9ZC5i+haFOL68BpmR/QXk99YfuHoKwXvteDmykw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/keyring": "^13.5.9", + "@polkadot/types-augment": "16.5.3", + "@polkadot/types-codec": "16.5.3", + "@polkadot/types-create": "16.5.3", + "@polkadot/util": "^13.5.9", + "@polkadot/util-crypto": "^13.5.9", + "rxjs": "^7.8.1", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/types-augment": { + "version": "16.5.3", + "resolved": "https://registry.npmjs.org/@polkadot/types-augment/-/types-augment-16.5.3.tgz", + "integrity": "sha512-SfS4arJUxW6BeCEhLMVPrZwWOLte69k5+/lvEKOKHQA8Mz0MEkD4uqGZGibDjgBgdnu8N+3b+rs+Fn3YfZu4yA==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/types": "16.5.3", + "@polkadot/types-codec": "16.5.3", + "@polkadot/util": "^13.5.9", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/types-codec": { + "version": "16.5.3", + "resolved": "https://registry.npmjs.org/@polkadot/types-codec/-/types-codec-16.5.3.tgz", + "integrity": "sha512-b+oKMrIZrsFH4pPwvGQ6lMS8oFrYAGMy9QSbytA+KDmXAgTCtShz5XGvdQabvsGCjJ45EKgkKpKynVcYh3gk8g==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/util": "^13.5.9", + "@polkadot/x-bigint": "^13.5.9", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/types-create": { + "version": "16.5.3", + "resolved": "https://registry.npmjs.org/@polkadot/types-create/-/types-create-16.5.3.tgz", + "integrity": "sha512-XGnBLNamPh7eQGcHNGFghA/prH7z2BsQ+9EVSbHCvw9ENr/Ow24mmmkZyMG5WM/5I6/4HRdfwFJucYt1GL/p9g==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/types-codec": "16.5.3", + "@polkadot/util": "^13.5.9", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/types-known": { + "version": "16.5.3", + "resolved": "https://registry.npmjs.org/@polkadot/types-known/-/types-known-16.5.3.tgz", + "integrity": "sha512-ZLAZI24bQD0C9CJWYHxrLG8QSmzRzfWa51rlSNwZ9Atsc3R+GeX1YZGc9IljpQxYJCHrCqd6X8TXpAmEJdnbKw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/networks": "^13.5.9", + "@polkadot/types": "16.5.3", + "@polkadot/types-codec": "16.5.3", + "@polkadot/types-create": "16.5.3", + "@polkadot/util": "^13.5.9", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/types-support": { + "version": "16.5.3", + "resolved": "https://registry.npmjs.org/@polkadot/types-support/-/types-support-16.5.3.tgz", + "integrity": "sha512-ggyIRV+4Kn+aG1PiVT0PE00pAqMveyS3CuFsW9gJnKxeev4VrGfr08R4vw/61D7uIfpilkQdkXNgXAbeN09Mxg==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/util": "^13.5.9", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/types/node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@polkadot/types/node_modules/@polkadot/util-crypto": { + "version": "13.5.9", + "resolved": "https://registry.npmjs.org/@polkadot/util-crypto/-/util-crypto-13.5.9.tgz", + "integrity": "sha512-foUesMhxkTk8CZ0/XEcfvHk6I0O+aICqqVJllhOpyp/ZVnrTBKBf59T6RpsXx2pCtBlMsLRvg/6Mw7RND1HqDg==", + "license": "Apache-2.0", + "dependencies": { + "@noble/curves": "^1.3.0", + "@noble/hashes": "^1.3.3", + "@polkadot/networks": "13.5.9", + "@polkadot/util": "13.5.9", + "@polkadot/wasm-crypto": "^7.5.3", + "@polkadot/wasm-util": "^7.5.3", + "@polkadot/x-bigint": "13.5.9", + "@polkadot/x-randomvalues": "13.5.9", + "@scure/base": "^1.1.7", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@polkadot/util": "13.5.9" + } + }, + "node_modules/@polkadot/util": { + "version": "13.5.9", + "resolved": "https://registry.npmjs.org/@polkadot/util/-/util-13.5.9.tgz", + "integrity": "sha512-pIK3XYXo7DKeFRkEBNYhf3GbCHg6dKQisSvdzZwuyzA6m7YxQq4DFw4IE464ve4Z7WsJFt3a6C9uII36hl9EWw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-bigint": "13.5.9", + "@polkadot/x-global": "13.5.9", + "@polkadot/x-textdecoder": "13.5.9", + "@polkadot/x-textencoder": "13.5.9", + "@types/bn.js": "^5.1.6", + "bn.js": "^5.2.1", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/util-crypto": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/@polkadot/util-crypto/-/util-crypto-14.0.1.tgz", + "integrity": "sha512-Cu7AKUzBTsUkbOtyuNzXcTpDjR9QW0fVR56o3gBmzfUCmvO1vlsuGzmmPzqpHymQQ3rrfqV78CPs62EGhw0R+A==", + "license": "Apache-2.0", + "dependencies": { + "@noble/curves": "^1.3.0", + "@noble/hashes": "^1.3.3", + "@polkadot/networks": "14.0.1", + "@polkadot/util": "14.0.1", + "@polkadot/wasm-crypto": "^7.5.3", + "@polkadot/wasm-util": "^7.5.3", + "@polkadot/x-bigint": "14.0.1", + "@polkadot/x-randomvalues": "14.0.1", + "@scure/base": "^1.1.7", + "@scure/sr25519": "^0.2.0", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@polkadot/util": "14.0.1" + } + }, + "node_modules/@polkadot/util-crypto/node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@polkadot/util-crypto/node_modules/@polkadot/networks": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/@polkadot/networks/-/networks-14.0.1.tgz", + "integrity": "sha512-wGlBtXDkusRAj4P7uxfPz80gLO1+j99MLBaQi3bEym2xrFrFhgIWVHOZlBit/1PfaBjhX2Z8XjRxaM2w1p7w2w==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/util": "14.0.1", + "@substrate/ss58-registry": "^1.51.0", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/util-crypto/node_modules/@polkadot/util": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/@polkadot/util/-/util-14.0.1.tgz", + "integrity": "sha512-764HhxkPV3x5rM0/p6QdynC2dw26n+SaE+jisjx556ViCd4E28Ke4xSPef6C0Spy4aoXf2gt0PuLEcBvd6fVZg==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-bigint": "14.0.1", + "@polkadot/x-global": "14.0.1", + "@polkadot/x-textdecoder": "14.0.1", + "@polkadot/x-textencoder": "14.0.1", + "@types/bn.js": "^5.1.6", + "bn.js": "^5.2.1", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/util-crypto/node_modules/@polkadot/x-bigint": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/@polkadot/x-bigint/-/x-bigint-14.0.1.tgz", + "integrity": "sha512-gfozjGnebr2rqURs31KtaWumbW4rRZpbiluhlmai6luCNrf5u8pB+oLA35kPEntrsLk9PnIG9OsC/n4hEtx4OQ==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "14.0.1", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/util-crypto/node_modules/@polkadot/x-global": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/@polkadot/x-global/-/x-global-14.0.1.tgz", + "integrity": "sha512-aCI44DJU4fU0XXqrrSGIpi7JrZXK2kpe0jaQ2p6oDVXOOYEnZYXnMhTTmBE1lF/xtxzX50MnZrrU87jziU0qbA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/util-crypto/node_modules/@polkadot/x-randomvalues": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/@polkadot/x-randomvalues/-/x-randomvalues-14.0.1.tgz", + "integrity": "sha512-/XkQcvshzJLHITuPrN3zmQKuFIPdKWoaiHhhVLD6rQWV60lTXA3ajw3ocju8ZN7xRxnweMS9Ce0kMPYa0NhRMg==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "14.0.1", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@polkadot/util": "14.0.1", + "@polkadot/wasm-util": "*" + } + }, + "node_modules/@polkadot/util-crypto/node_modules/@polkadot/x-textdecoder": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/@polkadot/x-textdecoder/-/x-textdecoder-14.0.1.tgz", + "integrity": "sha512-CcWiPCuPVJsNk4Vq43lgFHqLRBQHb4r9RD7ZIYgmwoebES8TNm4g2ew9ToCzakFKSpzKu6I07Ne9wv/dt5zLuw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "14.0.1", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/util-crypto/node_modules/@polkadot/x-textencoder": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/@polkadot/x-textencoder/-/x-textencoder-14.0.1.tgz", + "integrity": "sha512-VY51SpQmF1ccmAGLfxhYnAe95Spfz049WZ/+kK4NfsGF9WejxVdU53Im5C80l45r8qHuYQsCWU3+t0FNunh2Kg==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "14.0.1", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/util-crypto/node_modules/@scure/sr25519": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@scure/sr25519/-/sr25519-0.2.0.tgz", + "integrity": "sha512-uUuLP7Z126XdSizKtrCGqYyR3b3hYtJ6Fg/XFUXmc2//k2aXHDLqZwFeXxL97gg4XydPROPVnuaHGF2+xriSKg==", + "license": "MIT", + "dependencies": { + "@noble/curves": "~1.9.2", + "@noble/hashes": "~1.8.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@polkadot/wasm-bridge": { + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-bridge/-/wasm-bridge-7.5.3.tgz", + "integrity": "sha512-mUvwwNH+uP1wqpMuHjmEwHxRIaVc5csmb+ukycWQGhzwhpXe/0fvBEU2TQ8kwgqO2MU0FS3hN/QcIWKfPRJgxQ==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/wasm-util": "7.5.3", + "tslib": "^2.7.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@polkadot/util": "*", + "@polkadot/x-randomvalues": "*" + } + }, + "node_modules/@polkadot/wasm-crypto": { + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto/-/wasm-crypto-7.5.3.tgz", + "integrity": "sha512-dmKUM9vw1wrnCHGuIeOtQo1pwuSF7fkyF4TYimTn3tAa0+3cDctYBErtGxgUeqP0Bo4Q0Of4/vnHlSk5Rbt9Uw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/wasm-bridge": "7.5.3", + "@polkadot/wasm-crypto-asmjs": "7.5.3", + "@polkadot/wasm-crypto-init": "7.5.3", + "@polkadot/wasm-crypto-wasm": "7.5.3", + "@polkadot/wasm-util": "7.5.3", + "tslib": "^2.7.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@polkadot/util": "*", + "@polkadot/x-randomvalues": "*" + } + }, + "node_modules/@polkadot/wasm-crypto-asmjs": { + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto-asmjs/-/wasm-crypto-asmjs-7.5.3.tgz", + "integrity": "sha512-fSbbjI+4p0U3PQ8nOz/3p7euHriSdh+2CSywNuXHa8fMaYlMqCKt9K7+HI8CQ4RZNvZWDq+Py1nEDEkM4rZrvw==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.7.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@polkadot/util": "*" + } + }, + "node_modules/@polkadot/wasm-crypto-init": { + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto-init/-/wasm-crypto-init-7.5.3.tgz", + "integrity": "sha512-KvUpxqvW70XhuDiw/N6rM8fQ7zRjIFblw+vdJ0/wwyagwg9jrYNA9TMei5ksQd9sxGCGXN/xJmwHJXuUjkocmg==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/wasm-bridge": "7.5.3", + "@polkadot/wasm-crypto-asmjs": "7.5.3", + "@polkadot/wasm-crypto-wasm": "7.5.3", + "@polkadot/wasm-util": "7.5.3", + "tslib": "^2.7.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@polkadot/util": "*", + "@polkadot/x-randomvalues": "*" + } + }, + "node_modules/@polkadot/wasm-crypto-wasm": { + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto-wasm/-/wasm-crypto-wasm-7.5.3.tgz", + "integrity": "sha512-fc88+HyVxebB/40GVgGUOLBqyO3C571DXWPTFmtt5EX9H8gw7Jg0Bkitz7hgSVP2x4FjXpqS9UNTJ8trVH0x1A==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/wasm-util": "7.5.3", + "tslib": "^2.7.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@polkadot/util": "*" + } + }, + "node_modules/@polkadot/wasm-util": { + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-util/-/wasm-util-7.5.3.tgz", + "integrity": "sha512-hBr9bbjS+Yr7DrDUSkIIuvlTSoAlI8WXuo9YEB4C76j130u/cl+zyq6Iy/WnaTE6QH+8i9DhM8QTety6TqYnUQ==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.7.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@polkadot/util": "*" + } + }, + "node_modules/@polkadot/x-bigint": { + "version": "13.5.9", + "resolved": "https://registry.npmjs.org/@polkadot/x-bigint/-/x-bigint-13.5.9.tgz", + "integrity": "sha512-JVW6vw3e8fkcRyN9eoc6JIl63MRxNQCP/tuLdHWZts1tcAYao0hpWUzteqJY93AgvmQ91KPsC1Kf3iuuZCi74g==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "13.5.9", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/x-fetch": { + "version": "13.5.9", + "resolved": "https://registry.npmjs.org/@polkadot/x-fetch/-/x-fetch-13.5.9.tgz", + "integrity": "sha512-urwXQZtT4yYROiRdJS6zHu18J/jCoAGpbgPIAjwdqjT11t9XIq4SjuPMxD19xBRhbYe9ocWV8i1KHuoMbZgKbA==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "13.5.9", + "node-fetch": "^3.3.2", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/x-global": { + "version": "13.5.9", + "resolved": "https://registry.npmjs.org/@polkadot/x-global/-/x-global-13.5.9.tgz", + "integrity": "sha512-zSRWvELHd3Q+bFkkI1h2cWIqLo1ETm+MxkNXLec3lB56iyq/MjWBxfXnAFFYFayvlEVneo7CLHcp+YTFd9aVSA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/x-randomvalues": { + "version": "13.5.9", + "resolved": "https://registry.npmjs.org/@polkadot/x-randomvalues/-/x-randomvalues-13.5.9.tgz", + "integrity": "sha512-Uuuz3oubf1JCCK97fsnVUnHvk4BGp/W91mQWJlgl5TIOUSSTIRr+lb5GurCfl4kgnQq53Zi5fJV+qR9YumbnZw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "13.5.9", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@polkadot/util": "13.5.9", + "@polkadot/wasm-util": "*" + } + }, + "node_modules/@polkadot/x-textdecoder": { + "version": "13.5.9", + "resolved": "https://registry.npmjs.org/@polkadot/x-textdecoder/-/x-textdecoder-13.5.9.tgz", + "integrity": "sha512-W2HhVNUbC/tuFdzNMbnXAWsIHSg9SC9QWDNmFD3nXdSzlXNgL8NmuiwN2fkYvCQBtp/XSoy0gDLx0C+Fo19cfw==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "13.5.9", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/x-textencoder": { + "version": "13.5.9", + "resolved": "https://registry.npmjs.org/@polkadot/x-textencoder/-/x-textencoder-13.5.9.tgz", + "integrity": "sha512-SG0MHnLUgn1ZxFdm0KzMdTHJ47SfqFhdIPMcGA0Mg/jt2rwrfrP3jtEIJMsHfQpHvfsNPfv55XOMmoPWuQnP/Q==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "13.5.9", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/x-ws": { + "version": "13.5.9", + "resolved": "https://registry.npmjs.org/@polkadot/x-ws/-/x-ws-13.5.9.tgz", + "integrity": "sha512-NKVgvACTIvKT8CjaQu9d0dERkZsWIZngX/4NVSjc01WHmln4F4y/zyBdYn/Z2V0Zw28cISx+lB4qxRmqTe7gbg==", + "license": "Apache-2.0", + "dependencies": { + "@polkadot/x-global": "13.5.9", + "tslib": "^2.8.0", + "ws": "^8.18.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.3.tgz", + "integrity": "sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.3.tgz", + "integrity": "sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.3.tgz", + "integrity": "sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.3.tgz", + "integrity": "sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.3.tgz", + "integrity": "sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.3.tgz", + "integrity": "sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.3.tgz", + "integrity": "sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.3.tgz", + "integrity": "sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.3.tgz", + "integrity": "sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.3.tgz", + "integrity": "sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.3.tgz", + "integrity": "sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.3.tgz", + "integrity": "sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.3.tgz", + "integrity": "sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.3.tgz", + "integrity": "sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.3.tgz", + "integrity": "sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.3.tgz", + "integrity": "sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.3.tgz", + "integrity": "sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.3.tgz", + "integrity": "sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.3.tgz", + "integrity": "sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.3.tgz", + "integrity": "sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.3.tgz", + "integrity": "sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.3.tgz", + "integrity": "sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rx-state/core": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@rx-state/core/-/core-0.1.4.tgz", + "integrity": "sha512-Z+3hjU2xh1HisLxt+W5hlYX/eGSDaXXP+ns82gq/PLZpkXLu0uwcNUh9RLY3Clq4zT+hSsA3vcpIGt6+UAb8rQ==", + "license": "MIT", + "peerDependencies": { + "rxjs": ">=7" + } + }, + "node_modules/@scure/base": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.6.tgz", + "integrity": "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==", + "license": "MIT", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.7.0.tgz", + "integrity": "sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==", + "license": "MIT", + "dependencies": { + "@noble/curves": "~1.9.0", + "@noble/hashes": "~1.8.0", + "@scure/base": "~1.2.5" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32/node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip39": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.6.0.tgz", + "integrity": "sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "~1.8.0", + "@scure/base": "~1.2.5" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip39/node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/sr25519": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@scure/sr25519/-/sr25519-0.3.0.tgz", + "integrity": "sha512-SKsinX2sImunfcsH3seGrwH/OayBwwaJqVN8J1cJBNRCfbBq5q0jyTKGa9PcW1HWv9vXT6Yuq41JsxFLvF59ew==", + "license": "MIT", + "dependencies": { + "@noble/curves": "~2.0.0", + "@noble/hashes": "~2.0.0" + }, + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/sr25519/node_modules/@noble/curves": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-2.0.1.tgz", + "integrity": "sha512-vs1Az2OOTBiP4q0pwjW5aF0xp9n4MxVrmkFBxc6EKZc6ddYx5gaZiAsZoq0uRRXWbi3AT/sBqn05eRPtn1JCPw==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "2.0.1" + }, + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@sec-ant/readable-stream": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", + "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==", + "license": "MIT" + }, + "node_modules/@sindresorhus/merge-streams": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", + "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@substrate/connect": { + "version": "0.8.11", + "resolved": "https://registry.npmjs.org/@substrate/connect/-/connect-0.8.11.tgz", + "integrity": "sha512-ofLs1PAO9AtDdPbdyTYj217Pe+lBfTLltdHDs3ds8no0BseoLeAGxpz1mHfi7zB4IxI3YyAiLjH6U8cw4pj4Nw==", + "license": "GPL-3.0-only", + "optional": true, + "dependencies": { + "@substrate/connect-extension-protocol": "^2.0.0", + "@substrate/connect-known-chains": "^1.1.5", + "@substrate/light-client-extension-helpers": "^1.0.0", + "smoldot": "2.0.26" + } + }, + "node_modules/@substrate/connect-extension-protocol": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@substrate/connect-extension-protocol/-/connect-extension-protocol-2.2.2.tgz", + "integrity": "sha512-t66jwrXA0s5Goq82ZtjagLNd7DPGCNjHeehRlE/gcJmJ+G56C0W+2plqOMRicJ8XGR1/YFnUSEqUFiSNbjGrAA==", + "license": "GPL-3.0-only", + "optional": true + }, + "node_modules/@substrate/connect-known-chains": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/@substrate/connect-known-chains/-/connect-known-chains-1.10.3.tgz", + "integrity": "sha512-OJEZO1Pagtb6bNE3wCikc2wrmvEU5x7GxFFLqqbz1AJYYxSlrPCGu4N2og5YTExo4IcloNMQYFRkBGue0BKZ4w==", + "license": "GPL-3.0-only", + "optional": true + }, + "node_modules/@substrate/light-client-extension-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@substrate/light-client-extension-helpers/-/light-client-extension-helpers-1.0.0.tgz", + "integrity": "sha512-TdKlni1mBBZptOaeVrKnusMg/UBpWUORNDv5fdCaJklP4RJiFOzBCrzC+CyVI5kQzsXBisZ+2pXm+rIjS38kHg==", + "license": "MIT", + "optional": true, + "dependencies": { + "@polkadot-api/json-rpc-provider": "^0.0.1", + "@polkadot-api/json-rpc-provider-proxy": "^0.1.0", + "@polkadot-api/observable-client": "^0.3.0", + "@polkadot-api/substrate-client": "^0.1.2", + "@substrate/connect-extension-protocol": "^2.0.0", + "@substrate/connect-known-chains": "^1.1.5", + "rxjs": "^7.8.1" + }, + "peerDependencies": { + "smoldot": "2.x" + } + }, + "node_modules/@substrate/light-client-extension-helpers/node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "license": "MIT", + "optional": true, + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@substrate/light-client-extension-helpers/node_modules/@polkadot-api/json-rpc-provider": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@polkadot-api/json-rpc-provider/-/json-rpc-provider-0.0.1.tgz", + "integrity": "sha512-/SMC/l7foRjpykLTUTacIH05H3mr9ip8b5xxfwXlVezXrNVLp3Cv0GX6uItkKd+ZjzVPf3PFrDF2B2/HLSNESA==", + "license": "MIT", + "optional": true + }, + "node_modules/@substrate/light-client-extension-helpers/node_modules/@polkadot-api/json-rpc-provider-proxy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@polkadot-api/json-rpc-provider-proxy/-/json-rpc-provider-proxy-0.1.0.tgz", + "integrity": "sha512-8GSFE5+EF73MCuLQm8tjrbCqlgclcHBSRaswvXziJ0ZW7iw3UEMsKkkKvELayWyBuOPa2T5i1nj6gFOeIsqvrg==", + "license": "MIT", + "optional": true + }, + "node_modules/@substrate/light-client-extension-helpers/node_modules/@polkadot-api/metadata-builders": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@polkadot-api/metadata-builders/-/metadata-builders-0.3.2.tgz", + "integrity": "sha512-TKpfoT6vTb+513KDzMBTfCb/ORdgRnsS3TDFpOhAhZ08ikvK+hjHMt5plPiAX/OWkm1Wc9I3+K6W0hX5Ab7MVg==", + "license": "MIT", + "optional": true, + "dependencies": { + "@polkadot-api/substrate-bindings": "0.6.0", + "@polkadot-api/utils": "0.1.0" + } + }, + "node_modules/@substrate/light-client-extension-helpers/node_modules/@polkadot-api/observable-client": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@polkadot-api/observable-client/-/observable-client-0.3.2.tgz", + "integrity": "sha512-HGgqWgEutVyOBXoGOPp4+IAq6CNdK/3MfQJmhCJb8YaJiaK4W6aRGrdQuQSTPHfERHCARt9BrOmEvTXAT257Ug==", + "license": "MIT", + "optional": true, + "dependencies": { + "@polkadot-api/metadata-builders": "0.3.2", + "@polkadot-api/substrate-bindings": "0.6.0", + "@polkadot-api/utils": "0.1.0" + }, + "peerDependencies": { + "@polkadot-api/substrate-client": "0.1.4", + "rxjs": ">=7.8.0" + } + }, + "node_modules/@substrate/light-client-extension-helpers/node_modules/@polkadot-api/substrate-bindings": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@polkadot-api/substrate-bindings/-/substrate-bindings-0.6.0.tgz", + "integrity": "sha512-lGuhE74NA1/PqdN7fKFdE5C1gNYX357j1tWzdlPXI0kQ7h3kN0zfxNOpPUN7dIrPcOFZ6C0tRRVrBylXkI6xPw==", + "license": "MIT", + "optional": true, + "dependencies": { + "@noble/hashes": "^1.3.1", + "@polkadot-api/utils": "0.1.0", + "@scure/base": "^1.1.1", + "scale-ts": "^1.6.0" + } + }, + "node_modules/@substrate/light-client-extension-helpers/node_modules/@polkadot-api/substrate-client": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@polkadot-api/substrate-client/-/substrate-client-0.1.4.tgz", + "integrity": "sha512-MljrPobN0ZWTpn++da9vOvt+Ex+NlqTlr/XT7zi9sqPtDJiQcYl+d29hFAgpaeTqbeQKZwz3WDE9xcEfLE8c5A==", + "license": "MIT", + "optional": true, + "dependencies": { + "@polkadot-api/json-rpc-provider": "0.0.1", + "@polkadot-api/utils": "0.1.0" + } + }, + "node_modules/@substrate/light-client-extension-helpers/node_modules/@polkadot-api/utils": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@polkadot-api/utils/-/utils-0.1.0.tgz", + "integrity": "sha512-MXzWZeuGxKizPx2Xf/47wx9sr/uxKw39bVJUptTJdsaQn/TGq+z310mHzf1RCGvC1diHM8f593KrnDgc9oNbJA==", + "license": "MIT", + "optional": true + }, + "node_modules/@substrate/ss58-registry": { + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/@substrate/ss58-registry/-/ss58-registry-1.51.0.tgz", + "integrity": "sha512-TWDurLiPxndFgKjVavCniytBIw+t4ViOi7TYp9h/D0NMmkEc9klFTo+827eyEJ0lELpqO207Ey7uGxUa+BS1jQ==", + "license": "Apache-2.0" + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.12.tgz", + "integrity": "sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-DLbJ1BPqxvQhIGbeu8VbUC1DiAiahHtAYvA0ZEAa4P31F7IaArc8z3C3BRQdWX4mtLQuABG4yzp76ZrS02Ui1Q==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/bn.js/node_modules/@types/node": { + "version": "24.10.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.1.tgz", + "integrity": "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/@types/bn.js/node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "license": "MIT" + }, + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" + } + }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "license": "MIT" + }, + "node_modules/@types/mocha": { + "version": "10.0.10", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.10.tgz", + "integrity": "sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.19.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.1.tgz", + "integrity": "sha512-LCCV0HdSZZZb34qifBsyWlUmok6W7ouER+oQIGBScS8EsZsQbrtFTUrDX4hOl+CS6p7cnNC4td+qrSVGSCTUfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", + "license": "MIT" + }, + "node_modules/@types/ws": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/ws/node_modules/@types/node": { + "version": "24.10.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.1.tgz", + "integrity": "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/@types/ws/node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "license": "MIT" + }, + "node_modules/abitype": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/abitype/-/abitype-1.2.0.tgz", + "integrity": "sha512-fD3ROjckUrWsybaSor2AdWxzA0e/DSyV2dA4aYd7bd8orHsoJjl09fOgKfUkTDfk0BsDGBf4NBgu/c7JoS2Npw==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/wevm" + }, + "peerDependencies": { + "typescript": ">=5.0.4", + "zod": "^3.22.0 || ^4.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + }, + "zod": { + "optional": true + } + } + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/aes-js": { + "version": "4.0.0-beta.5", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-4.0.0-beta.5.tgz", + "integrity": "sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==", + "license": "MIT" + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "license": "MIT" + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true, + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/assert": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-2.1.0.tgz", + "integrity": "sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "is-nan": "^1.3.2", + "object-is": "^1.1.5", + "object.assign": "^4.1.4", + "util": "^0.12.5" + } + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, + "node_modules/bn.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.2.tgz", + "integrity": "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==", + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "license": "ISC" + }, + "node_modules/bundle-require": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/bundle-require/-/bundle-require-5.1.0.tgz", + "integrity": "sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==", + "license": "MIT", + "dependencies": { + "load-tsconfig": "^0.2.3" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "peerDependencies": { + "esbuild": ">=0.18" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/chai": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.1.tgz", + "integrity": "sha512-p4Z49OGG5W/WBCPSS/dH3jQ73kD6tiMmUM+bckNK6Jr5JHMG3k9bg/BvKR8lKmtVBKmOiuVaV2ws8s9oSbwysg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/cli-cursor": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", + "license": "MIT", + "dependencies": { + "restore-cursor": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-spinners": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-3.3.0.tgz", + "integrity": "sha512-/+40ljC3ONVnYIttjMWrlL51nItDAbBrq2upN8BPyvGU/2n5Oxw3tbNwORCaNuNqLJnxGqOfjUuhsv7l5Q4IsQ==", + "license": "MIT", + "engines": { + "node": ">=18.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/commander": { + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.2.tgz", + "integrity": "sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ==", + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "license": "MIT" + }, + "node_modules/consola": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", + "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", + "license": "MIT", + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deepmerge-ts": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/deepmerge-ts/-/deepmerge-ts-7.1.5.tgz", + "integrity": "sha512-HOJkrhaYsweh+W+e74Yn7YStZOilkoPb6fycpwNLKzSPtruFs48nYis0zy5yJz1+ktUhHxoRDJ27RQAWLIJVJw==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/detect-indent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-7.0.2.tgz", + "integrity": "sha512-y+8xyqdGLL+6sh0tVeHcfP/QDd8gUgbasolJJpY7NgeQGSZ739bDtSiaiDgtoicy+mtYB81dKLxO9xRhCyIB3A==", + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dotenv": { + "version": "17.2.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.1.tgz", + "integrity": "sha512-kQhDYKZecqnM0fCnzI5eIv5L4cAe/iRI+HqMbO/hbRdTAeXDG+M9FjipUxNfbARuEg4iHIbhnhs78BCHNbSxEQ==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "license": "MIT" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.12", + "@esbuild/android-arm": "0.25.12", + "@esbuild/android-arm64": "0.25.12", + "@esbuild/android-x64": "0.25.12", + "@esbuild/darwin-arm64": "0.25.12", + "@esbuild/darwin-x64": "0.25.12", + "@esbuild/freebsd-arm64": "0.25.12", + "@esbuild/freebsd-x64": "0.25.12", + "@esbuild/linux-arm": "0.25.12", + "@esbuild/linux-arm64": "0.25.12", + "@esbuild/linux-ia32": "0.25.12", + "@esbuild/linux-loong64": "0.25.12", + "@esbuild/linux-mips64el": "0.25.12", + "@esbuild/linux-ppc64": "0.25.12", + "@esbuild/linux-riscv64": "0.25.12", + "@esbuild/linux-s390x": "0.25.12", + "@esbuild/linux-x64": "0.25.12", + "@esbuild/netbsd-arm64": "0.25.12", + "@esbuild/netbsd-x64": "0.25.12", + "@esbuild/openbsd-arm64": "0.25.12", + "@esbuild/openbsd-x64": "0.25.12", + "@esbuild/openharmony-arm64": "0.25.12", + "@esbuild/sunos-x64": "0.25.12", + "@esbuild/win32-arm64": "0.25.12", + "@esbuild/win32-ia32": "0.25.12", + "@esbuild/win32-x64": "0.25.12" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ethers": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.16.0.tgz", + "integrity": "sha512-U1wulmetNymijEhpSEQ7Ct/P/Jw9/e7R1j5XIbPRydgV2DjLVMsULDlNksq3RQnFgKoLlZf88ijYtWEXcPa07A==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/ethers-io/" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@adraffy/ens-normalize": "1.10.1", + "@noble/curves": "1.2.0", + "@noble/hashes": "1.3.2", + "@types/node": "22.7.5", + "aes-js": "4.0.0-beta.5", + "tslib": "2.7.0", + "ws": "8.17.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/ethers/node_modules/@adraffy/ens-normalize": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz", + "integrity": "sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==", + "license": "MIT" + }, + "node_modules/ethers/node_modules/@noble/curves": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", + "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.3.2" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ethers/node_modules/@noble/hashes": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", + "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ethers/node_modules/@types/node": { + "version": "22.7.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz", + "integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/ethers/node_modules/tslib": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", + "license": "0BSD" + }, + "node_modules/ethers/node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "license": "MIT" + }, + "node_modules/ethers/node_modules/ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "license": "MIT" + }, + "node_modules/execa": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-9.6.1.tgz", + "integrity": "sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==", + "license": "MIT", + "dependencies": { + "@sindresorhus/merge-streams": "^4.0.0", + "cross-spawn": "^7.0.6", + "figures": "^6.1.0", + "get-stream": "^9.0.0", + "human-signals": "^8.0.1", + "is-plain-obj": "^4.1.0", + "is-stream": "^4.0.1", + "npm-run-path": "^6.0.0", + "pretty-ms": "^9.2.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^4.0.0", + "yoctocolors": "^2.1.1" + }, + "engines": { + "node": "^18.19.0 || >=20.5.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, + "node_modules/figures": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz", + "integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==", + "license": "MIT", + "dependencies": { + "is-unicode-supported": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/fix-dts-default-cjs-exports": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fix-dts-default-cjs-exports/-/fix-dts-default-cjs-exports-1.0.1.tgz", + "integrity": "sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==", + "license": "MIT", + "dependencies": { + "magic-string": "^0.30.17", + "mlly": "^1.7.4", + "rollup": "^4.34.8" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "license": "MIT", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/fs.promises.exists": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/fs.promises.exists/-/fs.promises.exists-1.1.4.tgz", + "integrity": "sha512-lJzUGWbZn8vhGWBedA+RYjB/BeJ+3458ljUfmplqhIeb6ewzTFWNPCR1HCiYCkXV9zxcHz9zXkJzMsEgDLzh3Q==", + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/fs.promises.exists?sponsor=1" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", + "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", + "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", + "license": "MIT", + "dependencies": { + "@sec-ant/readable-stream": "^0.4.1", + "is-stream": "^4.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/hosted-git-info": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-9.0.2.tgz", + "integrity": "sha512-M422h7o/BR3rmCQ8UHi7cyyMqKltdP9Uo+J2fXK+RSAY+wTcKOIRyhTuKv4qn+DJf3g+PL890AzId5KZpX+CBg==", + "license": "ISC", + "dependencies": { + "lru-cache": "^11.1.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "11.2.4", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.4.tgz", + "integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==", + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/human-signals": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.1.tgz", + "integrity": "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/index-to-position": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/index-to-position/-/index-to-position-1.2.0.tgz", + "integrity": "sha512-Yg7+ztRkqslMAS2iFaU+Oa4KTSidr63OsFGlOrJoW981kIYO3CGCS3wA95P1mUi/IVSJkn0D479KTJpVpvFNuw==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/is-arguments": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz", + "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-interactive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", + "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-nan": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", + "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", + "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-unicode-supported": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", + "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/isows": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/isows/-/isows-1.0.6.tgz", + "integrity": "sha512-lPHCayd40oW98/I0uvgaHKWCSvkzY27LjWLbtzOm64yQ+G3Q5npjjbdppU65iZXkK1Zt+kH9pfegli0AYfwYYw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/wevm" + } + ], + "license": "MIT", + "peerDependencies": { + "ws": "*" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/joycon": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", + "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "license": "ISC" + }, + "node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "license": "MIT" + }, + "node_modules/load-tsconfig": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/load-tsconfig/-/load-tsconfig-0.2.5.tgz", + "integrity": "sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC" + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true, + "license": "ISC" + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mlly": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.0.tgz", + "integrity": "sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==", + "license": "MIT", + "dependencies": { + "acorn": "^8.15.0", + "pathe": "^2.0.3", + "pkg-types": "^1.3.1", + "ufo": "^1.6.1" + } + }, + "node_modules/mocha": { + "version": "11.7.5", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.7.5.tgz", + "integrity": "sha512-mTT6RgopEYABzXWFx+GcJ+ZQ32kp4fMf0xvpZIIfSq9Z8lC/++MtcCnQ9t5FP2veYEP95FIYSvW+U9fV4xrlig==", + "license": "MIT", + "dependencies": { + "browser-stdout": "^1.3.1", + "chokidar": "^4.0.1", + "debug": "^4.3.5", + "diff": "^7.0.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^10.4.5", + "he": "^1.2.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^9.0.5", + "ms": "^2.1.3", + "picocolors": "^1.1.1", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^9.2.0", + "yargs": "^17.7.2", + "yargs-parser": "^21.1.1", + "yargs-unparser": "^2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/mocha/node_modules/diff": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz", + "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/mock-socket": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/mock-socket/-/mock-socket-9.3.1.tgz", + "integrity": "sha512-qxBgB7Qa2sEQgHFjj0dSigq7fX4k6Saisd5Nelwp2q8mlbAFh5dHV9JTTlF8viYJLSSWgMCZFUom8PJcMNBoJw==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nock": { + "version": "13.5.6", + "resolved": "https://registry.npmjs.org/nock/-/nock-13.5.6.tgz", + "integrity": "sha512-o2zOYiCpzRqSzPj0Zt/dQ/DqZeYoaQ7TUonc/xUPjCGl9WeHpNbxgVvOquXYAaJzI0M9BXV3HTzG0p8IUAbBTQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.1.0", + "json-stringify-safe": "^5.0.1", + "propagate": "^2.0.0" + }, + "engines": { + "node": ">= 10.13" + } + }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "license": "MIT", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/normalize-package-data": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-8.0.0.tgz", + "integrity": "sha512-RWk+PI433eESQ7ounYxIp67CYuVsS1uYSonX3kA6ps/3LWfjVQa/ptEg6Y3T6uAMq1mWpX9PQ+qx+QaHpsc7gQ==", + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^9.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm-run-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz", + "integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==", + "license": "MIT", + "dependencies": { + "path-key": "^4.0.0", + "unicorn-magic": "^0.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-is": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", + "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/onetime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "license": "MIT", + "dependencies": { + "mimic-function": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-9.0.0.tgz", + "integrity": "sha512-m0pg2zscbYgWbqRR6ABga5c3sZdEon7bSgjnlXC64kxtxLOyjRcbbUkLj7HFyy/FTD+P2xdBWu8snGhYI0jc4A==", + "license": "MIT", + "dependencies": { + "chalk": "^5.6.2", + "cli-cursor": "^5.0.0", + "cli-spinners": "^3.2.0", + "is-interactive": "^2.0.0", + "is-unicode-supported": "^2.1.0", + "log-symbols": "^7.0.1", + "stdin-discarder": "^0.2.2", + "string-width": "^8.1.0", + "strip-ansi": "^7.1.2" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ora/node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/ora/node_modules/log-symbols": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-7.0.1.tgz", + "integrity": "sha512-ja1E3yCr9i/0hmBVaM0bfwDjnGy8I/s6PP4DFp+yP+a+mrHO4Rm7DtmnqROTUkHIkqffC84YY7AeqX6oFk0WFg==", + "license": "MIT", + "dependencies": { + "is-unicode-supported": "^2.0.0", + "yoctocolors": "^2.1.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/string-width": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.1.0.tgz", + "integrity": "sha512-Kxl3KJGb/gxkaUMOjRsQ8IrXiGW75O4E3RPjFIINOVH8AMl2SQ/yWdTzWwF3FevIX9LcMAjJW+GRwAlAbTSXdg==", + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.3.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/ox": { + "version": "0.6.7", + "resolved": "https://registry.npmjs.org/ox/-/ox-0.6.7.tgz", + "integrity": "sha512-17Gk/eFsFRAZ80p5eKqv89a57uXjd3NgIf1CaXojATPBuujVc/fQSVhBeAU9JCRB+k7J50WQAyWTxK19T9GgbA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/wevm" + } + ], + "license": "MIT", + "dependencies": { + "@adraffy/ens-normalize": "^1.10.1", + "@noble/curves": "^1.6.0", + "@noble/hashes": "^1.5.0", + "@scure/bip32": "^1.5.0", + "@scure/bip39": "^1.4.0", + "abitype": "^1.0.6", + "eventemitter3": "5.0.1" + }, + "peerDependencies": { + "typescript": ">=5.4.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/ox/node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "license": "BlueOak-1.0.0" + }, + "node_modules/parse-json": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.3.0.tgz", + "integrity": "sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.26.2", + "index-to-position": "^1.1.0", + "type-fest": "^4.39.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-ms": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz", + "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-types": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", + "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", + "license": "MIT", + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.4", + "pathe": "^2.0.1" + } + }, + "node_modules/polkadot-api": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/polkadot-api/-/polkadot-api-1.22.0.tgz", + "integrity": "sha512-uREBLroPbnJxBBQ+qSkKLF493qukX4PAg32iThlELrZdxfNNgro6nvWRdVmBv73tFHvf+nyWWHKTx1c57nbixg==", + "license": "MIT", + "dependencies": { + "@polkadot-api/cli": "0.16.3", + "@polkadot-api/ink-contracts": "0.4.3", + "@polkadot-api/json-rpc-provider": "0.0.4", + "@polkadot-api/known-chains": "0.9.15", + "@polkadot-api/logs-provider": "0.0.6", + "@polkadot-api/metadata-builders": "0.13.7", + "@polkadot-api/metadata-compatibility": "0.4.1", + "@polkadot-api/observable-client": "0.17.0", + "@polkadot-api/pjs-signer": "0.6.17", + "@polkadot-api/polkadot-sdk-compat": "2.3.3", + "@polkadot-api/polkadot-signer": "0.1.6", + "@polkadot-api/signer": "0.2.11", + "@polkadot-api/sm-provider": "0.1.14", + "@polkadot-api/smoldot": "0.3.14", + "@polkadot-api/substrate-bindings": "0.16.5", + "@polkadot-api/substrate-client": "0.4.7", + "@polkadot-api/utils": "0.2.0", + "@polkadot-api/ws-provider": "0.7.4", + "@rx-state/core": "^0.1.4" + }, + "bin": { + "papi": "bin/cli.mjs", + "polkadot-api": "bin/cli.mjs" + }, + "peerDependencies": { + "rxjs": ">=7.8.0" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss-load-config": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz", + "integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "lilconfig": "^3.1.1" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "jiti": ">=1.21.0", + "postcss": ">=8.0.9", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + }, + "postcss": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/prettier": { + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.7.4.tgz", + "integrity": "sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/pretty-ms": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.3.0.tgz", + "integrity": "sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==", + "license": "MIT", + "dependencies": { + "parse-ms": "^4.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/propagate": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", + "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/read-pkg": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-10.0.0.tgz", + "integrity": "sha512-A70UlgfNdKI5NSvTTfHzLQj7NJRpJ4mT5tGafkllJ4wh71oYuGm/pzphHcmW4s35iox56KSK721AihodoXSc/A==", + "license": "MIT", + "dependencies": { + "@types/normalize-package-data": "^2.4.4", + "normalize-package-data": "^8.0.0", + "parse-json": "^8.3.0", + "type-fest": "^5.2.0", + "unicorn-magic": "^0.3.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg/node_modules/type-fest": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.3.0.tgz", + "integrity": "sha512-d9CwU93nN0IA1QL+GSNDdwLAu1Ew5ZjTwupvedwg3WdfoH6pIDvYQ2hV0Uc2nKBLPq7NB5apCx57MLS5qlmO5g==", + "license": "(MIT OR CC0-1.0)", + "dependencies": { + "tagged-tag": "^1.0.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/restore-cursor": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "license": "MIT", + "dependencies": { + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/rollup": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.3.tgz", + "integrity": "sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==", + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.53.3", + "@rollup/rollup-android-arm64": "4.53.3", + "@rollup/rollup-darwin-arm64": "4.53.3", + "@rollup/rollup-darwin-x64": "4.53.3", + "@rollup/rollup-freebsd-arm64": "4.53.3", + "@rollup/rollup-freebsd-x64": "4.53.3", + "@rollup/rollup-linux-arm-gnueabihf": "4.53.3", + "@rollup/rollup-linux-arm-musleabihf": "4.53.3", + "@rollup/rollup-linux-arm64-gnu": "4.53.3", + "@rollup/rollup-linux-arm64-musl": "4.53.3", + "@rollup/rollup-linux-loong64-gnu": "4.53.3", + "@rollup/rollup-linux-ppc64-gnu": "4.53.3", + "@rollup/rollup-linux-riscv64-gnu": "4.53.3", + "@rollup/rollup-linux-riscv64-musl": "4.53.3", + "@rollup/rollup-linux-s390x-gnu": "4.53.3", + "@rollup/rollup-linux-x64-gnu": "4.53.3", + "@rollup/rollup-linux-x64-musl": "4.53.3", + "@rollup/rollup-openharmony-arm64": "4.53.3", + "@rollup/rollup-win32-arm64-msvc": "4.53.3", + "@rollup/rollup-win32-ia32-msvc": "4.53.3", + "@rollup/rollup-win32-x64-gnu": "4.53.3", + "@rollup/rollup-win32-x64-msvc": "4.53.3", + "fsevents": "~2.3.2" + } + }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/scale-ts": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/scale-ts/-/scale-ts-1.6.1.tgz", + "integrity": "sha512-PBMc2AWc6wSEqJYBDPcyCLUj9/tMKnLX70jLOSndMtcUoLQucP/DM0vnQo1wJAYjTrQiq8iG9rD0q6wFzgjH7g==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/smoldot": { + "version": "2.0.26", + "resolved": "https://registry.npmjs.org/smoldot/-/smoldot-2.0.26.tgz", + "integrity": "sha512-F+qYmH4z2s2FK+CxGj8moYcd1ekSIKH8ywkdqlOz88Dat35iB1DIYL11aILN46YSGMzQW/lbJNS307zBSDN5Ig==", + "license": "GPL-3.0-or-later WITH Classpath-exception-2.0", + "optional": true, + "dependencies": { + "ws": "^8.8.1" + } + }, + "node_modules/sort-keys": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-5.1.0.tgz", + "integrity": "sha512-aSbHV0DaBcr7u0PVHXzM6NbZNAtrr9sF6+Qfs9UUVG7Ll3jQ6hHi8F/xqIIcn2rvIVbr0v/2zyjSdwSV47AgLQ==", + "license": "MIT", + "dependencies": { + "is-plain-obj": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/source-map": { + "version": "0.8.0-beta.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", + "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", + "license": "BSD-3-Clause", + "dependencies": { + "whatwg-url": "^7.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.22", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.22.tgz", + "integrity": "sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==", + "license": "CC0-1.0" + }, + "node_modules/stdin-discarder": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.2.2.tgz", + "integrity": "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz", + "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/sucrase": { + "version": "3.35.1", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.1.tgz", + "integrity": "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "tinyglobby": "^0.2.11", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/sucrase/node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/tagged-tag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/tagged-tag/-/tagged-tag-1.0.0.tgz", + "integrity": "sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==", + "license": "MIT", + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", + "license": "MIT", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "license": "Apache-2.0" + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/tsc-prog": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tsc-prog/-/tsc-prog-2.3.0.tgz", + "integrity": "sha512-ycET2d75EgcX7y8EmG4KiZkLAwUzbY4xRhA6NU0uVbHkY4ZjrAAuzTMxXI85kOwATqPnBI5C/7y7rlpY0xdqHA==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "typescript": ">=4" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/tsup": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/tsup/-/tsup-8.5.0.tgz", + "integrity": "sha512-VmBp77lWNQq6PfuMqCHD3xWl22vEoWsKajkF8t+yMBawlUS8JzEI+vOVMeuNZIuMML8qXRizFKi9oD5glKQVcQ==", + "license": "MIT", + "dependencies": { + "bundle-require": "^5.1.0", + "cac": "^6.7.14", + "chokidar": "^4.0.3", + "consola": "^3.4.0", + "debug": "^4.4.0", + "esbuild": "^0.25.0", + "fix-dts-default-cjs-exports": "^1.0.0", + "joycon": "^3.1.1", + "picocolors": "^1.1.1", + "postcss-load-config": "^6.0.1", + "resolve-from": "^5.0.0", + "rollup": "^4.34.8", + "source-map": "0.8.0-beta.0", + "sucrase": "^3.35.0", + "tinyexec": "^0.3.2", + "tinyglobby": "^0.2.11", + "tree-kill": "^1.2.2" + }, + "bin": { + "tsup": "dist/cli-default.js", + "tsup-node": "dist/cli-node.js" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@microsoft/api-extractor": "^7.36.0", + "@swc/core": "^1", + "postcss": "^8.4.12", + "typescript": ">=4.5.0" + }, + "peerDependenciesMeta": { + "@microsoft/api-extractor": { + "optional": true + }, + "@swc/core": { + "optional": true + }, + "postcss": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ufo": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz", + "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==", + "license": "MIT" + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/unicorn-magic": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", + "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true, + "license": "MIT" + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/viem": { + "version": "2.23.4", + "resolved": "https://registry.npmjs.org/viem/-/viem-2.23.4.tgz", + "integrity": "sha512-UQquuolKlS1w5H5e0Fd1KKoUlIPJryIEBzY5AUhGyV1ka+9O6+3uYVhUzj6RbvGK0PtsMKn2ddwPZFwjNDVU/A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/wevm" + } + ], + "license": "MIT", + "dependencies": { + "@noble/curves": "1.8.1", + "@noble/hashes": "1.7.1", + "@scure/bip32": "1.6.2", + "@scure/bip39": "1.5.4", + "abitype": "1.0.8", + "isows": "1.0.6", + "ox": "0.6.7", + "ws": "8.18.0" + }, + "peerDependencies": { + "typescript": ">=5.0.4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/viem/node_modules/@noble/curves": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.8.1.tgz", + "integrity": "sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.7.1" + }, + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/viem/node_modules/@noble/hashes": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.1.tgz", + "integrity": "sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/viem/node_modules/@scure/bip32": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.6.2.tgz", + "integrity": "sha512-t96EPDMbtGgtb7onKKqxRLfE5g05k7uHnHRM2xdE6BP/ZmxaLtPek4J4KfVn/90IQNrU1IOAqMgiDtUdtbe3nw==", + "license": "MIT", + "dependencies": { + "@noble/curves": "~1.8.1", + "@noble/hashes": "~1.7.1", + "@scure/base": "~1.2.2" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/viem/node_modules/@scure/bip32/node_modules/@noble/curves": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.8.2.tgz", + "integrity": "sha512-vnI7V6lFNe0tLAuJMu+2sX+FcL14TaCWy1qiczg1VwRmPrpQCdq5ESXQMqUc2tluRNf6irBXrWbl1mGN8uaU/g==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.7.2" + }, + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/viem/node_modules/@scure/bip32/node_modules/@noble/hashes": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.2.tgz", + "integrity": "sha512-biZ0NUSxyjLLqo6KxEJ1b+C2NAx0wtDoFvCaXHGgUkeHzf3Xc1xKumFKREuT7f7DARNZ/slvYUwFG6B0f2b6hQ==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/viem/node_modules/@scure/bip39": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.5.4.tgz", + "integrity": "sha512-TFM4ni0vKvCfBpohoh+/lY05i9gRbSwXWngAsF4CABQxoaOHijxuaZ2R6cStDQ5CHtHO9aGJTr4ksVJASRRyMA==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "~1.7.1", + "@scure/base": "~1.2.4" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/viem/node_modules/abitype": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/abitype/-/abitype-1.0.8.tgz", + "integrity": "sha512-ZeiI6h3GnW06uYDLx0etQtX/p8E24UaHHBj57RSjK7YBFe7iuVn07EDpOeP451D06sF27VOz9JJPlIKJmXgkEg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/wevm" + }, + "peerDependencies": { + "typescript": ">=5.0.4", + "zod": "^3 >=3.22.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + }, + "zod": { + "optional": true + } + } + }, + "node_modules/viem/node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "license": "MIT", + "dependencies": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/workerpool": { + "version": "9.3.4", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-9.3.4.tgz", + "integrity": "sha512-TmPRQYYSAnnDiEB0P/Ytip7bFGvqnSU6I2BcuSw7Hx+JSg/DsUi5ebYfc8GYaSdpuvOcEs6dXxPurOYpe9QFwg==", + "license": "Apache-2.0" + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/write-file-atomic": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", + "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/write-json-file": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/write-json-file/-/write-json-file-6.0.0.tgz", + "integrity": "sha512-MNHcU3f9WxnNyR6MxsYSj64Jz0+dwIpisWKWq9gqLj/GwmA9INg3BZ3vt70/HB3GEwrnDQWr4RPrywnhNzmUFA==", + "license": "MIT", + "dependencies": { + "detect-indent": "^7.0.1", + "is-plain-obj": "^4.1.0", + "sort-keys": "^5.0.0", + "write-file-atomic": "^5.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/write-package": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/write-package/-/write-package-7.2.0.tgz", + "integrity": "sha512-uMQTubF/vcu+Wd0b5BGtDmiXePd/+44hUWQz2nZPbs92/BnxRo74tqs+hqDo12RLiEd+CXFKUwxvvIZvtt34Jw==", + "license": "MIT", + "dependencies": { + "deepmerge-ts": "^7.1.0", + "read-pkg": "^9.0.1", + "sort-keys": "^5.0.0", + "type-fest": "^4.23.0", + "write-json-file": "^6.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/write-package/node_modules/hosted-git-info": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", + "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", + "license": "ISC", + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/write-package/node_modules/normalize-package-data": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz", + "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==", + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^7.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/write-package/node_modules/read-pkg": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-9.0.1.tgz", + "integrity": "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==", + "license": "MIT", + "dependencies": { + "@types/normalize-package-data": "^2.4.3", + "normalize-package-data": "^6.0.0", + "parse-json": "^8.0.0", + "type-fest": "^4.6.0", + "unicorn-magic": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/write-package/node_modules/unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ws": { + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "license": "MIT", + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser/node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yoctocolors": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.2.tgz", + "integrity": "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/contract-tests/src/contracts/precompileWrapper.sol b/contract-tests/src/contracts/precompileWrapper.sol new file mode 100644 index 0000000000..9f5fe242c1 --- /dev/null +++ b/contract-tests/src/contracts/precompileWrapper.sol @@ -0,0 +1,362 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +// Precompile addresses +address constant ISUBTENSOR_BALANCE_TRANSFER_ADDRESS = 0x0000000000000000000000000000000000000800; +address constant IMETAGRAPH_ADDRESS = 0x0000000000000000000000000000000000000802; +address constant ISUBNET_ADDRESS = 0x0000000000000000000000000000000000000803; +address constant INEURON_ADDRESS = 0x0000000000000000000000000000000000000804; +address constant ISTAKING_V2_ADDRESS = 0x0000000000000000000000000000000000000805; +address constant IUID_LOOKUP_ADDRESS = 0x0000000000000000000000000000000000000806; +address constant IALPHA_ADDRESS = 0x0000000000000000000000000000000000000808; +address constant ICROWDLOAN_ADDRESS = 0x0000000000000000000000000000000000000809; +address constant ILEASING_ADDRESS = 0x000000000000000000000000000000000000080a; +address constant IPROXY_ADDRESS = 0x000000000000000000000000000000000000080b; +address constant IADDRESS_MAPPING_ADDRESS = 0x000000000000000000000000000000000000080C; + +// Interface definitions +interface ISubtensorBalanceTransfer { + function transfer(bytes32 data) external payable; +} + +interface IMetagraph { + function getUidCount(uint16 netuid) external view returns (uint16); +} + +interface ISubnet { + function registerNetwork( + bytes32 hotkey, + string memory subnetName, + string memory githubRepo, + string memory subnetContact, + string memory subnetUrl, + string memory discord, + string memory description, + string memory additional + ) external payable; + function getServingRateLimit(uint16 netuid) external view returns (uint64); +} + +interface INeuron { + function burnedRegister(uint16 netuid, bytes32 hotkey) external payable; +} + +interface IStaking { + function addStake( + bytes32 hotkey, + uint256 amount, + uint256 netuid + ) external payable; + function removeStake( + bytes32 hotkey, + uint256 amount, + uint256 netuid + ) external payable; + function getTotalColdkeyStake( + bytes32 coldkey + ) external view returns (uint256); + function getTotalHotkeyStake( + bytes32 hotkey + ) external view returns (uint256); +} + +struct LookupItem { + uint16 uid; + uint64 block_associated; +} + +interface IUidLookup { + function uidLookup( + uint16 netuid, + address evm_address, + uint16 limit + ) external view returns (LookupItem[] memory); +} + +interface IAlpha { + function getAlphaPrice(uint16 netuid) external view returns (uint256); +} + +struct CrowdloanInfo { + bytes32 creator; + uint64 deposit; + uint64 min_contribution; + uint32 end; + uint64 cap; + bytes32 funds_account; + uint64 raised; + bool has_target_address; + bytes32 target_address; + bool finalized; + uint32 contributors_count; +} + +interface ICrowdloan { + function getCrowdloan( + uint32 crowdloanId + ) external view returns (CrowdloanInfo memory); + function getContribution( + uint32 crowdloanId, + bytes32 coldkey + ) external view returns (uint64); + function create( + uint64 deposit, + uint64 minContribution, + uint64 cap, + uint32 end, + address targetAddress + ) external payable; +} + +struct LeaseInfo { + bytes32 beneficiary; + bytes32 coldkey; + bytes32 hotkey; + uint8 emissions_share; + bool has_end_block; + uint32 end_block; + uint16 netuid; + uint64 cost; +} + +interface ILeasing { + function getContributorShare( + uint32 leaseId, + bytes32 contributor + ) external view returns (uint128, uint128); + function createLeaseCrowdloan( + uint64 crowdloanDeposit, + uint64 crowdloanMinContribution, + uint64 crowdloanCap, + uint32 crowdloanEnd, + uint8 leasingEmissionsShare, + bool hasLeasingEndBlock, + uint32 leasingEndBlock + ) external payable; +} + +interface IProxy { + struct ProxyInfo { + bytes32 delegate; + uint256 proxy_type; + uint256 delay; + } + + function addProxy( + bytes32 delegate, + uint8 proxy_type, + uint32 delay + ) external; + function proxyCall( + bytes32 real, + uint8[] memory force_proxy_type, + uint8[] memory call + ) external; + function getProxies( + bytes32 account + ) external view returns (ProxyInfo[] memory); +} + +interface IAddressMapping { + function addressMapping( + address target_address + ) external view returns (bytes32); +} + +/** + * @title PrecompileWrapper + * @dev A wrapper contract that calls all precompile functions directly + * instead of using low-level calls like address.call() + */ +contract PrecompileWrapper { + ISubtensorBalanceTransfer public constant balanceTransfer = + ISubtensorBalanceTransfer(ISUBTENSOR_BALANCE_TRANSFER_ADDRESS); + IMetagraph public constant metagraph = IMetagraph(IMETAGRAPH_ADDRESS); + ISubnet public constant subnet = ISubnet(ISUBNET_ADDRESS); + INeuron public constant neuron = INeuron(INEURON_ADDRESS); + IStaking public constant staking = IStaking(ISTAKING_V2_ADDRESS); + IUidLookup public constant uidLookupPrecompile = + IUidLookup(IUID_LOOKUP_ADDRESS); + IAlpha public constant alpha = IAlpha(IALPHA_ADDRESS); + ICrowdloan public constant crowdloan = ICrowdloan(ICROWDLOAN_ADDRESS); + ILeasing public constant leasing = ILeasing(ILEASING_ADDRESS); + IProxy public constant proxy = IProxy(IPROXY_ADDRESS); + IAddressMapping public constant addressMappingPrecompile = + IAddressMapping(IADDRESS_MAPPING_ADDRESS); + + // ============ SubtensorBalanceTransfer Functions ============ + function transfer(bytes32 data) external payable { + balanceTransfer.transfer{value: msg.value}(data); + } + + // ============ Metagraph Functions ============ + + function getUidCount(uint16 netuid) external view returns (uint16) { + return metagraph.getUidCount(netuid); + } + + // ============ Subnet Functions ============ + + function registerNetworkWithDetails( + bytes32 hotkey, + string memory subnetName, + string memory githubRepo, + string memory subnetContact, + string memory subnetUrl, + string memory discord, + string memory description, + string memory additional + ) external payable { + subnet.registerNetwork( + hotkey, + subnetName, + githubRepo, + subnetContact, + subnetUrl, + discord, + description, + additional + ); + } + + function getServingRateLimit(uint16 netuid) external view returns (uint64) { + return subnet.getServingRateLimit(netuid); + } + + // ============ Neuron Functions ============ + + function burnedRegister(uint16 netuid, bytes32 hotkey) external payable { + neuron.burnedRegister{value: msg.value}(netuid, hotkey); + } + + // ============ Staking Functions ============ + function addStake( + bytes32 hotkey, + uint256 amount, + uint256 netuid + ) external payable { + staking.addStake(hotkey, amount, netuid); + } + + function removeStake( + bytes32 hotkey, + uint256 amount, + uint256 netuid + ) external payable { + staking.removeStake(hotkey, amount, netuid); + } + + function getTotalColdkeyStake( + bytes32 coldkey + ) external view returns (uint256) { + return staking.getTotalColdkeyStake(coldkey); + } + + function getTotalHotkeyStake( + bytes32 hotkey + ) external view returns (uint256) { + return staking.getTotalHotkeyStake(hotkey); + } + + // ============ Alpha Functions ============ + + function getAlphaPrice(uint16 netuid) external view returns (uint256) { + return alpha.getAlphaPrice(netuid); + } + + // ============ Address Mapping Functions ============ + + function addressMapping( + address target_address + ) external view returns (bytes32) { + return addressMappingPrecompile.addressMapping(target_address); + } + + // ============ Proxy Functions ============ + + function proxyCall( + bytes32 real, + uint8[] memory force_proxy_type, + uint8[] memory call + ) external { + proxy.proxyCall(real, force_proxy_type, call); + } + + function addProxy( + bytes32 delegate, + uint8 proxy_type, + uint32 delay + ) external { + proxy.addProxy(delegate, proxy_type, delay); + } + + function getProxies( + bytes32 account + ) external view returns (IProxy.ProxyInfo[] memory) { + return proxy.getProxies(account); + } + + // ============ UID Lookup Functions ============ + + function uidLookup( + uint16 netuid, + address evm_address, + uint16 limit + ) external view returns (LookupItem[] memory) { + return uidLookupPrecompile.uidLookup(netuid, evm_address, limit); + } + + // ============ Crowdloan Functions ============ + + function getCrowdloan( + uint32 crowdloanId + ) external view returns (CrowdloanInfo memory) { + return crowdloan.getCrowdloan(crowdloanId); + } + + function getContribution( + uint32 crowdloanId, + bytes32 coldkey + ) external view returns (uint64) { + return crowdloan.getContribution(crowdloanId, coldkey); + } + + function createCrowdloan( + uint64 deposit, + uint64 minContribution, + uint64 cap, + uint32 end, + address targetAddress + ) external payable { + crowdloan.create(deposit, minContribution, cap, end, targetAddress); + } + + // ============ Leasing Functions ============ + + function getContributorShare( + uint32 leaseId, + bytes32 contributor + ) external view returns (uint128, uint128) { + return leasing.getContributorShare(leaseId, contributor); + } + + function createLeaseCrowdloan( + uint64 crowdloanDeposit, + uint64 crowdloanMinContribution, + uint64 crowdloanCap, + uint32 crowdloanEnd, + uint8 leasingEmissionsShare, + bool hasLeasingEndBlock, + uint32 leasingEndBlock + ) external payable { + leasing.createLeaseCrowdloan( + crowdloanDeposit, + crowdloanMinContribution, + crowdloanCap, + crowdloanEnd, + leasingEmissionsShare, + hasLeasingEndBlock, + leasingEndBlock + ); + } +} diff --git a/contract-tests/src/contracts/precompileWrapper.ts b/contract-tests/src/contracts/precompileWrapper.ts new file mode 100644 index 0000000000..9916b735e9 --- /dev/null +++ b/contract-tests/src/contracts/precompileWrapper.ts @@ -0,0 +1,714 @@ +export const PRECOMPILE_WRAPPER_ABI = [ + { + "inputs": [ + { + "internalType": "bytes32", + "name": "delegate", + "type": "bytes32" + }, + { + "internalType": "uint8", + "name": "proxy_type", + "type": "uint8" + }, + { + "internalType": "uint32", + "name": "delay", + "type": "uint32" + } + ], + "name": "addProxy", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "hotkey", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "netuid", + "type": "uint256" + } + ], + "name": "addStake", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target_address", + "type": "address" + } + ], + "name": "addressMapping", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "addressMappingPrecompile", + "outputs": [ + { + "internalType": "contract IAddressMapping", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "alpha", + "outputs": [ + { + "internalType": "contract IAlpha", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "balanceTransfer", + "outputs": [ + { + "internalType": "contract ISubtensorBalanceTransfer", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "bytes32", + "name": "hotkey", + "type": "bytes32" + } + ], + "name": "burnedRegister", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "deposit", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "minContribution", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "cap", + "type": "uint64" + }, + { + "internalType": "uint32", + "name": "end", + "type": "uint32" + }, + { + "internalType": "address", + "name": "targetAddress", + "type": "address" + } + ], + "name": "createCrowdloan", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "crowdloanDeposit", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "crowdloanMinContribution", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "crowdloanCap", + "type": "uint64" + }, + { + "internalType": "uint32", + "name": "crowdloanEnd", + "type": "uint32" + }, + { + "internalType": "uint8", + "name": "leasingEmissionsShare", + "type": "uint8" + }, + { + "internalType": "bool", + "name": "hasLeasingEndBlock", + "type": "bool" + }, + { + "internalType": "uint32", + "name": "leasingEndBlock", + "type": "uint32" + } + ], + "name": "createLeaseCrowdloan", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "crowdloan", + "outputs": [ + { + "internalType": "contract ICrowdloan", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + } + ], + "name": "getAlphaPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "crowdloanId", + "type": "uint32" + }, + { + "internalType": "bytes32", + "name": "coldkey", + "type": "bytes32" + } + ], + "name": "getContribution", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "leaseId", + "type": "uint32" + }, + { + "internalType": "bytes32", + "name": "contributor", + "type": "bytes32" + } + ], + "name": "getContributorShare", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "crowdloanId", + "type": "uint32" + } + ], + "name": "getCrowdloan", + "outputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "creator", + "type": "bytes32" + }, + { + "internalType": "uint64", + "name": "deposit", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "min_contribution", + "type": "uint64" + }, + { + "internalType": "uint32", + "name": "end", + "type": "uint32" + }, + { + "internalType": "uint64", + "name": "cap", + "type": "uint64" + }, + { + "internalType": "bytes32", + "name": "funds_account", + "type": "bytes32" + }, + { + "internalType": "uint64", + "name": "raised", + "type": "uint64" + }, + { + "internalType": "bool", + "name": "has_target_address", + "type": "bool" + }, + { + "internalType": "bytes32", + "name": "target_address", + "type": "bytes32" + }, + { + "internalType": "bool", + "name": "finalized", + "type": "bool" + }, + { + "internalType": "uint32", + "name": "contributors_count", + "type": "uint32" + } + ], + "internalType": "struct CrowdloanInfo", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "account", + "type": "bytes32" + } + ], + "name": "getProxies", + "outputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "delegate", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "proxy_type", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "delay", + "type": "uint256" + } + ], + "internalType": "struct IProxy.ProxyInfo[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + } + ], + "name": "getServingRateLimit", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "coldkey", + "type": "bytes32" + } + ], + "name": "getTotalColdkeyStake", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "hotkey", + "type": "bytes32" + } + ], + "name": "getTotalHotkeyStake", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + } + ], + "name": "getUidCount", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "leasing", + "outputs": [ + { + "internalType": "contract ILeasing", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "metagraph", + "outputs": [ + { + "internalType": "contract IMetagraph", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "neuron", + "outputs": [ + { + "internalType": "contract INeuron", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "proxy", + "outputs": [ + { + "internalType": "contract IProxy", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "real", + "type": "bytes32" + }, + { + "internalType": "uint8[]", + "name": "force_proxy_type", + "type": "uint8[]" + }, + { + "internalType": "uint8[]", + "name": "call", + "type": "uint8[]" + } + ], + "name": "proxyCall", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "hotkey", + "type": "bytes32" + }, + { + "internalType": "string", + "name": "subnetName", + "type": "string" + }, + { + "internalType": "string", + "name": "githubRepo", + "type": "string" + }, + { + "internalType": "string", + "name": "subnetContact", + "type": "string" + }, + { + "internalType": "string", + "name": "subnetUrl", + "type": "string" + }, + { + "internalType": "string", + "name": "discord", + "type": "string" + }, + { + "internalType": "string", + "name": "description", + "type": "string" + }, + { + "internalType": "string", + "name": "additional", + "type": "string" + } + ], + "name": "registerNetworkWithDetails", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "hotkey", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "netuid", + "type": "uint256" + } + ], + "name": "removeStake", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "staking", + "outputs": [ + { + "internalType": "contract IStaking", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "subnet", + "outputs": [ + { + "internalType": "contract ISubnet", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "data", + "type": "bytes32" + } + ], + "name": "transfer", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "address", + "name": "evm_address", + "type": "address" + }, + { + "internalType": "uint16", + "name": "limit", + "type": "uint16" + } + ], + "name": "uidLookup", + "outputs": [ + { + "components": [ + { + "internalType": "uint16", + "name": "uid", + "type": "uint16" + }, + { + "internalType": "uint64", + "name": "block_associated", + "type": "uint64" + } + ], + "internalType": "struct LookupItem[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "uidLookupPrecompile", + "outputs": [ + { + "internalType": "contract IUidLookup", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +]; + +export const PRECOMPILE_WRAPPER_BYTECODE = "6080604052348015600e575f5ffd5b50612bb98061001c5f395ff3fe6080604052600436106101d6575f3560e01c80637d691e3011610101578063b1f789ef11610094578063d75e3e0d11610063578063d75e3e0d146106a9578063db1d0fd5146106d3578063ec556889146106fd578063fc6679fb14610727576101d6565b8063b1f789ef146105fd578063bfe252a214610639578063caf2ebf214610663578063cd6f4eb11461068d576101d6565b80639f246f6f116100d05780639f246f6f14610551578063a21762761461058d578063ac3166bf146105b7578063afed65f9146105e1576101d6565b80637d691e30146104815780638bba466c1461049d57806394e3ac6f146104d9578063998538c414610515576101d6565b80634c378a96116101795780635e25f3f8116101485780635e25f3f8146103d157806369e38bc3146103ed57806371214e27146104295780637444dadc14610445576101d6565b80634c378a96146103175780634cf088d9146103415780635b53ddde1461036b5780635b7210c514610395576101d6565b80631f193572116101b55780631f193572146102665780631fc9b141146102a25780633175bd98146102be5780634054ecca146102fb576101d6565b80620ae759146101da5780630494cd9a146102025780630cadeda51461023e575b5f5ffd5b3480156101e5575f5ffd5b5061020060048036038101906101fb91906113ab565b610751565b005b34801561020d575f5ffd5b506102286004803603810190610223919061148d565b6107c1565b60405161023591906114c7565b60405180910390f35b348015610249575f5ffd5b50610264600480360381019061025f9190611519565b610843565b005b348015610271575f5ffd5b5061028c600480360381019061028791906115a0565b6108b4565b60405161029991906115da565b60405180910390f35b6102bc60048036038101906102b79190611626565b610936565b005b3480156102c9575f5ffd5b506102e460048036038101906102df9190611676565b6109a7565b6040516102f29291906116de565b60405180910390f35b61031560048036038101906103109190611705565b610a2f565b005b348015610322575f5ffd5b5061032b610a9d565b604051610338919061179e565b60405180910390f35b34801561034c575f5ffd5b50610355610aa3565b60405161036291906117d7565b60405180910390f35b348015610376575f5ffd5b5061037f610aa9565b60405161038c9190611810565b60405180910390f35b3480156103a0575f5ffd5b506103bb60048036038101906103b69190611676565b610aaf565b6040516103c8919061184b565b60405180910390f35b6103eb60048036038101906103e69190611914565b610b34565b005b3480156103f8575f5ffd5b50610413600480360381019061040e91906115a0565b610bb4565b6040516104209190611a98565b60405180910390f35b610443600480360381019061043e9190611adb565b610c36565b005b348015610450575f5ffd5b5061046b600480360381019061046691906115a0565b610cad565b604051610478919061184b565b60405180910390f35b61049b60048036038101906104969190611626565b610d2f565b005b3480156104a8575f5ffd5b506104c360048036038101906104be9190611b52565b610da0565b6040516104d09190611ca3565b60405180910390f35b3480156104e4575f5ffd5b506104ff60048036038101906104fa9190611cbd565b610e2a565b60405161050c9190611ddf565b60405180910390f35b348015610520575f5ffd5b5061053b60048036038101906105369190611cbd565b610eb0565b6040516105489190611a98565b60405180910390f35b34801561055c575f5ffd5b5061057760048036038101906105729190611cbd565b610f32565b6040516105849190611a98565b60405180910390f35b348015610598575f5ffd5b506105a1610fb4565b6040516105ae9190611e1f565b60405180910390f35b3480156105c2575f5ffd5b506105cb610fba565b6040516105d89190611e58565b60405180910390f35b6105fb60048036038101906105f69190611e9b565b610fc0565b005b348015610608575f5ffd5b50610623600480360381019061061e9190611f38565b61103d565b604051610630919061206c565b60405180910390f35b348015610644575f5ffd5b5061064d6110c9565b60405161065a91906120ac565b60405180910390f35b34801561066e575f5ffd5b506106776110cf565b60405161068491906120e5565b60405180910390f35b6106a760048036038101906106a29190611cbd565b6110d5565b005b3480156106b4575f5ffd5b506106bd611142565b6040516106ca919061211e565b60405180910390f35b3480156106de575f5ffd5b506106e7611148565b6040516106f49190612157565b60405180910390f35b348015610708575f5ffd5b5061071161114e565b60405161071e9190612190565b60405180910390f35b348015610732575f5ffd5b5061073b611154565b60405161074891906121c9565b60405180910390f35b61080b73ffffffffffffffffffffffffffffffffffffffff16620ae7598484846040518463ffffffff1660e01b815260040161078f93929190612299565b5f604051808303815f87803b1580156107a6575f5ffd5b505af11580156107b8573d5f5f3e3d5ffd5b50505050505050565b5f61080c73ffffffffffffffffffffffffffffffffffffffff16630494cd9a836040518263ffffffff1660e01b81526004016107fd91906122eb565b602060405180830381865afa158015610818573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061083c9190612318565b9050919050565b61080b73ffffffffffffffffffffffffffffffffffffffff16630cadeda58484846040518463ffffffff1660e01b815260040161088293929190612361565b5f604051808303815f87803b158015610899575f5ffd5b505af11580156108ab573d5f5f3e3d5ffd5b50505050505050565b5f61080273ffffffffffffffffffffffffffffffffffffffff16631f193572836040518263ffffffff1660e01b81526004016108f091906115da565b602060405180830381865afa15801561090b573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061092f91906123aa565b9050919050565b61080573ffffffffffffffffffffffffffffffffffffffff16631fc9b1418484846040518463ffffffff1660e01b8152600401610975939291906123d5565b5f604051808303815f87803b15801561098c575f5ffd5b505af115801561099e573d5f5f3e3d5ffd5b50505050505050565b5f5f61080a73ffffffffffffffffffffffffffffffffffffffff16633175bd9885856040518363ffffffff1660e01b81526004016109e692919061240a565b6040805180830381865afa158015610a00573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a24919061245b565b915091509250929050565b61080473ffffffffffffffffffffffffffffffffffffffff16634054ecca83836040518363ffffffff1660e01b8152600401610a6c929190612499565b5f604051808303815f87803b158015610a83575f5ffd5b505af1158015610a95573d5f5f3e3d5ffd5b505050505050565b61080481565b61080581565b61080a81565b5f61080973ffffffffffffffffffffffffffffffffffffffff16635b7210c584846040518363ffffffff1660e01b8152600401610aed92919061240a565b602060405180830381865afa158015610b08573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b2c91906124d4565b905092915050565b61080373ffffffffffffffffffffffffffffffffffffffff16631cf98c6b89898989898989896040518963ffffffff1660e01b8152600401610b7d98979695949392919061255f565b5f604051808303815f87803b158015610b94575f5ffd5b505af1158015610ba6573d5f5f3e3d5ffd5b505050505050505050505050565b5f61080873ffffffffffffffffffffffffffffffffffffffff166369e38bc3836040518263ffffffff1660e01b8152600401610bf091906115da565b602060405180830381865afa158015610c0b573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c2f9190612620565b9050919050565b61080973ffffffffffffffffffffffffffffffffffffffff1663127e1adb86868686866040518663ffffffff1660e01b8152600401610c7995949392919061264b565b5f604051808303815f87803b158015610c90575f5ffd5b505af1158015610ca2573d5f5f3e3d5ffd5b505050505050505050565b5f61080373ffffffffffffffffffffffffffffffffffffffff16637444dadc836040518263ffffffff1660e01b8152600401610ce991906115da565b602060405180830381865afa158015610d04573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d2891906124d4565b9050919050565b61080573ffffffffffffffffffffffffffffffffffffffff16637d691e308484846040518463ffffffff1660e01b8152600401610d6e939291906123d5565b5f604051808303815f87803b158015610d85575f5ffd5b505af1158015610d97573d5f5f3e3d5ffd5b50505050505050565b610da861115a565b61080973ffffffffffffffffffffffffffffffffffffffff16638bba466c836040518263ffffffff1660e01b8152600401610de3919061269c565b61016060405180830381865afa158015610dff573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e2391906127ea565b9050919050565b606061080b73ffffffffffffffffffffffffffffffffffffffff166394e3ac6f836040518263ffffffff1660e01b8152600401610e6791906114c7565b5f60405180830381865afa158015610e81573d5f5f3e3d5ffd5b505050506040513d5f823e3d601f19601f82011682018060405250810190610ea99190612937565b9050919050565b5f61080573ffffffffffffffffffffffffffffffffffffffff1663998538c4836040518263ffffffff1660e01b8152600401610eec91906114c7565b602060405180830381865afa158015610f07573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f2b9190612620565b9050919050565b5f61080573ffffffffffffffffffffffffffffffffffffffff16639f246f6f836040518263ffffffff1660e01b8152600401610f6e91906114c7565b602060405180830381865afa158015610f89573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610fad9190612620565b9050919050565b61080681565b61080c81565b61080a73ffffffffffffffffffffffffffffffffffffffff1663afed65f9888888888888886040518863ffffffff1660e01b8152600401611007979695949392919061298d565b5f604051808303815f87803b15801561101e575f5ffd5b505af1158015611030573d5f5f3e3d5ffd5b5050505050505050505050565b606061080673ffffffffffffffffffffffffffffffffffffffff1663b1f789ef8585856040518463ffffffff1660e01b815260040161107e939291906129fa565b5f60405180830381865afa158015611098573d5f5f3e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906110c09190612b3c565b90509392505050565b61080981565b61080381565b61080073ffffffffffffffffffffffffffffffffffffffff1663cd6f4eb134836040518363ffffffff1660e01b815260040161111191906114c7565b5f604051808303818588803b158015611128575f5ffd5b505af115801561113a573d5f5f3e3d5ffd5b505050505050565b61080081565b61080881565b61080b81565b61080281565b6040518061016001604052805f81526020015f67ffffffffffffffff1681526020015f67ffffffffffffffff1681526020015f63ffffffff1681526020015f67ffffffffffffffff1681526020015f81526020015f67ffffffffffffffff1681526020015f151581526020015f81526020015f151581526020015f63ffffffff1681525090565b5f604051905090565b5f5ffd5b5f5ffd5b5f819050919050565b611204816111f2565b811461120e575f5ffd5b50565b5f8135905061121f816111fb565b92915050565b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61126f82611229565b810181811067ffffffffffffffff8211171561128e5761128d611239565b5b80604052505050565b5f6112a06111e1565b90506112ac8282611266565b919050565b5f67ffffffffffffffff8211156112cb576112ca611239565b5b602082029050602081019050919050565b5f5ffd5b5f60ff82169050919050565b6112f5816112e0565b81146112ff575f5ffd5b50565b5f81359050611310816112ec565b92915050565b5f611328611323846112b1565b611297565b9050808382526020820190506020840283018581111561134b5761134a6112dc565b5b835b8181101561137457806113608882611302565b84526020840193505060208101905061134d565b5050509392505050565b5f82601f83011261139257611391611225565b5b81356113a2848260208601611316565b91505092915050565b5f5f5f606084860312156113c2576113c16111ea565b5b5f6113cf86828701611211565b935050602084013567ffffffffffffffff8111156113f0576113ef6111ee565b5b6113fc8682870161137e565b925050604084013567ffffffffffffffff81111561141d5761141c6111ee565b5b6114298682870161137e565b9150509250925092565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61145c82611433565b9050919050565b61146c81611452565b8114611476575f5ffd5b50565b5f8135905061148781611463565b92915050565b5f602082840312156114a2576114a16111ea565b5b5f6114af84828501611479565b91505092915050565b6114c1816111f2565b82525050565b5f6020820190506114da5f8301846114b8565b92915050565b5f63ffffffff82169050919050565b6114f8816114e0565b8114611502575f5ffd5b50565b5f81359050611513816114ef565b92915050565b5f5f5f606084860312156115305761152f6111ea565b5b5f61153d86828701611211565b935050602061154e86828701611302565b925050604061155f86828701611505565b9150509250925092565b5f61ffff82169050919050565b61157f81611569565b8114611589575f5ffd5b50565b5f8135905061159a81611576565b92915050565b5f602082840312156115b5576115b46111ea565b5b5f6115c28482850161158c565b91505092915050565b6115d481611569565b82525050565b5f6020820190506115ed5f8301846115cb565b92915050565b5f819050919050565b611605816115f3565b811461160f575f5ffd5b50565b5f81359050611620816115fc565b92915050565b5f5f5f6060848603121561163d5761163c6111ea565b5b5f61164a86828701611211565b935050602061165b86828701611612565b925050604061166c86828701611612565b9150509250925092565b5f5f6040838503121561168c5761168b6111ea565b5b5f61169985828601611505565b92505060206116aa85828601611211565b9150509250929050565b5f6fffffffffffffffffffffffffffffffff82169050919050565b6116d8816116b4565b82525050565b5f6040820190506116f15f8301856116cf565b6116fe60208301846116cf565b9392505050565b5f5f6040838503121561171b5761171a6111ea565b5b5f6117288582860161158c565b925050602061173985828601611211565b9150509250929050565b5f819050919050565b5f61176661176161175c84611433565b611743565b611433565b9050919050565b5f6117778261174c565b9050919050565b5f6117888261176d565b9050919050565b6117988161177e565b82525050565b5f6020820190506117b15f83018461178f565b92915050565b5f6117c18261176d565b9050919050565b6117d1816117b7565b82525050565b5f6020820190506117ea5f8301846117c8565b92915050565b5f6117fa8261176d565b9050919050565b61180a816117f0565b82525050565b5f6020820190506118235f830184611801565b92915050565b5f67ffffffffffffffff82169050919050565b61184581611829565b82525050565b5f60208201905061185e5f83018461183c565b92915050565b5f5ffd5b5f67ffffffffffffffff82111561188257611881611239565b5b61188b82611229565b9050602081019050919050565b828183375f83830152505050565b5f6118b86118b384611868565b611297565b9050828152602081018484840111156118d4576118d3611864565b5b6118df848285611898565b509392505050565b5f82601f8301126118fb576118fa611225565b5b813561190b8482602086016118a6565b91505092915050565b5f5f5f5f5f5f5f5f610100898b031215611931576119306111ea565b5b5f61193e8b828c01611211565b985050602089013567ffffffffffffffff81111561195f5761195e6111ee565b5b61196b8b828c016118e7565b975050604089013567ffffffffffffffff81111561198c5761198b6111ee565b5b6119988b828c016118e7565b965050606089013567ffffffffffffffff8111156119b9576119b86111ee565b5b6119c58b828c016118e7565b955050608089013567ffffffffffffffff8111156119e6576119e56111ee565b5b6119f28b828c016118e7565b94505060a089013567ffffffffffffffff811115611a1357611a126111ee565b5b611a1f8b828c016118e7565b93505060c089013567ffffffffffffffff811115611a4057611a3f6111ee565b5b611a4c8b828c016118e7565b92505060e089013567ffffffffffffffff811115611a6d57611a6c6111ee565b5b611a798b828c016118e7565b9150509295985092959890939650565b611a92816115f3565b82525050565b5f602082019050611aab5f830184611a89565b92915050565b611aba81611829565b8114611ac4575f5ffd5b50565b5f81359050611ad581611ab1565b92915050565b5f5f5f5f5f60a08688031215611af457611af36111ea565b5b5f611b0188828901611ac7565b9550506020611b1288828901611ac7565b9450506040611b2388828901611ac7565b9350506060611b3488828901611505565b9250506080611b4588828901611479565b9150509295509295909350565b5f60208284031215611b6757611b666111ea565b5b5f611b7484828501611505565b91505092915050565b611b86816111f2565b82525050565b611b9581611829565b82525050565b611ba4816114e0565b82525050565b5f8115159050919050565b611bbe81611baa565b82525050565b61016082015f820151611bd95f850182611b7d565b506020820151611bec6020850182611b8c565b506040820151611bff6040850182611b8c565b506060820151611c126060850182611b9b565b506080820151611c256080850182611b8c565b5060a0820151611c3860a0850182611b7d565b5060c0820151611c4b60c0850182611b8c565b5060e0820151611c5e60e0850182611bb5565b50610100820151611c73610100850182611b7d565b50610120820151611c88610120850182611bb5565b50610140820151611c9d610140850182611b9b565b50505050565b5f61016082019050611cb75f830184611bc4565b92915050565b5f60208284031215611cd257611cd16111ea565b5b5f611cdf84828501611211565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b611d1a816115f3565b82525050565b606082015f820151611d345f850182611b7d565b506020820151611d476020850182611d11565b506040820151611d5a6040850182611d11565b50505050565b5f611d6b8383611d20565b60608301905092915050565b5f602082019050919050565b5f611d8d82611ce8565b611d978185611cf2565b9350611da283611d02565b805f5b83811015611dd2578151611db98882611d60565b9750611dc483611d77565b925050600181019050611da5565b5085935050505092915050565b5f6020820190508181035f830152611df78184611d83565b905092915050565b5f611e098261176d565b9050919050565b611e1981611dff565b82525050565b5f602082019050611e325f830184611e10565b92915050565b5f611e428261176d565b9050919050565b611e5281611e38565b82525050565b5f602082019050611e6b5f830184611e49565b92915050565b611e7a81611baa565b8114611e84575f5ffd5b50565b5f81359050611e9581611e71565b92915050565b5f5f5f5f5f5f5f60e0888a031215611eb657611eb56111ea565b5b5f611ec38a828b01611ac7565b9750506020611ed48a828b01611ac7565b9650506040611ee58a828b01611ac7565b9550506060611ef68a828b01611505565b9450506080611f078a828b01611302565b93505060a0611f188a828b01611e87565b92505060c0611f298a828b01611505565b91505092959891949750929550565b5f5f5f60608486031215611f4f57611f4e6111ea565b5b5f611f5c8682870161158c565b9350506020611f6d86828701611479565b9250506040611f7e8682870161158c565b9150509250925092565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b611fba81611569565b82525050565b604082015f820151611fd45f850182611fb1565b506020820151611fe76020850182611b8c565b50505050565b5f611ff88383611fc0565b60408301905092915050565b5f602082019050919050565b5f61201a82611f88565b6120248185611f92565b935061202f83611fa2565b805f5b8381101561205f5781516120468882611fed565b975061205183612004565b925050600181019050612032565b5085935050505092915050565b5f6020820190508181035f8301526120848184612010565b905092915050565b5f6120968261176d565b9050919050565b6120a68161208c565b82525050565b5f6020820190506120bf5f83018461209d565b92915050565b5f6120cf8261176d565b9050919050565b6120df816120c5565b82525050565b5f6020820190506120f85f8301846120d6565b92915050565b5f6121088261176d565b9050919050565b612118816120fe565b82525050565b5f6020820190506121315f83018461210f565b92915050565b5f6121418261176d565b9050919050565b61215181612137565b82525050565b5f60208201905061216a5f830184612148565b92915050565b5f61217a8261176d565b9050919050565b61218a81612170565b82525050565b5f6020820190506121a35f830184612181565b92915050565b5f6121b38261176d565b9050919050565b6121c3816121a9565b82525050565b5f6020820190506121dc5f8301846121ba565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b612214816112e0565b82525050565b5f612225838361220b565b60208301905092915050565b5f602082019050919050565b5f612247826121e2565b61225181856121ec565b935061225c836121fc565b805f5b8381101561228c578151612273888261221a565b975061227e83612231565b92505060018101905061225f565b5085935050505092915050565b5f6060820190506122ac5f8301866114b8565b81810360208301526122be818561223d565b905081810360408301526122d2818461223d565b9050949350505050565b6122e581611452565b82525050565b5f6020820190506122fe5f8301846122dc565b92915050565b5f81519050612312816111fb565b92915050565b5f6020828403121561232d5761232c6111ea565b5b5f61233a84828501612304565b91505092915050565b61234c816112e0565b82525050565b61235b816114e0565b82525050565b5f6060820190506123745f8301866114b8565b6123816020830185612343565b61238e6040830184612352565b949350505050565b5f815190506123a481611576565b92915050565b5f602082840312156123bf576123be6111ea565b5b5f6123cc84828501612396565b91505092915050565b5f6060820190506123e85f8301866114b8565b6123f56020830185611a89565b6124026040830184611a89565b949350505050565b5f60408201905061241d5f830185612352565b61242a60208301846114b8565b9392505050565b61243a816116b4565b8114612444575f5ffd5b50565b5f8151905061245581612431565b92915050565b5f5f60408385031215612471576124706111ea565b5b5f61247e85828601612447565b925050602061248f85828601612447565b9150509250929050565b5f6040820190506124ac5f8301856115cb565b6124b960208301846114b8565b9392505050565b5f815190506124ce81611ab1565b92915050565b5f602082840312156124e9576124e86111ea565b5b5f6124f6848285016124c0565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f612531826124ff565b61253b8185612509565b935061254b818560208601612519565b61255481611229565b840191505092915050565b5f610100820190506125735f83018b6114b8565b8181036020830152612585818a612527565b905081810360408301526125998189612527565b905081810360608301526125ad8188612527565b905081810360808301526125c18187612527565b905081810360a08301526125d58186612527565b905081810360c08301526125e98185612527565b905081810360e08301526125fd8184612527565b90509998505050505050505050565b5f8151905061261a816115fc565b92915050565b5f60208284031215612635576126346111ea565b5b5f6126428482850161260c565b91505092915050565b5f60a08201905061265e5f83018861183c565b61266b602083018761183c565b612678604083018661183c565b6126856060830185612352565b61269260808301846122dc565b9695505050505050565b5f6020820190506126af5f830184612352565b92915050565b5f5ffd5b5f815190506126c7816114ef565b92915050565b5f815190506126db81611e71565b92915050565b5f61016082840312156126f7576126f66126b5565b5b612702610160611297565b90505f61271184828501612304565b5f830152506020612724848285016124c0565b6020830152506040612738848285016124c0565b604083015250606061274c848285016126b9565b6060830152506080612760848285016124c0565b60808301525060a061277484828501612304565b60a08301525060c0612788848285016124c0565b60c08301525060e061279c848285016126cd565b60e0830152506101006127b184828501612304565b610100830152506101206127c7848285016126cd565b610120830152506101406127dd848285016126b9565b6101408301525092915050565b5f6101608284031215612800576127ff6111ea565b5b5f61280d848285016126e1565b91505092915050565b5f67ffffffffffffffff8211156128305761282f611239565b5b602082029050602081019050919050565b5f60608284031215612856576128556126b5565b5b6128606060611297565b90505f61286f84828501612304565b5f8301525060206128828482850161260c565b60208301525060406128968482850161260c565b60408301525092915050565b5f6128b46128af84612816565b611297565b905080838252602082019050606084028301858111156128d7576128d66112dc565b5b835b8181101561290057806128ec8882612841565b8452602084019350506060810190506128d9565b5050509392505050565b5f82601f83011261291e5761291d611225565b5b815161292e8482602086016128a2565b91505092915050565b5f6020828403121561294c5761294b6111ea565b5b5f82015167ffffffffffffffff811115612969576129686111ee565b5b6129758482850161290a565b91505092915050565b61298781611baa565b82525050565b5f60e0820190506129a05f83018a61183c565b6129ad602083018961183c565b6129ba604083018861183c565b6129c76060830187612352565b6129d46080830186612343565b6129e160a083018561297e565b6129ee60c0830184612352565b98975050505050505050565b5f606082019050612a0d5f8301866115cb565b612a1a60208301856122dc565b612a2760408301846115cb565b949350505050565b5f67ffffffffffffffff821115612a4957612a48611239565b5b602082029050602081019050919050565b5f60408284031215612a6f57612a6e6126b5565b5b612a796040611297565b90505f612a8884828501612396565b5f830152506020612a9b848285016124c0565b60208301525092915050565b5f612ab9612ab484612a2f565b611297565b90508083825260208201905060408402830185811115612adc57612adb6112dc565b5b835b81811015612b055780612af18882612a5a565b845260208401935050604081019050612ade565b5050509392505050565b5f82601f830112612b2357612b22611225565b5b8151612b33848260208601612aa7565b91505092915050565b5f60208284031215612b5157612b506111ea565b5b5f82015167ffffffffffffffff811115612b6e57612b6d6111ee565b5b612b7a84828501612b0f565b9150509291505056fea2646970667358221220768c64014d2253c661e44d07f480f7a203eb9e422f680d00272498325a4f6ad964736f6c634300081e0033"; diff --git a/contract-tests/src/contracts/votingPower.ts b/contract-tests/src/contracts/votingPower.ts new file mode 100644 index 0000000000..bbcc3ca6e6 --- /dev/null +++ b/contract-tests/src/contracts/votingPower.ts @@ -0,0 +1,104 @@ +export const IVOTING_POWER_ADDRESS = "0x000000000000000000000000000000000000080d"; + +export const IVotingPowerABI = [ + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "bytes32", + "name": "hotkey", + "type": "bytes32" + } + ], + "name": "getVotingPower", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + } + ], + "name": "isVotingPowerTrackingEnabled", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + } + ], + "name": "getVotingPowerDisableAtBlock", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + } + ], + "name": "getVotingPowerEmaAlpha", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + } + ], + "name": "getTotalVotingPower", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/contract-tests/src/subtensor.ts b/contract-tests/src/subtensor.ts index fab9e8cc10..f5829c76aa 100644 --- a/contract-tests/src/subtensor.ts +++ b/contract-tests/src/subtensor.ts @@ -1,17 +1,20 @@ import * as assert from "assert"; import { devnet, MultiAddress } from '@polkadot-api/descriptors'; -import { TypedApi, TxCallData, Binary, Enum } from 'polkadot-api'; +import { TypedApi, TxCallData, Binary, Enum, getTypedCodecs } from 'polkadot-api'; import { KeyPair } from "@polkadot-labs/hdkd-helpers" import { getAliceSigner, waitForTransactionCompletion, getSignerFromKeypair, waitForTransactionWithRetry } from './substrate' import { convertH160ToSS58, convertPublicKeyToSs58, ethAddressToH160 } from './address-utils' import { tao } from './balance-math' import internal from "stream"; +import { createCodec } from "scale-ts"; // create a new subnet and return netuid export async function addNewSubnetwork(api: TypedApi, hotkey: KeyPair, coldkey: KeyPair) { const alice = getAliceSigner() const totalNetworks = await api.query.SubtensorModule.TotalNetworks.getValue() + const defaultNetworkLastLockCost = await api.query.SubtensorModule.NetworkLastLockCost.getValue() + const rateLimit = await api.query.SubtensorModule.NetworkRateLimit.getValue() if (rateLimit !== BigInt(0)) { const internalCall = api.tx.AdminUtils.sudo_set_network_rate_limit({ rate_limit: BigInt(0) }) @@ -26,6 +29,9 @@ export async function addNewSubnetwork(api: TypedApi, hotkey: Key const newTotalNetworks = await api.query.SubtensorModule.TotalNetworks.getValue() // could create multiple subnetworks during retry, just return the first created one assert.ok(newTotalNetworks > totalNetworks) + + // reset network last lock cost to 0, to avoid the lock cost calculation error + await setNetworkLastLockCost(api, defaultNetworkLastLockCost) return totalNetworks } @@ -398,4 +404,19 @@ export async function sendWasmContractExtrinsic(api: TypedApi, co storage_deposit_limit: BigInt(1000000000) }) await waitForTransactionWithRetry(api, tx, signer) -} \ No newline at end of file +} + +export async function setNetworkLastLockCost(api: TypedApi, defaultNetworkLastLockCost: bigint) { + const alice = getAliceSigner() + const key = await api.query.SubtensorModule.NetworkLastLockCost.getKey() + const codec = await getTypedCodecs(devnet); + const value = codec.query.SubtensorModule.NetworkLastLockCost.value.enc(defaultNetworkLastLockCost) + const internalCall = api.tx.System.set_storage({ + items: [[Binary.fromHex(key), Binary.fromBytes(value)]] + }) + const tx = api.tx.Sudo.sudo({ call: internalCall.decodedCall }) + await waitForTransactionWithRetry(api, tx, alice) + + const valueOnChain = await api.query.SubtensorModule.NetworkLastLockCost.getValue() + assert.equal(defaultNetworkLastLockCost, valueOnChain) +} \ No newline at end of file diff --git a/contract-tests/test/precompileWrapper.direct-call.test.ts b/contract-tests/test/precompileWrapper.direct-call.test.ts new file mode 100644 index 0000000000..5d63dfbb44 --- /dev/null +++ b/contract-tests/test/precompileWrapper.direct-call.test.ts @@ -0,0 +1,403 @@ +import * as assert from "assert"; +import { getDevnetApi, getRandomSubstrateKeypair, getBalance, getSignerFromKeypair } from "../src/substrate"; +import { devnet } from "@polkadot-api/descriptors"; +import { TypedApi, Binary } from "polkadot-api"; +import { convertH160ToSS58, convertPublicKeyToSs58, convertH160ToPublicKey } from "../src/address-utils"; +import { tao, raoToEth } from "../src/balance-math"; +import { + forceSetBalanceToSs58Address, + addNewSubnetwork, + startCall, + disableWhiteListCheck, + forceSetBalanceToEthAddress, + +} from "../src/subtensor"; +import { ethers } from "ethers"; +import { generateRandomEthersWallet, getPublicClient } from "../src/utils"; +import { PRECOMPILE_WRAPPER_ABI, PRECOMPILE_WRAPPER_BYTECODE } from "../src/contracts/precompileWrapper"; +import { ETH_LOCAL_URL } from "../src/config"; +import { PublicClient } from "viem"; +import { IProxyABI, IPROXY_ADDRESS } from "../src/contracts/proxy" + +describe("PrecompileWrapper - Direct Call Tests", () => { + const hotkey = getRandomSubstrateKeypair(); + const coldkey = getRandomSubstrateKeypair(); + const wallet1 = generateRandomEthersWallet(); + const wallet2 = generateRandomEthersWallet(); + + let api: TypedApi; + let publicClient: PublicClient; + let wrapperContract: ethers.Contract; + let wrapperAddress: string; + let netuid: number; + + before(async () => { + api = await getDevnetApi(); + publicClient = await getPublicClient(ETH_LOCAL_URL); + await disableWhiteListCheck(api, true); + await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(hotkey.publicKey)); + await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(coldkey.publicKey)); + await forceSetBalanceToEthAddress(api, wallet1.address); + await forceSetBalanceToEthAddress(api, wallet2.address); + await addNewSubnetwork(api, hotkey, coldkey); + netuid = (await api.query.SubtensorModule.TotalNetworks.getValue()) - 1; + await startCall(api, netuid, coldkey); + + const factory = new ethers.ContractFactory( + PRECOMPILE_WRAPPER_ABI, + PRECOMPILE_WRAPPER_BYTECODE, + wallet1 + ); + const deployContract = await factory.deploy(); + await deployContract.waitForDeployment(); + wrapperAddress = await deployContract.getAddress(); + await forceSetBalanceToEthAddress(api, wrapperAddress); + + console.log("Wrapper contract deployed at:", wrapperAddress); + console.log("Testing in subnet:", netuid); + + wrapperContract = new ethers.Contract(wrapperAddress, PRECOMPILE_WRAPPER_ABI, wallet1); + }); + + describe("Balance Transfer Precompile Direct Calls", () => { + it("Should transfer balance via wrapper", async () => { + const keypair = getRandomSubstrateKeypair(); + const transferAmount = raoToEth(tao(1)); + + // Transfer via wrapper + const transferTx = await wrapperContract.transfer(keypair.publicKey, { value: transferAmount.toString() }); + await transferTx.wait(); + + const balance = await getBalance(api, convertPublicKeyToSs58(keypair.publicKey)); + assert.ok(balance >= tao(1), "Balance should be transferred"); + }); + }); + + describe("Metagraph Precompile Direct Calls", () => { + it("Should get UID count via wrapper", async () => { + const uidCountViaWrapper = await wrapperContract.getUidCount(netuid); + assert.ok(uidCountViaWrapper !== undefined, "UID count should be not undefined"); + }); + }); + + describe("Subnet Precompile Direct Calls", () => { + it("Should get serving rate limit via wrapper", async () => { + const rateLimitViaWrapper = await wrapperContract.getServingRateLimit(netuid); + + assert.ok(rateLimitViaWrapper !== undefined, "Rate limit should be not undefined"); + }); + + it("Should register network with details via wrapper", async () => { + const newHotkey = getRandomSubstrateKeypair(); + await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(newHotkey.publicKey)); + + const totalNetworksBefore = await api.query.SubtensorModule.TotalNetworks.getValue(); + + const registerTx = await wrapperContract.registerNetworkWithDetails( + newHotkey.publicKey, + "Test Subnet", + "https://github.com/test/repo", + "test@example.com", + "https://test.example.com", + "test#1234", + "Test description", + "Additional info", + { value: raoToEth(tao(100)).toString() } + ); + await registerTx.wait(); + + const totalNetworksAfter = await api.query.SubtensorModule.TotalNetworks.getValue(); + const beforeValue = typeof totalNetworksBefore === 'bigint' ? totalNetworksBefore : BigInt(totalNetworksBefore); + assert.equal(totalNetworksAfter, beforeValue + BigInt(1), "Network should be registered"); + }); + }); + + describe("Neuron Precompile Direct Calls", () => { + it("Should register neuron via wrapper", async () => { + const newHotkey = getRandomSubstrateKeypair(); + const newColdkey = getRandomSubstrateKeypair(); + await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(newHotkey.publicKey)); + await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(newColdkey.publicKey)); + + // Use a reasonable burn amount (100 TAO) + const burnAmount = tao(100); + + const registerTx = await wrapperContract.burnedRegister( + netuid, + newHotkey.publicKey, + { value: raoToEth(burnAmount).toString() } + ); + await registerTx.wait(); + + const uid = await api.query.SubtensorModule.Uids.getValue(netuid, convertPublicKeyToSs58(newHotkey.publicKey)); + assert.ok(uid !== undefined, "Neuron should be registered"); + }); + }); + + describe("Staking Precompile Direct Calls", () => { + it("Should get total coldkey stake via wrapper", async () => { + const stakeViaWrapper = await wrapperContract.getTotalColdkeyStake(coldkey.publicKey); + assert.ok(stakeViaWrapper !== undefined, "Total coldkey stake should be not undefined"); + }); + + it("Should get total hotkey stake via wrapper", async () => { + const stakeViaWrapper = await wrapperContract.getTotalHotkeyStake(hotkey.publicKey); + assert.ok(stakeViaWrapper !== undefined, "Total hotkey stake should be not undefined"); + }); + + it("Should add stake via wrapper", async () => { + const stakeAmount = tao(2); + const stakeBefore = await api.query.SubtensorModule.Alpha.getValue( + convertPublicKeyToSs58(hotkey.publicKey), + convertH160ToSS58(wrapperAddress), + netuid + ); + + const addStakeTx = await wrapperContract.addStake( + hotkey.publicKey, + stakeAmount.toString(), + netuid, + { value: raoToEth(stakeAmount).toString() } + ); + await addStakeTx.wait(); + + const stakeAfter = await api.query.SubtensorModule.Alpha.getValue( + convertPublicKeyToSs58(hotkey.publicKey), + convertH160ToSS58(wrapperAddress), + netuid + ); + assert.ok(stakeAfter > stakeBefore, "Stake should be increased"); + }); + + it("Should remove stake via wrapper", async () => { + const removeAmount = tao(1); + const stakeBefore = await api.query.SubtensorModule.Alpha.getValue( + convertPublicKeyToSs58(hotkey.publicKey), + convertH160ToSS58(wrapperAddress), + netuid + ); + + const removeStakeTx = await wrapperContract.removeStake( + hotkey.publicKey, + removeAmount.toString(), + netuid + ); + await removeStakeTx.wait(); + + const stakeAfter = await api.query.SubtensorModule.Alpha.getValue( + convertPublicKeyToSs58(hotkey.publicKey), + convertH160ToSS58(wrapperAddress), + netuid + ); + assert.ok(stakeAfter < stakeBefore, "Stake should be decreased"); + }); + }); + + describe("UID Lookup Precompile Direct Calls", () => { + it("Should lookup UID via wrapper", async () => { + const evmAddress = wallet1.address; + const limit = 10; + const lookupViaWrapper = await wrapperContract.uidLookup(netuid, evmAddress, limit); + + assert.ok(Array.isArray(lookupViaWrapper), "Lookup should return an array"); + }); + }); + + describe("Alpha Precompile Direct Calls", () => { + it("Should get alpha price via wrapper", async () => { + const priceViaWrapper = await wrapperContract.getAlphaPrice(netuid); + assert.ok(priceViaWrapper !== undefined, "Alpha price should be not undefined"); + }); + }); + + describe("Crowdloan Precompile Direct Calls", () => { + it("Should get crowdloan via wrapper", async () => { + // First create a crowdloan via substrate + const nextId = await api.query.Crowdloan.NextCrowdloanId.getValue(); + const end = await api.query.System.Number.getValue() + 100; + const deposit = BigInt(15_000_000_000); // 15 TAO + const minContribution = BigInt(1_000_000_000); // 1 TAO + const cap = BigInt(100_000_000_000); // 100 TAO + + const signer = getSignerFromKeypair(coldkey); + await api.tx.Crowdloan.create({ + deposit, + min_contribution: minContribution, + cap, + end, + target_address: undefined, + call: api.tx.System.remark({ remark: Binary.fromText("test") }).decodedCall + }).signAndSubmit(signer); + + // Wait a bit for the transaction to be included + await new Promise(resolve => setTimeout(resolve, 2000)); + + const crowdloanViaWrapper = await wrapperContract.getCrowdloan(nextId); + + assert.ok(crowdloanViaWrapper !== undefined, "Crowdloan should be not undefined"); + }); + + it("Should get contribution via wrapper", async () => { + const nextId = await api.query.Crowdloan.NextCrowdloanId.getValue(); + const contributionViaWrapper = await wrapperContract.getContribution(nextId - 1, coldkey.publicKey); + + assert.ok(contributionViaWrapper !== undefined, "Contribution should be not undefined"); + }); + + it("Should create crowdloan via wrapper", async () => { + const deposit = BigInt(20_000_000_000); // 20 TAO + const minContribution = BigInt(2_000_000_000); // 2 TAO + const cap = BigInt(200_000_000_000); // 200 TAO + const end = Number(await api.query.System.Number.getValue()) + 100; + const targetAddress = wallet2.address; + + const nextIdBefore = await api.query.Crowdloan.NextCrowdloanId.getValue(); + + const createTx = await wrapperContract.createCrowdloan( + deposit.toString(), + minContribution.toString(), + cap.toString(), + end, + targetAddress, + { value: raoToEth(deposit).toString() } + ); + await createTx.wait(); + + const nextIdAfter = await api.query.Crowdloan.NextCrowdloanId.getValue(); + const beforeId = typeof nextIdBefore === 'bigint' ? nextIdBefore : BigInt(nextIdBefore); + assert.equal(nextIdAfter, beforeId + BigInt(1), "Crowdloan should be created"); + }); + }); + + + describe("Leasing Precompile Direct Calls", () => { + it("Should get contributor share via wrapper", async () => { + // First create a lease crowdloan + const nextCrowdloanId = await api.query.Crowdloan.NextCrowdloanId.getValue(); + const crowdloanDeposit = BigInt(100_000_000_000); // 100 TAO + const networkLastLockCost = await api.query.SubtensorModule.NetworkLastLockCost.getValue(); + const lockCostValue = typeof networkLastLockCost === 'bigint' ? networkLastLockCost : BigInt(networkLastLockCost); + const crowdloanCap = lockCostValue * BigInt(2); + const currentBlock = await api.query.System.Number.getValue(); + const crowdloanEnd = currentBlock + 100; + const leasingEmissionsShare = 15; + const leasingEndBlock = currentBlock + 300; + + const signer = getSignerFromKeypair(coldkey); + await api.tx.Crowdloan.create({ + deposit: crowdloanDeposit, + min_contribution: BigInt(1_000_000_000), + cap: crowdloanCap, + end: crowdloanEnd, + target_address: undefined, + call: api.tx.SubtensorModule.register_leased_network({ + emissions_share: leasingEmissionsShare, + end_block: leasingEndBlock, + }).decodedCall + }).signAndSubmit(signer); + + await new Promise(resolve => setTimeout(resolve, 2000)); + + const nextLeaseId = await api.query.SubtensorModule.NextSubnetLeaseId.getValue(); + + // Get contributor share + const shareViaWrapper = await wrapperContract.getContributorShare(nextLeaseId, coldkey.publicKey); + + assert.ok(shareViaWrapper !== undefined, "Share should be not undefined"); + + }); + + it("Should create lease crowdloan via wrapper", async () => { + const crowdloanDeposit = BigInt(100_000_000_000); // 100 TAO + const crowdloanMinContribution = BigInt(1_000_000_000); // 1 TAO + const networkLastLockCost = await api.query.SubtensorModule.NetworkLastLockCost.getValue(); + const lockCostValue = typeof networkLastLockCost === 'bigint' ? networkLastLockCost : BigInt(networkLastLockCost); + const crowdloanCap = lockCostValue * BigInt(2); + const currentBlock = await api.query.System.Number.getValue(); + const currentBlockValue = typeof currentBlock === 'bigint' ? Number(currentBlock) : currentBlock; + const crowdloanEnd = currentBlockValue + 100; + const leasingEmissionsShare = 15; + const hasLeasingEndBlock = true; + const leasingEndBlock = currentBlockValue + 300; + + const nextCrowdloanIdBefore = await api.query.Crowdloan.NextCrowdloanId.getValue(); + + const createTx = await wrapperContract.createLeaseCrowdloan( + crowdloanDeposit.toString(), + crowdloanMinContribution.toString(), + crowdloanCap.toString(), + crowdloanEnd, + leasingEmissionsShare, + hasLeasingEndBlock, + leasingEndBlock, + { value: raoToEth(crowdloanDeposit).toString() } + ); + await createTx.wait(); + + const nextCrowdloanIdAfter = await api.query.Crowdloan.NextCrowdloanId.getValue(); + const beforeId = typeof nextCrowdloanIdBefore === 'bigint' ? nextCrowdloanIdBefore : BigInt(nextCrowdloanIdBefore); + assert.equal(nextCrowdloanIdAfter, beforeId + BigInt(1), "Lease crowdloan should be created"); + }); + }); + + + describe("Proxy Precompile Direct Calls", () => { + it("Should get proxies via wrapper", async () => { + const accountKey = convertH160ToPublicKey(wallet1.address); + const proxiesViaWrapper = await wrapperContract.getProxies(accountKey); + + assert.ok(proxiesViaWrapper !== undefined, "Proxies should be not undefined"); + assert.ok(Array.isArray(proxiesViaWrapper), "Proxies should be an array"); + }); + it("Should add proxy via wrapper", async () => { + const delegate = getRandomSubstrateKeypair(); + await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(delegate.publicKey)); + const delegateKey = delegate.publicKey; + const proxyType = 0; + const delay = 0; + + const proxiesBefore = await api.query.Proxy.Proxies.getValue(convertH160ToSS58(wrapperAddress)); + + const addProxyTx = await wrapperContract.addProxy(delegateKey, proxyType, delay); + await addProxyTx.wait(); + + const proxiesAfter = await api.query.Proxy.Proxies.getValue(convertH160ToSS58(wrapperAddress)); + assert.ok(proxiesAfter[0].length > proxiesBefore[0].length, "Proxy should be added"); + }); + + it("Should proxy call via wrapper", async () => { + const proxyType = 0; + const delay = 0; + + const proxyContract = new ethers.Contract(IPROXY_ADDRESS, IProxyABI, wallet1); + const addProxyTx = await proxyContract.addProxy(convertH160ToPublicKey(wrapperAddress), proxyType, delay); + await addProxyTx.wait(); + + // Create a simple call (remark) + const remarkCall = api.tx.System.remark({ remark: Binary.fromText("") }); + + const callData = await remarkCall.getEncodedData(); + const data = callData.asBytes(); + + const proxyCallTx = await wrapperContract.proxyCall( + convertH160ToPublicKey(wallet1.address), + [proxyType], + [...data] + ); + await proxyCallTx.wait(); + + // Verify the call was executed (no error means success) + assert.ok(proxyCallTx, "Proxy call should succeed"); + }); + }); + + describe("Address Mapping Precompile Direct Calls", () => { + it("Should map address via wrapper", async () => { + const testAddress = wallet1.address; + const mappedViaWrapper = await wrapperContract.addressMapping(testAddress); + + assert.ok(mappedViaWrapper !== undefined, "Mapped address should be not undefined"); + assert.ok(mappedViaWrapper !== "0x0000000000000000000000000000000000000000000000000000000000000000", "Mapped address should not be zero"); + }); + }); +}); diff --git a/contract-tests/test/runtime.call.precompile.test.ts b/contract-tests/test/runtime.call.precompile.test.ts index c409b25c8b..7bacc947fd 100644 --- a/contract-tests/test/runtime.call.precompile.test.ts +++ b/contract-tests/test/runtime.call.precompile.test.ts @@ -66,7 +66,7 @@ describe("Test the dispatch precompile", () => { it("Storage query only allow some pallets prefixed storage", async () => { const authorizedKeys = [ await api.query.SubtensorModule.TotalNetworks.getKey(), - await api.query.Swap.AlphaSqrtPrice.getKey(), + await api.query.Swap.FeeRate.getKey(), await api.query.Balances.TotalIssuance.getKey(), await api.query.Proxy.Announcements.getKey(), await api.query.Scheduler.Agenda.getKey(), diff --git a/contract-tests/test/subnet.precompile.hyperparameter.test.ts b/contract-tests/test/subnet.precompile.hyperparameter.test.ts index 8598b45a81..75d361a77f 100644 --- a/contract-tests/test/subnet.precompile.hyperparameter.test.ts +++ b/contract-tests/test/subnet.precompile.hyperparameter.test.ts @@ -2,12 +2,13 @@ import * as assert from "assert"; import { getAliceSigner, getDevnetApi, getRandomSubstrateKeypair, waitForTransactionWithRetry } from "../src/substrate" import { devnet } from "@polkadot-api/descriptors" -import { Binary, TypedApi, getTypedCodecs } from "polkadot-api"; +import { Binary, FixedSizeBinary, TypedApi, getTypedCodecs } from "polkadot-api"; import { convertH160ToSS58, convertPublicKeyToSs58 } from "../src/address-utils" import { generateRandomEthersWallet } from "../src/utils"; import { ISubnetABI, ISUBNET_ADDRESS } from "../src/contracts/subnet" import { ethers } from "ethers" import { disableAdminFreezeWindowAndOwnerHyperparamRateLimit, forceSetBalanceToEthAddress, forceSetBalanceToSs58Address } from "../src/subtensor" +import { blake2AsU8a } from "@polkadot/util-crypto" describe("Test the Subnet precompile contract", () => { // init eth part @@ -552,16 +553,16 @@ describe("Test the Subnet precompile contract", () => { const netuid = totalNetwork - 1; const coldkeySs58 = convertH160ToSS58(wallet.address) - const newColdkeySs58 = convertPublicKeyToSs58(hotkey1.publicKey) + const newColdkeyHash = FixedSizeBinary.fromBytes(blake2AsU8a(hotkey1.publicKey)) const currentBlock = await api.query.System.Number.getValue() const executionBlock = currentBlock + 10 const codec = await getTypedCodecs(devnet); - const valueBytes = codec.query.SubtensorModule.ColdkeySwapScheduled.value.enc([ + const valueBytes = codec.query.SubtensorModule.ColdkeySwapAnnouncements.value.enc([ executionBlock, - newColdkeySs58, + newColdkeyHash ]) - const key = await api.query.SubtensorModule.ColdkeySwapScheduled.getKey(coldkeySs58); + const key = await api.query.SubtensorModule.ColdkeySwapAnnouncements.getKey(coldkeySs58); // Use sudo + set_storage since the swap-scheduled check only exists in the tx extension. const setStorageCall = api.tx.System.set_storage({ @@ -570,8 +571,9 @@ describe("Test the Subnet precompile contract", () => { const sudoTx = api.tx.Sudo.sudo({ call: setStorageCall.decodedCall }) await waitForTransactionWithRetry(api, sudoTx, getAliceSigner()) - const storedValue = await api.query.SubtensorModule.ColdkeySwapScheduled.getValue(coldkeySs58) - assert.deepStrictEqual(storedValue, [executionBlock, newColdkeySs58]) + const storedValue = await api.query.SubtensorModule.ColdkeySwapAnnouncements.getValue(coldkeySs58) + assert.equal(storedValue?.[0], executionBlock) + assert.equal(storedValue?.[1].asHex(), newColdkeyHash.asHex()) await assert.rejects(async () => { const tx = await contract.setServingRateLimit(netuid, 100); diff --git a/contract-tests/test/transaction.replace.test.ts b/contract-tests/test/transaction.replace.test.ts new file mode 100644 index 0000000000..afb95ed9d5 --- /dev/null +++ b/contract-tests/test/transaction.replace.test.ts @@ -0,0 +1,83 @@ +import * as assert from "assert"; + +import { getDevnetApi, getRandomSubstrateSigner, } from "../src/substrate" +import { getPublicClient } from "../src/utils"; +import { ETH_LOCAL_URL, IBALANCETRANSFER_ADDRESS, IBalanceTransferABI } from "../src/config"; +import { devnet } from "@polkadot-api/descriptors" +import { PublicClient } from "viem"; +import { TypedApi } from "polkadot-api"; +import { generateRandomEthersWallet } from "../src/utils"; +import { tao, raoToEth } from "../src/balance-math"; +import { toViemAddress, } from "../src/address-utils" +import { getContract } from "../src/eth" +import { forceSetBalanceToEthAddress, } from "../src/subtensor"; + +describe("Transaction replace tests", () => { + // init eth part + const wallet = generateRandomEthersWallet(); + const wallet2 = generateRandomEthersWallet(); + const signer = getRandomSubstrateSigner(); + let publicClient: PublicClient; + let api: TypedApi + + before(async () => { + + publicClient = await getPublicClient(ETH_LOCAL_URL) + api = await getDevnetApi() + await forceSetBalanceToEthAddress(api, wallet.address) + }); + + it("Can replace simple transfer transaction", async () => { + const transferBalance = raoToEth(tao(1)) + + const gasPrice = BigInt(10e9) + const gasLimit = BigInt(1000000) + const nonce = await publicClient.getTransactionCount({ address: toViemAddress(wallet.address) }) + + for (let i = 1; i < 10; i++) { + const transfer = { + to: wallet2.address, + value: transferBalance.toString(), + nonce: nonce, + gasPrice: gasPrice * BigInt(i), + gasLimit: gasLimit * BigInt(i) + } + + try { + await wallet.sendTransaction(transfer) + } catch (error) { + // ignore error, previous transaction could be mined. the nonce is wrong. + } + await new Promise(resolve => setTimeout(resolve, 10)) + } + + // check the node not crashed + await forceSetBalanceToEthAddress(api, wallet.address) + }) + + it("Can replace precompile call transaction", async () => { + const contract = getContract(IBALANCETRANSFER_ADDRESS, IBalanceTransferABI, wallet) + const transferBalance = raoToEth(tao(1)) + + const gasPrice = BigInt(10e9) + const gasLimit = BigInt(1000000) + const nonce = await publicClient.getTransactionCount({ address: toViemAddress(wallet.address) }) + + for (let i = 1; i < 10; i++) { + try { + await contract.transfer(signer.publicKey, { + value: transferBalance.toString(), + nonce: nonce, + gasPrice: gasPrice * BigInt(i), + gasLimit: gasLimit * BigInt(i) + }) + } catch (error) { + // ignore error, previous transaction could be mined. the nonce is wrong. + } + + await new Promise(resolve => setTimeout(resolve, 10)) + } + // check the node not crashed + await forceSetBalanceToEthAddress(api, wallet.address) + }) +}) \ No newline at end of file diff --git a/contract-tests/test/votingPower.precompile.test.ts b/contract-tests/test/votingPower.precompile.test.ts new file mode 100644 index 0000000000..f98edd5fc1 --- /dev/null +++ b/contract-tests/test/votingPower.precompile.test.ts @@ -0,0 +1,226 @@ +import * as assert from "assert"; + +import { getDevnetApi, getRandomSubstrateKeypair, getAliceSigner, getSignerFromKeypair, waitForTransactionWithRetry } from "../src/substrate" +import { getPublicClient } from "../src/utils"; +import { ETH_LOCAL_URL } from "../src/config"; +import { devnet } from "@polkadot-api/descriptors" +import { PublicClient } from "viem"; +import { PolkadotSigner, TypedApi } from "polkadot-api"; +import { toViemAddress, convertPublicKeyToSs58 } from "../src/address-utils" +import { IVotingPowerABI, IVOTING_POWER_ADDRESS } from "../src/contracts/votingPower" +import { forceSetBalanceToSs58Address, addNewSubnetwork, startCall } from "../src/subtensor"; + +describe("Test VotingPower Precompile", () => { + // init substrate part + const hotkey = getRandomSubstrateKeypair(); + const coldkey = getRandomSubstrateKeypair(); + let publicClient: PublicClient; + + let api: TypedApi; + + // sudo account alice as signer + let alice: PolkadotSigner; + + // init other variable + let subnetId = 0; + + before(async () => { + // init variables got from await and async + publicClient = await getPublicClient(ETH_LOCAL_URL) + api = await getDevnetApi() + alice = await getAliceSigner(); + + await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(hotkey.publicKey)) + await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(coldkey.publicKey)) + + let netuid = await addNewSubnetwork(api, hotkey, coldkey) + await startCall(api, netuid, coldkey) + subnetId = netuid + }) + + describe("VotingPower Tracking Status Functions", () => { + it("isVotingPowerTrackingEnabled returns false by default", async () => { + const isEnabled = await publicClient.readContract({ + abi: IVotingPowerABI, + address: toViemAddress(IVOTING_POWER_ADDRESS), + functionName: "isVotingPowerTrackingEnabled", + args: [subnetId] + }) + + assert.ok(isEnabled !== undefined, "isVotingPowerTrackingEnabled should return a value"); + assert.strictEqual(typeof isEnabled, 'boolean', "isVotingPowerTrackingEnabled should return a boolean"); + // By default, voting power tracking is disabled + assert.strictEqual(isEnabled, false, "Voting power tracking should be disabled by default"); + }); + + it("getVotingPowerDisableAtBlock returns 0 when not scheduled", async () => { + const disableAtBlock = await publicClient.readContract({ + abi: IVotingPowerABI, + address: toViemAddress(IVOTING_POWER_ADDRESS), + functionName: "getVotingPowerDisableAtBlock", + args: [subnetId] + }) + + assert.ok(disableAtBlock !== undefined, "getVotingPowerDisableAtBlock should return a value"); + assert.strictEqual(typeof disableAtBlock, 'bigint', "getVotingPowerDisableAtBlock should return a bigint"); + assert.strictEqual(disableAtBlock, BigInt(0), "Disable at block should be 0 when not scheduled"); + }); + + it("getVotingPowerEmaAlpha returns default alpha value", async () => { + const alpha = await publicClient.readContract({ + abi: IVotingPowerABI, + address: toViemAddress(IVOTING_POWER_ADDRESS), + functionName: "getVotingPowerEmaAlpha", + args: [subnetId] + }) + + assert.ok(alpha !== undefined, "getVotingPowerEmaAlpha should return a value"); + assert.strictEqual(typeof alpha, 'bigint', "getVotingPowerEmaAlpha should return a bigint"); + // Default alpha is 0_003_570_000_000_000_000 // 0.00357 * 10^18 = 2 weeks e-folding (time-constant) @ 361 + assert.strictEqual(alpha, BigInt("3570000000000000"), "Default alpha should be 0.00357 * 10^18 (3570000000000000)"); + }); + }); + + describe("VotingPower Query Functions", () => { + it("getVotingPower returns 0 for hotkey without voting power", async () => { + // Convert hotkey public key to bytes32 format (0x prefixed hex string) + const hotkeyBytes32 = '0x' + Buffer.from(hotkey.publicKey).toString('hex'); + + const votingPower = await publicClient.readContract({ + abi: IVotingPowerABI, + address: toViemAddress(IVOTING_POWER_ADDRESS), + functionName: "getVotingPower", + args: [subnetId, hotkeyBytes32 as `0x${string}`] + }) + + assert.ok(votingPower !== undefined, "getVotingPower should return a value"); + assert.strictEqual(typeof votingPower, 'bigint', "getVotingPower should return a bigint"); + // Without voting power tracking enabled, voting power should be 0 + assert.strictEqual(votingPower, BigInt(0), "Voting power should be 0 when tracking is disabled"); + }); + + it("getVotingPower returns 0 for unknown hotkey", async () => { + // Generate a random hotkey that doesn't exist + const randomHotkey = getRandomSubstrateKeypair(); + const randomHotkeyBytes32 = '0x' + Buffer.from(randomHotkey.publicKey).toString('hex'); + + const votingPower = await publicClient.readContract({ + abi: IVotingPowerABI, + address: toViemAddress(IVOTING_POWER_ADDRESS), + functionName: "getVotingPower", + args: [subnetId, randomHotkeyBytes32 as `0x${string}`] + }) + + assert.ok(votingPower !== undefined, "getVotingPower should return a value"); + assert.strictEqual(votingPower, BigInt(0), "Voting power should be 0 for unknown hotkey"); + }); + + it("getTotalVotingPower returns 0 when no voting power exists", async () => { + const totalVotingPower = await publicClient.readContract({ + abi: IVotingPowerABI, + address: toViemAddress(IVOTING_POWER_ADDRESS), + functionName: "getTotalVotingPower", + args: [subnetId] + }) + + assert.ok(totalVotingPower !== undefined, "getTotalVotingPower should return a value"); + assert.strictEqual(typeof totalVotingPower, 'bigint', "getTotalVotingPower should return a bigint"); + assert.strictEqual(totalVotingPower, BigInt(0), "Total voting power should be 0 when tracking is disabled"); + }); + }); + + describe("VotingPower with Tracking Enabled", () => { + let enabledSubnetId: number; + + before(async () => { + // Create a new subnet for this test + const hotkey2 = getRandomSubstrateKeypair(); + const coldkey2 = getRandomSubstrateKeypair(); + + await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(hotkey2.publicKey)) + await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(coldkey2.publicKey)) + + enabledSubnetId = await addNewSubnetwork(api, hotkey2, coldkey2) + await startCall(api, enabledSubnetId, coldkey2) + + // Enable voting power tracking via sudo + const internalCall = api.tx.SubtensorModule.enable_voting_power_tracking({ netuid: enabledSubnetId }) + const tx = api.tx.Sudo.sudo({ call: internalCall.decodedCall }) + await waitForTransactionWithRetry(api, tx, alice) + }); + + it("isVotingPowerTrackingEnabled returns true after enabling", async () => { + const isEnabled = await publicClient.readContract({ + abi: IVotingPowerABI, + address: toViemAddress(IVOTING_POWER_ADDRESS), + functionName: "isVotingPowerTrackingEnabled", + args: [enabledSubnetId] + }) + + assert.strictEqual(isEnabled, true, "Voting power tracking should be enabled"); + }); + + it("getVotingPowerDisableAtBlock still returns 0 when enabled but not scheduled for disable", async () => { + const disableAtBlock = await publicClient.readContract({ + abi: IVotingPowerABI, + address: toViemAddress(IVOTING_POWER_ADDRESS), + functionName: "getVotingPowerDisableAtBlock", + args: [enabledSubnetId] + }) + + assert.strictEqual(disableAtBlock, BigInt(0), "Disable at block should still be 0"); + }); + }); + + describe("All precompile functions are accessible", () => { + it("All VotingPower precompile functions can be called", async () => { + const hotkeyBytes32 = '0x' + Buffer.from(hotkey.publicKey).toString('hex'); + + // Test all five functions + const results = await Promise.all([ + publicClient.readContract({ + abi: IVotingPowerABI, + address: toViemAddress(IVOTING_POWER_ADDRESS), + functionName: "getVotingPower", + args: [subnetId, hotkeyBytes32 as `0x${string}`] + }), + publicClient.readContract({ + abi: IVotingPowerABI, + address: toViemAddress(IVOTING_POWER_ADDRESS), + functionName: "isVotingPowerTrackingEnabled", + args: [subnetId] + }), + publicClient.readContract({ + abi: IVotingPowerABI, + address: toViemAddress(IVOTING_POWER_ADDRESS), + functionName: "getVotingPowerDisableAtBlock", + args: [subnetId] + }), + publicClient.readContract({ + abi: IVotingPowerABI, + address: toViemAddress(IVOTING_POWER_ADDRESS), + functionName: "getVotingPowerEmaAlpha", + args: [subnetId] + }), + publicClient.readContract({ + abi: IVotingPowerABI, + address: toViemAddress(IVOTING_POWER_ADDRESS), + functionName: "getTotalVotingPower", + args: [subnetId] + }) + ]); + + // All functions should return defined values + results.forEach((result: unknown, index: number) => { + assert.ok(result !== undefined, `Function ${index} should return a value`); + }); + + // Verify types + assert.strictEqual(typeof results[0], 'bigint', "getVotingPower should return bigint"); + assert.strictEqual(typeof results[1], 'boolean', "isVotingPowerTrackingEnabled should return boolean"); + assert.strictEqual(typeof results[2], 'bigint', "getVotingPowerDisableAtBlock should return bigint"); + assert.strictEqual(typeof results[3], 'bigint', "getVotingPowerEmaAlpha should return bigint"); + assert.strictEqual(typeof results[4], 'bigint', "getTotalVotingPower should return bigint"); + }); + }); +}); diff --git a/contract-tests/yarn.lock b/contract-tests/yarn.lock index 25300ca989..080ecb1325 100644 --- a/contract-tests/yarn.lock +++ b/contract-tests/yarn.lock @@ -155,35 +155,50 @@ dependencies: "@noble/hashes" "1.8.0" -"@noble/hashes@^1.3.1", "@noble/hashes@^1.3.3", "@noble/hashes@^1.5.0", "@noble/hashes@^1.8.0", "@noble/hashes@~1.8.0", "@noble/hashes@1.8.0": +"@noble/hashes@^1.3.1": version "1.8.0" resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz" integrity sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A== -"@noble/hashes@^2.0.0", "@noble/hashes@~2.0.0", "@noble/hashes@2.0.1": - version "2.0.1" - resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-2.0.1.tgz" - integrity sha512-XlOlEbQcE9fmuXxrVTXCTlG2nlRXa9Rj3rr5Ue/+tX+nmkgbX720YHh0VR3hBF9xDvwnb8D2shVGOwNx+ulArw== +"@noble/hashes@^1.3.3", "@noble/hashes@~1.8.0": + version "1.8.0" + resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz" + integrity sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A== + +"@noble/hashes@^1.5.0": + version "1.8.0" + resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz" + integrity sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A== -"@noble/hashes@^2.0.1", "@noble/hashes@2.0.1": +"@noble/hashes@^1.8.0", "@noble/hashes@1.8.0": + version "1.8.0" + resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz" + integrity sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A== + +"@noble/hashes@^2.0.0", "@noble/hashes@^2.0.1", "@noble/hashes@~2.0.0", "@noble/hashes@2.0.1": version "2.0.1" resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-2.0.1.tgz" integrity sha512-XlOlEbQcE9fmuXxrVTXCTlG2nlRXa9Rj3rr5Ue/+tX+nmkgbX720YHh0VR3hBF9xDvwnb8D2shVGOwNx+ulArw== -"@noble/hashes@~1.7.1", "@noble/hashes@1.7.2": - version "1.7.2" - resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.2.tgz" - integrity sha512-biZ0NUSxyjLLqo6KxEJ1b+C2NAx0wtDoFvCaXHGgUkeHzf3Xc1xKumFKREuT7f7DARNZ/slvYUwFG6B0f2b6hQ== +"@noble/hashes@~1.7.1", "@noble/hashes@1.7.1": + version "1.7.1" + resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.1.tgz" + integrity sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ== + +"@noble/hashes@~1.8.0": + version "1.8.0" + resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz" + integrity sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A== "@noble/hashes@1.3.2": version "1.3.2" resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz" integrity sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ== -"@noble/hashes@1.7.1": - version "1.7.1" - resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.1.tgz" - integrity sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ== +"@noble/hashes@1.7.2": + version "1.7.2" + resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.2.tgz" + integrity sha512-biZ0NUSxyjLLqo6KxEJ1b+C2NAx0wtDoFvCaXHGgUkeHzf3Xc1xKumFKREuT7f7DARNZ/slvYUwFG6B0f2b6hQ== "@pkgjs/parseargs@^0.11.0": version "0.11.0" @@ -240,7 +255,7 @@ integrity sha512-cgA9fh8dfBai9b46XaaQmj9vwzyHStQjc/xrAvQksgF6SqvZ0yAfxVqLvGrsz/Xi3dsAdKLg09PybC7MUAMv9w== "@polkadot-api/descriptors@file:.papi/descriptors": - version "0.1.0-autogenerated.14746733976505338329" + version "0.1.0-autogenerated.5063582544821983772" resolved "file:.papi/descriptors" "@polkadot-api/ink-contracts@^0.4.1", "@polkadot-api/ink-contracts@>=0.4.0", "@polkadot-api/ink-contracts@0.4.3": @@ -262,7 +277,7 @@ resolved "https://registry.npmjs.org/@polkadot-api/json-rpc-provider-proxy/-/json-rpc-provider-proxy-0.2.7.tgz" integrity sha512-+HM4JQXzO2GPUD2++4GOLsmFL6LO8RoLvig0HgCLuypDgfdZMlwd8KnyGHjRnVEHA5X+kvXbk84TDcAXVxTazQ== -"@polkadot-api/json-rpc-provider@^0.0.1": +"@polkadot-api/json-rpc-provider@^0.0.1", "@polkadot-api/json-rpc-provider@0.0.1": version "0.0.1" resolved "https://registry.npmjs.org/@polkadot-api/json-rpc-provider/-/json-rpc-provider-0.0.1.tgz" integrity sha512-/SMC/l7foRjpykLTUTacIH05H3mr9ip8b5xxfwXlVezXrNVLp3Cv0GX6uItkKd+ZjzVPf3PFrDF2B2/HLSNESA== @@ -445,7 +460,15 @@ "@scure/base" "^1.1.1" scale-ts "^1.6.0" -"@polkadot-api/substrate-client@^0.1.2", "@polkadot-api/substrate-client@0.1.4", "@polkadot-api/substrate-client@0.4.7": +"@polkadot-api/substrate-client@^0.1.2", "@polkadot-api/substrate-client@0.1.4": + version "0.1.4" + resolved "https://registry.npmjs.org/@polkadot-api/substrate-client/-/substrate-client-0.1.4.tgz" + integrity sha512-MljrPobN0ZWTpn++da9vOvt+Ex+NlqTlr/XT7zi9sqPtDJiQcYl+d29hFAgpaeTqbeQKZwz3WDE9xcEfLE8c5A== + dependencies: + "@polkadot-api/json-rpc-provider" "0.0.1" + "@polkadot-api/utils" "0.1.0" + +"@polkadot-api/substrate-client@0.4.7": version "0.4.7" resolved "https://registry.npmjs.org/@polkadot-api/substrate-client/-/substrate-client-0.4.7.tgz" integrity sha512-Mmx9VKincVqfVQmq89gzDk4DN3uKwf8CxoqYvq+EiPUZ1QmMUc7X4QMwG1MXIlYdnm5LSXzn+2Jn8ik8xMgL+w== @@ -2476,6 +2499,13 @@ signal-exit@^4.0.1, signal-exit@^4.1.0: resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz" integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== +smoldot@2.0.26, smoldot@2.x: + version "2.0.26" + resolved "https://registry.npmjs.org/smoldot/-/smoldot-2.0.26.tgz" + integrity sha512-F+qYmH4z2s2FK+CxGj8moYcd1ekSIKH8ywkdqlOz88Dat35iB1DIYL11aILN46YSGMzQW/lbJNS307zBSDN5Ig== + dependencies: + ws "^8.8.1" + smoldot@2.0.39: version "2.0.39" resolved "https://registry.npmjs.org/smoldot/-/smoldot-2.0.39.tgz" diff --git a/node/src/benchmarking.rs b/node/src/benchmarking.rs index 5430a75d9e..02e31e750e 100644 --- a/node/src/benchmarking.rs +++ b/node/src/benchmarking.rs @@ -124,28 +124,25 @@ pub fn create_benchmark_extrinsic( .checked_next_power_of_two() .map(|c| c / 2) .unwrap_or(2) as u64; - let extra: runtime::TransactionExtensions = - ( - frame_system::CheckNonZeroSender::::new(), - frame_system::CheckSpecVersion::::new(), - frame_system::CheckTxVersion::::new(), - frame_system::CheckGenesis::::new(), - frame_system::CheckEra::::from(sp_runtime::generic::Era::mortal( - period, - best_block.saturated_into(), - )), - check_nonce::CheckNonce::::from(nonce), - frame_system::CheckWeight::::new(), - transaction_payment_wrapper::ChargeTransactionPaymentWrapper::new( - pallet_transaction_payment::ChargeTransactionPayment::::from(0), - ), - sudo_wrapper::SudoTransactionExtension::::new(), - pallet_subtensor::transaction_extension::SubtensorTransactionExtension::< - runtime::Runtime, - >::new(), - pallet_drand::drand_priority::DrandPriority::::new(), - frame_metadata_hash_extension::CheckMetadataHash::::new(true), - ); + let extra: runtime::TransactionExtensions = ( + frame_system::CheckNonZeroSender::::new(), + frame_system::CheckSpecVersion::::new(), + frame_system::CheckTxVersion::::new(), + frame_system::CheckGenesis::::new(), + frame_system::CheckEra::::from(sp_runtime::generic::Era::mortal( + period, + best_block.saturated_into(), + )), + check_nonce::CheckNonce::::from(nonce), + frame_system::CheckWeight::::new(), + transaction_payment_wrapper::ChargeTransactionPaymentWrapper::new( + pallet_transaction_payment::ChargeTransactionPayment::::from(0), + ), + sudo_wrapper::SudoTransactionExtension::::new(), + pallet_subtensor::SubtensorTransactionExtension::::new(), + pallet_drand::drand_priority::DrandPriority::::new(), + frame_metadata_hash_extension::CheckMetadataHash::::new(true), + ); let raw_payload = runtime::SignedPayload::from_raw( call.clone(), diff --git a/node/src/mev_shield/author.rs b/node/src/mev_shield/author.rs index 8ac57b1d52..35f362df3d 100644 --- a/node/src/mev_shield/author.rs +++ b/node/src/mev_shield/author.rs @@ -375,28 +375,24 @@ where let current_block: u64 = info.best_number.saturated_into(); let era = Era::mortal(ERA_PERIOD, current_block); - let extra: Extra = - ( - frame_system::CheckNonZeroSender::::new(), - frame_system::CheckSpecVersion::::new(), - frame_system::CheckTxVersion::::new(), - frame_system::CheckGenesis::::new(), - frame_system::CheckEra::::from(era), - node_subtensor_runtime::check_nonce::CheckNonce::::from(nonce).into(), - frame_system::CheckWeight::::new(), - node_subtensor_runtime::transaction_payment_wrapper::ChargeTransactionPaymentWrapper::< - runtime::Runtime, - >::new(pallet_transaction_payment::ChargeTransactionPayment::< - runtime::Runtime, - >::from(0u64)), - node_subtensor_runtime::sudo_wrapper::SudoTransactionExtension::::new( - ), - pallet_subtensor::transaction_extension::SubtensorTransactionExtension::< - runtime::Runtime, - >::new(), - pallet_drand::drand_priority::DrandPriority::::new(), - frame_metadata_hash_extension::CheckMetadataHash::::new(false), - ); + let extra: Extra = ( + frame_system::CheckNonZeroSender::::new(), + frame_system::CheckSpecVersion::::new(), + frame_system::CheckTxVersion::::new(), + frame_system::CheckGenesis::::new(), + frame_system::CheckEra::::from(era), + node_subtensor_runtime::check_nonce::CheckNonce::::from(nonce).into(), + frame_system::CheckWeight::::new(), + node_subtensor_runtime::transaction_payment_wrapper::ChargeTransactionPaymentWrapper::< + runtime::Runtime, + >::new(pallet_transaction_payment::ChargeTransactionPayment::< + runtime::Runtime, + >::from(0u64)), + node_subtensor_runtime::sudo_wrapper::SudoTransactionExtension::::new(), + pallet_subtensor::SubtensorTransactionExtension::::new(), + pallet_drand::drand_priority::DrandPriority::::new(), + frame_metadata_hash_extension::CheckMetadataHash::::new(false), + ); // 3) Manually construct the `Implicit` tuple that the runtime will also derive. type Implicit = >::Implicit; diff --git a/pallets/admin-utils/src/benchmarking.rs b/pallets/admin-utils/src/benchmarking.rs index 7b8124144d..1a16c1f721 100644 --- a/pallets/admin-utils/src/benchmarking.rs +++ b/pallets/admin-utils/src/benchmarking.rs @@ -18,6 +18,8 @@ use super::*; #[benchmarks] mod benchmarks { use super::*; + #[cfg(test)] + use crate::tests::mock; use subtensor_runtime_common::NetUid; #[benchmark] @@ -263,7 +265,7 @@ mod benchmarks { ); #[extrinsic_call] - _(RawOrigin::Root, 1u16.into()/*netuid*/, 2048u16/*max_allowed_uids*/)/*sudo_set_max_allowed_uids*/; + _(RawOrigin::Root, 1u16.into()/*netuid*/, 256u16/*max_allowed_uids*/)/*sudo_set_max_allowed_uids*/; } #[benchmark] @@ -480,7 +482,13 @@ mod benchmarks { } #[benchmark] - fn sudo_set_coldkey_swap_schedule_duration() { + fn sudo_set_coldkey_swap_announcement_delay() { + #[extrinsic_call] + _(RawOrigin::Root, 100u32.into()); + } + + #[benchmark] + fn sudo_set_coldkey_swap_reannouncement_delay() { #[extrinsic_call] _(RawOrigin::Root, 100u32.into()); } @@ -645,5 +653,5 @@ mod benchmarks { ); /* sudo_set_min_non_immune_uids() */ } - //impl_benchmark_test_suite!(AdminUtils, crate::mock::new_test_ext(), crate::mock::Test); + impl_benchmark_test_suite!(AdminUtils, mock::new_test_ext(), mock::Test); } diff --git a/pallets/admin-utils/src/lib.rs b/pallets/admin-utils/src/lib.rs index 4143e3fb3a..532bb50227 100644 --- a/pallets/admin-utils/src/lib.rs +++ b/pallets/admin-utils/src/lib.rs @@ -14,7 +14,7 @@ use sp_runtime::{DispatchResult, RuntimeAppPublic, Vec, traits::Member}; mod benchmarking; #[cfg(test)] -mod tests; +pub(crate) mod tests; #[deny(missing_docs)] #[frame_support::pallet] @@ -145,6 +145,8 @@ pub mod pallet { Leasing, /// Address mapping precompile AddressMapping, + /// Voting power precompile + VotingPower, } #[pallet::type_value] @@ -505,7 +507,7 @@ pub mod pallet { /// The extrinsic will call the Subtensor pallet to set the maximum allowed UIDs for a subnet. #[pallet::call_index(15)] #[pallet::weight(Weight::from_parts(32_140_000, 0) - .saturating_add(::DbWeight::get().reads(5_u64)) + .saturating_add(::DbWeight::get().reads(6_u64)) .saturating_add(::DbWeight::get().writes(1_u64)))] pub fn sudo_set_max_allowed_uids( origin: OriginFor, @@ -534,6 +536,12 @@ pub mod pallet { max_allowed_uids <= DefaultMaxAllowedUids::::get(), Error::::MaxAllowedUidsGreaterThanDefaultMaxAllowedUids ); + // Prevent chain bloat: Require max UIDs to be limited + let mechanism_count = pallet_subtensor::MechanismCountCurrent::::get(netuid); + pallet_subtensor::Pallet::::ensure_max_uids_over_all_mechanisms( + max_allowed_uids, + mechanism_count.into(), + )?; pallet_subtensor::Pallet::::set_max_allowed_uids(netuid, max_allowed_uids); pallet_subtensor::Pallet::::record_owner_rl( maybe_owner, @@ -1291,40 +1299,6 @@ pub mod pallet { res } - /// Sets the duration of the coldkey swap schedule. - /// - /// This extrinsic allows the root account to set the duration for the coldkey swap schedule. - /// The coldkey swap schedule determines how long it takes for a coldkey swap operation to complete. - /// - /// # Arguments - /// * `origin` - The origin of the call, which must be the root account. - /// * `duration` - The new duration for the coldkey swap schedule, in number of blocks. - /// - /// # Errors - /// * `BadOrigin` - If the caller is not the root account. - /// - /// # Weight - /// Weight is handled by the `#[pallet::weight]` attribute. - #[pallet::call_index(54)] - #[pallet::weight(Weight::from_parts(5_000_000, 0) - .saturating_add(T::DbWeight::get().reads(0_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)))] - pub fn sudo_set_coldkey_swap_schedule_duration( - origin: OriginFor, - duration: BlockNumberFor, - ) -> DispatchResult { - // Ensure the call is made by the root account - ensure_root(origin)?; - - // Set the new duration of schedule coldkey swap - pallet_subtensor::Pallet::::set_coldkey_swap_schedule_duration(duration); - - // Log the change - log::trace!("ColdkeySwapScheduleDurationSet( duration: {duration:?} )"); - - Ok(()) - } - /// Sets the duration of the dissolve network schedule. /// /// This extrinsic allows the root account to set the duration for the dissolve network schedule. @@ -2091,6 +2065,20 @@ pub mod pallet { Ok(()) } + /// Sets the global maximum number of mechanisms in a subnet + #[pallet::call_index(88)] + #[pallet::weight(Weight::from_parts(15_000_000, 0) + .saturating_add(::DbWeight::get().reads(1_u64)) + .saturating_add(::DbWeight::get().writes(1_u64)))] + pub fn sudo_set_max_mechanism_count( + origin: OriginFor, + max_mechanism_count: MechId, + ) -> DispatchResult { + ensure_root(origin)?; + pallet_subtensor::Pallet::::do_set_max_mechanism_count(max_mechanism_count)?; + Ok(()) + } + /// Sets the minimum number of non-immortal & non-immune UIDs that must remain in a subnet #[pallet::call_index(84)] #[pallet::weight(Weight::from_parts(7_114_000, 0) @@ -2116,6 +2104,36 @@ pub mod pallet { log::debug!("StartCallDelay( delay: {delay:?} ) "); Ok(()) } + + /// Sets the announcement delay for coldkey swap. + #[pallet::call_index(86)] + #[pallet::weight(Weight::from_parts(5_000_000, 0) + .saturating_add(::DbWeight::get().reads(0_u64)) + .saturating_add(::DbWeight::get().writes(1_u64)))] + pub fn sudo_set_coldkey_swap_announcement_delay( + origin: OriginFor, + duration: BlockNumberFor, + ) -> DispatchResult { + ensure_root(origin)?; + pallet_subtensor::Pallet::::set_coldkey_swap_announcement_delay(duration); + log::trace!("ColdkeySwapAnnouncementDelaySet( duration: {duration:?} )"); + Ok(()) + } + + /// Sets the coldkey swap reannouncement delay. + #[pallet::call_index(87)] + #[pallet::weight(Weight::from_parts(5_000_000, 0) + .saturating_add(::DbWeight::get().reads(0_u64)) + .saturating_add(::DbWeight::get().writes(1_u64)))] + pub fn sudo_set_coldkey_swap_reannouncement_delay( + origin: OriginFor, + duration: BlockNumberFor, + ) -> DispatchResult { + ensure_root(origin)?; + pallet_subtensor::Pallet::::set_coldkey_swap_reannouncement_delay(duration); + log::trace!("ColdkeySwapReannouncementDelaySet( duration: {duration:?} )"); + Ok(()) + } } } diff --git a/pallets/admin-utils/src/tests/mock.rs b/pallets/admin-utils/src/tests/mock.rs index 0117dff889..2d51ecf105 100644 --- a/pallets/admin-utils/src/tests/mock.rs +++ b/pallets/admin-utils/src/tests/mock.rs @@ -19,7 +19,7 @@ use sp_runtime::{ }; use sp_std::cmp::Ordering; use sp_weights::Weight; -use subtensor_runtime_common::{NetUid, TaoCurrency}; +use subtensor_runtime_common::{AuthorshipInfo, NetUid, TaoCurrency}; type Block = frame_system::mocking::MockBlock; // Configure a mock runtime to test the pallet. @@ -74,6 +74,14 @@ pub type BlockNumber = u64; pub type TestAuthId = test_crypto::TestAuthId; pub type UncheckedExtrinsic = TestXt; +pub struct MockAuthorshipProvider; + +impl AuthorshipInfo for MockAuthorshipProvider { + fn author() -> Option { + Some(U256::from(12345u64)) + } +} + parameter_types! { pub const InitialMinAllowedWeights: u16 = 0; pub const InitialEmissionValue: u16 = 0; @@ -91,7 +99,7 @@ parameter_types! { pub const SelfOwnership: u64 = 2; pub const InitialImmunityPeriod: u16 = 2; pub const InitialMinAllowedUids: u16 = 2; - pub const InitialMaxAllowedUids: u16 = 16; + pub const InitialMaxAllowedUids: u16 = 256; pub const InitialBondsMovingAverage: u64 = 900_000; pub const InitialBondsPenalty: u16 = u16::MAX; pub const InitialBondsResetOn: bool = false; @@ -131,17 +139,14 @@ parameter_types! { pub const InitialNetworkMinLockCost: u64 = 100_000_000_000; pub const InitialSubnetOwnerCut: u16 = 0; // 0%. 100% of rewards go to validators + miners. pub const InitialNetworkLockReductionInterval: u64 = 2; // 2 blocks. - // pub const InitialSubnetLimit: u16 = 10; // (DEPRECATED) pub const InitialNetworkRateLimit: u64 = 0; pub const InitialKeySwapCost: u64 = 1_000_000_000; pub const InitialAlphaHigh: u16 = 58982; // Represents 0.9 as per the production default pub const InitialAlphaLow: u16 = 45875; // Represents 0.7 as per the production default pub const InitialLiquidAlphaOn: bool = false; // Default value for LiquidAlphaOn pub const InitialYuma3On: bool = false; // Default value for Yuma3On - // pub const InitialHotkeyEmissionTempo: u64 = 1; // (DEPRECATED) - // pub const InitialNetworkMaxStake: u64 = u64::MAX; // (DEPRECATED) - pub const InitialColdkeySwapScheduleDuration: u64 = 5 * 24 * 60 * 60 / 12; // 5 days - pub const InitialColdkeySwapRescheduleDuration: u64 = 24 * 60 * 60 / 12; // 1 day + pub const InitialColdkeySwapAnnouncementDelay: u64 = 50; + pub const InitialColdkeySwapReannouncementDelay: u64 = 10; pub const InitialDissolveNetworkScheduleDuration: u64 = 5 * 24 * 60 * 60 / 12; // 5 days pub const InitialTaoWeight: u64 = u64::MAX/10; // 10% global weight. pub const InitialEmaPriceHalvingPeriod: u64 = 201_600_u64; // 4 weeks @@ -210,8 +215,8 @@ impl pallet_subtensor::Config for Test { type LiquidAlphaOn = InitialLiquidAlphaOn; type Yuma3On = InitialYuma3On; type Preimages = (); - type InitialColdkeySwapScheduleDuration = InitialColdkeySwapScheduleDuration; - type InitialColdkeySwapRescheduleDuration = InitialColdkeySwapRescheduleDuration; + type InitialColdkeySwapAnnouncementDelay = InitialColdkeySwapAnnouncementDelay; + type InitialColdkeySwapReannouncementDelay = InitialColdkeySwapReannouncementDelay; type InitialDissolveNetworkScheduleDuration = InitialDissolveNetworkScheduleDuration; type InitialTaoWeight = InitialTaoWeight; type InitialEmaPriceHalvingPeriod = InitialEmaPriceHalvingPeriod; @@ -225,6 +230,7 @@ impl pallet_subtensor::Config for Test { type MaxImmuneUidsPercentage = MaxImmuneUidsPercentage; type CommitmentsInterface = CommitmentsI; type EvmKeyAssociateRateLimit = EvmKeyAssociateRateLimit; + type AuthorshipProvider = MockAuthorshipProvider; } parameter_types! { diff --git a/pallets/admin-utils/src/tests/mod.rs b/pallets/admin-utils/src/tests/mod.rs index 93d56ec343..be86489446 100644 --- a/pallets/admin-utils/src/tests/mod.rs +++ b/pallets/admin-utils/src/tests/mod.rs @@ -10,7 +10,10 @@ use pallet_subtensor::{ TargetRegistrationsPerInterval, Tempo, WeightsVersionKeyRateLimit, *, }; // use pallet_subtensor::{migrations, Event}; -use pallet_subtensor::{Event, utils::rate_limiting::TransactionType}; +use pallet_subtensor::{ + Event, subnets::mechanism::MAX_MECHANISM_COUNT_PER_SUBNET, + utils::rate_limiting::TransactionType, +}; use sp_consensus_grandpa::AuthorityId as GrandpaId; use sp_core::{Get, Pair, U256, ed25519}; use substrate_fixed::types::I96F32; @@ -20,7 +23,7 @@ use crate::Error; use crate::pallet::PrecompileEnable; use mock::*; -mod mock; +pub(crate) mod mock; #[test] fn test_sudo_set_default_take() { @@ -540,6 +543,20 @@ fn test_sudo_set_max_allowed_uids() { Error::::MaxAllowedUidsGreaterThanDefaultMaxAllowedUids ); + // Trying to set max allowed uids that would cause max_allowed_uids * mechanism_count > 256 + MaxAllowedUids::::insert(netuid, 8); + MechanismCountCurrent::::insert(netuid, MechId::from(32)); + let large_max_uids = 16; + assert_noop!( + AdminUtils::sudo_set_max_allowed_uids( + <::RuntimeOrigin>::root(), + netuid, + large_max_uids + ), + SubtensorError::::TooManyUIDsPerMechanism + ); + MechanismCountCurrent::::insert(netuid, MechId::from(1)); + // Normal case assert_ok!(AdminUtils::sudo_set_max_allowed_uids( <::RuntimeOrigin>::root(), @@ -1382,39 +1399,74 @@ fn test_sudo_get_set_alpha() { } #[test] -fn test_sudo_set_coldkey_swap_schedule_duration() { +fn test_sudo_set_coldkey_swap_announcement_delay() { new_test_ext().execute_with(|| { // Arrange let root = RuntimeOrigin::root(); let non_root = RuntimeOrigin::signed(U256::from(1)); - let new_duration = 100u32.into(); + let new_delay = 100u32.into(); // Act & Assert: Non-root account should fail assert_noop!( - AdminUtils::sudo_set_coldkey_swap_schedule_duration(non_root, new_duration), + AdminUtils::sudo_set_coldkey_swap_announcement_delay(non_root, new_delay), DispatchError::BadOrigin ); // Act: Root account should succeed - assert_ok!(AdminUtils::sudo_set_coldkey_swap_schedule_duration( + assert_ok!(AdminUtils::sudo_set_coldkey_swap_announcement_delay( root.clone(), - new_duration + new_delay )); - // Assert: Check if the duration was actually set + // Assert: Check if the delay was actually set assert_eq!( - pallet_subtensor::ColdkeySwapScheduleDuration::::get(), - new_duration + pallet_subtensor::ColdkeySwapAnnouncementDelay::::get(), + new_delay ); // Act & Assert: Setting the same value again should succeed (idempotent operation) - assert_ok!(AdminUtils::sudo_set_coldkey_swap_schedule_duration( - root, - new_duration + assert_ok!(AdminUtils::sudo_set_coldkey_swap_announcement_delay( + root, new_delay )); // You might want to check for events here if your pallet emits them - System::assert_last_event(Event::ColdkeySwapScheduleDurationSet(new_duration).into()); + System::assert_last_event(Event::ColdkeySwapAnnouncementDelaySet(new_delay).into()); + }); +} + +#[test] +fn test_sudo_set_coldkey_swap_reannouncement_delay() { + new_test_ext().execute_with(|| { + // Arrange + let root = RuntimeOrigin::root(); + let non_root = RuntimeOrigin::signed(U256::from(1)); + let new_delay = 100u32.into(); + + // Act & Assert: Non-root account should fail + assert_noop!( + AdminUtils::sudo_set_coldkey_swap_reannouncement_delay(non_root, new_delay), + DispatchError::BadOrigin + ); + + // Act: Root account should succeed + assert_ok!(AdminUtils::sudo_set_coldkey_swap_reannouncement_delay( + root.clone(), + new_delay + )); + + // Assert: Check if the delay was actually set + assert_eq!( + pallet_subtensor::ColdkeySwapReannouncementDelay::::get(), + new_delay + ); + + // Act & Assert: Setting the same value again should succeed (idempotent operation) + assert_ok!(AdminUtils::sudo_set_coldkey_swap_reannouncement_delay( + root, new_delay + )); + + // You might want to check for events here if your pallet emits them + System::assert_last_event(Event::ColdkeySwapReannouncementDelaySet(new_delay).into()); }); } @@ -2341,6 +2393,7 @@ fn test_sudo_set_mechanism_count() { add_network(netuid, 10); // Set the Subnet Owner SubnetOwner::::insert(netuid, sn_owner); + MaxAllowedUids::::insert(netuid, 256_u16); assert_eq!( AdminUtils::sudo_set_mechanism_count( @@ -2354,7 +2407,13 @@ fn test_sudo_set_mechanism_count() { AdminUtils::sudo_set_mechanism_count(RuntimeOrigin::root(), netuid, ss_count_bad), pallet_subtensor::Error::::InvalidValue ); + assert_noop!( + AdminUtils::sudo_set_mechanism_count(RuntimeOrigin::root(), netuid, ss_count_ok), + pallet_subtensor::Error::::TooManyUIDsPerMechanism + ); + // Reduce max UIDs to 128 + MaxAllowedUids::::insert(netuid, 128_u16); assert_ok!(AdminUtils::sudo_set_mechanism_count( <::RuntimeOrigin>::root(), netuid, @@ -2380,6 +2439,8 @@ fn test_sudo_set_mechanism_count_and_emissions() { add_network(netuid, 10); // Set the Subnet Owner SubnetOwner::::insert(netuid, sn_owner); + MaxMechanismCount::::set(MechId::from(2)); + MaxAllowedUids::::set(netuid, 128_u16); assert_ok!(AdminUtils::sudo_set_mechanism_count( <::RuntimeOrigin>::signed(sn_owner), @@ -2868,6 +2929,35 @@ fn test_sudo_set_min_allowed_uids() { }); } +#[test] +fn test_sudo_set_max_mechanism_count() { + new_test_ext().execute_with(|| { + // Normal case + assert_ok!(AdminUtils::sudo_set_max_mechanism_count( + <::RuntimeOrigin>::root(), + MechId::from(10) + )); + + // Zero fails + assert_noop!( + AdminUtils::sudo_set_max_mechanism_count( + <::RuntimeOrigin>::root(), + MechId::from(0) + ), + pallet_subtensor::Error::::InvalidValue + ); + + // Over max bound fails + assert_noop!( + AdminUtils::sudo_set_max_mechanism_count( + <::RuntimeOrigin>::root(), + MechId::from(MAX_MECHANISM_COUNT_PER_SUBNET + 1) + ), + pallet_subtensor::Error::::InvalidValue + ); + }); +} + #[test] fn test_sudo_set_min_non_immune_uids() { new_test_ext().execute_with(|| { diff --git a/pallets/proxy/Cargo.toml b/pallets/proxy/Cargo.toml index 3d8da72029..9331739325 100644 --- a/pallets/proxy/Cargo.toml +++ b/pallets/proxy/Cargo.toml @@ -19,6 +19,8 @@ codec = { workspace = true, features = ["max-encoded-len"] } frame = { workspace = true, features = ["runtime"] } scale-info = { workspace = true, features = ["derive"] } subtensor-macros.workspace = true +frame-system.workspace = true +frame-support.workspace = true [dev-dependencies] pallet-balances = { default-features = true, workspace = true } @@ -26,14 +28,24 @@ pallet-subtensor-utility = { default-features = true, workspace = true } [features] default = ["std"] -std = ["codec/std", "frame/std", "scale-info/std"] +std = [ + "codec/std", + "frame/std", + "scale-info/std", + "frame-support/std", + "frame-system/std", +] runtime-benchmarks = [ "frame/runtime-benchmarks", "pallet-balances/runtime-benchmarks", "pallet-subtensor-utility/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", ] try-runtime = [ "frame/try-runtime", "pallet-balances/try-runtime", "pallet-subtensor-utility/try-runtime", + "frame-support/try-runtime", + "frame-system/try-runtime", ] diff --git a/pallets/proxy/src/benchmarking.rs b/pallets/proxy/src/benchmarking.rs index 9a759e1846..9bf21cb951 100644 --- a/pallets/proxy/src/benchmarking.rs +++ b/pallets/proxy/src/benchmarking.rs @@ -491,5 +491,28 @@ mod benchmarks { Ok(()) } + #[benchmark] + fn set_real_pays_fee(p: Linear<1, { T::MaxProxies::get() - 1 }>) -> Result<(), BenchmarkError> { + add_proxies::(p, None)?; + let caller: T::AccountId = whitelisted_caller(); + let delegate: T::AccountId = account("target", 0, SEED); + let delegate_lookup = T::Lookup::unlookup(delegate.clone()); + + #[extrinsic_call] + _(RawOrigin::Signed(caller.clone()), delegate_lookup, true); + + assert!(RealPaysFee::::contains_key(&caller, &delegate)); + assert_last_event::( + Event::RealPaysFeeSet { + real: caller, + delegate, + pays_fee: true, + } + .into(), + ); + + Ok(()) + } + impl_benchmark_test_suite!(Proxy, crate::tests::new_test_ext(), crate::tests::Test); } diff --git a/pallets/proxy/src/lib.rs b/pallets/proxy/src/lib.rs index a255f99b48..1fca855327 100644 --- a/pallets/proxy/src/lib.rs +++ b/pallets/proxy/src/lib.rs @@ -674,6 +674,44 @@ pub mod pallet { Pays::Yes.into() }) } + + /// Set whether the real account pays transaction fees for proxy calls made by a + /// specific delegate. + /// + /// The dispatch origin for this call must be _Signed_ and must be the real (delegator) + /// account that has an existing proxy relationship with the delegate. + /// + /// Parameters: + /// - `delegate`: The proxy account for which to set the fee payment preference. + /// - `pays_fee`: If `true`, the real account will pay fees for proxy calls made by + /// this delegate. If `false`, the delegate pays (default behavior). + #[pallet::call_index(11)] + #[pallet::weight(T::WeightInfo::set_real_pays_fee(T::MaxProxies::get()))] + pub fn set_real_pays_fee( + origin: OriginFor, + delegate: AccountIdLookupOf, + pays_fee: bool, + ) -> DispatchResult { + let real = ensure_signed(origin)?; + let delegate = T::Lookup::lookup(delegate)?; + + // Verify proxy relationship exists + Self::find_proxy(&real, &delegate, None)?; + + if pays_fee { + RealPaysFee::::insert(&real, &delegate, ()); + } else { + RealPaysFee::::remove(&real, &delegate); + } + + Self::deposit_event(Event::RealPaysFeeSet { + real, + delegate, + pays_fee, + }); + + Ok(()) + } } #[pallet::event] @@ -727,6 +765,12 @@ pub mod pallet { old_deposit: BalanceOf, new_deposit: BalanceOf, }, + /// The real-pays-fee setting was updated for a proxy relationship. + RealPaysFeeSet { + real: T::AccountId, + delegate: T::AccountId, + pays_fee: bool, + }, } #[pallet::error] @@ -796,6 +840,21 @@ pub mod pallet { pub type LastCallResult = StorageMap<_, Twox64Concat, T::AccountId, DispatchResult, OptionQuery>; + /// Tracks which (real, delegate) pairs have opted in to the real account paying + /// transaction fees for proxy calls made by the delegate. + /// Existence of an entry means the real account pays; absence means the delegate pays + /// (default). + #[pallet::storage] + pub type RealPaysFee = StorageDoubleMap< + _, + Twox64Concat, + T::AccountId, // real + Twox64Concat, + T::AccountId, // delegate + (), + OptionQuery, + >; + #[pallet::view_functions] impl Pallet { /// Check if a `RuntimeCall` is allowed for a given `ProxyType`. @@ -951,6 +1010,9 @@ impl Pallet { if !proxies.is_empty() { *x = Some((proxies, new_deposit)) } + // Clean up real-pays-fee flag for this specific proxy relationship + RealPaysFee::::remove(delegator, &delegatee); + Self::deposit_event(Event::::ProxyRemoved { delegator: delegator.clone(), delegatee, @@ -1081,5 +1143,12 @@ impl Pallet { pub fn remove_all_proxy_delegates(delegator: &T::AccountId) { let (_, old_deposit) = Proxies::::take(delegator); T::Currency::unreserve(delegator, old_deposit); + // Clean up all real-pays-fee flags for this delegator + let _ = RealPaysFee::::clear_prefix(delegator, u32::MAX, None); + } + + /// Check if the real account has opted in to paying fees for a specific delegate. + pub fn is_real_pays_fee(real: &T::AccountId, delegate: &T::AccountId) -> bool { + RealPaysFee::::contains_key(real, delegate) } } diff --git a/pallets/proxy/src/tests.rs b/pallets/proxy/src/tests.rs index ea64aef030..5bc5be2415 100644 --- a/pallets/proxy/src/tests.rs +++ b/pallets/proxy/src/tests.rs @@ -1251,3 +1251,125 @@ fn poke_deposit_fails_for_unsigned_origin() { ); }); } + +#[test] +fn set_real_pays_fee_works() { + new_test_ext().execute_with(|| { + // Account 1 adds account 3 as proxy + assert_ok!(Proxy::add_proxy( + RuntimeOrigin::signed(1), + 3, + ProxyType::Any, + 0 + )); + + // Account 1 (real) enables real-pays-fee for delegate 3 + assert_ok!(Proxy::set_real_pays_fee(RuntimeOrigin::signed(1), 3, true)); + assert!(Proxy::is_real_pays_fee(&1, &3)); + System::assert_last_event( + ProxyEvent::RealPaysFeeSet { + real: 1, + delegate: 3, + pays_fee: true, + } + .into(), + ); + + // Disable it + assert_ok!(Proxy::set_real_pays_fee(RuntimeOrigin::signed(1), 3, false)); + assert!(!Proxy::is_real_pays_fee(&1, &3)); + System::assert_last_event( + ProxyEvent::RealPaysFeeSet { + real: 1, + delegate: 3, + pays_fee: false, + } + .into(), + ); + }); +} + +#[test] +fn set_real_pays_fee_fails_without_proxy() { + new_test_ext().execute_with(|| { + // No proxy relationship between 1 and 3 + assert_noop!( + Proxy::set_real_pays_fee(RuntimeOrigin::signed(1), 3, true), + Error::::NotProxy, + ); + }); +} + +#[test] +fn set_real_pays_fee_fails_unsigned() { + new_test_ext().execute_with(|| { + assert_noop!( + Proxy::set_real_pays_fee(RuntimeOrigin::none(), 3, true), + DispatchError::BadOrigin, + ); + }); +} + +#[test] +fn set_real_pays_fee_fails_root() { + new_test_ext().execute_with(|| { + assert_noop!( + Proxy::set_real_pays_fee(RuntimeOrigin::root(), 3, true), + DispatchError::BadOrigin, + ); + }); +} + +#[test] +fn real_pays_fee_cleaned_on_remove_proxy() { + new_test_ext().execute_with(|| { + assert_ok!(Proxy::add_proxy( + RuntimeOrigin::signed(1), + 3, + ProxyType::Any, + 0 + )); + assert_ok!(Proxy::set_real_pays_fee(RuntimeOrigin::signed(1), 3, true)); + assert!(Proxy::is_real_pays_fee(&1, &3)); + + // Remove the proxy + assert_ok!(Proxy::remove_proxy( + RuntimeOrigin::signed(1), + 3, + ProxyType::Any, + 0 + )); + + // Flag should be cleaned up + assert!(!Proxy::is_real_pays_fee(&1, &3)); + }); +} + +#[test] +fn real_pays_fee_cleaned_on_remove_proxies() { + new_test_ext().execute_with(|| { + assert_ok!(Proxy::add_proxy( + RuntimeOrigin::signed(1), + 2, + ProxyType::Any, + 0 + )); + assert_ok!(Proxy::add_proxy( + RuntimeOrigin::signed(1), + 3, + ProxyType::Any, + 0 + )); + assert_ok!(Proxy::set_real_pays_fee(RuntimeOrigin::signed(1), 2, true)); + assert_ok!(Proxy::set_real_pays_fee(RuntimeOrigin::signed(1), 3, true)); + assert!(Proxy::is_real_pays_fee(&1, &2)); + assert!(Proxy::is_real_pays_fee(&1, &3)); + + // Remove all proxies + assert_ok!(Proxy::remove_proxies(RuntimeOrigin::signed(1))); + + // Both flags should be cleaned up + assert!(!Proxy::is_real_pays_fee(&1, &2)); + assert!(!Proxy::is_real_pays_fee(&1, &3)); + }); +} diff --git a/pallets/proxy/src/weights.rs b/pallets/proxy/src/weights.rs index 6a14c7de2c..d8f463497f 100644 --- a/pallets/proxy/src/weights.rs +++ b/pallets/proxy/src/weights.rs @@ -17,42 +17,40 @@ //! Autogenerated weights for `pallet_proxy` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2025-03-04, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 49.1.0 +//! DATE: 2026-02-27, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `99fc4dfa9c86`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `Ubuntu-2404-noble-amd64-base`, CPU: `AMD Ryzen 9 5950X 16-Core Processor` //! WASM-EXECUTION: `Compiled`, CHAIN: `None`, DB CACHE: `1024` // Executed Command: -// frame-omni-bencher -// v1 +// ./target/production/node-subtensor // benchmark // pallet // --extrinsic=* -// --runtime=target/production/wbuild/kitchensink-runtime/kitchensink_runtime.wasm -// --pallet=pallet_proxy -// --header=/__w/polkadot-sdk/polkadot-sdk/substrate/HEADER-APACHE2 -// --output=/__w/polkadot-sdk/polkadot-sdk/substrate/frame/proxy/src/weights.rs +// --runtime=target/production/wbuild/node-subtensor-runtime/node_subtensor_runtime.wasm +// --genesis-builder=runtime +// --genesis-builder-preset=benchmark +// --pallet=pallet_subtensor_proxy +// --output=pallets/proxy/src/weights.rs // --wasm-execution=compiled // --steps=50 // --repeat=20 // --heap-pages=4096 -// --template=substrate/.maintain/frame-umbrella-weight-template.hbs +// --template=.maintain/frame-weight-template.hbs // --no-storage-info // --no-min-squares // --no-median-slopes -// --exclude-pallets=pallet_xcm,pallet_xcm_benchmarks::fungible,pallet_xcm_benchmarks::generic,pallet_nomination_pools,pallet_remark,pallet_transaction_storage,pallet_election_provider_multi_block,pallet_election_provider_multi_block::signed,pallet_election_provider_multi_block::unsigned,pallet_election_provider_multi_block::verifier #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] #![allow(unused_imports)] #![allow(missing_docs)] -#![allow(dead_code)] -use crate as pallet_proxy; -use frame::weights_prelude::*; +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use core::marker::PhantomData; -/// Weight functions needed for `pallet_proxy`. +/// Weight functions needed for `pallet_subtensor_proxy`. pub trait WeightInfo { fn proxy(p: u32, ) -> Weight; fn proxy_announced(a: u32, p: u32, ) -> Weight; @@ -65,385 +63,438 @@ pub trait WeightInfo { fn create_pure(p: u32, ) -> Weight; fn kill_pure(p: u32, ) -> Weight; fn poke_deposit() -> Weight; + fn set_real_pays_fee(p: u32, ) -> Weight; } -/// Weights for `pallet_proxy` using the Substrate node and recommended hardware. +/// Weights for `pallet_subtensor_proxy` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { /// Storage: `Proxy::Proxies` (r:1 w:0) - /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(789), added: 3264, mode: `MaxEncodedLen`) /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `TxPause::PausedCalls` (r:1 w:0) - /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) - /// The range of component `p` is `[1, 31]`. + /// Storage: `SubtensorModule::ColdkeySwapAnnouncements` (r:1 w:0) + /// Proof: `SubtensorModule::ColdkeySwapAnnouncements` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Proxy::LastCallResult` (r:0 w:1) + /// Proof: `Proxy::LastCallResult` (`max_values`: None, `max_size`: Some(47), added: 2522, mode: `MaxEncodedLen`) + /// The range of component `p` is `[1, 19]`. fn proxy(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `339 + p * (37 ±0)` - // Estimated: `4706` - // Minimum execution time: 23_353_000 picoseconds. - Weight::from_parts(25_084_085, 4706) - // Standard Error: 2_569 - .saturating_add(Weight::from_parts(33_574, 0).saturating_mul(p.into())) + // Measured: `625 + p * (37 ±0)` + // Estimated: `4254 + p * (37 ±0)` + // Minimum execution time: 19_346_000 picoseconds. + Weight::from_parts(19_857_012, 4254) + // Standard Error: 1_610 + .saturating_add(Weight::from_parts(42_156, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + .saturating_add(Weight::from_parts(0, 37).saturating_mul(p.into())) } /// Storage: `Proxy::Proxies` (r:1 w:0) - /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(789), added: 3264, mode: `MaxEncodedLen`) /// Storage: `Proxy::Announcements` (r:1 w:1) - /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(2233), added: 4708, mode: `MaxEncodedLen`) + /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(5150), added: 7625, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(104), added: 2579, mode: `MaxEncodedLen`) /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `TxPause::PausedCalls` (r:1 w:0) - /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) - /// The range of component `a` is `[0, 31]`. - /// The range of component `p` is `[1, 31]`. + /// Storage: `SubtensorModule::ColdkeySwapAnnouncements` (r:1 w:0) + /// Proof: `SubtensorModule::ColdkeySwapAnnouncements` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Proxy::LastCallResult` (r:0 w:1) + /// Proof: `Proxy::LastCallResult` (`max_values`: None, `max_size`: Some(47), added: 2522, mode: `MaxEncodedLen`) + /// The range of component `a` is `[0, 74]`. + /// The range of component `p` is `[1, 19]`. fn proxy_announced(a: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `666 + a * (68 ±0) + p * (37 ±0)` - // Estimated: `5698` - // Minimum execution time: 47_196_000 picoseconds. - Weight::from_parts(48_686_812, 5698) - // Standard Error: 3_711 - .saturating_add(Weight::from_parts(171_107, 0).saturating_mul(a.into())) - // Standard Error: 3_834 - .saturating_add(Weight::from_parts(34_523, 0).saturating_mul(p.into())) + // Measured: `882 + a * (68 ±0) + p * (37 ±0)` + // Estimated: `8615 + a * (68 ±0) + p * (37 ±0)` + // Minimum execution time: 37_952_000 picoseconds. + Weight::from_parts(37_943_137, 8615) + // Standard Error: 994 + .saturating_add(Weight::from_parts(155_667, 0).saturating_mul(a.into())) + // Standard Error: 3_984 + .saturating_add(Weight::from_parts(20_119, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(5_u64)) - .saturating_add(T::DbWeight::get().writes(2_u64)) + .saturating_add(T::DbWeight::get().writes(3_u64)) + .saturating_add(Weight::from_parts(0, 68).saturating_mul(a.into())) + .saturating_add(Weight::from_parts(0, 37).saturating_mul(p.into())) } /// Storage: `Proxy::Announcements` (r:1 w:1) - /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(2233), added: 4708, mode: `MaxEncodedLen`) + /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(5150), added: 7625, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// The range of component `a` is `[0, 31]`. - /// The range of component `p` is `[1, 31]`. + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(104), added: 2579, mode: `MaxEncodedLen`) + /// The range of component `a` is `[0, 74]`. + /// The range of component `p` is `[1, 19]`. fn remove_announcement(a: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `436 + a * (68 ±0)` - // Estimated: `5698` - // Minimum execution time: 29_341_000 picoseconds. - Weight::from_parts(30_320_504, 5698) - // Standard Error: 1_821 - .saturating_add(Weight::from_parts(158_572, 0).saturating_mul(a.into())) - // Standard Error: 1_881 - .saturating_add(Weight::from_parts(8_433, 0).saturating_mul(p.into())) + // Measured: `299 + a * (68 ±0)` + // Estimated: `8615` + // Minimum execution time: 18_064_000 picoseconds. + Weight::from_parts(18_046_024, 8615) + // Standard Error: 690 + .saturating_add(Weight::from_parts(130_637, 0).saturating_mul(a.into())) + // Standard Error: 2_766 + .saturating_add(Weight::from_parts(27_361, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `Proxy::Announcements` (r:1 w:1) - /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(2233), added: 4708, mode: `MaxEncodedLen`) + /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(5150), added: 7625, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// The range of component `a` is `[0, 31]`. - /// The range of component `p` is `[1, 31]`. + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(104), added: 2579, mode: `MaxEncodedLen`) + /// The range of component `a` is `[0, 74]`. + /// The range of component `p` is `[1, 19]`. fn reject_announcement(a: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `436 + a * (68 ±0)` - // Estimated: `5698` - // Minimum execution time: 28_422_000 picoseconds. - Weight::from_parts(29_754_384, 5698) - // Standard Error: 1_840 - .saturating_add(Weight::from_parts(176_827, 0).saturating_mul(a.into())) - // Standard Error: 1_901 - .saturating_add(Weight::from_parts(9_607, 0).saturating_mul(p.into())) + // Measured: `299 + a * (68 ±0)` + // Estimated: `8615` + // Minimum execution time: 17_964_000 picoseconds. + Weight::from_parts(18_288_524, 8615) + // Standard Error: 953 + .saturating_add(Weight::from_parts(136_907, 0).saturating_mul(a.into())) + // Standard Error: 3_819 + .saturating_add(Weight::from_parts(11_084, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `Proxy::Proxies` (r:1 w:0) - /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(789), added: 3264, mode: `MaxEncodedLen`) /// Storage: `Proxy::Announcements` (r:1 w:1) - /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(2233), added: 4708, mode: `MaxEncodedLen`) + /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(5150), added: 7625, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// The range of component `a` is `[0, 31]`. - /// The range of component `p` is `[1, 31]`. + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(104), added: 2579, mode: `MaxEncodedLen`) + /// The range of component `a` is `[0, 74]`. + /// The range of component `p` is `[1, 19]`. fn announce(a: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `453 + a * (68 ±0) + p * (37 ±0)` - // Estimated: `5698` - // Minimum execution time: 36_885_000 picoseconds. - Weight::from_parts(38_080_636, 5698) - // Standard Error: 2_642 - .saturating_add(Weight::from_parts(157_335, 0).saturating_mul(a.into())) - // Standard Error: 2_730 - .saturating_add(Weight::from_parts(28_872, 0).saturating_mul(p.into())) + // Measured: `308 + a * (68 ±0) + p * (37 ±0)` + // Estimated: `8615` + // Minimum execution time: 23_855_000 picoseconds. + Weight::from_parts(23_721_196, 8615) + // Standard Error: 813 + .saturating_add(Weight::from_parts(135_522, 0).saturating_mul(a.into())) + // Standard Error: 3_256 + .saturating_add(Weight::from_parts(42_377, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `Proxy::Proxies` (r:1 w:1) - /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) - /// The range of component `p` is `[1, 31]`. + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(789), added: 3264, mode: `MaxEncodedLen`) + /// The range of component `p` is `[1, 19]`. fn add_proxy(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `194 + p * (37 ±0)` - // Estimated: `4706` - // Minimum execution time: 27_016_000 picoseconds. - Weight::from_parts(28_296_216, 4706) - // Standard Error: 1_643 - .saturating_add(Weight::from_parts(50_271, 0).saturating_mul(p.into())) + // Measured: `119 + p * (37 ±0)` + // Estimated: `4254` + // Minimum execution time: 17_854_000 picoseconds. + Weight::from_parts(18_203_947, 4254) + // Standard Error: 1_051 + .saturating_add(Weight::from_parts(44_781, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Proxy::Proxies` (r:1 w:1) - /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) - /// The range of component `p` is `[1, 31]`. + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(789), added: 3264, mode: `MaxEncodedLen`) + /// Storage: `Proxy::RealPaysFee` (r:0 w:1) + /// Proof: `Proxy::RealPaysFee` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`) + /// The range of component `p` is `[1, 19]`. fn remove_proxy(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `194 + p * (37 ±0)` - // Estimated: `4706` - // Minimum execution time: 26_955_000 picoseconds. - Weight::from_parts(28_379_566, 4706) - // Standard Error: 1_547 - .saturating_add(Weight::from_parts(45_784, 0).saturating_mul(p.into())) + // Measured: `119 + p * (37 ±0)` + // Estimated: `4254` + // Minimum execution time: 18_815_000 picoseconds. + Weight::from_parts(19_464_499, 4254) + // Standard Error: 1_215 + .saturating_add(Weight::from_parts(44_540, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `Proxy::Proxies` (r:1 w:1) - /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) - /// The range of component `p` is `[1, 31]`. + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(789), added: 3264, mode: `MaxEncodedLen`) + /// The range of component `p` is `[1, 19]`. fn remove_proxies(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `194 + p * (37 ±0)` - // Estimated: `4706` - // Minimum execution time: 24_656_000 picoseconds. - Weight::from_parts(25_821_878, 4706) - // Standard Error: 2_300 - .saturating_add(Weight::from_parts(33_972, 0).saturating_mul(p.into())) + // Measured: `119 + p * (37 ±0)` + // Estimated: `4254` + // Minimum execution time: 18_245_000 picoseconds. + Weight::from_parts(18_987_977, 4254) + // Standard Error: 1_120 + .saturating_add(Weight::from_parts(18_728, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Proxy::Proxies` (r:1 w:1) - /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) - /// The range of component `p` is `[1, 31]`. + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(789), added: 3264, mode: `MaxEncodedLen`) + /// The range of component `p` is `[1, 19]`. fn create_pure(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `206` - // Estimated: `4706` - // Minimum execution time: 28_416_000 picoseconds. - Weight::from_parts(29_662_728, 4706) - // Standard Error: 1_851 - .saturating_add(Weight::from_parts(29_928, 0).saturating_mul(p.into())) + // Measured: `139` + // Estimated: `4254` + // Minimum execution time: 18_836_000 picoseconds. + Weight::from_parts(19_336_942, 4254) + // Standard Error: 1_099 + .saturating_add(Weight::from_parts(17_419, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Proxy::Proxies` (r:1 w:1) - /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) - /// The range of component `p` is `[0, 30]`. + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(789), added: 3264, mode: `MaxEncodedLen`) + /// The range of component `p` is `[0, 18]`. fn kill_pure(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `231 + p * (37 ±0)` - // Estimated: `4706` - // Minimum execution time: 25_505_000 picoseconds. - Weight::from_parts(26_780_627, 4706) - // Standard Error: 1_581 - .saturating_add(Weight::from_parts(33_085, 0).saturating_mul(p.into())) + // Measured: `156 + p * (37 ±0)` + // Estimated: `4254` + // Minimum execution time: 17_853_000 picoseconds. + Weight::from_parts(18_593_111, 4254) + // Standard Error: 990 + .saturating_add(Weight::from_parts(23_569, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Proxy::Proxies` (r:1 w:1) - /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(789), added: 3264, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(104), added: 2579, mode: `MaxEncodedLen`) /// Storage: `Proxy::Announcements` (r:1 w:1) - /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(2233), added: 4708, mode: `MaxEncodedLen`) + /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(5150), added: 7625, mode: `MaxEncodedLen`) fn poke_deposit() -> Weight { // Proof Size summary in bytes: - // Measured: `519` - // Estimated: `5698` - // Minimum execution time: 46_733_000 picoseconds. - Weight::from_parts(47_972_000, 5698) + // Measured: `412` + // Estimated: `8615` + // Minimum execution time: 31_739_000 picoseconds. + Weight::from_parts(32_491_000, 8615) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } + /// Storage: `Proxy::Proxies` (r:1 w:0) + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(789), added: 3264, mode: `MaxEncodedLen`) + /// Storage: `Proxy::RealPaysFee` (r:0 w:1) + /// Proof: `Proxy::RealPaysFee` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`) + /// The range of component `p` is `[1, 19]`. + fn set_real_pays_fee(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `119 + p * (37 ±0)` + // Estimated: `4254` + // Minimum execution time: 9_568_000 picoseconds. + Weight::from_parts(10_007_076, 4254) + // Standard Error: 854 + .saturating_add(Weight::from_parts(24_307, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } } // For backwards compatibility and tests. impl WeightInfo for () { /// Storage: `Proxy::Proxies` (r:1 w:0) - /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(789), added: 3264, mode: `MaxEncodedLen`) /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `TxPause::PausedCalls` (r:1 w:0) - /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) - /// The range of component `p` is `[1, 31]`. + /// Storage: `SubtensorModule::ColdkeySwapAnnouncements` (r:1 w:0) + /// Proof: `SubtensorModule::ColdkeySwapAnnouncements` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Proxy::LastCallResult` (r:0 w:1) + /// Proof: `Proxy::LastCallResult` (`max_values`: None, `max_size`: Some(47), added: 2522, mode: `MaxEncodedLen`) + /// The range of component `p` is `[1, 19]`. fn proxy(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `339 + p * (37 ±0)` - // Estimated: `4706` - // Minimum execution time: 23_353_000 picoseconds. - Weight::from_parts(25_084_085, 4706) - // Standard Error: 2_569 - .saturating_add(Weight::from_parts(33_574, 0).saturating_mul(p.into())) + // Measured: `625 + p * (37 ±0)` + // Estimated: `4254 + p * (37 ±0)` + // Minimum execution time: 19_346_000 picoseconds. + Weight::from_parts(19_857_012, 4254) + // Standard Error: 1_610 + .saturating_add(Weight::from_parts(42_156, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + .saturating_add(Weight::from_parts(0, 37).saturating_mul(p.into())) } /// Storage: `Proxy::Proxies` (r:1 w:0) - /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(789), added: 3264, mode: `MaxEncodedLen`) /// Storage: `Proxy::Announcements` (r:1 w:1) - /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(2233), added: 4708, mode: `MaxEncodedLen`) + /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(5150), added: 7625, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(104), added: 2579, mode: `MaxEncodedLen`) /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `TxPause::PausedCalls` (r:1 w:0) - /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) - /// The range of component `a` is `[0, 31]`. - /// The range of component `p` is `[1, 31]`. + /// Storage: `SubtensorModule::ColdkeySwapAnnouncements` (r:1 w:0) + /// Proof: `SubtensorModule::ColdkeySwapAnnouncements` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Proxy::LastCallResult` (r:0 w:1) + /// Proof: `Proxy::LastCallResult` (`max_values`: None, `max_size`: Some(47), added: 2522, mode: `MaxEncodedLen`) + /// The range of component `a` is `[0, 74]`. + /// The range of component `p` is `[1, 19]`. fn proxy_announced(a: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `666 + a * (68 ±0) + p * (37 ±0)` - // Estimated: `5698` - // Minimum execution time: 47_196_000 picoseconds. - Weight::from_parts(48_686_812, 5698) - // Standard Error: 3_711 - .saturating_add(Weight::from_parts(171_107, 0).saturating_mul(a.into())) - // Standard Error: 3_834 - .saturating_add(Weight::from_parts(34_523, 0).saturating_mul(p.into())) + // Measured: `882 + a * (68 ±0) + p * (37 ±0)` + // Estimated: `8615 + a * (68 ±0) + p * (37 ±0)` + // Minimum execution time: 37_952_000 picoseconds. + Weight::from_parts(37_943_137, 8615) + // Standard Error: 994 + .saturating_add(Weight::from_parts(155_667, 0).saturating_mul(a.into())) + // Standard Error: 3_984 + .saturating_add(Weight::from_parts(20_119, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(5_u64)) - .saturating_add(RocksDbWeight::get().writes(2_u64)) + .saturating_add(RocksDbWeight::get().writes(3_u64)) + .saturating_add(Weight::from_parts(0, 68).saturating_mul(a.into())) + .saturating_add(Weight::from_parts(0, 37).saturating_mul(p.into())) } /// Storage: `Proxy::Announcements` (r:1 w:1) - /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(2233), added: 4708, mode: `MaxEncodedLen`) + /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(5150), added: 7625, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// The range of component `a` is `[0, 31]`. - /// The range of component `p` is `[1, 31]`. + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(104), added: 2579, mode: `MaxEncodedLen`) + /// The range of component `a` is `[0, 74]`. + /// The range of component `p` is `[1, 19]`. fn remove_announcement(a: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `436 + a * (68 ±0)` - // Estimated: `5698` - // Minimum execution time: 29_341_000 picoseconds. - Weight::from_parts(30_320_504, 5698) - // Standard Error: 1_821 - .saturating_add(Weight::from_parts(158_572, 0).saturating_mul(a.into())) - // Standard Error: 1_881 - .saturating_add(Weight::from_parts(8_433, 0).saturating_mul(p.into())) + // Measured: `299 + a * (68 ±0)` + // Estimated: `8615` + // Minimum execution time: 18_064_000 picoseconds. + Weight::from_parts(18_046_024, 8615) + // Standard Error: 690 + .saturating_add(Weight::from_parts(130_637, 0).saturating_mul(a.into())) + // Standard Error: 2_766 + .saturating_add(Weight::from_parts(27_361, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `Proxy::Announcements` (r:1 w:1) - /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(2233), added: 4708, mode: `MaxEncodedLen`) + /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(5150), added: 7625, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// The range of component `a` is `[0, 31]`. - /// The range of component `p` is `[1, 31]`. + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(104), added: 2579, mode: `MaxEncodedLen`) + /// The range of component `a` is `[0, 74]`. + /// The range of component `p` is `[1, 19]`. fn reject_announcement(a: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `436 + a * (68 ±0)` - // Estimated: `5698` - // Minimum execution time: 28_422_000 picoseconds. - Weight::from_parts(29_754_384, 5698) - // Standard Error: 1_840 - .saturating_add(Weight::from_parts(176_827, 0).saturating_mul(a.into())) - // Standard Error: 1_901 - .saturating_add(Weight::from_parts(9_607, 0).saturating_mul(p.into())) + // Measured: `299 + a * (68 ±0)` + // Estimated: `8615` + // Minimum execution time: 17_964_000 picoseconds. + Weight::from_parts(18_288_524, 8615) + // Standard Error: 953 + .saturating_add(Weight::from_parts(136_907, 0).saturating_mul(a.into())) + // Standard Error: 3_819 + .saturating_add(Weight::from_parts(11_084, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `Proxy::Proxies` (r:1 w:0) - /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(789), added: 3264, mode: `MaxEncodedLen`) /// Storage: `Proxy::Announcements` (r:1 w:1) - /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(2233), added: 4708, mode: `MaxEncodedLen`) + /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(5150), added: 7625, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// The range of component `a` is `[0, 31]`. - /// The range of component `p` is `[1, 31]`. + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(104), added: 2579, mode: `MaxEncodedLen`) + /// The range of component `a` is `[0, 74]`. + /// The range of component `p` is `[1, 19]`. fn announce(a: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `453 + a * (68 ±0) + p * (37 ±0)` - // Estimated: `5698` - // Minimum execution time: 36_885_000 picoseconds. - Weight::from_parts(38_080_636, 5698) - // Standard Error: 2_642 - .saturating_add(Weight::from_parts(157_335, 0).saturating_mul(a.into())) - // Standard Error: 2_730 - .saturating_add(Weight::from_parts(28_872, 0).saturating_mul(p.into())) + // Measured: `308 + a * (68 ±0) + p * (37 ±0)` + // Estimated: `8615` + // Minimum execution time: 23_855_000 picoseconds. + Weight::from_parts(23_721_196, 8615) + // Standard Error: 813 + .saturating_add(Weight::from_parts(135_522, 0).saturating_mul(a.into())) + // Standard Error: 3_256 + .saturating_add(Weight::from_parts(42_377, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `Proxy::Proxies` (r:1 w:1) - /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) - /// The range of component `p` is `[1, 31]`. + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(789), added: 3264, mode: `MaxEncodedLen`) + /// The range of component `p` is `[1, 19]`. fn add_proxy(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `194 + p * (37 ±0)` - // Estimated: `4706` - // Minimum execution time: 27_016_000 picoseconds. - Weight::from_parts(28_296_216, 4706) - // Standard Error: 1_643 - .saturating_add(Weight::from_parts(50_271, 0).saturating_mul(p.into())) + // Measured: `119 + p * (37 ±0)` + // Estimated: `4254` + // Minimum execution time: 17_854_000 picoseconds. + Weight::from_parts(18_203_947, 4254) + // Standard Error: 1_051 + .saturating_add(Weight::from_parts(44_781, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Proxy::Proxies` (r:1 w:1) - /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) - /// The range of component `p` is `[1, 31]`. + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(789), added: 3264, mode: `MaxEncodedLen`) + /// Storage: `Proxy::RealPaysFee` (r:0 w:1) + /// Proof: `Proxy::RealPaysFee` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`) + /// The range of component `p` is `[1, 19]`. fn remove_proxy(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `194 + p * (37 ±0)` - // Estimated: `4706` - // Minimum execution time: 26_955_000 picoseconds. - Weight::from_parts(28_379_566, 4706) - // Standard Error: 1_547 - .saturating_add(Weight::from_parts(45_784, 0).saturating_mul(p.into())) + // Measured: `119 + p * (37 ±0)` + // Estimated: `4254` + // Minimum execution time: 18_815_000 picoseconds. + Weight::from_parts(19_464_499, 4254) + // Standard Error: 1_215 + .saturating_add(Weight::from_parts(44_540, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) - .saturating_add(RocksDbWeight::get().writes(1_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `Proxy::Proxies` (r:1 w:1) - /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) - /// The range of component `p` is `[1, 31]`. + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(789), added: 3264, mode: `MaxEncodedLen`) + /// The range of component `p` is `[1, 19]`. fn remove_proxies(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `194 + p * (37 ±0)` - // Estimated: `4706` - // Minimum execution time: 24_656_000 picoseconds. - Weight::from_parts(25_821_878, 4706) - // Standard Error: 2_300 - .saturating_add(Weight::from_parts(33_972, 0).saturating_mul(p.into())) + // Measured: `119 + p * (37 ±0)` + // Estimated: `4254` + // Minimum execution time: 18_245_000 picoseconds. + Weight::from_parts(18_987_977, 4254) + // Standard Error: 1_120 + .saturating_add(Weight::from_parts(18_728, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Proxy::Proxies` (r:1 w:1) - /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) - /// The range of component `p` is `[1, 31]`. + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(789), added: 3264, mode: `MaxEncodedLen`) + /// The range of component `p` is `[1, 19]`. fn create_pure(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `206` - // Estimated: `4706` - // Minimum execution time: 28_416_000 picoseconds. - Weight::from_parts(29_662_728, 4706) - // Standard Error: 1_851 - .saturating_add(Weight::from_parts(29_928, 0).saturating_mul(p.into())) + // Measured: `139` + // Estimated: `4254` + // Minimum execution time: 18_836_000 picoseconds. + Weight::from_parts(19_336_942, 4254) + // Standard Error: 1_099 + .saturating_add(Weight::from_parts(17_419, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Proxy::Proxies` (r:1 w:1) - /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) - /// The range of component `p` is `[0, 30]`. + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(789), added: 3264, mode: `MaxEncodedLen`) + /// The range of component `p` is `[0, 18]`. fn kill_pure(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `231 + p * (37 ±0)` - // Estimated: `4706` - // Minimum execution time: 25_505_000 picoseconds. - Weight::from_parts(26_780_627, 4706) - // Standard Error: 1_581 - .saturating_add(Weight::from_parts(33_085, 0).saturating_mul(p.into())) + // Measured: `156 + p * (37 ±0)` + // Estimated: `4254` + // Minimum execution time: 17_853_000 picoseconds. + Weight::from_parts(18_593_111, 4254) + // Standard Error: 990 + .saturating_add(Weight::from_parts(23_569, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Proxy::Proxies` (r:1 w:1) - /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(789), added: 3264, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(104), added: 2579, mode: `MaxEncodedLen`) /// Storage: `Proxy::Announcements` (r:1 w:1) - /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(2233), added: 4708, mode: `MaxEncodedLen`) + /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(5150), added: 7625, mode: `MaxEncodedLen`) fn poke_deposit() -> Weight { // Proof Size summary in bytes: - // Measured: `519` - // Estimated: `5698` - // Minimum execution time: 46_733_000 picoseconds. - Weight::from_parts(47_972_000, 5698) + // Measured: `412` + // Estimated: `8615` + // Minimum execution time: 31_739_000 picoseconds. + Weight::from_parts(32_491_000, 8615) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } -} + /// Storage: `Proxy::Proxies` (r:1 w:0) + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(789), added: 3264, mode: `MaxEncodedLen`) + /// Storage: `Proxy::RealPaysFee` (r:0 w:1) + /// Proof: `Proxy::RealPaysFee` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`) + /// The range of component `p` is `[1, 19]`. + fn set_real_pays_fee(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `119 + p * (37 ±0)` + // Estimated: `4254` + // Minimum execution time: 9_568_000 picoseconds. + Weight::from_parts(10_007_076, 4254) + // Standard Error: 854 + .saturating_add(Weight::from_parts(24_307, 0).saturating_mul(p.into())) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } +} \ No newline at end of file diff --git a/pallets/shield/src/benchmarking.rs b/pallets/shield/src/benchmarking.rs index 1414779314..e3890bae76 100644 --- a/pallets/shield/src/benchmarking.rs +++ b/pallets/shield/src/benchmarking.rs @@ -4,7 +4,7 @@ use frame_benchmarking::v2::*; use frame_support::{BoundedVec, pallet_prelude::ConstU32}; use frame_system::{RawOrigin, pallet_prelude::BlockNumberFor}; use sp_core::sr25519; -use sp_runtime::traits::Hash as HashT; +use sp_runtime::{AccountId32, traits::Hash as HashT}; use sp_std::vec; // /// Helper to build bounded bytes (public key) of a given length. @@ -40,6 +40,8 @@ fn bounded_ct(len: usize) -> BoundedVec> { ::RuntimeCall: From>, // Needed so we can seed Authorities from a dev sr25519 pubkey. ::AuthorityId: From, + ::AccountId: From + Into, + ::RuntimeOrigin: From> )] mod benches { use super::*; diff --git a/pallets/shield/src/lib.rs b/pallets/shield/src/lib.rs index eed0161f20..e0fc250058 100644 --- a/pallets/shield/src/lib.rs +++ b/pallets/shield/src/lib.rs @@ -86,9 +86,7 @@ pub mod pallet { #[pallet::config] pub trait Config: - frame_system::Config>> - + pallet_timestamp::Config - + pallet_aura::Config + frame_system::Config>> + pallet_aura::Config { type RuntimeCall: Parameter + sp_runtime::traits::Dispatchable< @@ -96,7 +94,7 @@ pub mod pallet { PostInfo = PostDispatchInfo, > + GetDispatchInfo; - type AuthorityOrigin: AuthorityOriginExt; + type AuthorityOrigin: AuthorityOriginExt; } #[pallet::pallet] @@ -246,13 +244,9 @@ pub mod pallet { /// Announce the ML‑KEM public key that will become `CurrentKey` in /// the following block. #[pallet::call_index(0)] - #[pallet::weight(( - Weight::from_parts(20_999_999_999, 0) - .saturating_add(T::DbWeight::get().reads(1_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)), - DispatchClass::Operational, - Pays::Yes - ))] + #[pallet::weight(Weight::from_parts(20_999_999_999, 0) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)))] #[allow(clippy::useless_conversion)] pub fn announce_next_key( origin: OriginFor, diff --git a/pallets/subtensor/Cargo.toml b/pallets/subtensor/Cargo.toml index 2e35a89d19..a6fadec1f4 100644 --- a/pallets/subtensor/Cargo.toml +++ b/pallets/subtensor/Cargo.toml @@ -55,11 +55,15 @@ sha2.workspace = true rand_chacha.workspace = true pallet-crowdloan.workspace = true pallet-subtensor-proxy.workspace = true +pallet-shield.workspace = true [dev-dependencies] pallet-balances = { workspace = true, features = ["std"] } pallet-scheduler.workspace = true pallet-subtensor-proxy.workspace = true +pallet-aura.workspace = true +pallet-timestamp.workspace = true +sp-consensus-aura.workspace = true subtensor-runtime-common.workspace = true pallet-subtensor-swap.workspace = true sp-version.workspace = true @@ -87,7 +91,10 @@ try-runtime = [ "pallet-crowdloan/try-runtime", "pallet-drand/try-runtime", "pallet-subtensor-proxy/try-runtime", - "pallet-subtensor-utility/try-runtime" + "pallet-subtensor-utility/try-runtime", + "pallet-shield/try-runtime", + "pallet-timestamp/try-runtime", + "pallet-aura/try-runtime", ] default = ["std"] std = [ @@ -115,6 +122,10 @@ std = [ "pallet-drand/std", "pallet-subtensor-proxy/std", "pallet-subtensor-swap/std", + "pallet-shield/std", + "pallet-timestamp/std", + "pallet-aura/std", + "sp-consensus-aura/std", "subtensor-swap-interface/std", "pallet-subtensor-utility/std", "safe-math/std", @@ -147,7 +158,9 @@ runtime-benchmarks = [ "pallet-drand/runtime-benchmarks", "pallet-subtensor-proxy/runtime-benchmarks", "pallet-subtensor-swap/runtime-benchmarks", - "pallet-subtensor-utility/runtime-benchmarks" + "pallet-subtensor-utility/runtime-benchmarks", + "pallet-shield/runtime-benchmarks", + "pallet-timestamp/runtime-benchmarks" ] pow-faucet = [] fast-runtime = ["subtensor-runtime-common/fast-runtime"] diff --git a/pallets/subtensor/src/benchmarks.rs b/pallets/subtensor/src/benchmarks.rs index f61c35aede..b9abd4e3ee 100644 --- a/pallets/subtensor/src/benchmarks.rs +++ b/pallets/subtensor/src/benchmarks.rs @@ -18,10 +18,29 @@ use sp_std::collections::btree_set::BTreeSet; use sp_std::vec; use subtensor_runtime_common::{AlphaCurrency, NetUid, TaoCurrency}; -#[frame_benchmarking::v2::benchmarks] +#[benchmarks( + where + T: pallet_balances::Config, + ::ExistentialDeposit: Get, +)] mod pallet_benchmarks { use super::*; + fn seed_swap_reserves(netuid: NetUid) { + let tao_reserve = TaoCurrency::from(150_000_000_000); + let alpha_in = AlphaCurrency::from(100_000_000_000); + set_reserves::(netuid, tao_reserve, alpha_in); + } + + fn set_reserves(netuid: NetUid, tao_reserve: TaoCurrency, alpha_in: AlphaCurrency) { + SubnetTAO::::insert(netuid, tao_reserve); + SubnetAlphaIn::::insert(netuid, alpha_in); + } + + fn benchmark_registration_burn() -> TaoCurrency { + TaoCurrency::from(1_000_000) + } + #[benchmark] fn register() { let netuid = NetUid::from(1); @@ -32,6 +51,7 @@ mod pallet_benchmarks { Subtensor::::init_new_network(netuid, tempo); Subtensor::::set_network_registration_allowed(netuid, true); Subtensor::::set_network_pow_registration_allowed(netuid, true); + Subtensor::::set_difficulty(netuid, 1); let block_number: u64 = Subtensor::::get_current_block_as_u64(); let (nonce, work): (u64, Vec) = @@ -62,6 +82,7 @@ mod pallet_benchmarks { Subtensor::::set_max_registrations_per_block(netuid, 4096); Subtensor::::set_target_registrations_per_interval(netuid, 4096); Subtensor::::set_commit_reveal_weights_enabled(netuid, false); + Subtensor::::set_weights_set_rate_limit(netuid, 0); let mut seed: u32 = 1; let mut dests = Vec::new(); @@ -73,7 +94,8 @@ mod pallet_benchmarks { let coldkey: T::AccountId = account("Test", 0, seed); seed += 1; - Subtensor::::set_burn(netuid, 1.into()); + Subtensor::::set_burn(netuid, benchmark_registration_burn()); + seed_swap_reserves::(netuid); let amount_to_be_staked: u64 = 1_000_000; Subtensor::::add_balance_to_coldkey_account(&coldkey, amount_to_be_staked); @@ -106,7 +128,7 @@ mod pallet_benchmarks { Subtensor::::init_new_network(netuid, tempo); SubtokenEnabled::::insert(netuid, true); - Subtensor::::set_burn(netuid, 1.into()); + Subtensor::::set_burn(netuid, benchmark_registration_burn()); Subtensor::::set_network_registration_allowed(netuid, true); Subtensor::::set_max_allowed_uids(netuid, 4096); @@ -116,6 +138,7 @@ mod pallet_benchmarks { let total_stake = TaoCurrency::from(1_000_000_000); let amount = TaoCurrency::from(60_000_000); + seed_swap_reserves::(netuid); Subtensor::::add_balance_to_coldkey_account(&coldkey, total_stake.into()); assert_ok!(Subtensor::::do_burned_registration( RawOrigin::Signed(coldkey.clone()).into(), @@ -150,6 +173,7 @@ mod pallet_benchmarks { let reg_fee = Subtensor::::get_burn(netuid); let deposit = reg_fee.saturating_mul(2.into()); + seed_swap_reserves::(netuid); Subtensor::::add_balance_to_coldkey_account(&caller, deposit.into()); assert_ok!(Subtensor::::do_burned_registration( @@ -188,6 +212,7 @@ mod pallet_benchmarks { let reg_fee = Subtensor::::get_burn(netuid); let deposit = reg_fee.saturating_mul(2.into()); + seed_swap_reserves::(netuid); Subtensor::::add_balance_to_coldkey_account(&caller, deposit.into()); assert_ok!(Subtensor::::do_burned_registration( @@ -217,7 +242,7 @@ mod pallet_benchmarks { Subtensor::::init_new_network(netuid, 1); SubtokenEnabled::::insert(netuid, true); - Subtensor::::set_burn(netuid, 1.into()); + Subtensor::::set_burn(netuid, benchmark_registration_burn()); let amount: u64 = 1_000_000; Subtensor::::add_balance_to_coldkey_account(&coldkey, amount); @@ -235,12 +260,18 @@ mod pallet_benchmarks { Subtensor::::init_new_network(netuid, 1); SubtokenEnabled::::insert(netuid, true); - Subtensor::::set_burn(netuid, 1.into()); + Subtensor::::set_burn(netuid, benchmark_registration_burn()); Subtensor::::set_network_registration_allowed(netuid, true); Subtensor::::set_max_allowed_uids(netuid, 4096); assert_eq!(Subtensor::::get_max_allowed_uids(netuid), 4096); + Subtensor::::init_new_network(NetUid::ROOT, 1); + Subtensor::::set_network_registration_allowed(NetUid::ROOT, true); + Subtensor::::set_network_pow_registration_allowed(NetUid::ROOT, true); + FirstEmissionBlockNumber::::insert(NetUid::ROOT, 1); + SubtokenEnabled::::insert(NetUid::ROOT, true); let amount: u64 = 100_000_000_000_000; + seed_swap_reserves::(netuid); Subtensor::::add_balance_to_coldkey_account(&coldkey, amount); assert_ok!(Subtensor::::do_burned_registration( @@ -288,6 +319,8 @@ mod pallet_benchmarks { Subtensor::::init_new_network(netuid, tempo); Subtensor::::set_network_pow_registration_allowed(netuid, true); + Subtensor::::set_weights_set_rate_limit(netuid, 0); + Subtensor::::set_difficulty(netuid, 1); let block_number: u64 = Subtensor::::get_current_block_as_u64(); let (nonce, work) = Subtensor::::create_work_for_block_number( @@ -326,6 +359,8 @@ mod pallet_benchmarks { Subtensor::::init_new_network(netuid, tempo); Subtensor::::set_network_registration_allowed(netuid, true); Subtensor::::set_network_pow_registration_allowed(netuid, true); + Subtensor::::set_weights_set_rate_limit(netuid, 0); + Subtensor::::set_difficulty(netuid, 1); let block_number: u64 = Subtensor::::get_current_block_as_u64(); let (nonce, work) = @@ -352,11 +387,19 @@ mod pallet_benchmarks { salt.clone(), version_key, )); - let _ = Subtensor::::commit_weights( + let commit_block = Subtensor::::get_current_block_as_u64(); + assert_ok!(Subtensor::::commit_weights( RawOrigin::Signed(hotkey.clone()).into(), netuid, commit_hash, - ); + )); + + let (first_reveal_block, _) = Subtensor::::get_reveal_blocks(netuid, commit_block); + let reveal_block: BlockNumberFor = first_reveal_block + .try_into() + .ok() + .expect("can't convert to block number"); + frame_system::Pallet::::set_block_number(reveal_block); #[extrinsic_call] _( @@ -369,17 +412,6 @@ mod pallet_benchmarks { ); } - #[benchmark] - fn schedule_swap_coldkey() { - let old_coldkey: T::AccountId = account("old_cold", 0, 1); - let new_coldkey: T::AccountId = account("new_cold", 1, 2); - let amount: u64 = 100_000_000_000_000; - Subtensor::::add_balance_to_coldkey_account(&old_coldkey, amount); - - #[extrinsic_call] - _(RawOrigin::Signed(old_coldkey.clone()), new_coldkey.clone()); - } - #[benchmark] fn sudo_set_tx_childkey_take_rate_limit() { let new_rate_limit: u64 = 100; @@ -401,6 +433,7 @@ mod pallet_benchmarks { let reg_fee = Subtensor::::get_burn(netuid); let deposit = reg_fee.saturating_mul(2.into()); + seed_swap_reserves::(netuid); Subtensor::::add_balance_to_coldkey_account(&coldkey, deposit.into()); assert_ok!(Subtensor::::do_burned_registration( @@ -419,17 +452,69 @@ mod pallet_benchmarks { } #[benchmark] - fn swap_coldkey() { + fn announce_coldkey_swap() { + let coldkey: T::AccountId = account("old_coldkey", 0, 0); + let new_coldkey: T::AccountId = account("new_coldkey", 0, 0); + let new_coldkey_hash: T::Hash = ::Hashing::hash_of(&new_coldkey); + + let ed = ::ExistentialDeposit::get(); + let swap_cost = Subtensor::::get_key_swap_cost(); + Subtensor::::add_balance_to_coldkey_account(&coldkey, swap_cost.to_u64() + ed); + + #[extrinsic_call] + _(RawOrigin::Signed(coldkey), new_coldkey_hash); + } + + #[benchmark] + fn swap_coldkey_announced() { let old_coldkey: T::AccountId = account("old_coldkey", 0, 0); let new_coldkey: T::AccountId = account("new_coldkey", 0, 0); + let new_coldkey_hash: T::Hash = ::Hashing::hash_of(&new_coldkey); let hotkey1: T::AccountId = account("hotkey1", 0, 0); + + let now = frame_system::Pallet::::block_number(); + let delay = ColdkeySwapAnnouncementDelay::::get(); + ColdkeySwapAnnouncements::::insert(&old_coldkey, (now, new_coldkey_hash)); + frame_system::Pallet::::set_block_number(now + delay + 1u32.into()); + let netuid = NetUid::from(1); + Subtensor::::init_new_network(netuid, 1); + Subtensor::::set_network_registration_allowed(netuid, true); + Subtensor::::set_network_pow_registration_allowed(netuid, true); + Subtensor::::set_difficulty(netuid, 1); + + let block_number = Subtensor::::get_current_block_as_u64(); + let (nonce, work) = + Subtensor::::create_work_for_block_number(netuid, block_number, 3, &hotkey1); + let _ = Subtensor::::register( + RawOrigin::Signed(old_coldkey.clone()).into(), + netuid, + block_number, + nonce, + work.clone(), + hotkey1.clone(), + old_coldkey.clone(), + ); + + #[extrinsic_call] + _(RawOrigin::Signed(old_coldkey), new_coldkey); + } + + #[benchmark] + fn swap_coldkey() { + let old_coldkey: T::AccountId = account("old_coldkey", 0, 0); + let new_coldkey: T::AccountId = account("new_coldkey", 0, 0); + let hotkey1: T::AccountId = account("hotkey1", 0, 0); + + let ed = ::ExistentialDeposit::get(); let swap_cost = Subtensor::::get_key_swap_cost(); - let free_balance_old = swap_cost + 12345.into(); + Subtensor::::add_balance_to_coldkey_account(&old_coldkey, swap_cost.to_u64() + ed); + let netuid = NetUid::from(1); Subtensor::::init_new_network(netuid, 1); Subtensor::::set_network_registration_allowed(netuid, true); Subtensor::::set_network_pow_registration_allowed(netuid, true); + Subtensor::::set_difficulty(netuid, 1); let block_number = Subtensor::::get_current_block_as_u64(); let (nonce, work) = @@ -444,19 +529,6 @@ mod pallet_benchmarks { old_coldkey.clone(), ); - Subtensor::::add_balance_to_coldkey_account(&old_coldkey, free_balance_old.into()); - let name: Vec = b"The fourth Coolest Identity".to_vec(); - let identity = ChainIdentityV2 { - name, - url: vec![], - github_repo: vec![], - image: vec![], - discord: vec![], - description: vec![], - additional: vec![], - }; - IdentitiesV2::::insert(&old_coldkey, identity); - #[extrinsic_call] _( RawOrigin::Root, @@ -466,6 +538,31 @@ mod pallet_benchmarks { ); } + #[benchmark] + fn dispute_coldkey_swap() { + let coldkey: T::AccountId = account("old_coldkey", 0, 0); + let coldkey_hash: T::Hash = ::Hashing::hash_of(&coldkey); + let now = frame_system::Pallet::::block_number(); + + ColdkeySwapAnnouncements::::insert(&coldkey, (now, coldkey_hash)); + + #[extrinsic_call] + _(RawOrigin::Signed(coldkey)); + } + + #[benchmark] + fn reset_coldkey_swap() { + let coldkey: T::AccountId = account("old_coldkey", 0, 0); + let coldkey_hash: T::Hash = ::Hashing::hash_of(&coldkey); + let now = frame_system::Pallet::::block_number(); + + ColdkeySwapAnnouncements::::insert(&coldkey, (now, coldkey_hash)); + ColdkeySwapDisputes::::insert(&coldkey, now); + + #[extrinsic_call] + _(RawOrigin::Root, coldkey); + } + #[benchmark] fn batch_reveal_weights() { let tempo: u16 = 0; @@ -480,6 +577,7 @@ mod pallet_benchmarks { Subtensor::::set_network_pow_registration_allowed(netuid, true); Subtensor::::set_commit_reveal_weights_enabled(netuid, true); Subtensor::::set_weights_set_rate_limit(netuid, 0); + Subtensor::::set_difficulty(netuid, 1); let block_number: u64 = Subtensor::::get_current_block_as_u64(); let (nonce, work) = @@ -501,6 +599,7 @@ mod pallet_benchmarks { let mut salts_list = Vec::new(); let mut version_keys = Vec::new(); + let commit_block = Subtensor::::get_current_block_as_u64(); for i in 0..num_commits { let uids = vec![0u16]; let values = vec![i as u16]; @@ -528,6 +627,13 @@ mod pallet_benchmarks { version_keys.push(version_key_i); } + let (first_reveal_block, _) = Subtensor::::get_reveal_blocks(netuid, commit_block); + let reveal_block: BlockNumberFor = first_reveal_block + .try_into() + .ok() + .expect("can't convert to block number"); + frame_system::Pallet::::set_block_number(reveal_block); + #[extrinsic_call] _( RawOrigin::Signed(hotkey.clone()), @@ -549,9 +655,10 @@ mod pallet_benchmarks { Subtensor::::init_new_network(netuid, 1); SubtokenEnabled::::insert(netuid, true); Subtensor::::set_network_registration_allowed(netuid, true); - Subtensor::::set_burn(netuid, 1.into()); + Subtensor::::set_burn(netuid, benchmark_registration_burn()); let amount_to_be_staked = 1_000_000_000; + seed_swap_reserves::(netuid); Subtensor::::add_balance_to_coldkey_account(&coldkey, amount_to_be_staked); assert_ok!(Subtensor::::do_burned_registration( RawOrigin::Signed(coldkey.clone()).into(), @@ -592,9 +699,10 @@ mod pallet_benchmarks { Subtensor::::init_new_network(netuid, 1); SubtokenEnabled::::insert(netuid, true); Subtensor::::set_network_registration_allowed(netuid, true); - Subtensor::::set_burn(netuid, 1.into()); + Subtensor::::set_burn(netuid, benchmark_registration_burn()); let amount_to_be_staked: u64 = 1_000_000_000; + seed_swap_reserves::(netuid); Subtensor::::add_balance_to_coldkey_account(&coldkey, amount_to_be_staked); assert_ok!(Subtensor::::do_burned_registration( RawOrigin::Signed(coldkey.clone()).into(), @@ -634,8 +742,9 @@ mod pallet_benchmarks { SubtokenEnabled::::insert(netuid, true); Subtensor::::set_network_registration_allowed(netuid, true); - Subtensor::::set_burn(netuid, 1.into()); + Subtensor::::set_burn(netuid, benchmark_registration_burn()); let amount_to_be_staked = 1_000_000; + seed_swap_reserves::(netuid); Subtensor::::add_balance_to_coldkey_account(&coldkey, amount_to_be_staked); SubnetOwner::::set(netuid, coldkey.clone()); @@ -667,7 +776,7 @@ mod pallet_benchmarks { Subtensor::::init_new_network(netuid, tempo); SubtokenEnabled::::insert(netuid, true); - Subtensor::::set_burn(netuid, 1.into()); + Subtensor::::set_burn(netuid, benchmark_registration_burn()); Subtensor::::set_network_registration_allowed(netuid, true); Subtensor::::set_max_allowed_uids(netuid, 4096); @@ -681,8 +790,7 @@ mod pallet_benchmarks { let tao_reserve = TaoCurrency::from(150_000_000_000); let alpha_in = AlphaCurrency::from(100_000_000_000); - SubnetTAO::::insert(netuid, tao_reserve); - SubnetAlphaIn::::insert(netuid, alpha_in); + set_reserves::(netuid, tao_reserve, alpha_in); assert_ok!(Subtensor::::do_burned_registration( RawOrigin::Signed(coldkey.clone()).into(), @@ -722,8 +830,7 @@ mod pallet_benchmarks { origin.clone() )); - SubnetTAO::::insert(netuid, deposit); - SubnetAlphaIn::::insert(netuid, AlphaCurrency::from(deposit.to_u64())); + set_reserves::(netuid, deposit, AlphaCurrency::from(deposit.to_u64())); TotalStake::::set(deposit); assert_ok!(Subtensor::::add_stake_limit( @@ -772,13 +879,12 @@ mod pallet_benchmarks { let coldkey: T::AccountId = account("Test", 0, seed); let hotkey: T::AccountId = account("Alice", 0, seed); - Subtensor::::set_burn(netuid, 1.into()); + Subtensor::::set_burn(netuid, benchmark_registration_burn()); let limit = TaoCurrency::from(1_000_000_000); let tao_reserve = TaoCurrency::from(150_000_000_000); let alpha_in = AlphaCurrency::from(100_000_000_000); - SubnetTAO::::insert(netuid, tao_reserve); - SubnetAlphaIn::::insert(netuid, alpha_in); + set_reserves::(netuid, tao_reserve, alpha_in); let wallet_bal = 1000000u32.into(); Subtensor::::add_balance_to_coldkey_account(&coldkey.clone(), wallet_bal); @@ -830,8 +936,7 @@ mod pallet_benchmarks { let tao_reserve = TaoCurrency::from(150_000_000_000); let alpha_in = AlphaCurrency::from(100_000_000_000); - SubnetTAO::::insert(netuid1, tao_reserve); - SubnetAlphaIn::::insert(netuid1, alpha_in); + set_reserves::(netuid1, tao_reserve, alpha_in); SubnetTAO::::insert(netuid2, tao_reserve); Subtensor::::increase_total_stake(1_000_000_000_000.into()); @@ -900,8 +1005,7 @@ mod pallet_benchmarks { hot.clone() )); - SubnetTAO::::insert(netuid, deposit); - SubnetAlphaIn::::insert(netuid, AlphaCurrency::from(deposit.to_u64())); + set_reserves::(netuid, deposit, AlphaCurrency::from(deposit.to_u64())); TotalStake::::set(deposit); assert_ok!(Subtensor::::add_stake_limit( @@ -955,10 +1059,8 @@ mod pallet_benchmarks { hot.clone() )); - SubnetTAO::::insert(netuid1, deposit); - SubnetAlphaIn::::insert(netuid1, AlphaCurrency::from(deposit.to_u64())); - SubnetTAO::::insert(netuid2, deposit); - SubnetAlphaIn::::insert(netuid2, AlphaCurrency::from(deposit.to_u64())); + set_reserves::(netuid1, deposit, AlphaCurrency::from(deposit.to_u64())); + set_reserves::(netuid2, deposit, AlphaCurrency::from(deposit.to_u64())); TotalStake::::set(deposit); assert_ok!(Subtensor::::add_stake_limit( @@ -997,6 +1099,7 @@ mod pallet_benchmarks { Subtensor::::init_new_network(netuid, 1); Subtensor::::set_network_pow_registration_allowed(netuid, true); SubtokenEnabled::::insert(netuid, true); + Subtensor::::set_weights_set_rate_limit(netuid, 0); let reg_fee = Subtensor::::get_burn(netuid); Subtensor::::add_balance_to_coldkey_account(&hotkey, reg_fee.to_u64().saturating_mul(2)); @@ -1060,9 +1163,11 @@ mod pallet_benchmarks { fn decrease_take() { let coldkey: T::AccountId = whitelisted_caller(); let hotkey: T::AccountId = account("Alice", 0, 1); - let take: u16 = 100; + let min_take = Subtensor::::get_min_delegate_take(); + let take: u16 = min_take; + let current_take = min_take.saturating_add(1); - Delegates::::insert(&hotkey, 200u16); + Delegates::::insert(&hotkey, current_take); Owner::::insert(&hotkey, &coldkey); #[extrinsic_call] @@ -1263,10 +1368,13 @@ mod pallet_benchmarks { let coldkey: T::AccountId = account("Test", 0, seed); let hotkey: T::AccountId = account("Alice", 0, seed); - Subtensor::::set_burn(netuid, 1.into()); + Subtensor::::set_burn(netuid, benchmark_registration_burn()); - SubnetTAO::::insert(netuid, TaoCurrency::from(150_000_000_000)); - SubnetAlphaIn::::insert(netuid, AlphaCurrency::from(100_000_000_000)); + set_reserves::( + netuid, + TaoCurrency::from(150_000_000_000), + AlphaCurrency::from(100_000_000_000), + ); Subtensor::::add_balance_to_coldkey_account(&coldkey.clone(), 1000000u32.into()); @@ -1311,13 +1419,12 @@ mod pallet_benchmarks { let coldkey: T::AccountId = account("Test", 0, seed); let hotkey: T::AccountId = account("Alice", 0, seed); - Subtensor::::set_burn(netuid, 1.into()); + Subtensor::::set_burn(netuid, benchmark_registration_burn()); let limit = TaoCurrency::from(1_000_000_000); let tao_reserve = TaoCurrency::from(150_000_000_000); let alpha_in = AlphaCurrency::from(100_000_000_000); - SubnetTAO::::insert(netuid, tao_reserve); - SubnetAlphaIn::::insert(netuid, alpha_in); + set_reserves::(netuid, tao_reserve, alpha_in); let wallet_bal = 1000000u32.into(); Subtensor::::add_balance_to_coldkey_account(&coldkey.clone(), wallet_bal); @@ -1666,4 +1773,46 @@ mod pallet_benchmarks { #[extrinsic_call] _(RawOrigin::Root, netuid, 100); } + + #[benchmark] + fn add_stake_burn() { + let netuid = NetUid::from(1); + let tempo: u16 = 1; + let seed: u32 = 1; + + Subtensor::::init_new_network(netuid, tempo); + SubtokenEnabled::::insert(netuid, true); + Subtensor::::set_burn(netuid, benchmark_registration_burn()); + Subtensor::::set_network_registration_allowed(netuid, true); + Subtensor::::set_max_allowed_uids(netuid, 4096); + + let coldkey: T::AccountId = account("Test", 0, seed); + let hotkey: T::AccountId = account("Alice", 0, seed); + + SubnetOwner::::set(netuid, coldkey.clone()); + + let balance_update = 900_000_000_000; + let limit = TaoCurrency::from(6_000_000_000); + let amount = TaoCurrency::from(44_000_000_000); + Subtensor::::add_balance_to_coldkey_account(&coldkey.clone(), balance_update); + + let tao_reserve = TaoCurrency::from(150_000_000_000); + let alpha_in = AlphaCurrency::from(100_000_000_000); + set_reserves::(netuid, tao_reserve, alpha_in); + + assert_ok!(Subtensor::::do_burned_registration( + RawOrigin::Signed(coldkey.clone()).into(), + netuid, + hotkey.clone() + )); + + #[extrinsic_call] + _( + RawOrigin::Signed(coldkey.clone()), + hotkey, + netuid, + amount, + Some(limit), + ); + } } diff --git a/pallets/subtensor/src/coinbase/block_emission.rs b/pallets/subtensor/src/coinbase/block_emission.rs index 064bab4d2a..3aefef927f 100644 --- a/pallets/subtensor/src/coinbase/block_emission.rs +++ b/pallets/subtensor/src/coinbase/block_emission.rs @@ -1,90 +1,10 @@ use super::*; use frame_support::traits::Get; use safe_math::*; -use substrate_fixed::{ - transcendental::log2, - types::{I96F32, U96F32}, -}; -use subtensor_runtime_common::{NetUid, TaoCurrency}; -use subtensor_swap_interface::SwapHandler; +use substrate_fixed::{transcendental::log2, types::I96F32}; +use subtensor_runtime_common::TaoCurrency; impl Pallet { - /// Calculates the dynamic TAO emission for a given subnet. - /// - /// This function determines the three terms tao_in, alpha_in, alpha_out - /// which are consecutively, 1) the amount of tao injected into the pool - /// 2) the amount of alpha injected into the pool, and 3) the amount of alpha - /// left to be distributed towards miners/validators/owners per block. - /// - /// # Arguments - /// * `netuid` - The unique identifier of the subnet. - /// * `tao_emission` - The amount of tao to distribute for this subnet. - /// * `alpha_block_emission` - The maximum alpha emission allowed for the block. - /// - /// # Returns - /// * `(u64, u64, u64)` - A tuple containing: - /// - `tao_in_emission`: The adjusted TAO emission always lower or equal to tao_emission - /// - `alpha_in_emission`: The adjusted alpha emission amount to be added into the pool. - /// - `alpha_out_emission`: The remaining alpha emission after adjustments to be distributed to miners/validators. - /// - /// The algorithm ensures that the pool injection of tao_in_emission, alpha_in_emission does not effect the pool price - /// It also ensures that the total amount of alpha_in_emission + alpha_out_emission sum to 2 * alpha_block_emission - /// It also ensures that 1 < alpha_out_emission < 2 * alpha_block_emission and 0 < alpha_in_emission < alpha_block_emission. - pub fn get_dynamic_tao_emission( - netuid: NetUid, - tao_emission: u64, - alpha_block_emission: u64, - ) -> (u64, u64, u64) { - // Init terms. - let mut tao_in_emission: U96F32 = U96F32::saturating_from_num(tao_emission); - let float_alpha_block_emission: U96F32 = U96F32::saturating_from_num(alpha_block_emission); - - // Get alpha price for subnet. - let alpha_price = T::SwapInterface::current_alpha_price(netuid.into()); - log::debug!("{netuid:?} - alpha_price: {alpha_price:?}"); - - // Get initial alpha_in - let mut alpha_in_emission: U96F32 = U96F32::saturating_from_num(tao_emission) - .checked_div(alpha_price) - .unwrap_or(float_alpha_block_emission); - - // Check if we are emitting too much alpha_in - if alpha_in_emission >= float_alpha_block_emission { - log::debug!( - "{netuid:?} - alpha_in_emission: {alpha_in_emission:?} > alpha_block_emission: {float_alpha_block_emission:?}" - ); - - // Scale down tao_in - // tao_in_emission = alpha_price.saturating_mul(float_alpha_block_emission); - - // Set to max alpha_block_emission - alpha_in_emission = float_alpha_block_emission; - } - - // Avoid rounding errors. - if tao_in_emission < U96F32::saturating_from_num(1) - || alpha_in_emission < U96F32::saturating_from_num(1) - { - alpha_in_emission = U96F32::saturating_from_num(0); - tao_in_emission = U96F32::saturating_from_num(0); - } - - // Set Alpha in emission. - let alpha_out_emission = float_alpha_block_emission; - - // Log results. - log::debug!("{netuid:?} - tao_in_emission: {tao_in_emission:?}"); - log::debug!("{netuid:?} - alpha_in_emission: {alpha_in_emission:?}"); - log::debug!("{netuid:?} - alpha_out_emission: {alpha_out_emission:?}"); - - // Return result. - ( - tao_in_emission.saturating_to_num::(), - alpha_in_emission.saturating_to_num::(), - alpha_out_emission.saturating_to_num::(), - ) - } - /// Calculates the block emission based on the total issuance. /// /// This function computes the block emission by applying a logarithmic function diff --git a/pallets/subtensor/src/epoch/run_epoch.rs b/pallets/subtensor/src/epoch/run_epoch.rs index f56b8a89a4..2290b49b8d 100644 --- a/pallets/subtensor/src/epoch/run_epoch.rs +++ b/pallets/subtensor/src/epoch/run_epoch.rs @@ -22,6 +22,7 @@ pub struct EpochTerms { pub validator_trust: u16, pub new_validator_permit: bool, pub bond: Vec<(u16, u16)>, + pub stake: AlphaCurrency, } pub struct EpochOutput(pub BTreeMap); @@ -988,6 +989,10 @@ impl Pallet { .iter() .map(|xi| fixed_proportion_to_u16(*xi)) .collect::>(); + let raw_stake: Vec = total_stake + .iter() + .map(|s| s.saturating_to_num::()) + .collect::>(); for (_hotkey, terms) in terms_map.iter_mut() { terms.dividend = cloned_dividends.get(terms.uid).copied().unwrap_or_default(); @@ -1012,6 +1017,7 @@ impl Pallet { .get(terms.uid) .copied() .unwrap_or_default(); + terms.stake = raw_stake.get(terms.uid).copied().unwrap_or_default().into(); let old_validator_permit = validator_permits .get(terms.uid) .copied() diff --git a/pallets/subtensor/src/extensions/mod.rs b/pallets/subtensor/src/extensions/mod.rs new file mode 100644 index 0000000000..9171c222be --- /dev/null +++ b/pallets/subtensor/src/extensions/mod.rs @@ -0,0 +1,3 @@ +mod subtensor; + +pub use subtensor::*; diff --git a/pallets/subtensor/src/transaction_extension.rs b/pallets/subtensor/src/extensions/subtensor.rs similarity index 69% rename from pallets/subtensor/src/transaction_extension.rs rename to pallets/subtensor/src/extensions/subtensor.rs index cf1d410ea9..950326c653 100644 --- a/pallets/subtensor/src/transaction_extension.rs +++ b/pallets/subtensor/src/extensions/subtensor.rs @@ -1,24 +1,27 @@ -use crate::{ - BalancesCall, Call, ColdkeySwapScheduled, Config, CustomTransactionError, Error, Pallet, - TransactionType, -}; +use crate::{BalancesCall, Call, Config, CustomTransactionError, Error, Pallet, TransactionType}; use codec::{Decode, DecodeWithMemTracking, Encode}; use frame_support::dispatch::{DispatchInfo, PostDispatchInfo}; -use frame_support::pallet_prelude::Weight; use frame_support::traits::IsSubType; use scale_info::TypeInfo; use sp_runtime::traits::{ AsSystemOriginSigner, DispatchInfoOf, Dispatchable, Implication, TransactionExtension, ValidateResult, }; -use sp_runtime::transaction_validity::{ - TransactionSource, TransactionValidity, TransactionValidityError, ValidTransaction, +use sp_runtime::transaction_validity::{InvalidTransaction, TransactionValidityError}; +use sp_runtime::{ + impl_tx_ext_default, + transaction_validity::{TransactionSource, TransactionValidity, ValidTransaction}, }; use sp_std::marker::PhantomData; use sp_std::vec::Vec; use subtensor_macros::freeze_struct; use subtensor_runtime_common::{NetUid, NetUidStorageIndex}; +const ADD_STAKE_BURN_PRIORITY_BOOST: u64 = 100; + +type CallOf = ::RuntimeCall; +type OriginOf = ::RuntimeOrigin; + #[freeze_struct("2e02eb32e5cb25d3")] #[derive(Default, Encode, Decode, DecodeWithMemTracking, Clone, Eq, PartialEq, TypeInfo)] pub struct SubtensorTransactionExtension(pub PhantomData); @@ -31,9 +34,7 @@ impl sp_std::fmt::Debug for SubtensorTransac impl SubtensorTransactionExtension where - ::RuntimeCall: - Dispatchable, - ::RuntimeCall: IsSubType>, + CallOf: Dispatchable + IsSubType>, { pub fn new() -> Self { Self(Default::default()) @@ -52,30 +53,29 @@ where pub fn result_to_validity(result: Result<(), Error>, priority: u64) -> TransactionValidity { if let Err(err) = result { Err(match err { - Error::::AmountTooLow => CustomTransactionError::StakeAmountTooLow.into(), - Error::::SubnetNotExists => CustomTransactionError::SubnetNotExists.into(), - Error::::NotEnoughBalanceToStake => CustomTransactionError::BalanceTooLow.into(), + Error::::AmountTooLow => CustomTransactionError::StakeAmountTooLow, + Error::::SubnetNotExists => CustomTransactionError::SubnetNotExists, + Error::::NotEnoughBalanceToStake => CustomTransactionError::BalanceTooLow, Error::::HotKeyAccountNotExists => { - CustomTransactionError::HotkeyAccountDoesntExist.into() + CustomTransactionError::HotkeyAccountDoesntExist } Error::::NotEnoughStakeToWithdraw => { - CustomTransactionError::NotEnoughStakeToWithdraw.into() + CustomTransactionError::NotEnoughStakeToWithdraw } - Error::::InsufficientLiquidity => { - CustomTransactionError::InsufficientLiquidity.into() - } - Error::::SlippageTooHigh => CustomTransactionError::SlippageTooHigh.into(), - Error::::TransferDisallowed => CustomTransactionError::TransferDisallowed.into(), + Error::::InsufficientLiquidity => CustomTransactionError::InsufficientLiquidity, + Error::::SlippageTooHigh => CustomTransactionError::SlippageTooHigh, + Error::::TransferDisallowed => CustomTransactionError::TransferDisallowed, Error::::HotKeyNotRegisteredInNetwork => { - CustomTransactionError::HotKeyNotRegisteredInNetwork.into() + CustomTransactionError::HotKeyNotRegisteredInNetwork } - Error::::InvalidIpAddress => CustomTransactionError::InvalidIpAddress.into(), + Error::::InvalidIpAddress => CustomTransactionError::InvalidIpAddress, Error::::ServingRateLimitExceeded => { - CustomTransactionError::ServingRateLimitExceeded.into() + CustomTransactionError::ServingRateLimitExceeded } - Error::::InvalidPort => CustomTransactionError::InvalidPort.into(), - _ => CustomTransactionError::BadRequest.into(), - }) + Error::::InvalidPort => CustomTransactionError::InvalidPort, + _ => CustomTransactionError::BadRequest, + } + .into()) } else { Ok(ValidTransaction { priority, @@ -85,56 +85,39 @@ where } } -impl - TransactionExtension<::RuntimeCall> - for SubtensorTransactionExtension +impl TransactionExtension> for SubtensorTransactionExtension where - ::RuntimeCall: - Dispatchable, - ::RuntimeOrigin: AsSystemOriginSigner + Clone, - ::RuntimeCall: IsSubType>, - ::RuntimeCall: IsSubType>, + T: Config + Send + Sync + TypeInfo + pallet_balances::Config, + CallOf: Dispatchable + + IsSubType> + + IsSubType>, + OriginOf: AsSystemOriginSigner + Clone, { const IDENTIFIER: &'static str = "SubtensorTransactionExtension"; type Implicit = (); - type Val = Option; + type Val = (); type Pre = (); - fn weight(&self, _call: &::RuntimeCall) -> Weight { - // TODO: benchmark transaction extension - Weight::zero() - } - fn validate( &self, - origin: ::RuntimeOrigin, - call: &::RuntimeCall, - _info: &DispatchInfoOf<::RuntimeCall>, + origin: OriginOf, + call: &CallOf, + _info: &DispatchInfoOf>, _len: usize, _self_implicit: Self::Implicit, _inherited_implication: &impl Implication, _source: TransactionSource, - ) -> ValidateResult::RuntimeCall> { + ) -> ValidateResult> { // Ensure the transaction is signed, else we just skip the extension. let Some(who) = origin.as_system_origin_signer() else { - return Ok((Default::default(), None, origin)); + return Ok((Default::default(), (), origin)); }; - // Verify ColdkeySwapScheduled map for coldkey - match call.is_sub_type() { - // Whitelist - Some(Call::schedule_swap_coldkey { .. }) => {} - _ => { - if ColdkeySwapScheduled::::contains_key(who) { - return Err(CustomTransactionError::ColdkeyInSwapSchedule.into()); - } - } - } match call.is_sub_type() { Some(Call::commit_weights { netuid, .. }) => { if Self::check_weights_min_stake(who, *netuid) { - Ok((Default::default(), Some(who.clone()), origin)) + Ok((Default::default(), (), origin)) } else { Err(CustomTransactionError::StakeAmountTooLow.into()) } @@ -158,7 +141,7 @@ where match Pallet::::find_commit_block_via_hash(provided_hash) { Some(commit_block) => { if Pallet::::is_reveal_block_range(*netuid, commit_block) { - Ok((Default::default(), Some(who.clone()), origin)) + Ok((Default::default(), (), origin)) } else { Err(CustomTransactionError::CommitBlockNotInRevealRange.into()) } @@ -203,7 +186,7 @@ where if provided_hashes.len() == batch_reveal_block.len() { if Pallet::::is_batch_reveal_block_range(*netuid, batch_reveal_block) { - Ok((Default::default(), Some(who.clone()), origin)) + Ok((Default::default(), (), origin)) } else { Err(CustomTransactionError::CommitBlockNotInRevealRange.into()) } @@ -219,7 +202,7 @@ where } Some(Call::set_weights { netuid, .. }) => { if Self::check_weights_min_stake(who, *netuid) { - Ok((Default::default(), Some(who.clone()), origin)) + Ok((Default::default(), (), origin)) } else { Err(CustomTransactionError::StakeAmountTooLow.into()) } @@ -233,7 +216,7 @@ where if *reveal_round < pallet_drand::LastStoredRound::::get() { return Err(CustomTransactionError::InvalidRevealRound.into()); } - Ok((Default::default(), Some(who.clone()), origin)) + Ok((Default::default(), (), origin)) } else { Err(CustomTransactionError::StakeAmountTooLow.into()) } @@ -249,7 +232,7 @@ where return Err(CustomTransactionError::RateLimitExceeded.into()); } - Ok((Default::default(), Some(who.clone()), origin)) + Ok((Default::default(), (), origin)) } Some(Call::serve_axon { netuid, @@ -276,41 +259,32 @@ where ), 0u64, ) - .map(|validity| (validity, Some(who.clone()), origin.clone())) + .map(|validity| (validity, (), origin.clone())) } Some(Call::register_network { .. }) => { if !TransactionType::RegisterNetwork.passes_rate_limit::(who) { return Err(CustomTransactionError::RateLimitExceeded.into()); } - Ok((Default::default(), Some(who.clone()), origin)) + Ok((Default::default(), (), origin)) } Some(Call::associate_evm_key { netuid, .. }) => { - match Pallet::::get_uid_for_net_and_hotkey(*netuid, who) { - Ok(uid) => { - match Pallet::::ensure_evm_key_associate_rate_limit(*netuid, uid) { - Ok(_) => Ok((Default::default(), Some(who.clone()), origin)), - Err(_) => { - Err(CustomTransactionError::EvmKeyAssociateRateLimitExceeded.into()) - } - } - } - Err(_) => Err(CustomTransactionError::UidNotFound.into()), - } + let uid = Pallet::::get_uid_for_net_and_hotkey(*netuid, who) + .map_err(|_| CustomTransactionError::UidNotFound)?; + Pallet::::ensure_evm_key_associate_rate_limit(*netuid, uid) + .map_err(|_| CustomTransactionError::EvmKeyAssociateRateLimitExceeded)?; + Ok((Default::default(), (), origin)) + } + Some(Call::add_stake_burn { netuid, .. }) => { + Pallet::::ensure_subnet_owner(origin.clone(), *netuid).map_err(|_| { + TransactionValidityError::Invalid(InvalidTransaction::BadSigner) + })?; + + Ok((Self::validity_ok(ADD_STAKE_BURN_PRIORITY_BOOST), (), origin)) } - _ => Ok((Default::default(), Some(who.clone()), origin)), + _ => Ok((Default::default(), (), origin)), } } - // NOTE: Add later when we put in a pre and post dispatch step. - fn prepare( - self, - _val: Self::Val, - _origin: &::RuntimeOrigin, - _call: &::RuntimeCall, - _info: &DispatchInfoOf<::RuntimeCall>, - _len: usize, - ) -> Result { - Ok(()) - } + impl_tx_ext_default!(CallOf; weight prepare); } diff --git a/pallets/subtensor/src/guards/check_coldkey_swap.rs b/pallets/subtensor/src/guards/check_coldkey_swap.rs new file mode 100644 index 0000000000..95a640b9dc --- /dev/null +++ b/pallets/subtensor/src/guards/check_coldkey_swap.rs @@ -0,0 +1,312 @@ +use crate::{Call, ColdkeySwapAnnouncements, ColdkeySwapDisputes, Config, Error}; +use frame_support::dispatch::{ + DispatchGuard, DispatchInfo, DispatchResultWithPostInfo, PostDispatchInfo, +}; +use frame_support::traits::{IsSubType, OriginTrait}; +use sp_runtime::traits::Dispatchable; +use sp_std::marker::PhantomData; + +type CallOf = ::RuntimeCall; +type DispatchableOriginOf = as Dispatchable>::RuntimeOrigin; + +/// Dispatch guard that blocks most calls when a coldkey swap is active. +/// +/// When a coldkey swap has been announced for the signing account: +/// - If the swap is disputed, ALL calls are blocked. +/// - Otherwise, only swap-related calls and MEV-protected calls (`submit_encrypted`) +/// are allowed through. +/// +/// Root origin bypasses this guard entirely (handled by `check_dispatch_guard`). +/// Non-signed origins pass through. +/// +/// Because this is a `DispatchGuard` (not a `TransactionExtension`), it fires at every +/// `call.dispatch(origin)` site — including inside the proxy pallet's `do_proxy()`. +/// This means nested proxies of any depth are handled automatically with the real +/// resolved origin. +pub struct CheckColdkeySwap(PhantomData); + +impl DispatchGuard<::RuntimeCall> for CheckColdkeySwap +where + T: Config + pallet_shield::Config, + ::RuntimeCall: Dispatchable + + IsSubType> + + IsSubType>, + DispatchableOriginOf: OriginTrait, +{ + fn check(origin: &DispatchableOriginOf, call: &CallOf) -> DispatchResultWithPostInfo { + // Only care about signed origins. + // Root is already bypassed by check_dispatch_guard() before we get here. + let Some(who) = origin.as_signer() else { + return Ok(().into()); + }; + + if ColdkeySwapAnnouncements::::contains_key(who) { + if ColdkeySwapDisputes::::contains_key(who) { + return Err(Error::::ColdkeySwapDisputed.into()); + } + + let is_allowed_direct = matches!( + call.is_sub_type(), + Some( + Call::announce_coldkey_swap { .. } + | Call::swap_coldkey_announced { .. } + | Call::dispute_coldkey_swap { .. } + ) + ); + + let is_mev_protected = matches!( + IsSubType::>::is_sub_type(call), + Some(pallet_shield::Call::submit_encrypted { .. }) + ); + + if !is_allowed_direct && !is_mev_protected { + return Err(Error::::ColdkeySwapAnnounced.into()); + } + } + + Ok(().into()) + } +} + +#[cfg(test)] +#[allow(clippy::expect_used, clippy::unwrap_used)] +mod tests { + use crate::{ColdkeySwapAnnouncements, ColdkeySwapDisputes, Error, tests::mock::*}; + use frame_support::{BoundedVec, assert_ok}; + use frame_system::Call as SystemCall; + use pallet_subtensor_proxy::Call as ProxyCall; + use sp_core::U256; + use sp_runtime::traits::{Dispatchable, Hash}; + use subtensor_runtime_common::ProxyType; + + type HashingOf = ::Hashing; + + /// Calls that should be blocked when a coldkey swap is active. + fn forbidden_calls() -> Vec { + vec![ + RuntimeCall::System(SystemCall::remark { remark: vec![] }), + RuntimeCall::SubtensorModule(crate::Call::add_stake { + hotkey: U256::from(1), + netuid: 1u16.into(), + amount_staked: 1_000u64.into(), + }), + RuntimeCall::SubtensorModule(crate::Call::remove_stake { + hotkey: U256::from(1), + netuid: 1u16.into(), + amount_unstaked: 1_000u64.into(), + }), + RuntimeCall::SubtensorModule(crate::Call::set_weights { + netuid: 1u16.into(), + dests: vec![], + weights: vec![], + version_key: 0, + }), + RuntimeCall::SubtensorModule(crate::Call::register_network { + hotkey: U256::from(1), + }), + ] + } + + /// Calls that should be allowed through the guard during an active (undisputed) swap. + fn authorized_calls() -> Vec { + vec![ + RuntimeCall::SubtensorModule(crate::Call::announce_coldkey_swap { + new_coldkey_hash: HashingOf::::hash_of(&U256::from(99)), + }), + RuntimeCall::SubtensorModule(crate::Call::swap_coldkey_announced { + new_coldkey: U256::from(42), + }), + RuntimeCall::SubtensorModule(crate::Call::dispute_coldkey_swap {}), + RuntimeCall::Shield(pallet_shield::Call::submit_encrypted { + commitment: HashingOf::::hash_of(&U256::from(42)), + ciphertext: BoundedVec::truncate_from(vec![1, 2, 3, 4]), + }), + ] + } + + fn setup_swap_announced(who: &U256) { + let now = System::block_number(); + let hash = HashingOf::::hash_of(&U256::from(42)); + ColdkeySwapAnnouncements::::insert(who, (now, hash)); + } + + fn setup_swap_disputed(who: &U256) { + setup_swap_announced(who); + ColdkeySwapDisputes::::insert(who, System::block_number()); + } + + fn remark_call() -> RuntimeCall { + RuntimeCall::System(SystemCall::remark { remark: vec![] }) + } + + #[test] + fn no_active_swap_allows_calls() { + new_test_ext(1).execute_with(|| { + let who = U256::from(1); + assert_ok!(remark_call().dispatch(RuntimeOrigin::signed(who))); + }); + } + + #[test] + fn none_bypasses_guard() { + new_test_ext(1).execute_with(|| { + let who = U256::from(1); + setup_swap_disputed(&who); + + assert_ok!(remark_call().dispatch(RuntimeOrigin::none())); + }); + } + + #[test] + fn root_bypasses_guard() { + new_test_ext(1).execute_with(|| { + let who = U256::from(1); + setup_swap_disputed(&who); + + assert_ok!(remark_call().dispatch(RuntimeOrigin::root())); + }); + } + + #[test] + fn active_swap_blocks_forbidden_calls() { + new_test_ext(1).execute_with(|| { + let who = U256::from(1); + setup_swap_announced(&who); + + for call in forbidden_calls() { + assert_eq!( + call.dispatch(RuntimeOrigin::signed(who)).unwrap_err().error, + Error::::ColdkeySwapAnnounced.into() + ); + } + }); + } + + #[test] + fn active_swap_allows_authorized_calls() { + new_test_ext(1).execute_with(|| { + let who = U256::from(1); + setup_swap_announced(&who); + + for call in authorized_calls() { + if let Err(err) = call.dispatch(RuntimeOrigin::signed(who)) { + assert_ne!( + err.error, + Error::::ColdkeySwapAnnounced.into(), + "Authorized call should not be blocked by the guard" + ); + } + } + }); + } + + #[test] + fn disputed_swap_blocks_all_calls() { + new_test_ext(1).execute_with(|| { + let who = U256::from(1); + setup_swap_disputed(&who); + + // Both forbidden and authorized calls should be blocked during dispute + let all_calls = forbidden_calls() + .into_iter() + .chain(authorized_calls()) + .collect::>(); + + for call in all_calls { + assert_eq!( + call.dispatch(RuntimeOrigin::signed(who)).unwrap_err().error, + Error::::ColdkeySwapDisputed.into() + ); + } + }); + } + + #[test] + fn proxied_forbidden_call_blocked() { + new_test_ext(1).execute_with(|| { + let real = U256::from(1); + let delegate = U256::from(2); + let now = System::block_number(); + let hash = HashingOf::::hash_of(&U256::from(42)); + ColdkeySwapAnnouncements::::insert(real, (now, hash)); + + // Give delegate enough balance for proxy deposit + SubtensorModule::add_balance_to_coldkey_account(&real, 1_000_000_000); + SubtensorModule::add_balance_to_coldkey_account(&delegate, 1_000_000_000); + + // Register proxy: delegate can act on behalf of real + assert_ok!(Proxy::add_proxy( + RuntimeOrigin::signed(real), + delegate, + ProxyType::Any, + 0 + )); + + // Dispatch a proxy call as delegate + let proxy_call = RuntimeCall::Proxy(ProxyCall::proxy { + real, + force_proxy_type: None, + call: Box::new(remark_call()), + }); + + // The outer proxy call itself succeeds + assert_ok!(proxy_call.dispatch(RuntimeOrigin::signed(delegate))); + + // The inner call was blocked — check via LastCallResult storage. + assert_eq!( + pallet_subtensor_proxy::LastCallResult::::get(real), + Some(Err(Error::::ColdkeySwapAnnounced.into())) + ); + }); + } + + #[test] + fn nested_proxy_blocked() { + new_test_ext(1).execute_with(|| { + let real = U256::from(1); + let delegate1 = U256::from(2); + let delegate2 = U256::from(3); + let now = System::block_number(); + let hash = HashingOf::::hash_of(&U256::from(42)); + ColdkeySwapAnnouncements::::insert(real, (now, hash)); + + SubtensorModule::add_balance_to_coldkey_account(&real, 1_000_000_000); + SubtensorModule::add_balance_to_coldkey_account(&delegate1, 1_000_000_000); + SubtensorModule::add_balance_to_coldkey_account(&delegate2, 1_000_000_000); + + // delegate1 can proxy for real, delegate2 can proxy for delegate1 + assert_ok!(Proxy::add_proxy( + RuntimeOrigin::signed(real), + delegate1, + ProxyType::Any, + 0 + )); + assert_ok!(Proxy::add_proxy( + RuntimeOrigin::signed(delegate1), + delegate2, + ProxyType::Any, + 0 + )); + + // Nested: delegate2 -> delegate1 -> proxy(real, remark) + let inner_proxy = RuntimeCall::Proxy(ProxyCall::proxy { + real, + force_proxy_type: None, + call: Box::new(remark_call()), + }); + let outer_proxy = RuntimeCall::Proxy(ProxyCall::proxy { + real: delegate1, + force_proxy_type: None, + call: Box::new(inner_proxy), + }); + + assert_ok!(outer_proxy.dispatch(RuntimeOrigin::signed(delegate2))); + + // The innermost call (remark as real) was blocked. + assert_eq!( + pallet_subtensor_proxy::LastCallResult::::get(real), + Some(Err(Error::::ColdkeySwapAnnounced.into())) + ); + }); + } +} diff --git a/pallets/subtensor/src/guards/mod.rs b/pallets/subtensor/src/guards/mod.rs new file mode 100644 index 0000000000..44fba0c50f --- /dev/null +++ b/pallets/subtensor/src/guards/mod.rs @@ -0,0 +1,3 @@ +mod check_coldkey_swap; + +pub use check_coldkey_swap::*; diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index 6ae43ac384..c0000d2662 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -1,6 +1,7 @@ #![cfg_attr(not(feature = "std"), no_std)] #![recursion_limit = "512"] #![allow(clippy::too_many_arguments)] +#![allow(clippy::zero_prefixed_literal)] // Edit this file to define custom logic or remove it if it is not needed. // Learn more about FRAME and the core library of Substrate FRAME pallets: // @@ -35,6 +36,8 @@ mod benchmarks; // ========================= pub mod coinbase; pub mod epoch; +pub mod extensions; +pub mod guards; pub mod macros; pub mod migrations; pub mod rpc_info; @@ -45,9 +48,11 @@ pub mod utils; use crate::utils::rate_limiting::{Hyperparameter, TransactionType}; use macros::{config, dispatches, errors, events, genesis, hooks}; +pub use extensions::*; +pub use guards::*; + #[cfg(test)] -mod tests; -pub mod transaction_extension; +pub(crate) mod tests; // apparently this is stabilized since rust 1.36 extern crate alloc; @@ -944,16 +949,16 @@ pub mod pallet { (45875, 58982) } - /// Default value for coldkey swap schedule duration + /// Default value for coldkey swap announcement delay. #[pallet::type_value] - pub fn DefaultColdkeySwapScheduleDuration() -> BlockNumberFor { - T::InitialColdkeySwapScheduleDuration::get() + pub fn DefaultColdkeySwapAnnouncementDelay() -> BlockNumberFor { + T::InitialColdkeySwapAnnouncementDelay::get() } - /// Default value for coldkey swap reschedule duration + /// Default value for coldkey swap reannouncement delay. #[pallet::type_value] - pub fn DefaultColdkeySwapRescheduleDuration() -> BlockNumberFor { - T::InitialColdkeySwapRescheduleDuration::get() + pub fn DefaultColdkeySwapReannouncementDelay() -> BlockNumberFor { + T::InitialColdkeySwapReannouncementDelay::get() } /// Default value for applying pending items (e.g. childkeys). @@ -1018,15 +1023,6 @@ pub mod pallet { 360 } - /// Default value for coldkey swap scheduled - #[pallet::type_value] - pub fn DefaultColdkeySwapScheduled() -> (BlockNumberFor, T::AccountId) { - #[allow(clippy::expect_used)] - let default_account = T::AccountId::decode(&mut TrailingZeroInput::zeroes()) - .expect("trailing zeroes always produce a valid account ID; qed"); - (BlockNumberFor::::from(0_u32), default_account) - } - /// Default value for setting subnet owner hotkey rate limit #[pallet::type_value] pub fn DefaultSetSNOwnerHotkeyRateLimit() -> u64 { @@ -1083,16 +1079,6 @@ pub mod pallet { pub type OwnerHyperparamRateLimit = StorageValue<_, u16, ValueQuery, DefaultOwnerHyperparamRateLimit>; - /// Duration of coldkey swap schedule before execution - #[pallet::storage] - pub type ColdkeySwapScheduleDuration = - StorageValue<_, BlockNumberFor, ValueQuery, DefaultColdkeySwapScheduleDuration>; - - /// Duration of coldkey swap reschedule before execution - #[pallet::storage] - pub type ColdkeySwapRescheduleDuration = - StorageValue<_, BlockNumberFor, ValueQuery, DefaultColdkeySwapRescheduleDuration>; - /// Duration of dissolve network schedule before execution #[pallet::storage] pub type DissolveNetworkScheduleDuration = @@ -1241,7 +1227,7 @@ pub mod pallet { /// ================== /// ==== Coinbase ==== /// ================== - /// --- ITEM ( global_block_emission ) + /// --- ITEM ( global_block_emission ) #[pallet::storage] pub type BlockEmission = StorageValue<_, u64, ValueQuery, DefaultBlockEmission>; @@ -1281,7 +1267,7 @@ pub mod pallet { #[pallet::storage] pub type TotalStake = StorageValue<_, TaoCurrency, ValueQuery, DefaultZeroTao>; - /// --- ITEM ( moving_alpha ) -- subnet moving alpha. + /// --- ITEM ( moving_alpha ) -- subnet moving alpha. #[pallet::storage] pub type SubnetMovingAlpha = StorageValue<_, I96F32, ValueQuery, DefaultMovingAlpha>; @@ -1374,16 +1360,27 @@ pub mod pallet { ValueQuery, >; - /// --- DMAP ( cold ) --> (block_expected, new_coldkey), Maps coldkey to the block to swap at and new coldkey. + /// The delay after an announcement before a coldkey swap can be performed. #[pallet::storage] - pub type ColdkeySwapScheduled = StorageMap< - _, - Blake2_128Concat, - T::AccountId, - (BlockNumberFor, T::AccountId), - ValueQuery, - DefaultColdkeySwapScheduled, - >; + pub type ColdkeySwapAnnouncementDelay = + StorageValue<_, BlockNumberFor, ValueQuery, DefaultColdkeySwapAnnouncementDelay>; + + /// The delay after the initial delay has passed before a new announcement can be made. + #[pallet::storage] + pub type ColdkeySwapReannouncementDelay = + StorageValue<_, BlockNumberFor, ValueQuery, DefaultColdkeySwapReannouncementDelay>; + + /// A map of the coldkey swap announcements from a coldkey + /// to the block number the coldkey swap can be performed. + #[pallet::storage] + pub type ColdkeySwapAnnouncements = + StorageMap<_, Twox64Concat, T::AccountId, (BlockNumberFor, T::Hash), OptionQuery>; + + /// A map of the coldkey swap disputes from a coldkey to the + /// block number the coldkey swap was disputed. + #[pallet::storage] + pub type ColdkeySwapDisputes = + StorageMap<_, Twox64Concat, T::AccountId, BlockNumberFor, OptionQuery>; /// --- DMAP ( hot, netuid ) --> alpha | Returns the total amount of alpha a hotkey owns. #[pallet::storage] @@ -1894,8 +1891,52 @@ pub mod pallet { pub type SubtokenEnabled = StorageMap<_, Identity, NetUid, bool, ValueQuery, DefaultFalse>; - /// Default value for burn keys limit + // ======================================= + // ==== VotingPower Storage ==== + // ======================================= + #[pallet::type_value] + /// Default VotingPower EMA alpha value (0.1 represented as u64 with 18 decimals) + /// alpha = 0.1 means slow response, 10% weight to new values per epoch + pub fn DefaultVotingPowerEmaAlpha() -> u64 { + 0_003_570_000_000_000_000 // 0.00357 * 10^18 = 2 weeks e-folding (time-constant) @ 361 + // blocks per tempo + // After 2 weeks -> EMA reaches 63.2% of a step change + // After ~4 weeks -> 86.5% + // After ~6 weeks -> 95% + } + + #[pallet::storage] + /// --- DMAP ( netuid, hotkey ) --> voting_power | EMA of stake for voting + /// This tracks stake EMA updated every epoch when VotingPowerTrackingEnabled is true. + /// Used by smart contracts to determine validator voting power for subnet governance. + pub type VotingPower = + StorageDoubleMap<_, Identity, NetUid, Blake2_128Concat, T::AccountId, u64, ValueQuery>; + + #[pallet::storage] + /// --- MAP ( netuid ) --> bool | Whether voting power tracking is enabled for this subnet. + /// When enabled, VotingPower EMA is updated every epoch. Default is false. + /// When disabled with disable_at_block set, tracking continues until that block. + pub type VotingPowerTrackingEnabled = + StorageMap<_, Identity, NetUid, bool, ValueQuery, DefaultFalse>; + + #[pallet::storage] + /// --- MAP ( netuid ) --> block_number | Block at which voting power tracking will be disabled. + /// When set (non-zero), tracking continues until this block, then automatically disables + /// and clears VotingPower entries for the subnet. Provides a 14-day grace period. + pub type VotingPowerDisableAtBlock = + StorageMap<_, Identity, NetUid, u64, ValueQuery>; + + #[pallet::storage] + /// --- MAP ( netuid ) --> u64 | EMA alpha value for voting power calculation. + /// Higher alpha = faster response to stake changes. + /// Stored as u64 with 18 decimal precision (1.0 = 10^18). + /// Only settable by sudo/root. + pub type VotingPowerEmaAlpha = + StorageMap<_, Identity, NetUid, u64, ValueQuery, DefaultVotingPowerEmaAlpha>; + + #[pallet::type_value] + /// Default value for burn keys limit pub fn DefaultImmuneOwnerUidsLimit() -> u16 { 1 } @@ -2328,12 +2369,17 @@ pub mod pallet { MechId::from(1) } - /// -- ITEM (Maximum number of sub-subnets) + /// -- ITEM (Maximum number of mechanisms) #[pallet::type_value] - pub fn MaxMechanismCount() -> MechId { + pub fn DefaultMaxMechanismCount() -> MechId { MechId::from(2) } + /// ITEM( max_mechanism_count ) + #[pallet::storage] + pub type MaxMechanismCount = + StorageValue<_, MechId, ValueQuery, DefaultMaxMechanismCount>; + /// -- ITEM (Rate limit for mechanism count updates) #[pallet::type_value] pub fn MechanismCountSetRateLimit() -> u64 { @@ -2441,6 +2487,8 @@ pub mod pallet { #[derive(Debug, PartialEq)] pub enum CustomTransactionError { + /// Deprecated: coldkey swap now uses announcements and check moved to DispatchGuard + #[deprecated] ColdkeyInSwapSchedule, StakeAmountTooLow, BalanceTooLow, @@ -2468,6 +2516,7 @@ pub enum CustomTransactionError { impl From for u8 { fn from(variant: CustomTransactionError) -> u8 { match variant { + #[allow(deprecated)] CustomTransactionError::ColdkeyInSwapSchedule => 0, CustomTransactionError::StakeAmountTooLow => 1, CustomTransactionError::BalanceTooLow => 2, @@ -2674,6 +2723,9 @@ pub enum RateLimitKey { // Last tx block delegate key limit per account ID #[codec(index = 5)] LastTxBlockDelegateTake(AccountId), + // "Add stake and burn" rate limit + #[codec(index = 6)] + AddStakeBurn(NetUid), } pub trait ProxyInterface { diff --git a/pallets/subtensor/src/macros/config.rs b/pallets/subtensor/src/macros/config.rs index 2124ec5f3f..528e5c9fd5 100644 --- a/pallets/subtensor/src/macros/config.rs +++ b/pallets/subtensor/src/macros/config.rs @@ -8,6 +8,7 @@ mod config { use crate::{CommitmentsInterface, GetAlphaForTao, GetTaoForAlpha}; use pallet_commitments::GetCommitments; + use subtensor_runtime_common::AuthorshipInfo; use subtensor_swap_interface::{SwapEngine, SwapHandler}; /// Configure the pallet by specifying the parameters and types on which it depends. @@ -59,6 +60,9 @@ mod config { /// Rate limit for associating an EVM key. type EvmKeyAssociateRateLimit: Get; + /// Provider of current block author + type AuthorshipProvider: AuthorshipInfo; + /// ================================= /// ==== Initial Value Constants ==== /// ================================= @@ -214,16 +218,14 @@ mod config { #[pallet::constant] type LiquidAlphaOn: Get; /// A flag to indicate if Yuma3 is enabled. + #[pallet::constant] type Yuma3On: Get; - // /// Initial hotkey emission tempo. - // #[pallet::constant] - // type InitialHotkeyEmissionTempo: Get; - /// Coldkey swap schedule duartion. + /// Coldkey swap announcement delay. #[pallet::constant] - type InitialColdkeySwapScheduleDuration: Get>; - /// Coldkey swap reschedule duration. + type InitialColdkeySwapAnnouncementDelay: Get>; + /// Coldkey swap reannouncement delay. #[pallet::constant] - type InitialColdkeySwapRescheduleDuration: Get>; + type InitialColdkeySwapReannouncementDelay: Get>; /// Dissolve network schedule duration #[pallet::constant] type InitialDissolveNetworkScheduleDuration: Get>; diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 5c5d5ed1a7..7656985819 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -6,11 +6,10 @@ use frame_support::pallet_macros::pallet_section; #[pallet_section] mod dispatches { use crate::subnets::leasing::SubnetLeasingWeightInfo; - use frame_support::traits::schedule::DispatchTime; use frame_support::traits::schedule::v3::Anon as ScheduleAnon; use frame_system::pallet_prelude::BlockNumberFor; use sp_core::ecdsa::Signature; - use sp_runtime::{Percent, traits::Saturating}; + use sp_runtime::{Percent, Saturating, traits::Hash}; use crate::MAX_CRV3_COMMIT_SIZE_BYTES; use crate::MAX_NUM_ROOT_CLAIMS; @@ -720,7 +719,7 @@ mod dispatches { netuid: NetUid, amount_staked: TaoCurrency, ) -> DispatchResult { - Self::do_add_stake(origin, hotkey, netuid, amount_staked) + Self::do_add_stake(origin, hotkey, netuid, amount_staked).map(|_| ()) } /// Remove stake from the staking account. The call must be made @@ -1055,7 +1054,7 @@ mod dispatches { /// The extrinsic for user to change its hotkey in subnet or all subnets. #[pallet::call_index(70)] #[pallet::weight((Weight::from_parts(275_300_000, 0) - .saturating_add(T::DbWeight::get().reads(50_u64)) + .saturating_add(T::DbWeight::get().reads(52_u64)) .saturating_add(T::DbWeight::get().writes(35_u64)), DispatchClass::Normal, Pays::No))] pub fn swap_hotkey( origin: OriginFor, @@ -1066,36 +1065,31 @@ mod dispatches { Self::do_swap_hotkey(origin, &hotkey, &new_hotkey, netuid) } - /// The extrinsic for user to change the coldkey associated with their account. + /// Performs an arbitrary coldkey swap for any coldkey. /// - /// # Arguments - /// - /// * `origin` - The origin of the call, must be signed by the old coldkey. - /// * `old_coldkey` - The current coldkey associated with the account. - /// * `new_coldkey` - The new coldkey to be associated with the account. - /// - /// # Returns - /// - /// Returns a `DispatchResultWithPostInfo` indicating success or failure of the operation. - /// - /// # Weight - /// - /// Weight is calculated based on the number of database reads and writes. + /// Only callable by root as it doesn't require an announcement and can be used to swap any coldkey. #[pallet::call_index(71)] #[pallet::weight(Weight::from_parts(161_700_000, 0) - .saturating_add(T::DbWeight::get().reads(16_u64)) - .saturating_add(T::DbWeight::get().writes(11_u64)))] + .saturating_add(T::DbWeight::get().reads(17_u64)) + .saturating_add(T::DbWeight::get().writes(10_u64)))] pub fn swap_coldkey( origin: OriginFor, old_coldkey: T::AccountId, new_coldkey: T::AccountId, swap_cost: TaoCurrency, - ) -> DispatchResultWithPostInfo { - // Ensure it's called with root privileges (scheduler has root privileges) + ) -> DispatchResult { ensure_root(origin)?; - log::debug!("swap_coldkey: {:?} -> {:?}", old_coldkey, new_coldkey); - Self::do_swap_coldkey(&old_coldkey, &new_coldkey, swap_cost) + if swap_cost.to_u64() > 0 { + Self::charge_swap_cost(&old_coldkey, swap_cost)?; + } + Self::do_swap_coldkey(&old_coldkey, &new_coldkey)?; + + // We also clear any announcement or dispute for security reasons + ColdkeySwapAnnouncements::::remove(&old_coldkey); + ColdkeySwapDisputes::::remove(old_coldkey); + + Ok(()) } /// Sets the childkey take for a given hotkey. @@ -1321,94 +1315,15 @@ mod dispatches { /// Schedules a coldkey swap operation to be executed at a future block. /// - /// This function allows a user to schedule the swapping of their coldkey to a new one - /// at a specified future block. The swap is not executed immediately but is scheduled - /// to occur at the specified block number. - /// - /// # Arguments - /// - /// * `origin` - The origin of the call, which should be signed by the current coldkey owner. - /// * `new_coldkey` - The account ID of the new coldkey that will replace the current one. - /// * `when` - The block number at which the coldkey swap should be executed. - /// - /// # Returns - /// - /// Returns a `DispatchResultWithPostInfo` indicating whether the scheduling was successful. - /// - /// # Errors - /// - /// This function may return an error if: - /// * The origin is not signed. - /// * The scheduling fails due to conflicts or system constraints. - /// - /// # Notes - /// - /// - The actual swap is not performed by this function. It merely schedules the swap operation. - /// - The weight of this call is set to a fixed value and may need adjustment based on benchmarking. - /// - /// # TODO - /// - /// - Implement proper weight calculation based on the complexity of the operation. - /// - Consider adding checks to prevent scheduling too far into the future. - /// TODO: Benchmark this call + /// WARNING: This function is deprecated, please migrate to `announce_coldkey_swap`/`coldkey_swap` #[pallet::call_index(73)] - #[pallet::weight((Weight::from_parts(37_830_000, 0) - .saturating_add(T::DbWeight::get().reads(4)) - .saturating_add(T::DbWeight::get().writes(2)), DispatchClass::Normal, Pays::Yes))] + #[pallet::weight(T::DbWeight::get().reads(5))] + #[deprecated(note = "Deprecated, please migrate to `announce_coldkey_swap`/`coldkey_swap`")] pub fn schedule_swap_coldkey( - origin: OriginFor, - new_coldkey: T::AccountId, - ) -> DispatchResultWithPostInfo { - let who = ensure_signed(origin)?; - let current_block = >::block_number(); - - // If the coldkey has a scheduled swap, check if we can reschedule it - if ColdkeySwapScheduled::::contains_key(&who) { - let (scheduled_block, _scheduled_coldkey) = ColdkeySwapScheduled::::get(&who); - let reschedule_duration = ColdkeySwapRescheduleDuration::::get(); - let redo_when = scheduled_block.saturating_add(reschedule_duration); - ensure!(redo_when <= current_block, Error::::SwapAlreadyScheduled); - } - - // Calculate the swap cost and ensure sufficient balance - let swap_cost = Self::get_key_swap_cost(); - ensure!( - Self::can_remove_balance_from_coldkey_account(&who, swap_cost.into()), - Error::::NotEnoughBalanceToPaySwapColdKey - ); - - let current_block: BlockNumberFor = >::block_number(); - let duration: BlockNumberFor = ColdkeySwapScheduleDuration::::get(); - let when: BlockNumberFor = current_block.saturating_add(duration); - - let call = Call::::swap_coldkey { - old_coldkey: who.clone(), - new_coldkey: new_coldkey.clone(), - swap_cost, - }; - - let bound_call = ::Preimages::bound(LocalCallOf::::from(call.clone())) - .map_err(|_| Error::::FailedToSchedule)?; - - T::Scheduler::schedule( - DispatchTime::At(when), - None, - 63, - frame_system::RawOrigin::Root.into(), - bound_call, - ) - .map_err(|_| Error::::FailedToSchedule)?; - - ColdkeySwapScheduled::::insert(&who, (when, new_coldkey.clone())); - // Emit the SwapScheduled event - Self::deposit_event(Event::ColdkeySwapScheduled { - old_coldkey: who.clone(), - new_coldkey: new_coldkey.clone(), - execution_block: when, - swap_cost, - }); - - Ok(().into()) + _origin: OriginFor, + _new_coldkey: T::AccountId, + ) -> DispatchResult { + Err(Error::::Deprecated.into()) } /// ---- Set prometheus information for the neuron. @@ -1505,7 +1420,7 @@ mod dispatches { /// User register a new subnetwork #[pallet::call_index(79)] - #[pallet::weight((Weight::from_parts(234_200_000, 0) + #[pallet::weight((Weight::from_parts(396_000_000, 0) .saturating_add(T::DbWeight::get().reads(35_u64)) .saturating_add(T::DbWeight::get().writes(51_u64)), DispatchClass::Normal, Pays::Yes))] pub fn register_network_with_identity( @@ -1773,6 +1688,7 @@ mod dispatches { limit_price, allow_partial, ) + .map(|_| ()) } /// --- Removes stake from a hotkey on a subnet with a price limit. @@ -1819,8 +1735,8 @@ mod dispatches { /// #[pallet::call_index(89)] #[pallet::weight((Weight::from_parts(377_400_000, 0) - .saturating_add(T::DbWeight::get().reads(29_u64)) - .saturating_add(T::DbWeight::get().writes(15_u64)), DispatchClass::Normal, Pays::Yes))] + .saturating_add(T::DbWeight::get().reads(28_u64)) + .saturating_add(T::DbWeight::get().writes(14_u64)), DispatchClass::Normal, Pays::Yes))] pub fn remove_stake_limit( origin: OriginFor, hotkey: T::AccountId, @@ -2041,8 +1957,8 @@ mod dispatches { /// Without limit_price it remove all the stake similar to `remove_stake` extrinsic #[pallet::call_index(103)] #[pallet::weight((Weight::from_parts(395_300_000, 10142) - .saturating_add(T::DbWeight::get().reads(29_u64)) - .saturating_add(T::DbWeight::get().writes(15_u64)), DispatchClass::Normal, Pays::Yes))] + .saturating_add(T::DbWeight::get().reads(28_u64)) + .saturating_add(T::DbWeight::get().writes(14_u64)), DispatchClass::Normal, Pays::Yes))] pub fn remove_stake_full_limit( origin: T::RuntimeOrigin, hotkey: T::AccountId, @@ -2416,5 +2332,242 @@ mod dispatches { Ok(()) } + + /// Announces a coldkey swap using BlakeTwo256 hash of the new coldkey. + /// + /// This is required before the coldkey swap can be performed + /// after the delay period. + /// + /// It can be reannounced after a delay of `ColdkeySwapReannouncementDelay` following + /// the first valid execution block of the original announcement. + /// + /// The dispatch origin of this call must be the original coldkey that made the announcement. + /// + /// - `new_coldkey_hash`: The hash of the new coldkey using BlakeTwo256. + /// + /// The `ColdkeySwapAnnounced` event is emitted on successful announcement. + /// + #[pallet::call_index(125)] + #[pallet::weight( + Weight::from_parts(55_700_000, 0) + .saturating_add(T::DbWeight::get().reads(4_u64)) + .saturating_add(T::DbWeight::get().writes(3_u64)) + )] + pub fn announce_coldkey_swap( + origin: OriginFor, + new_coldkey_hash: T::Hash, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + let now = >::block_number(); + + if let Some((when, _)) = ColdkeySwapAnnouncements::::get(who.clone()) { + let reannouncement_delay = ColdkeySwapReannouncementDelay::::get(); + let new_when = when.saturating_add(reannouncement_delay); + ensure!(now >= new_when, Error::::ColdkeySwapReannouncedTooEarly); + } else { + // Only charge the swap cost on the first announcement + let swap_cost = Self::get_key_swap_cost(); + Self::charge_swap_cost(&who, swap_cost)?; + } + + let delay = ColdkeySwapAnnouncementDelay::::get(); + let when = now.saturating_add(delay); + ColdkeySwapAnnouncements::::insert(who.clone(), (when, new_coldkey_hash.clone())); + + Self::deposit_event(Event::ColdkeySwapAnnounced { + who, + new_coldkey_hash, + }); + Ok(()) + } + + /// Performs a coldkey swap if an announcement has been made. + /// + /// The dispatch origin of this call must be the original coldkey that made the announcement. + /// + /// - `new_coldkey`: The new coldkey to swap to. The BlakeTwo256 hash of the new coldkey must be + /// the same as the announced coldkey hash. + /// + /// The `ColdkeySwapped` event is emitted on successful swap. + #[pallet::call_index(126)] + #[pallet::weight( + Weight::from_parts(110_700_000, 0) + .saturating_add(T::DbWeight::get().reads(16_u64)) + .saturating_add(T::DbWeight::get().writes(6_u64)) + )] + pub fn swap_coldkey_announced( + origin: OriginFor, + new_coldkey: T::AccountId, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + + let (when, new_coldkey_hash) = ColdkeySwapAnnouncements::::take(who.clone()) + .ok_or(Error::::ColdkeySwapAnnouncementNotFound)?; + + ensure!( + new_coldkey_hash == T::Hashing::hash_of(&new_coldkey), + Error::::AnnouncedColdkeyHashDoesNotMatch + ); + + let now = >::block_number(); + ensure!(now >= when, Error::::ColdkeySwapTooEarly); + + Self::do_swap_coldkey(&who, &new_coldkey)?; + + Ok(()) + } + + /// Dispute a coldkey swap. + /// + /// This will prevent any further actions on the coldkey swap + /// until triumvirate step in to resolve the issue. + /// + /// - `coldkey`: The coldkey to dispute the swap for. + /// + #[pallet::call_index(127)] + #[pallet::weight( + Weight::from_parts(20_750_000, 0) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + )] + pub fn dispute_coldkey_swap(origin: OriginFor) -> DispatchResult { + let coldkey = ensure_signed(origin)?; + + ensure!( + ColdkeySwapAnnouncements::::contains_key(&coldkey), + Error::::ColdkeySwapAnnouncementNotFound + ); + ensure!( + !ColdkeySwapDisputes::::contains_key(&coldkey), + Error::::ColdkeySwapAlreadyDisputed + ); + + let now = >::block_number(); + ColdkeySwapDisputes::::insert(&coldkey, now); + + Self::deposit_event(Event::ColdkeySwapDisputed { coldkey }); + Ok(()) + } + + /// Reset a coldkey swap by clearing the announcement and dispute status. + /// + /// The dispatch origin of this call must be root. + /// + /// - `coldkey`: The coldkey to reset the swap for. + /// + #[pallet::call_index(128)] + #[pallet::weight( + Weight::from_parts(8_977_000, 0) + .saturating_add(T::DbWeight::get().reads(0_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) + )] + pub fn reset_coldkey_swap(origin: OriginFor, coldkey: T::AccountId) -> DispatchResult { + ensure_root(origin)?; + + ColdkeySwapAnnouncements::::remove(&coldkey); + ColdkeySwapDisputes::::remove(&coldkey); + + Self::deposit_event(Event::ColdkeySwapReset { who: coldkey }); + Ok(()) + } + + /// Enables voting power tracking for a subnet. + /// + /// This function can be called by the subnet owner or root. + /// When enabled, voting power EMA is updated every epoch for all validators. + /// Voting power starts at 0 and increases over epochs. + /// + /// # Arguments: + /// * `origin` - The origin of the call, must be subnet owner or root. + /// * `netuid` - The subnet to enable voting power tracking for. + /// + /// # Errors: + /// * `SubnetNotExist` - If the subnet does not exist. + /// * `NotSubnetOwner` - If the caller is not the subnet owner or root. + #[pallet::call_index(129)] + #[pallet::weight(Weight::from_parts(10_000, 0) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)))] + pub fn enable_voting_power_tracking( + origin: OriginFor, + netuid: NetUid, + ) -> DispatchResult { + Self::ensure_subnet_owner_or_root(origin, netuid)?; + Self::do_enable_voting_power_tracking(netuid) + } + + /// Schedules disabling of voting power tracking for a subnet. + /// + /// This function can be called by the subnet owner or root. + /// Voting power tracking will continue for 14 days (grace period) after this call, + /// then automatically disable and clear all VotingPower entries for the subnet. + /// + /// # Arguments: + /// * `origin` - The origin of the call, must be subnet owner or root. + /// * `netuid` - The subnet to schedule disabling voting power tracking for. + /// + /// # Errors: + /// * `SubnetNotExist` - If the subnet does not exist. + /// * `NotSubnetOwner` - If the caller is not the subnet owner or root. + /// * `VotingPowerTrackingNotEnabled` - If voting power tracking is not enabled. + #[pallet::call_index(130)] + #[pallet::weight(Weight::from_parts(10_000, 0) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)))] + pub fn disable_voting_power_tracking( + origin: OriginFor, + netuid: NetUid, + ) -> DispatchResult { + Self::ensure_subnet_owner_or_root(origin, netuid)?; + Self::do_disable_voting_power_tracking(netuid) + } + + /// Sets the EMA alpha value for voting power calculation on a subnet. + /// + /// This function can only be called by root (sudo). + /// Higher alpha = faster response to stake changes. + /// Alpha is stored as u64 with 18 decimal precision (1.0 = 10^18). + /// + /// # Arguments: + /// * `origin` - The origin of the call, must be root. + /// * `netuid` - The subnet to set the alpha for. + /// * `alpha` - The new alpha value (u64 with 18 decimal precision). + /// + /// # Errors: + /// * `BadOrigin` - If the origin is not root. + /// * `SubnetNotExist` - If the subnet does not exist. + /// * `InvalidVotingPowerEmaAlpha` - If alpha is greater than 10^18 (1.0). + #[pallet::call_index(131)] + #[pallet::weight(Weight::from_parts(6_000, 0) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)))] + pub fn sudo_set_voting_power_ema_alpha( + origin: OriginFor, + netuid: NetUid, + alpha: u64, + ) -> DispatchResult { + ensure_root(origin)?; + Self::do_set_voting_power_ema_alpha(netuid, alpha) + } + + /// --- The extrinsic is a combination of add_stake(add_stake_limit) and burn_alpha. We buy + /// alpha token first and immediately burn the acquired amount of alpha (aka Subnet buyback). + #[pallet::call_index(132)] + #[pallet::weight(( + Weight::from_parts(368_000_000, 8556) + .saturating_add(T::DbWeight::get().reads(28_u64)) + .saturating_add(T::DbWeight::get().writes(17_u64)), + DispatchClass::Normal, + Pays::Yes + ))] + pub fn add_stake_burn( + origin: T::RuntimeOrigin, + hotkey: T::AccountId, + netuid: NetUid, + amount: TaoCurrency, + limit: Option, + ) -> DispatchResult { + Self::do_add_stake_burn(origin, hotkey, netuid, amount, limit) + } } } diff --git a/pallets/subtensor/src/macros/errors.rs b/pallets/subtensor/src/macros/errors.rs index 6c3d7a35df..e6c3aa5e78 100644 --- a/pallets/subtensor/src/macros/errors.rs +++ b/pallets/subtensor/src/macros/errors.rs @@ -138,8 +138,6 @@ mod errors { ColdKeyAlreadyAssociated, /// The coldkey balance is not enough to pay for the swap NotEnoughBalanceToPaySwapColdKey, - /// The coldkey is in arbitration - ColdkeyIsInArbitration, /// Attempting to set an invalid child for a hotkey on a network. InvalidChild, /// Duplicate child when setting children. @@ -150,10 +148,16 @@ mod errors { TooManyChildren, /// Default transaction rate limit exceeded. TxRateLimitExceeded, - /// Swap already scheduled. - SwapAlreadyScheduled, - /// failed to swap coldkey - FailedToSchedule, + /// Coldkey swap announcement not found + ColdkeySwapAnnouncementNotFound, + /// Coldkey swap too early. + ColdkeySwapTooEarly, + /// Coldkey swap reannounced too early. + ColdkeySwapReannouncedTooEarly, + /// The announced coldkey hash does not match the new coldkey hash. + AnnouncedColdkeyHashDoesNotMatch, + /// Coldkey swap already disputed + ColdkeySwapAlreadyDisputed, /// New coldkey is hotkey NewColdKeyIsHotkey, /// Childkey take is invalid. @@ -266,7 +270,21 @@ mod errors { InvalidRootClaimThreshold, /// Exceeded subnet limit number or zero. InvalidSubnetNumber, + /// The maximum allowed UIDs times mechanism count should not exceed 256. + TooManyUIDsPerMechanism, + /// Voting power tracking is not enabled for this subnet. + VotingPowerTrackingNotEnabled, + /// Invalid voting power EMA alpha value (must be <= 10^18). + InvalidVotingPowerEmaAlpha, /// Unintended precision loss when unstaking alpha PrecisionLoss, + /// Deprecated call. + Deprecated, + /// "Add stake and burn" exceeded the operation rate limit + AddStakeBurnRateLimitExceeded, + /// A coldkey swap has been announced for this account. + ColdkeySwapAnnounced, + /// A coldkey swap for this account is under dispute. + ColdkeySwapDisputed, } } diff --git a/pallets/subtensor/src/macros/events.rs b/pallets/subtensor/src/macros/events.rs index c86cc1a1e5..65c33aee87 100644 --- a/pallets/subtensor/src/macros/events.rs +++ b/pallets/subtensor/src/macros/events.rs @@ -172,14 +172,29 @@ mod events { MaxDelegateTakeSet(u16), /// minimum delegate take is set by sudo/admin transaction MinDelegateTakeSet(u16), - /// A coldkey has been swapped + /// A coldkey swap announcement has been made. + ColdkeySwapAnnounced { + /// The account ID of the coldkey that made the announcement. + who: T::AccountId, + /// The hash of the new coldkey. + new_coldkey_hash: T::Hash, + }, + /// A coldkey swap has been reset. + ColdkeySwapReset { + /// The account ID of the coldkey for which the swap has been reset. + who: T::AccountId, + }, + /// A coldkey has been swapped. ColdkeySwapped { - /// the account ID of old coldkey + /// The account ID of old coldkey. old_coldkey: T::AccountId, - /// the account ID of new coldkey + /// The account ID of new coldkey. new_coldkey: T::AccountId, - /// the swap cost - swap_cost: TaoCurrency, + }, + /// A coldkey swap has been disputed. + ColdkeySwapDisputed { + /// The account ID of the coldkey that was disputed. + coldkey: T::AccountId, }, /// All balance of a hotkey has been unstaked and transferred to a new coldkey AllBalanceUnstakedAndTransferredToNewColdkey { @@ -192,17 +207,6 @@ mod events { ::AccountId, >>::Balance, }, - /// A coldkey swap has been scheduled - ColdkeySwapScheduled { - /// The account ID of the old coldkey - old_coldkey: T::AccountId, - /// The account ID of the new coldkey - new_coldkey: T::AccountId, - /// The arbitration block for the coldkey swap - execution_block: BlockNumberFor, - /// The swap cost - swap_cost: TaoCurrency, - }, /// The arbitration period has been extended ArbitrationPeriodExtended { /// The account ID of the coldkey @@ -224,15 +228,17 @@ mod events { SubnetIdentityRemoved(NetUid), /// A dissolve network extrinsic scheduled. DissolveNetworkScheduled { - /// The account ID schedule the dissolve network extrisnic + /// The account ID schedule the dissolve network extrinsic account: T::AccountId, /// network ID will be dissolved netuid: NetUid, /// extrinsic execution block number execution_block: BlockNumberFor, }, - /// The duration of schedule coldkey swap has been set - ColdkeySwapScheduleDurationSet(BlockNumberFor), + /// The coldkey swap announcement delay has been set. + ColdkeySwapAnnouncementDelaySet(BlockNumberFor), + /// The coldkey swap reannouncement delay has been set. + ColdkeySwapReannouncementDelaySet(BlockNumberFor), /// The duration of dissolve network has been set DissolveNetworkScheduleDurationSet(BlockNumberFor), /// Commit-reveal v3 weights have been successfully committed. @@ -472,6 +478,35 @@ mod events { root_claim_type: RootClaimTypeEnum, }, + /// Voting power tracking has been enabled for a subnet. + VotingPowerTrackingEnabled { + /// The subnet ID + netuid: NetUid, + }, + + /// Voting power tracking has been scheduled for disabling. + /// Tracking will continue until disable_at_block, then stop and clear entries. + VotingPowerTrackingDisableScheduled { + /// The subnet ID + netuid: NetUid, + /// Block at which tracking will be disabled + disable_at_block: u64, + }, + + /// Voting power tracking has been fully disabled and entries cleared. + VotingPowerTrackingDisabled { + /// The subnet ID + netuid: NetUid, + }, + + /// Voting power EMA alpha has been set for a subnet. + VotingPowerEmaAlphaSet { + /// The subnet ID + netuid: NetUid, + /// The new alpha value (u64 with 18 decimal precision) + alpha: u64, + }, + /// Subnet lease dividends have been distributed. SubnetLeaseDividendsDistributed { /// The lease ID @@ -481,5 +516,17 @@ mod events { /// The amount of alpha distributed alpha: AlphaCurrency, }, + + /// "Add stake and burn" event: alpha token was purchased and burned. + AddStakeBurn { + /// The subnet ID + netuid: NetUid, + /// hotky account ID + hotkey: T::AccountId, + /// Tao provided + amount: TaoCurrency, + /// Alpha burned + alpha: AlphaCurrency, + }, } } diff --git a/pallets/subtensor/src/macros/genesis.rs b/pallets/subtensor/src/macros/genesis.rs index 0014b63540..f16f2f7a3a 100644 --- a/pallets/subtensor/src/macros/genesis.rs +++ b/pallets/subtensor/src/macros/genesis.rs @@ -106,7 +106,6 @@ mod genesis { netuid, U64F64::saturating_from_num(1_000_000_000), ); - // TotalColdkeyAlpha::::insert(hotkey.clone(), netuid, 1_000_000_000); SubnetAlphaOut::::insert(netuid, AlphaCurrency::from(1_000_000_000)); let mut staking_hotkeys = StakingHotkeys::::get(hotkey.clone()); if !staking_hotkeys.contains(&hotkey) { diff --git a/pallets/subtensor/src/macros/hooks.rs b/pallets/subtensor/src/macros/hooks.rs index ed57d52c8b..899e8d32f2 100644 --- a/pallets/subtensor/src/macros/hooks.rs +++ b/pallets/subtensor/src/macros/hooks.rs @@ -164,7 +164,9 @@ mod hooks { // Remove unknown neuron axon, certificate prom .saturating_add(migrations::migrate_remove_unknown_neuron_axon_cert_prom::migrate_remove_unknown_neuron_axon_cert_prom::()) // Fix staking hot keys - .saturating_add(migrations::migrate_fix_staking_hot_keys::migrate_fix_staking_hot_keys::()); + .saturating_add(migrations::migrate_fix_staking_hot_keys::migrate_fix_staking_hot_keys::()) + // Migrate coldkey swap scheduled to announcements + .saturating_add(migrations::migrate_coldkey_swap_scheduled_to_announcements::migrate_coldkey_swap_scheduled_to_announcements::()); weight } diff --git a/pallets/subtensor/src/migrations/migrate_coldkey_swap_scheduled.rs b/pallets/subtensor/src/migrations/migrate_coldkey_swap_scheduled.rs index 8854f76387..243d953ac1 100644 --- a/pallets/subtensor/src/migrations/migrate_coldkey_swap_scheduled.rs +++ b/pallets/subtensor/src/migrations/migrate_coldkey_swap_scheduled.rs @@ -55,13 +55,6 @@ pub fn migrate_coldkey_swap_scheduled() -> Weight { } } - let default_value = DefaultColdkeySwapScheduled::::get(); - ColdkeySwapScheduled::::translate::<(), _>(|_coldkey: AccountIdOf, _: ()| { - Some((default_value.0, default_value.1.clone())) - }); - // write once for each item in the map, no matter remove or translate - weight.saturating_accrue(T::DbWeight::get().writes(curr_keys.len() as u64)); - // ------------------------------ // Step 2: Mark Migration as Completed // ------------------------------ diff --git a/pallets/subtensor/src/migrations/migrate_coldkey_swap_scheduled_to_announcements.rs b/pallets/subtensor/src/migrations/migrate_coldkey_swap_scheduled_to_announcements.rs new file mode 100644 index 0000000000..12fa3f5768 --- /dev/null +++ b/pallets/subtensor/src/migrations/migrate_coldkey_swap_scheduled_to_announcements.rs @@ -0,0 +1,91 @@ +use super::*; +use crate::AccountIdOf; +use frame_support::{pallet_prelude::Blake2_128Concat, traits::Get, weights::Weight}; +use frame_system::pallet_prelude::BlockNumberFor; +use scale_info::prelude::string::String; +use sp_io::storage::clear; +use sp_runtime::{Saturating, traits::Hash}; + +pub mod deprecated { + use super::*; + use frame_support::storage_alias; + + #[storage_alias] + pub type ColdkeySwapScheduleDuration = + StorageValue, BlockNumberFor, OptionQuery>; + + #[storage_alias] + pub type ColdkeySwapRescheduleDuration = + StorageValue, BlockNumberFor, OptionQuery>; + + #[storage_alias] + pub type ColdkeySwapScheduled = StorageMap< + Pallet, + Blake2_128Concat, + AccountIdOf, + (BlockNumberFor, AccountIdOf), + OptionQuery, + >; +} + +pub fn migrate_coldkey_swap_scheduled_to_announcements() -> Weight { + let migration_name = b"migrate_coldkey_swap_scheduled_to_announcements".to_vec(); + let mut weight = T::DbWeight::get().reads(1); + + if HasMigrationRun::::get(&migration_name) { + log::info!( + "Migration '{:?}' has already run. Skipping.", + String::from_utf8_lossy(&migration_name) + ); + return weight; + } + + log::info!( + "Running migration '{}'", + String::from_utf8_lossy(&migration_name) + ); + + // Remove ColdkeySwapScheduleDuration and ColdkeySwapRescheduleDuration + let pallet_name = twox_128(b"SubtensorModule"); + let storage_name1 = twox_128(b"ColdkeySwapScheduleDuration"); + let storage_name2 = twox_128(b"ColdkeySwapRescheduleDuration"); + clear(&[pallet_name, storage_name1].concat()); + clear(&[pallet_name, storage_name2].concat()); + weight.saturating_accrue(T::DbWeight::get().writes(2)); + + // Migrate the ColdkeySwapScheduled entries to ColdkeySwapAnnouncements entries + let now = >::block_number(); + let scheduled = deprecated::ColdkeySwapScheduled::::iter(); + let delay = ColdkeySwapAnnouncementDelay::::get(); + + for (who, (when, new_coldkey)) in scheduled { + // Only migrate the scheduled coldkey swaps that are in the future + if when > now { + let coldkey_hash = ::Hashing::hash_of(&new_coldkey); + // The announcement should be at the scheduled time - delay to be able to call + // the swap_coldkey_announced call at the old scheduled time + ColdkeySwapAnnouncements::::insert(who, (when.saturating_sub(delay), coldkey_hash)); + weight.saturating_accrue(T::DbWeight::get().writes(1)); + } + weight.saturating_accrue(T::DbWeight::get().reads(1)); + } + + let results = deprecated::ColdkeySwapScheduled::::clear(u32::MAX, None); + weight.saturating_accrue( + T::DbWeight::get().reads_writes(results.loops as u64, results.backend as u64), + ); + + // ------------------------------ + // Step 2: Mark Migration as Completed + // ------------------------------ + + HasMigrationRun::::insert(&migration_name, true); + weight = weight.saturating_add(T::DbWeight::get().writes(1)); + + log::info!( + "Migration '{:?}' completed successfully.", + String::from_utf8_lossy(&migration_name) + ); + + weight +} diff --git a/pallets/subtensor/src/migrations/mod.rs b/pallets/subtensor/src/migrations/mod.rs index a03da9289e..23a2899b94 100644 --- a/pallets/subtensor/src/migrations/mod.rs +++ b/pallets/subtensor/src/migrations/mod.rs @@ -7,6 +7,7 @@ use sp_io::storage::clear_prefix; pub mod migrate_auto_stake_destination; pub mod migrate_clear_rank_trust_pruning_maps; pub mod migrate_coldkey_swap_scheduled; +pub mod migrate_coldkey_swap_scheduled_to_announcements; pub mod migrate_commit_reveal_settings; pub mod migrate_commit_reveal_v2; pub mod migrate_create_root_network; diff --git a/pallets/subtensor/src/staking/add_stake.rs b/pallets/subtensor/src/staking/add_stake.rs index ea33912bf1..b0c71a3a48 100644 --- a/pallets/subtensor/src/staking/add_stake.rs +++ b/pallets/subtensor/src/staking/add_stake.rs @@ -42,7 +42,7 @@ impl Pallet { hotkey: T::AccountId, netuid: NetUid, stake_to_be_added: TaoCurrency, - ) -> dispatch::DispatchResult { + ) -> Result { // 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!( @@ -77,10 +77,7 @@ impl Pallet { T::SwapInterface::max_price(), true, false, - )?; - - // Ok and return. - Ok(()) + ) } /// ---- The implementation for the extrinsic add_stake_limit: Adds stake to a hotkey @@ -130,7 +127,7 @@ impl Pallet { stake_to_be_added: TaoCurrency, limit_price: TaoCurrency, allow_partial: bool, - ) -> dispatch::DispatchResult { + ) -> Result { // 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!( @@ -173,10 +170,7 @@ impl Pallet { limit_price, true, false, - )?; - - // Ok and return. - Ok(()) + ) } // Returns the maximum amount of RAO that can be executed with price limit diff --git a/pallets/subtensor/src/staking/recycle_alpha.rs b/pallets/subtensor/src/staking/recycle_alpha.rs index 5229971ed0..b77982fa31 100644 --- a/pallets/subtensor/src/staking/recycle_alpha.rs +++ b/pallets/subtensor/src/staking/recycle_alpha.rs @@ -134,6 +134,43 @@ impl Pallet { netuid, )); + Ok(()) + } + pub(crate) fn do_add_stake_burn( + origin: T::RuntimeOrigin, + hotkey: T::AccountId, + netuid: NetUid, + amount: TaoCurrency, + limit: Option, + ) -> DispatchResult { + Self::ensure_subnet_owner(origin.clone(), netuid)?; + + let current_block = Self::get_current_block_as_u64(); + let last_block = Self::get_rate_limited_last_block(&RateLimitKey::AddStakeBurn(netuid)); + let rate_limit = TransactionType::AddStakeBurn.rate_limit_on_subnet::(netuid); + + ensure!( + last_block.is_zero() || current_block.saturating_sub(last_block) >= rate_limit, + Error::::AddStakeBurnRateLimitExceeded + ); + + let alpha = if let Some(limit) = limit { + Self::do_add_stake_limit(origin.clone(), hotkey.clone(), netuid, amount, limit, false)? + } else { + Self::do_add_stake(origin.clone(), hotkey.clone(), netuid, amount)? + }; + + Self::do_burn_alpha(origin, hotkey.clone(), alpha, netuid)?; + + Self::set_rate_limited_last_block(&RateLimitKey::AddStakeBurn(netuid), current_block); + + Self::deposit_event(Event::AddStakeBurn { + netuid, + hotkey, + amount, + alpha, + }); + Ok(()) } } diff --git a/pallets/subtensor/src/staking/stake_utils.rs b/pallets/subtensor/src/staking/stake_utils.rs index 1aeeacc33c..cf90131c4e 100644 --- a/pallets/subtensor/src/staking/stake_utils.rs +++ b/pallets/subtensor/src/staking/stake_utils.rs @@ -3,7 +3,7 @@ use safe_math::*; use share_pool::{SharePool, SharePoolDataOperations}; use sp_std::ops::Neg; use substrate_fixed::types::{I64F64, I96F32, U64F64, U96F32}; -use subtensor_runtime_common::{AlphaCurrency, Currency, NetUid, TaoCurrency}; +use subtensor_runtime_common::{AlphaCurrency, AuthorshipInfo, Currency, NetUid, TaoCurrency}; use subtensor_swap_interface::{Order, SwapHandler, SwapResult}; impl Pallet { @@ -596,6 +596,7 @@ impl Pallet { amount_paid_in: tao, amount_paid_out: tao.to_u64().into(), fee_paid: TaoCurrency::ZERO, + fee_to_block_author: TaoCurrency::ZERO, } }; @@ -649,19 +650,17 @@ impl Pallet { amount_paid_in: alpha, amount_paid_out: alpha.to_u64().into(), fee_paid: AlphaCurrency::ZERO, + fee_to_block_author: AlphaCurrency::ZERO, } }; - // Increase only the protocol Alpha reserve. We only use the sum of - // (SubnetAlphaIn + SubnetAlphaInProvided) in alpha_reserve(), so it is irrelevant - // which one to increase. + // Increase only the protocol Alpha reserve let alpha_delta = swap_result.paid_in_reserve_delta_i64().unsigned_abs(); SubnetAlphaIn::::mutate(netuid, |total| { *total = total.saturating_add(alpha_delta.into()); }); // Decrease Alpha outstanding. - // TODO: Deprecate, not accurate in v3 anymore SubnetAlphaOut::::mutate(netuid, |total| { *total = total.saturating_sub(alpha_delta.into()); }); @@ -712,6 +711,26 @@ impl Pallet { Self::increase_stake_for_hotkey_and_coldkey_on_subnet(hotkey, coldkey, netuid, refund); } + // Swap (in a fee-less way) the block builder alpha fee + let mut fee_outflow = 0_u64; + let maybe_block_author_coldkey = T::AuthorshipProvider::author(); + if let Some(block_author_coldkey) = maybe_block_author_coldkey { + let bb_swap_result = Self::swap_alpha_for_tao( + netuid, + swap_result.fee_to_block_author, + T::SwapInterface::min_price::(), + true, + )?; + Self::add_balance_to_coldkey_account( + &block_author_coldkey, + bb_swap_result.amount_paid_out.into(), + ); + fee_outflow = bb_swap_result.amount_paid_out.into(); + } else { + // block author is not found, burn this alpha + Self::burn_subnet_alpha(netuid, swap_result.fee_to_block_author); + } + // If this is a root-stake if netuid == NetUid::ROOT { // Adjust root claimed value for this hotkey and coldkey. @@ -727,7 +746,12 @@ impl Pallet { // } // Record TAO outflow - Self::record_tao_outflow(netuid, swap_result.amount_paid_out.into()); + Self::record_tao_outflow( + netuid, + swap_result + .amount_paid_out + .saturating_add(fee_outflow.into()), + ); LastColdkeyHotkeyStakeBlock::::insert(coldkey, hotkey, Self::get_current_block_as_u64()); @@ -803,6 +827,21 @@ impl Pallet { StakingHotkeys::::insert(coldkey, staking_hotkeys.clone()); } + // Increase the balance of the block author + let maybe_block_author_coldkey = T::AuthorshipProvider::author(); + if let Some(block_author_coldkey) = maybe_block_author_coldkey { + Self::add_balance_to_coldkey_account( + &block_author_coldkey, + swap_result.fee_to_block_author.into(), + ); + } else { + // Block author is not found - burn this TAO + // Pallet balances total issuance was taken care of when balance was withdrawn for this swap + TotalIssuance::::mutate(|ti| { + *ti = ti.saturating_sub(swap_result.fee_to_block_author); + }); + } + // Record TAO inflow Self::record_tao_inflow(netuid, swap_result.amount_paid_in.into()); diff --git a/pallets/subtensor/src/subnets/mechanism.rs b/pallets/subtensor/src/subnets/mechanism.rs index 481974ef05..55e459c9ba 100644 --- a/pallets/subtensor/src/subnets/mechanism.rs +++ b/pallets/subtensor/src/subnets/mechanism.rs @@ -95,7 +95,20 @@ impl Pallet { Ok(()) } - /// Set the desired valus of sub-subnet count for a subnet identified + pub fn ensure_max_uids_over_all_mechanisms( + max_uids: u16, + mechanism_count: MechId, + ) -> DispatchResult { + let max_uids_over_all_mechanisms = + max_uids.saturating_mul(u8::from(mechanism_count) as u16); + ensure!( + max_uids_over_all_mechanisms <= DefaultMaxAllowedUids::::get(), + Error::::TooManyUIDsPerMechanism + ); + Ok(()) + } + + /// Set the desired value of mechanism count for a subnet identified /// by netuid pub fn do_set_mechanism_count(netuid: NetUid, mechanism_count: MechId) -> DispatchResult { // Make sure the subnet exists @@ -113,6 +126,10 @@ impl Pallet { Error::::InvalidValue ); + // Prevent chain bloat: Require max UIDs to be limited + let max_uids = MaxAllowedUids::::get(netuid); + Self::ensure_max_uids_over_all_mechanisms(max_uids, mechanism_count)?; + // Make sure we are not allowing numbers that will break the math ensure!( mechanism_count <= MechId::from(MAX_MECHANISM_COUNT_PER_SUBNET), @@ -124,6 +141,22 @@ impl Pallet { Ok(()) } + /// Set the global maximum number of mechanisms per subnet + pub fn do_set_max_mechanism_count(max_mechanism_count: MechId) -> DispatchResult { + // Max count cannot be zero + ensure!(max_mechanism_count > 0.into(), Error::::InvalidValue); + + // Make sure we are not allowing numbers that will break the math + ensure!( + max_mechanism_count <= MechId::from(MAX_MECHANISM_COUNT_PER_SUBNET), + Error::::InvalidValue + ); + + MaxMechanismCount::::set(max_mechanism_count); + + Ok(()) + } + /// Update current count for a subnet identified by netuid /// - Cleans up all sub-subnet maps if count is reduced /// @@ -322,6 +355,7 @@ impl Pallet { sub_weight, ); acc_terms.new_validator_permit |= terms.new_validator_permit; + acc_terms.stake = acc_terms.stake.saturating_add(terms.stake); }) .or_insert_with(|| { // weighted insert for the first sub-subnet seen for this hotkey @@ -349,7 +383,8 @@ impl Pallet { sub_weight, ), new_validator_permit: terms.new_validator_permit, - bond: Vec::new(), // aggregated map doesn’t use bonds; keep empty + bond: Vec::new(), // aggregated map doesn't use bonds; keep empty + stake: terms.stake, } }); acc @@ -358,6 +393,9 @@ impl Pallet { // State updates from epoch function Self::persist_netuid_epoch_terms(netuid, &aggregated); + // Update voting power EMA for all validators on this subnet + Self::update_voting_power_for_subnet(netuid, &aggregated); + // Remap BTreeMap back to Vec<(T::AccountId, AlphaCurrency, AlphaCurrency)> format // for processing emissions in run_coinbase // Emission tuples ( hotkeys, server_emission, validator_emission ) diff --git a/pallets/subtensor/src/swap/swap_coldkey.rs b/pallets/subtensor/src/swap/swap_coldkey.rs index c81138b58c..54b07d9dbf 100644 --- a/pallets/subtensor/src/swap/swap_coldkey.rs +++ b/pallets/subtensor/src/swap/swap_coldkey.rs @@ -1,228 +1,134 @@ use super::*; -use frame_support::weights::Weight; -use sp_core::Get; use substrate_fixed::types::U64F64; impl Pallet { - /// Swaps the coldkey associated with a set of hotkeys from an old coldkey to a new coldkey. - /// - /// # Arguments - /// - /// * `origin` - The origin of the call, which must be signed by the old coldkey. - /// * `new_coldkey` - The account ID of the new coldkey. - /// - /// # Returns - /// - /// Returns a `DispatchResultWithPostInfo` indicating success or failure, along with the weight consumed. - /// - /// # Errors - /// - /// This function will return an error if: - /// - The caller is not a valid signed origin. - /// - The old coldkey (caller) is in arbitration. - /// - The new coldkey is already associated with other hotkeys or is a hotkey itself. - /// - There's not enough balance to pay for the swap. - /// - /// # Events - /// - /// Emits a `ColdkeySwapped` event when successful. - /// - /// # Weight - /// - /// Weight is tracked and updated throughout the function execution. + /// Transfer all assets, stakes, subnet ownerships, and hotkey associations from `old_coldkey` to + /// to `new_coldkey`. pub fn do_swap_coldkey( old_coldkey: &T::AccountId, new_coldkey: &T::AccountId, - swap_cost: TaoCurrency, - ) -> DispatchResultWithPostInfo { - // 2. Initialize the weight for this operation - let mut weight: Weight = T::DbWeight::get().reads(2); - // 3. Ensure the new coldkey is not associated with any hotkeys + ) -> DispatchResult { ensure!( StakingHotkeys::::get(new_coldkey).is_empty(), Error::::ColdKeyAlreadyAssociated ); - weight = weight.saturating_add(T::DbWeight::get().reads(1)); - - // 4. Ensure the new coldkey is not a hotkey ensure!( !Self::hotkey_account_exists(new_coldkey), Error::::NewColdKeyIsHotkey ); - weight = weight.saturating_add(T::DbWeight::get().reads(1)); - // 5. Swap the identity if the old coldkey has one - if let Some(identity) = IdentitiesV2::::take(old_coldkey) { - IdentitiesV2::::insert(new_coldkey, identity); + // Swap the identity if the old coldkey has one and the new coldkey doesn't + if IdentitiesV2::::get(new_coldkey).is_none() + && let Some(identity) = IdentitiesV2::::take(old_coldkey) + { + IdentitiesV2::::insert(new_coldkey.clone(), identity); } - // 6. Ensure sufficient balance for the swap cost - ensure!( - Self::can_remove_balance_from_coldkey_account(old_coldkey, swap_cost.into()), - Error::::NotEnoughBalanceToPaySwapColdKey - ); - - // 7. Remove and recycle the swap cost from the old coldkey's account - let actual_burn_amount = - Self::remove_balance_from_coldkey_account(old_coldkey, swap_cost.into())?; - Self::recycle_tao(actual_burn_amount); - - // 8. Update the weight for the balance operations - weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); + for netuid in Self::get_all_subnet_netuids() { + Self::transfer_subnet_ownership(netuid, old_coldkey, new_coldkey); + Self::transfer_auto_stake_destination(netuid, old_coldkey, new_coldkey); + Self::transfer_coldkey_stake(netuid, old_coldkey, new_coldkey); + } + Self::transfer_staking_hotkeys(old_coldkey, new_coldkey); + Self::transfer_hotkeys_ownership(old_coldkey, new_coldkey); - // 9. Perform the actual coldkey swap - let _ = Self::perform_swap_coldkey(old_coldkey, new_coldkey, &mut weight); + // Transfer any remaining balance from old_coldkey to new_coldkey + let remaining_balance = Self::get_coldkey_balance(old_coldkey); + if remaining_balance > 0 { + Self::kill_coldkey_account(old_coldkey, remaining_balance)?; + Self::add_balance_to_coldkey_account(new_coldkey, remaining_balance); + } - // 10. Update the last transaction block for the new coldkey Self::set_last_tx_block(new_coldkey, Self::get_current_block_as_u64()); - weight.saturating_accrue(T::DbWeight::get().writes(1)); - // 11. Remove the coldkey swap scheduled record - ColdkeySwapScheduled::::remove(old_coldkey); - - // 12. Emit the ColdkeySwapped event Self::deposit_event(Event::ColdkeySwapped { old_coldkey: old_coldkey.clone(), new_coldkey: new_coldkey.clone(), - swap_cost, }); + Ok(()) + } + + /// Charges the swap cost from the coldkey's account and recycles the tokens. + pub fn charge_swap_cost(coldkey: &T::AccountId, swap_cost: TaoCurrency) -> DispatchResult { + let burn_amount = Self::remove_balance_from_coldkey_account(coldkey, swap_cost.into()) + .map_err(|_| Error::::NotEnoughBalanceToPaySwapColdKey)?; + + if burn_amount < swap_cost { + return Err(Error::::NotEnoughBalanceToPaySwapColdKey.into()); + } + + Self::recycle_tao(burn_amount); - // 12. Return the result with the updated weight - Ok(Some(weight).into()) + Ok(()) } - /// Performs the actual coldkey swap operation, transferring all associated data and balances from the old coldkey to the new coldkey. - /// - /// # Arguments - /// - /// * `old_coldkey` - The account ID of the old coldkey. - /// * `new_coldkey` - The account ID of the new coldkey. - /// * `weight` - A mutable reference to the current transaction weight. - /// - /// # Returns - /// - /// Returns a `DispatchResult` indicating success or failure of the operation. - /// - /// # Steps - /// - /// 1. Swap TotalHotkeyColdkeyStakesThisInterval: - /// - For each hotkey owned by the old coldkey, transfer its stake and block data to the new coldkey. - /// - /// 2. Swap subnet ownership: - /// - For each subnet, if the old coldkey is the owner, transfer ownership to the new coldkey. - /// - /// 3. Swap Stakes: - /// - For each hotkey staking for the old coldkey, transfer its stake to the new coldkey. - /// - /// 4. Swap total coldkey stake: - /// - Transfer the total stake from the old coldkey to the new coldkey. - /// - /// 5. Swap StakingHotkeys: - /// - Transfer the list of staking hotkeys from the old coldkey to the new coldkey. - /// - /// 6. Swap hotkey owners: - /// - For each hotkey owned by the old coldkey, transfer ownership to the new coldkey. - /// - Update the list of owned hotkeys for both old and new coldkeys. - /// - /// 7. Transfer remaining balance: - /// - Transfer any remaining balance from the old coldkey to the new coldkey. - /// - /// Throughout the process, the function updates the transaction weight to reflect the operations performed. - /// - /// # Notes - /// - /// This function is a critical part of the coldkey swap process and should be called only after all necessary checks and validations have been performed. - pub fn perform_swap_coldkey( + /// Transfer the ownership of the subnet to the new coldkey if it is owned by the old coldkey. + fn transfer_subnet_ownership( + netuid: NetUid, old_coldkey: &T::AccountId, new_coldkey: &T::AccountId, - weight: &mut Weight, - ) -> DispatchResult { - // 1. Swap TotalHotkeyColdkeyStakesThisInterval - // TotalHotkeyColdkeyStakesThisInterval: MAP ( hotkey, coldkey ) --> ( stake, block ) | Stake of the hotkey for the coldkey. - // for hotkey in OwnedHotkeys::::get(old_coldkey).iter() { - // let (stake, block) = - // TotalHotkeyColdkeyStakesThisInterval::::get(&hotkey, old_coldkey); - // TotalHotkeyColdkeyStakesThisInterval::::remove(&hotkey, old_coldkey); - // TotalHotkeyColdkeyStakesThisInterval::::insert(&hotkey, new_coldkey, (stake, block)); - // weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); - // } (DEPRECATED) - - // 2. Swap subnet owner. - // SubnetOwner: MAP ( netuid ) --> (coldkey) | Owner of the subnet. - for netuid in Self::get_all_subnet_netuids() { - let subnet_owner = SubnetOwner::::get(netuid); - if subnet_owner == *old_coldkey { - SubnetOwner::::insert(netuid, new_coldkey.clone()); - } - weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); + ) { + let subnet_owner = SubnetOwner::::get(netuid); + if subnet_owner == *old_coldkey { + SubnetOwner::::insert(netuid, new_coldkey.clone()); + } + } - if let Some(old_auto_stake_hotkey) = AutoStakeDestination::::get(old_coldkey, netuid) - { - AutoStakeDestination::::remove(old_coldkey, netuid); - AutoStakeDestination::::insert( - new_coldkey, - netuid, - old_auto_stake_hotkey.clone(), - ); - AutoStakeDestinationColdkeys::::mutate(old_auto_stake_hotkey, netuid, |v| { - // Remove old/new coldkeys (avoid duplicates), then add the new one. - v.retain(|c| *c != *old_coldkey && *c != *new_coldkey); - v.push(new_coldkey.clone()); - }); - } + /// Transfer the auto stake destination from the old coldkey to the new coldkey if it is set. + fn transfer_auto_stake_destination( + netuid: NetUid, + old_coldkey: &T::AccountId, + new_coldkey: &T::AccountId, + ) { + if let Some(old_auto_stake_hotkey) = AutoStakeDestination::::get(old_coldkey, netuid) { + AutoStakeDestination::::remove(old_coldkey, netuid); + AutoStakeDestination::::insert(new_coldkey, netuid, old_auto_stake_hotkey.clone()); + AutoStakeDestinationColdkeys::::mutate(old_auto_stake_hotkey, netuid, |v| { + // Remove old/new coldkeys (avoid duplicates), then add the new one. + v.retain(|c| *c != *old_coldkey && *c != *new_coldkey); + v.push(new_coldkey.clone()); + }); } + } - // 3. Swap Stake. - // StakingHotkeys: MAP ( coldkey ) --> Vec( hotkey ) + /// Transfer the stake of all staking hotkeys linked to the old coldkey to the new coldkey. + fn transfer_coldkey_stake( + netuid: NetUid, + old_coldkey: &T::AccountId, + new_coldkey: &T::AccountId, + ) { for hotkey in StakingHotkeys::::get(old_coldkey) { - // 3.1 Swap Alpha - for netuid in Self::get_all_subnet_netuids() { - // Get the stake on the old (hot,coldkey) account. - let old_alpha: U64F64 = Alpha::::get((&hotkey, old_coldkey, netuid)); - // Get the stake on the new (hot,coldkey) account. - let new_alpha: U64F64 = Alpha::::get((&hotkey, new_coldkey, netuid)); - // Add the stake to new account. - Alpha::::insert( - (&hotkey, new_coldkey, netuid), - new_alpha.saturating_add(old_alpha), + // Get the stake on the old (hot,coldkey) account. + let old_alpha: U64F64 = Alpha::::get((&hotkey, old_coldkey, netuid)); + // Get the stake on the new (hot,coldkey) account. + let new_alpha: U64F64 = Alpha::::get((&hotkey, new_coldkey, netuid)); + // Add the stake to new account. + Alpha::::insert( + (&hotkey, new_coldkey, netuid), + new_alpha.saturating_add(old_alpha), + ); + // Remove the value from the old account. + Alpha::::remove((&hotkey, old_coldkey, netuid)); + + if new_alpha.saturating_add(old_alpha) > U64F64::from(0u64) { + Self::transfer_root_claimed_for_new_keys( + netuid, + &hotkey, + &hotkey, + old_coldkey, + new_coldkey, ); - // Remove the value from the old account. - Alpha::::remove((&hotkey, old_coldkey, netuid)); - - if new_alpha.saturating_add(old_alpha) > U64F64::from(0u64) { - Self::transfer_root_claimed_for_new_keys( - netuid, - &hotkey, - &hotkey, - old_coldkey, - new_coldkey, - ); - if netuid == NetUid::ROOT { - // Register new coldkey with root stake - Self::maybe_add_coldkey_index(new_coldkey); - } + if netuid == NetUid::ROOT { + // Register new coldkey with root stake + Self::maybe_add_coldkey_index(new_coldkey); } } - // Add the weight for the read and write. - weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2)); } + } - // 4. Swap TotalColdkeyAlpha (DEPRECATED) - // for netuid in Self::get_all_subnet_netuids() { - // let old_alpha_stake: u64 = TotalColdkeyAlpha::::get(old_coldkey, netuid); - // let new_alpha_stake: u64 = TotalColdkeyAlpha::::get(new_coldkey, netuid); - // TotalColdkeyAlpha::::insert( - // new_coldkey, - // netuid, - // new_alpha_stake.saturating_add(old_alpha_stake), - // ); - // TotalColdkeyAlpha::::remove(old_coldkey, netuid); - // } - // weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2)); - - // 5. Swap StakingHotkeys. - // StakingHotkeys: MAP ( coldkey ) --> Vec | Hotkeys staking for the coldkey. + /// Transfer staking hotkeys from the old coldkey to the new coldkey. + fn transfer_staking_hotkeys(old_coldkey: &T::AccountId, new_coldkey: &T::AccountId) { let old_staking_hotkeys: Vec = StakingHotkeys::::get(old_coldkey); let mut new_staking_hotkeys: Vec = StakingHotkeys::::get(new_coldkey); for hotkey in old_staking_hotkeys { @@ -231,13 +137,13 @@ impl Pallet { new_staking_hotkeys.push(hotkey); } } + StakingHotkeys::::remove(old_coldkey); StakingHotkeys::::insert(new_coldkey, new_staking_hotkeys); - weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2)); + } - // 6. Swap hotkey owners. - // Owner: MAP ( hotkey ) --> coldkey | Owner of the hotkey. - // OwnedHotkeys: MAP ( coldkey ) --> Vec | Hotkeys owned by the coldkey. + /// Transfer the ownership of the hotkeys owned by the old coldkey to the new coldkey. + fn transfer_hotkeys_ownership(old_coldkey: &T::AccountId, new_coldkey: &T::AccountId) { let old_owned_hotkeys: Vec = OwnedHotkeys::::get(old_coldkey); let mut new_owned_hotkeys: Vec = OwnedHotkeys::::get(new_coldkey); for owned_hotkey in old_owned_hotkeys.iter() { @@ -252,19 +158,5 @@ impl Pallet { } OwnedHotkeys::::remove(old_coldkey); OwnedHotkeys::::insert(new_coldkey, new_owned_hotkeys); - weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2)); - - // 7. Transfer remaining balance. - // Balance: MAP ( coldkey ) --> u64 | Balance of the coldkey. - // Transfer any remaining balance from old_coldkey to new_coldkey - let remaining_balance = Self::get_coldkey_balance(old_coldkey); - if remaining_balance > 0 { - Self::kill_coldkey_account(old_coldkey, remaining_balance)?; - Self::add_balance_to_coldkey_account(new_coldkey, remaining_balance); - } - weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2)); - - // Return ok. - Ok(()) } } diff --git a/pallets/subtensor/src/swap/swap_hotkey.rs b/pallets/subtensor/src/swap/swap_hotkey.rs index 4fdf87fb7b..a54a02a750 100644 --- a/pallets/subtensor/src/swap/swap_hotkey.rs +++ b/pallets/subtensor/src/swap/swap_hotkey.rs @@ -493,6 +493,11 @@ impl Pallet { // 8.3 Swap TaoDividendsPerSubnet // Tao dividends were removed + // 8.4 Swap VotingPower + // VotingPower( netuid, hotkey ) --> u64 -- the voting power EMA for the hotkey. + Self::swap_voting_power_for_hotkey(old_hotkey, new_hotkey, netuid); + weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2)); + // 9. Swap Alpha // Alpha( hotkey, coldkey, netuid ) -> alpha let old_alpha_values: Vec<((T::AccountId, NetUid), U64F64)> = diff --git a/pallets/subtensor/src/tests/claim_root.rs b/pallets/subtensor/src/tests/claim_root.rs index 717f3a5d28..6bcaee2fca 100644 --- a/pallets/subtensor/src/tests/claim_root.rs +++ b/pallets/subtensor/src/tests/claim_root.rs @@ -1184,13 +1184,7 @@ fn test_claim_root_with_swap_coldkey() { ); // Swap coldkey - let mut weight = Weight::zero(); - - assert_ok!(SubtensorModule::perform_swap_coldkey( - &coldkey, - &new_coldkey, - &mut weight - )); + assert_ok!(SubtensorModule::do_swap_coldkey(&coldkey, &new_coldkey,)); // Check swapped keys claimed values diff --git a/pallets/subtensor/src/tests/coinbase.rs b/pallets/subtensor/src/tests/coinbase.rs index a79f4b713a..093444e955 100644 --- a/pallets/subtensor/src/tests/coinbase.rs +++ b/pallets/subtensor/src/tests/coinbase.rs @@ -46,36 +46,6 @@ fn test_hotkey_take() { }); } -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::coinbase::test_dynamic_function_various_values --exact --show-output --nocapture -#[test] -fn test_dynamic_function_various_values() { - new_test_ext(1).execute_with(|| { - let price_values: [f64; 9] = [0.001, 0.1, 0.5, 1.0, 2.0, 10.0, 100.0, 200.0, 1000.0]; - let tao_in_values: [u64; 9] = [0, 1, 10, 100, 1_000, 1_000_000, 1_000_000_000, 1_000_000_000_000, 1_000_000_000_000_000 ]; - let alpha_emission_values: [u64; 9] = [0, 1, 10, 100, 1_000, 1_000_000, 1_000_000_000, 1_000_000_000_000, 1_000_000_000_000_000 ]; - - for &price in price_values.iter() { - for &tao_in in tao_in_values.iter() { - for &alpha_emission in alpha_emission_values.iter() { - // Set the price. - SubnetMechanism::::insert(NetUid::from(1), 1); - SubnetTAO::::insert(NetUid::from(1), TaoCurrency::from((price * 1_000_000_000.0) as u64)); - SubnetAlphaIn::::insert(NetUid::from(1), AlphaCurrency::from(1_000_000_000)); - let (tao_in_emission, alpha_in_emission, alpha_out_emission) = SubtensorModule::get_dynamic_tao_emission(1.into(), tao_in, alpha_emission); - assert!(tao_in_emission <= tao_in, "tao_in_emission is greater than tao_in"); - assert!(alpha_in_emission <= alpha_emission, "alpha_in_emission is greater than alpha_emission"); - assert!(alpha_out_emission <= 2 * alpha_emission, "alpha_out_emission is greater than 2 * alpha_emission"); - assert!((alpha_in_emission + alpha_out_emission) <= 2 * alpha_emission, "Sum of alpha_in_emission and alpha_out_emission is less than or equal to. 2 * alpha_emission"); - close( alpha_in_emission + alpha_out_emission, alpha_in_emission + alpha_emission, 10 ); - // if alpha_in_emission > 0 || tao_in_emission > 0 { - // assert!((tao_in_emission as f64 / alpha_in_emission as f64 - price).abs() < 1e-1, "Ratio of tao_in_emission to alpha_in_emission is not equal to price"); - // } - } - } - } - }); -} - // Test the base case of running coinbase with zero emission. // This test verifies that the coinbase mechanism can handle the edge case // of zero emission without errors or unexpected behavior. diff --git a/pallets/subtensor/src/tests/mechanism.rs b/pallets/subtensor/src/tests/mechanism.rs index 9e6450e09c..7f0ead8918 100644 --- a/pallets/subtensor/src/tests/mechanism.rs +++ b/pallets/subtensor/src/tests/mechanism.rs @@ -210,6 +210,7 @@ fn do_set_mechanism_count_ok_at_effective_cap() { new_test_ext(1).execute_with(|| { let netuid = NetUid::from(4u16); NetworksAdded::::insert(NetUid::from(4u16), true); // base subnet exists + MaxAllowedUids::::insert(netuid, 128u16); // Effective bound is min(runtime cap, compile-time cap) let runtime_cap = MaxMechanismCount::::get(); // e.g., MechId::from(8) diff --git a/pallets/subtensor/src/tests/migration.rs b/pallets/subtensor/src/tests/migration.rs index bed77e797f..beec7a3cba 100644 --- a/pallets/subtensor/src/tests/migration.rs +++ b/pallets/subtensor/src/tests/migration.rs @@ -25,7 +25,7 @@ use pallet_drand::types::RoundNumber; use scale_info::prelude::collections::VecDeque; use sp_core::{H256, U256, crypto::Ss58Codec}; use sp_io::hashing::twox_128; -use sp_runtime::traits::Zero; +use sp_runtime::{traits::Hash, traits::Zero}; use substrate_fixed::types::extra::U2; use substrate_fixed::types::{I96F32, U64F64}; use subtensor_runtime_common::{NetUidStorageIndex, TaoCurrency}; @@ -2875,7 +2875,6 @@ fn test_migrate_reset_unactive_sn_idempotence() { }); } -#[test] fn test_migrate_remove_old_identity_maps() { let migration = crate::migrations::migrate_remove_old_identity_maps::migrate_remove_old_identity_maps::; @@ -2968,3 +2967,75 @@ fn test_migrate_remove_unknown_neuron_axon_cert_prom() { } } } + +#[test] +fn test_migrate_coldkey_swap_scheduled_to_announcements() { + new_test_ext(1000).execute_with(|| { + const MIGRATION_NAME: &[u8] = b"migrate_coldkey_swap_scheduled_to_announcements"; + use crate::migrations::migrate_coldkey_swap_scheduled_to_announcements::*; + let now = frame_system::Pallet::::block_number(); + + // Set the schedule duration and reschedule duration + deprecated::ColdkeySwapScheduleDuration::::set(Some(now + 100)); + deprecated::ColdkeySwapRescheduleDuration::::set(Some(now + 200)); + + // Set some scheduled coldkey swaps + deprecated::ColdkeySwapScheduled::::insert( + U256::from(1), + (now + 100, U256::from(10)), + ); + deprecated::ColdkeySwapScheduled::::insert( + U256::from(2), + (now - 200, U256::from(20)), + ); + deprecated::ColdkeySwapScheduled::::insert( + U256::from(3), + (now + 200, U256::from(30)), + ); + deprecated::ColdkeySwapScheduled::::insert( + U256::from(4), + (now - 400, U256::from(40)), + ); + deprecated::ColdkeySwapScheduled::::insert( + U256::from(5), + (now + 300, U256::from(50)), + ); + + let w = migrate_coldkey_swap_scheduled_to_announcements::(); + + assert!(!w.is_zero(), "weight must be non-zero"); + assert!(HasMigrationRun::::get(MIGRATION_NAME)); + + // Ensure the deprecated storage is cleared + assert!(!deprecated::ColdkeySwapScheduleDuration::::exists()); + assert!(!deprecated::ColdkeySwapRescheduleDuration::::exists()); + assert_eq!(deprecated::ColdkeySwapScheduled::::iter().count(), 0); + + // Ensure scheduled have been migrated to announcements if not executed yet + // The announcement should be at the scheduled time - delay to be able to call + // the swap_coldkey_announced call at the old scheduled time + let delay = ColdkeySwapAnnouncementDelay::::get(); + assert_eq!(ColdkeySwapAnnouncements::::iter().count(), 3); + assert_eq!( + ColdkeySwapAnnouncements::::get(U256::from(1)), + Some(( + now + 100 - delay, + ::Hashing::hash_of(&U256::from(10)) + )) + ); + assert_eq!( + ColdkeySwapAnnouncements::::get(U256::from(3)), + Some(( + now + 200 - delay, + ::Hashing::hash_of(&U256::from(30)) + )) + ); + assert_eq!( + ColdkeySwapAnnouncements::::get(U256::from(5)), + Some(( + now + 300 - delay, + ::Hashing::hash_of(&U256::from(50)) + )) + ); + }); +} diff --git a/pallets/subtensor/src/tests/mock.rs b/pallets/subtensor/src/tests/mock.rs index b744c9b771..7af9420ba3 100644 --- a/pallets/subtensor/src/tests/mock.rs +++ b/pallets/subtensor/src/tests/mock.rs @@ -20,15 +20,16 @@ use frame_system as system; use frame_system::{EnsureRoot, RawOrigin, limits, offchain::CreateTransactionBase}; use pallet_subtensor_proxy as pallet_proxy; use pallet_subtensor_utility as pallet_utility; +use sp_consensus_aura::sr25519::AuthorityId as AuraId; use sp_core::{ConstU64, Get, H256, U256, offchain::KeyTypeId}; use sp_runtime::Perbill; use sp_runtime::{ BuildStorage, Percent, - traits::{BlakeTwo256, IdentityLookup}, + traits::{BadOrigin, BlakeTwo256, IdentityLookup}, }; use sp_std::{cell::RefCell, cmp::Ordering, sync::OnceLock}; use sp_tracing::tracing_subscriber; -use subtensor_runtime_common::{NetUid, TaoCurrency}; +use subtensor_runtime_common::{AuthorshipInfo, NetUid, TaoCurrency}; use subtensor_swap_interface::{Order, SwapHandler}; use tracing_subscriber::{EnvFilter, layer::SubscriberExt, util::SubscriberInitExt}; type Block = frame_system::mocking::MockBlock; @@ -37,16 +38,19 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event} = 1, - Balances: pallet_balances::{Pallet, Call, Config, Storage, Event} = 2, - SubtensorModule: crate::{Pallet, Call, Storage, Event} = 7, - Utility: pallet_utility::{Pallet, Call, Storage, Event} = 8, - Scheduler: pallet_scheduler::{Pallet, Call, Storage, Event} = 9, - Preimage: pallet_preimage::{Pallet, Call, Storage, Event} = 10, - Drand: pallet_drand::{Pallet, Call, Storage, Event} = 11, - Swap: pallet_subtensor_swap::{Pallet, Call, Storage, Event} = 12, - Crowdloan: pallet_crowdloan::{Pallet, Call, Storage, Event} = 13, - Proxy: pallet_subtensor_proxy = 14, + System: frame_system = 1, + Balances: pallet_balances = 2, + Timestamp: pallet_timestamp = 3, + Aura: pallet_aura = 4, + Shield: pallet_shield = 5, + SubtensorModule: crate = 6, + Utility: pallet_utility = 7, + Scheduler: pallet_scheduler = 8, + Preimage: pallet_preimage = 9, + Drand: pallet_drand = 10, + Swap: pallet_subtensor_swap = 11, + Crowdloan: pallet_crowdloan = 12, + Proxy: pallet_subtensor_proxy = 13, } ); @@ -142,6 +146,7 @@ impl system::Config for Test { type MaxConsumers = frame_support::traits::ConstU32<16>; type Nonce = u64; type Block = Block; + type DispatchGuard = crate::CheckColdkeySwap; } parameter_types! { @@ -149,6 +154,16 @@ parameter_types! { pub const SS58Prefix: u8 = 42; } +pub const MOCK_BLOCK_BUILDER: u64 = 12345u64; + +pub struct MockAuthorshipProvider; + +impl AuthorshipInfo for MockAuthorshipProvider { + fn author() -> Option { + Some(U256::from(MOCK_BLOCK_BUILDER)) + } +} + parameter_types! { pub const InitialMinAllowedWeights: u16 = 0; pub const InitialEmissionValue: u16 = 0; @@ -166,7 +181,7 @@ parameter_types! { pub const SelfOwnership: u64 = 2; pub const InitialImmunityPeriod: u16 = 2; pub const InitialMinAllowedUids: u16 = 2; - pub const InitialMaxAllowedUids: u16 = 4; + pub const InitialMaxAllowedUids: u16 = 256; pub const InitialBondsMovingAverage: u64 = 900_000; pub const InitialBondsPenalty:u16 = u16::MAX; pub const InitialBondsResetOn: bool = false; @@ -212,9 +227,8 @@ parameter_types! { pub const InitialAlphaLow: u16 = 45875; // Represents 0.7 as per the production default pub const InitialLiquidAlphaOn: bool = false; // Default value for LiquidAlphaOn pub const InitialYuma3On: bool = false; // Default value for Yuma3On - // pub const InitialNetworkMaxStake: u64 = u64::MAX; // (DEPRECATED) - pub const InitialColdkeySwapScheduleDuration: u64 = 5 * 24 * 60 * 60 / 12; // Default as 5 days - pub const InitialColdkeySwapRescheduleDuration: u64 = 24 * 60 * 60 / 12; // Default as 1 day + pub const InitialColdkeySwapAnnouncementDelay: u64 = 50; + pub const InitialColdkeySwapReannouncementDelay: u64 = 10; pub const InitialDissolveNetworkScheduleDuration: u64 = 5 * 24 * 60 * 60 / 12; // Default as 5 days pub const InitialTaoWeight: u64 = 0; // 100% global weight. pub const InitialEmaPriceHalvingPeriod: u64 = 201_600_u64; // 4 weeks @@ -284,8 +298,8 @@ impl crate::Config for Test { type LiquidAlphaOn = InitialLiquidAlphaOn; type Yuma3On = InitialYuma3On; type Preimages = Preimage; - type InitialColdkeySwapScheduleDuration = InitialColdkeySwapScheduleDuration; - type InitialColdkeySwapRescheduleDuration = InitialColdkeySwapRescheduleDuration; + type InitialColdkeySwapAnnouncementDelay = InitialColdkeySwapAnnouncementDelay; + type InitialColdkeySwapReannouncementDelay = InitialColdkeySwapReannouncementDelay; type InitialDissolveNetworkScheduleDuration = InitialDissolveNetworkScheduleDuration; type InitialTaoWeight = InitialTaoWeight; type InitialEmaPriceHalvingPeriod = InitialEmaPriceHalvingPeriod; @@ -299,6 +313,7 @@ impl crate::Config for Test { type MaxImmuneUidsPercentage = MaxImmuneUidsPercentage; type CommitmentsInterface = CommitmentsI; type EvmKeyAssociateRateLimit = EvmKeyAssociateRateLimit; + type AuthorshipProvider = MockAuthorshipProvider; } // Swap-related parameter types @@ -552,6 +567,41 @@ where } } +#[derive_impl(pallet_timestamp::config_preludes::TestDefaultConfig)] +impl pallet_timestamp::Config for Test { + type MinimumPeriod = ConstU64<0>; +} + +parameter_types! { + pub const MaxAuthorities: u32 = 32; + pub const AllowMultipleBlocksPerSlot: bool = false; + pub const SlotDuration: u64 = 6000; +} + +impl pallet_aura::Config for Test { + type AuthorityId = AuraId; + // For tests we don't need dynamic disabling; just use unit type. + type DisabledValidators = (); + type MaxAuthorities = MaxAuthorities; + type AllowMultipleBlocksPerSlot = AllowMultipleBlocksPerSlot; + type SlotDuration = SlotDuration; +} + +pub struct TestAuthorityOrigin; + +impl pallet_shield::AuthorityOriginExt for TestAuthorityOrigin { + type AccountId = U256; + + fn ensure_validator(_origin: RuntimeOrigin) -> Result { + Ok(U256::from(0)) + } +} + +impl pallet_shield::Config for Test { + type RuntimeCall = RuntimeCall; + type AuthorityOrigin = TestAuthorityOrigin; +} + static TEST_LOGS_INIT: OnceLock<()> = OnceLock::new(); pub fn init_logs_for_tests() { diff --git a/pallets/subtensor/src/tests/mod.rs b/pallets/subtensor/src/tests/mod.rs index bbaf25af58..8f07572e25 100644 --- a/pallets/subtensor/src/tests/mod.rs +++ b/pallets/subtensor/src/tests/mod.rs @@ -15,7 +15,7 @@ mod leasing; mod math; mod mechanism; mod migration; -mod mock; +pub(crate) mod mock; mod move_stake; mod networks; mod neuron_info; @@ -30,4 +30,5 @@ mod swap_coldkey; mod swap_hotkey; mod swap_hotkey_with_subnet; mod uids; +mod voting_power; mod weights; diff --git a/pallets/subtensor/src/tests/move_stake.rs b/pallets/subtensor/src/tests/move_stake.rs index dfd9927da4..57be08e2df 100644 --- a/pallets/subtensor/src/tests/move_stake.rs +++ b/pallets/subtensor/src/tests/move_stake.rs @@ -710,7 +710,7 @@ fn test_do_move_storage_updates() { destination_netuid ), alpha2, - epsilon = 2.into() + epsilon = 50.into() ); }); } diff --git a/pallets/subtensor/src/tests/networks.rs b/pallets/subtensor/src/tests/networks.rs index 4605ac8bef..aa45fb441a 100644 --- a/pallets/subtensor/src/tests/networks.rs +++ b/pallets/subtensor/src/tests/networks.rs @@ -826,7 +826,8 @@ fn destroy_alpha_out_many_stakers_complex_distribution() { netuid.into(), min_stake, ); - min_stake.saturating_add(fee) + // Double the fees because fee is calculated for min_stake, not for min_amount + min_stake + fee * 2.into() }; const N: usize = 20; diff --git a/pallets/subtensor/src/tests/recycle_alpha.rs b/pallets/subtensor/src/tests/recycle_alpha.rs index 32a95c700d..5cf589de97 100644 --- a/pallets/subtensor/src/tests/recycle_alpha.rs +++ b/pallets/subtensor/src/tests/recycle_alpha.rs @@ -1,12 +1,12 @@ +use super::mock; +use super::mock::*; +use crate::*; use approx::assert_abs_diff_eq; use frame_support::{assert_noop, assert_ok, traits::Currency}; use sp_core::U256; -use substrate_fixed::types::U64F64; +use substrate_fixed::types::{U64F64, U96F32}; use subtensor_runtime_common::{AlphaCurrency, Currency as CurrencyT}; - -use super::mock; -use super::mock::*; -use crate::*; +use subtensor_swap_interface::SwapHandler; #[test] fn test_recycle_success() { @@ -618,3 +618,288 @@ fn test_burn_precision_loss() { ); }); } + +#[test] +fn test_add_stake_burn_success() { + new_test_ext(1).execute_with(|| { + let hotkey_account_id = U256::from(533453); + let coldkey_account_id = U256::from(55453); + let amount = DefaultMinStake::::get().to_u64() * 10; + + let netuid = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); + + mock::setup_reserves( + netuid, + (amount * 1_000_000).into(), + (amount * 10_000_000).into(), + ); + + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount); + + // Check we have zero staked before transfer + assert_eq!( + SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), + TaoCurrency::ZERO + ); + + // Execute add_stake_burn - this stakes TAO to get Alpha, then burns the Alpha + assert_ok!(SubtensorModule::add_stake_burn( + RuntimeOrigin::signed(coldkey_account_id), + hotkey_account_id, + netuid, + amount.into(), + None, + )); + + // After "add stake and burn", hotkey should have zero stake since alpha is burned immediately + assert_eq!( + SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), + TaoCurrency::ZERO + ); + + // We spent TAO + assert_abs_diff_eq!( + SubtensorModule::get_coldkey_balance(&coldkey_account_id), + 0u64, + epsilon = 1u64 + ); + + // Verify AlphaBurned event was emitted + assert!(System::events().iter().any(|e| { + matches!( + &e.event, + RuntimeEvent::SubtensorModule(Event::AlphaBurned(..)) + ) + })); + + // Verify AddStakeBurn event was emitted + assert!(System::events().iter().any(|e| { + matches!( + &e.event, + RuntimeEvent::SubtensorModule(Event::AddStakeBurn { .. }) + ) + })); + }); +} + +#[test] +fn test_add_stake_burn_with_limit_success() { + new_test_ext(1).execute_with(|| { + let hotkey_account_id = U256::from(533453); + let coldkey_account_id = U256::from(55453); + let amount: u64 = 100_000_000_000; // 100 TAO - moderate amount + + // Add network + let netuid = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); + + // Setup reserves with large liquidity to minimize slippage + let tao_reserve = TaoCurrency::from(1_000_000_000_000); // 1000 TAO + let alpha_in = AlphaCurrency::from(1_000_000_000_000); // 1000 Alpha + mock::setup_reserves(netuid, tao_reserve, alpha_in); + + // Verify current price is 1.0 + let current_price = + ::SwapInterface::current_alpha_price(netuid.into()); + assert_eq!(current_price, U96F32::from_num(1.0)); + + // Give coldkey sufficient balance + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount); + + let initial_balance = SubtensorModule::get_coldkey_balance(&coldkey_account_id); + + // Setup limit price at 2.0 TAO per Alpha + // With 100 TAO into 1000/1000 pool, price moves from 1.0 to ~1.21 + let limit_price = TaoCurrency::from(2_000_000_000); // 2.0 TAO per Alpha + + // Execute add_stake_burn with limit + assert_ok!(SubtensorModule::add_stake_burn( + RuntimeOrigin::signed(coldkey_account_id), + hotkey_account_id, + netuid, + amount.into(), + Some(limit_price), + )); + + // After "add stake and burn", hotkey should have zero stake since alpha is burned immediately + assert_eq!( + SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), + TaoCurrency::ZERO + ); + + // TAO should have been spent + let final_balance = SubtensorModule::get_coldkey_balance(&coldkey_account_id); + assert!( + final_balance < initial_balance, + "TAO should have been spent" + ); + + // Final price should be between initial (1.0) and limit (2.0) + let final_price = + ::SwapInterface::current_alpha_price(netuid.into()); + assert!( + final_price.to_num::() >= 1.0 && final_price.to_num::() <= 2.0, + "Final price {} should be between 1.0 and 2.0", + final_price.to_num::() + ); + + // Verify AlphaBurned event was emitted + assert!(System::events().iter().any(|e| { + matches!( + &e.event, + RuntimeEvent::SubtensorModule(Event::AlphaBurned(..)) + ) + })); + }); +} + +#[test] +fn test_add_stake_burn_non_owner_fails() { + new_test_ext(1).execute_with(|| { + let hotkey_account_id = U256::from(1); + let coldkey_account_id = U256::from(2); + let non_owner_coldkey = U256::from(3); + let amount = DefaultMinStake::::get().to_u64() * 10; + + // Add network with coldkey_account_id as owner + let netuid = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); + + mock::setup_reserves( + netuid, + (amount * 1_000_000).into(), + (amount * 10_000_000).into(), + ); + + // Give non-owner some balance + SubtensorModule::add_balance_to_coldkey_account(&non_owner_coldkey, amount); + + // Non-owner trying to call add_stake_burn should fail with BadOrigin + assert_noop!( + SubtensorModule::add_stake_burn( + RuntimeOrigin::signed(non_owner_coldkey), + hotkey_account_id, + netuid, + amount.into(), + None, + ), + DispatchError::BadOrigin + ); + }); +} + +#[test] +fn test_add_stake_burn_nonexistent_subnet_fails() { + new_test_ext(1).execute_with(|| { + let hotkey_account_id = U256::from(1); + let coldkey_account_id = U256::from(2); + let amount = DefaultMinStake::::get().to_u64() * 10; + + // Give some balance + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount); + + // Try to call add_stake_burn on non-existent subnet + let nonexistent_netuid = NetUid::from(999); + assert_noop!( + SubtensorModule::add_stake_burn( + RuntimeOrigin::signed(coldkey_account_id), + hotkey_account_id, + nonexistent_netuid, + amount.into(), + None, + ), + DispatchError::BadOrigin + ); + }); +} + +#[test] +fn test_add_stake_burn_insufficient_balance_fails() { + new_test_ext(1).execute_with(|| { + let hotkey_account_id = U256::from(1); + let coldkey_account_id = U256::from(2); + let amount = DefaultMinStake::::get().to_u64() * 10; + + // Add network + let netuid = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); + + mock::setup_reserves( + netuid, + (amount * 1_000_000).into(), + (amount * 10_000_000).into(), + ); + + // Try to call add_stake_burn without sufficient balance + assert_noop!( + SubtensorModule::add_stake_burn( + RuntimeOrigin::signed(coldkey_account_id), + hotkey_account_id, + netuid, + amount.into(), + None, + ), + Error::::NotEnoughBalanceToStake + ); + }); +} + +#[test] +fn test_add_stake_burn_rate_limit_exceeded() { + new_test_ext(1).execute_with(|| { + let hotkey_account_id = U256::from(533453); + let coldkey_account_id = U256::from(55453); + let amount: u64 = 10_000_000_000; // 10 TAO + + // Add network + let netuid = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); + + // Setup reserves with large liquidity + let tao_reserve = TaoCurrency::from(1_000_000_000_000); + let alpha_in = AlphaCurrency::from(1_000_000_000_000); + mock::setup_reserves(netuid, tao_reserve, alpha_in); + + // Give coldkey sufficient balance for multiple "add stake and burn" operations. + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount * 10); + + assert_eq!( + SubtensorModule::get_rate_limited_last_block(&RateLimitKey::AddStakeBurn(netuid)), + 0 + ); + + // First "add stake and burn" should succeed + assert_ok!(SubtensorModule::add_stake_burn( + RuntimeOrigin::signed(coldkey_account_id), + hotkey_account_id, + netuid, + amount.into(), + None, + )); + + assert_eq!( + SubtensorModule::get_rate_limited_last_block(&RateLimitKey::AddStakeBurn(netuid)), + SubtensorModule::get_current_block_as_u64() + ); + + // Second "add stake and burn" immediately after should fail due to rate limit + assert_noop!( + SubtensorModule::add_stake_burn( + RuntimeOrigin::signed(coldkey_account_id), + hotkey_account_id, + netuid, + amount.into(), + None, + ), + Error::::AddStakeBurnRateLimitExceeded + ); + + // After stepping past the rate limit, "add stake and burn" should succeed again + let rate_limit = TransactionType::AddStakeBurn.rate_limit_on_subnet::(netuid); + step_block(rate_limit as u16); + + assert_ok!(SubtensorModule::add_stake_burn( + RuntimeOrigin::signed(coldkey_account_id), + hotkey_account_id, + netuid, + amount.into(), + None, + )); + }); +} diff --git a/pallets/subtensor/src/tests/registration.rs b/pallets/subtensor/src/tests/registration.rs index c82e173907..635b996cea 100644 --- a/pallets/subtensor/src/tests/registration.rs +++ b/pallets/subtensor/src/tests/registration.rs @@ -13,7 +13,7 @@ use subtensor_runtime_common::{AlphaCurrency, Currency as CurrencyT, NetUid, Net use super::mock; use super::mock::*; -use crate::transaction_extension::SubtensorTransactionExtension; +use crate::extensions::SubtensorTransactionExtension; use crate::{AxonInfoOf, CustomTransactionError, Error}; /******************************************** diff --git a/pallets/subtensor/src/tests/serving.rs b/pallets/subtensor/src/tests/serving.rs index b52666bf26..552af372e3 100644 --- a/pallets/subtensor/src/tests/serving.rs +++ b/pallets/subtensor/src/tests/serving.rs @@ -2,7 +2,7 @@ use super::mock::*; use crate::Error; -use crate::transaction_extension::SubtensorTransactionExtension; +use crate::extensions::SubtensorTransactionExtension; use crate::*; use frame_support::assert_noop; use frame_support::{ diff --git a/pallets/subtensor/src/tests/staking.rs b/pallets/subtensor/src/tests/staking.rs index 6c7e18b707..6a293fa11e 100644 --- a/pallets/subtensor/src/tests/staking.rs +++ b/pallets/subtensor/src/tests/staking.rs @@ -692,6 +692,9 @@ fn test_remove_stake_total_balance_no_change() { let netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); register_ok_neuron(netuid, hotkey_account_id, coldkey_account_id, 192213123); + // Set fee rate to 0 so that alpha fee is not moved to block producer + pallet_subtensor_swap::FeeRate::::insert(netuid, 0); + // Some basic assertions assert_eq!( SubtensorModule::get_total_stake(), @@ -910,6 +913,9 @@ fn test_remove_stake_total_issuance_no_change() { let netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); register_ok_neuron(netuid, hotkey_account_id, coldkey_account_id, 192213123); + // Set fee rate to 0 so that alpha fee is not moved to block producer + pallet_subtensor_swap::FeeRate::::insert(netuid, 0); + // Give it some $$$ in his coldkey balance SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount); @@ -975,7 +981,7 @@ fn test_remove_stake_total_issuance_no_change() { assert_abs_diff_eq!( SubtensorModule::get_total_stake(), SubtensorModule::get_network_min_lock() + total_fee.into(), - epsilon = TaoCurrency::from(fee) / 1000.into() + epsilon = TaoCurrency::from(fee) / 1000.into() + 1.into() ); // Check if total issuance is equal to the added stake, even after remove stake (no fee, @@ -1637,6 +1643,9 @@ fn test_clear_small_nominations() { let fee = DefaultMinStake::::get().to_u64(); let init_balance = amount + fee + ExistentialDeposit::get(); + // Set fee rate to 0 so that alpha fee is not moved to block producer + pallet_subtensor_swap::FeeRate::::insert(netuid, 0); + // Register hot1. register_ok_neuron(netuid, hot1, cold1, 0); Delegates::::insert(hot1, SubtensorModule::get_min_delegate_take()); @@ -2797,7 +2806,7 @@ fn test_max_amount_add_stable() { // cargo test --package pallet-subtensor --lib -- tests::staking::test_max_amount_add_dynamic --exact --show-output #[test] fn test_max_amount_add_dynamic() { - // tao_in, alpha_in, limit_price, expected_max_swappable + // tao_in, alpha_in, limit_price, expected_max_swappable (with 0.05% fees) [ // Zero handling (no panics) ( @@ -2811,16 +2820,16 @@ fn test_max_amount_add_dynamic() { // Low bounds (100, 100, 1_100_000_000, Ok(4)), (1_000, 1_000, 1_100_000_000, Ok(48)), - (10_000, 10_000, 1_100_000_000, Ok(489)), + (10_000, 10_000, 1_100_000_000, Ok(488)), // Basic math - (1_000_000, 1_000_000, 4_000_000_000, Ok(1_000_000)), - (1_000_000, 1_000_000, 9_000_000_000, Ok(2_000_000)), - (1_000_000, 1_000_000, 16_000_000_000, Ok(3_000_000)), + (1_000_000, 1_000_000, 4_000_000_000, Ok(1_000_500)), + (1_000_000, 1_000_000, 9_000_000_000, Ok(2_001_000)), + (1_000_000, 1_000_000, 16_000_000_000, Ok(3_001_500)), ( 1_000_000_000_000, 1_000_000_000_000, 16_000_000_000, - Ok(3_000_000_000_000), + Ok(3_001_500_000_000), ), // Normal range values with edge cases ( @@ -2861,7 +2870,7 @@ fn test_max_amount_add_dynamic() { 150_000_000_000, 100_000_000_000, 6_000_000_000, - Ok(150_000_000_000), + Ok(150_075_000_000), ), // Miscellaneous overflows and underflows (u64::MAX / 2, u64::MAX, u64::MAX, Ok(u64::MAX)), @@ -2905,7 +2914,7 @@ fn test_max_amount_add_dynamic() { Ok(v) => assert_abs_diff_eq!( SubtensorModule::get_max_amount_add(netuid, limit_price.into()).unwrap(), v, - epsilon = v / 100 + epsilon = v / 10000 ), } }); @@ -2999,7 +3008,7 @@ fn test_max_amount_remove_dynamic() { let subnet_owner_hotkey = U256::from(1002); let netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); - // tao_in, alpha_in, limit_price, expected_max_swappable + // tao_in, alpha_in, limit_price, expected_max_swappable (+ 0.05% fee) [ // Zero handling (no panics) ( @@ -3029,13 +3038,13 @@ fn test_max_amount_remove_dynamic() { (1_001, 1_001, 10_000, Ok(316_000)), (1_001, 1_001, 100_000, Ok(100_000)), // Basic math - (1_000_000, 1_000_000, 250_000_000, Ok(1_000_000)), - (1_000_000, 1_000_000, 62_500_000, Ok(3_000_000)), + (1_000_000, 1_000_000, 250_000_000, Ok(1_010_000)), + (1_000_000, 1_000_000, 62_500_000, Ok(3_030_000)), ( 1_000_000_000_000, 1_000_000_000_000, 62_500_000, - Ok(3_000_000_000_000), + Ok(3_030_000_000_000), ), // Normal range values with edge cases and sanity checks (200_000_000_000, 100_000_000_000, 0, Ok(u64::MAX)), @@ -3043,13 +3052,13 @@ fn test_max_amount_remove_dynamic() { 200_000_000_000, 100_000_000_000, 500_000_000, - Ok(100_000_000_000), + Ok(101_000_000_000), ), ( 200_000_000_000, 100_000_000_000, 125_000_000, - Ok(300_000_000_000), + Ok(303_000_000_000), ), ( 200_000_000_000, @@ -3068,7 +3077,7 @@ fn test_max_amount_remove_dynamic() { )), ), (200_000_000_000, 100_000_000_000, 1_999_999_999, Ok(24)), - (200_000_000_000, 100_000_000_000, 1_999_999_990, Ok(252)), + (200_000_000_000, 100_000_000_000, 1_999_999_990, Ok(250)), // Miscellaneous overflows and underflows ( 21_000_000_000_000_000, @@ -3076,7 +3085,7 @@ fn test_max_amount_remove_dynamic() { 21_000_000_000_000_000, Ok(30_700_000), ), - (21_000_000_000_000_000, 1_000_000, u64::MAX, Ok(67_164)), + (21_000_000_000_000_000, 1_000_000, u64::MAX, Ok(67_000)), ( 21_000_000_000_000_000, 1_000_000_000_000_000_000, @@ -3089,13 +3098,13 @@ fn test_max_amount_remove_dynamic() { 21_000_000_000_000_000, 1_000_000_000_000_000_000, 20_000_000, - Ok(24_800_000_000_000_000), + Ok(24_700_000_000_000_000), ), ( 21_000_000_000_000_000, 21_000_000_000_000_000, 999_999_999, - Ok(10_500_000), + Ok(10_605_000), ), ( 21_000_000_000_000_000, @@ -3434,8 +3443,8 @@ fn test_max_amount_move_dynamic_stable() { assert_abs_diff_eq!( SubtensorModule::get_max_amount_move(dynamic_netuid, stable_netuid, 375_000_000.into()) .unwrap(), - alpha_in, - epsilon = alpha_in / 1000.into(), + alpha_in + alpha_in / 2000.into(), // + 0.05% fee + epsilon = alpha_in / 10_000.into(), ); // Precision test: @@ -4091,6 +4100,10 @@ fn test_remove_99_9991_per_cent_stake_removes_all() { let netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); register_ok_neuron(netuid, hotkey_account_id, coldkey_account_id, 192213123); + // Set fee rate to 0 so that alpha fee is not moved to block producer + // and the hotkey stake does drop to 0 + pallet_subtensor_swap::FeeRate::::insert(netuid, 0); + // Give it some $$$ in his coldkey balance SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount); @@ -4152,6 +4165,10 @@ fn test_remove_99_9989_per_cent_stake_leaves_a_little() { let netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); register_ok_neuron(netuid, hotkey_account_id, coldkey_account_id, 192213123); + // Set fee rate to 0 so that alpha fee is not moved to block producer + // to avoid false success in this test + pallet_subtensor_swap::FeeRate::::insert(netuid, 0); + // Give it some $$$ in his coldkey balance SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount); @@ -4872,6 +4889,7 @@ fn test_swap_fees_tao_correctness() { let owner_hotkey = U256::from(1); let owner_coldkey = U256::from(2); let coldkey = U256::from(4); + let block_builder = U256::from(12345u64); let amount = 1_000_000_000; let owner_balance_before = amount * 10; let user_balance_before = amount * 100; @@ -4880,8 +4898,6 @@ fn test_swap_fees_tao_correctness() { let netuid = add_dynamic_network(&owner_hotkey, &owner_coldkey); SubtensorModule::add_balance_to_coldkey_account(&owner_coldkey, owner_balance_before); SubtensorModule::add_balance_to_coldkey_account(&coldkey, user_balance_before); - let fee_rate = pallet_subtensor_swap::FeeRate::::get(NetUid::from(netuid)) as f64 - / u16::MAX as f64; pallet_subtensor_swap::EnabledUserLiquidity::::insert(NetUid::from(netuid), true); // Forse-set alpha in and tao reserve to make price equal 0.25 @@ -4890,8 +4906,11 @@ fn test_swap_fees_tao_correctness() { mock::setup_reserves(netuid, tao_reserve, alpha_in); // Check starting "total TAO" - let total_tao_before = - user_balance_before + owner_balance_before + SubnetTAO::::get(netuid).to_u64(); + let block_builder_balance_before = SubtensorModule::get_coldkey_balance(&block_builder); + let total_tao_before = user_balance_before + + owner_balance_before + + SubnetTAO::::get(netuid).to_u64() + + block_builder_balance_before; // Get alpha for owner assert_ok!(SubtensorModule::add_stake( @@ -4900,7 +4919,6 @@ fn test_swap_fees_tao_correctness() { netuid, amount.into(), )); - let mut fees = (fee_rate * amount as f64) as u64; // Add owner coldkey Alpha as concentrated liquidity // between current price current price + 0.01 @@ -4931,7 +4949,6 @@ fn test_swap_fees_tao_correctness() { ((limit_price * u64::MAX as f64) as u64).into(), true )); - fees += (fee_rate * amount as f64) as u64; let user_alpha = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( &owner_hotkey, @@ -4945,15 +4962,26 @@ fn test_swap_fees_tao_correctness() { netuid, user_alpha, )); - // Do not add fees because selling fees are in alpha + + // TODO: This block is for balancer swap + // Cause tao fees to propagate to SubnetTAO + // let (claimed_tao_fees, _) = + // ::SwapInterface::adjust_protocol_liquidity( + // netuid, + // 0.into(), + // 0.into(), + // ); + // SubnetTAO::::mutate(netuid, |tao| *tao += claimed_tao_fees); // Check ending "total TAO" let owner_balance_after = SubtensorModule::get_coldkey_balance(&owner_coldkey); let user_balance_after = SubtensorModule::get_coldkey_balance(&coldkey); + let block_builder_balance_after = SubtensorModule::get_coldkey_balance(&block_builder); + let total_tao_after = user_balance_after + owner_balance_after + SubnetTAO::::get(netuid).to_u64() - + fees; + + block_builder_balance_after; // Total TAO does not change, leave some epsilon for rounding assert_abs_diff_eq!(total_tao_before, total_tao_after, epsilon = 2); @@ -5051,7 +5079,7 @@ fn test_remove_stake_full_limit_ok() { ); let new_balance = SubtensorModule::get_coldkey_balance(&coldkey_account_id); - assert_abs_diff_eq!(new_balance, 9_086_000_000, epsilon = 1_000_000); + assert_abs_diff_eq!(new_balance, 9_086_700_000, epsilon = 1_000_000); }); } @@ -5135,9 +5163,10 @@ fn test_remove_stake_full_limit_ok_with_no_limit_price() { ); let new_balance = SubtensorModule::get_coldkey_balance(&coldkey_account_id); - assert_abs_diff_eq!(new_balance, 9_086_000_000, epsilon = 1_000_000); + assert_abs_diff_eq!(new_balance, 9_086_700_000, epsilon = 1_000_000); }); } + /// This test verifies that minimum stake amount is sufficient to move price and apply /// non-zero staking fees #[test] @@ -5224,6 +5253,10 @@ fn test_update_position_fees() { let alpha_in = AlphaCurrency::from(400_000_000_000); mock::setup_reserves(netuid, tao_reserve, alpha_in); + // Get the block builder balance + let block_builder = U256::from(MOCK_BLOCK_BUILDER); + let block_builder_balance_before = Balances::free_balance(block_builder); + // Get alpha for owner assert_ok!(SubtensorModule::add_stake( RuntimeOrigin::signed(owner_coldkey), @@ -5275,13 +5308,8 @@ fn test_update_position_fees() { user_alpha, )); - // Modify position - fees should be collected and paid to the owner + // Modify position - fees should be collected and paid to the owner (block builder is already paid by now) let owner_tao_before = SubtensorModule::get_coldkey_balance(&owner_coldkey); - let owner_alpha_before = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( - &owner_hotkey, - &owner_coldkey, - netuid, - ); // Make small modification let delta = @@ -5297,6 +5325,7 @@ fn test_update_position_fees() { )); // Check ending owner TAO and alpha + let block_builder_balance_after_add = Balances::free_balance(block_builder); let owner_tao_after_add = SubtensorModule::get_coldkey_balance(&owner_coldkey); let owner_alpha_after_add = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( &owner_hotkey, @@ -5304,8 +5333,10 @@ fn test_update_position_fees() { netuid, ); - assert!(owner_tao_after_add > owner_tao_before); - assert!(owner_alpha_after_add > owner_alpha_before); // always greater because of claimed fees + assert!( + owner_tao_after_add + block_builder_balance_after_add + > owner_tao_before + block_builder_balance_before + ); // Make small modification again - should not claim more fees assert_ok!(Swap::modify_position( @@ -5638,11 +5669,15 @@ fn test_staking_records_flow() { )); // Check that outflow has been recorded (less unstaking fees) - let expected_unstake_fee = expected_flow * fee_rate; + // The block builder will receive a fraction of the fees in alpha and will be forced + // to unstake it. So, the additional out-flow is recorded for this. + let unstaked_block_builder_fraction = 1.; + let expected_unstake_fee = + expected_flow * fee_rate * (1. - unstaked_block_builder_fraction); assert_abs_diff_eq!( SubnetTaoFlow::::get(netuid), expected_unstake_fee as i64, - epsilon = (expected_unstake_fee / 100.0) as i64 + epsilon = ((expected_unstake_fee / 100.0) as i64).max(1) ); }); } diff --git a/pallets/subtensor/src/tests/swap_coldkey.rs b/pallets/subtensor/src/tests/swap_coldkey.rs index 9d3bdbfc62..36d083344c 100644 --- a/pallets/subtensor/src/tests/swap_coldkey.rs +++ b/pallets/subtensor/src/tests/swap_coldkey.rs @@ -3,21 +3,22 @@ clippy::expect_used, clippy::indexing_slicing, clippy::panic, - clippy::unwrap_used + clippy::unwrap_used, + clippy::arithmetic_side_effects )] use approx::assert_abs_diff_eq; use codec::Encode; -use frame_support::dispatch::DispatchInfo; +use frame_support::dispatch::{DispatchInfo, GetDispatchInfo}; use frame_support::error::BadOrigin; use frame_support::traits::OnInitialize; use frame_support::traits::schedule::DispatchTime; use frame_support::traits::schedule::v3::Named as ScheduleNamed; -use frame_support::weights::Weight; use frame_support::{assert_err, assert_noop, assert_ok}; use frame_system::{Config, RawOrigin}; use sp_core::{Get, H256, U256}; -use sp_runtime::traits::{DispatchInfoOf, TransactionExtension}; +use sp_runtime::traits::Hash; +use sp_runtime::traits::{DispatchInfoOf, DispatchTransaction, TransactionExtension}; use sp_runtime::{DispatchError, traits::TxBaseImplication}; use substrate_fixed::types::U96F32; use subtensor_runtime_common::{AlphaCurrency, Currency, SubnetInfo, TaoCurrency}; @@ -25,501 +26,767 @@ use subtensor_swap_interface::{SwapEngine, SwapHandler}; use super::mock; use super::mock::*; -use crate::transaction_extension::SubtensorTransactionExtension; +use crate::extensions::SubtensorTransactionExtension; use crate::*; -use crate::{Call, ColdkeySwapScheduleDuration, Error}; -// // SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_coldkey -- test_swap_total_hotkey_coldkey_stakes_this_interval --exact --nocapture -// #[test] -// fn test_swap_total_hotkey_coldkey_stakes_this_interval() { -// new_test_ext(1).execute_with(|| { -// let old_coldkey = U256::from(1); -// let new_coldkey = U256::from(2); -// let hotkey = U256::from(3); -// let stake = 100; -// let block = 42; - -// OwnedHotkeys::::insert(old_coldkey, vec![hotkey]); -// TotalHotkeyColdkeyStakesThisInterval::::insert(hotkey, old_coldkey, (stake, block)); - -// let mut weight = Weight::zero(); -// assert_ok!(SubtensorModule::perform_swap_coldkey( -// &old_coldkey, -// &new_coldkey, -// &mut weight -// )); - -// assert!(!TotalHotkeyColdkeyStakesThisInterval::::contains_key( -// hotkey, -// old_coldkey -// )); -// assert_eq!( -// TotalHotkeyColdkeyStakesThisInterval::::get(hotkey, new_coldkey), -// (stake, block) -// ); -// }); -// } - -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_coldkey -- test_swap_subnet_owner --exact --nocapture +use crate::{Call, Error}; + +fn run_to_block(n: u64) { + System::run_to_block_with::( + n, + frame_system::RunToBlockHooks::default().before_finalize(|bn| { + Timestamp::set_timestamp(bn); + }), + ); +} + #[test] -fn test_swap_subnet_owner() { +fn test_announce_coldkey_swap_works() { new_test_ext(1).execute_with(|| { - let old_coldkey = U256::from(1); + let who = U256::from(1); let new_coldkey = U256::from(2); - let netuid = NetUid::from(1u16); + let new_coldkey_hash = ::Hashing::hash_of(&new_coldkey); + let ed = ExistentialDeposit::get(); - add_network(netuid, 1, 0); - SubnetOwner::::insert(netuid, old_coldkey); + assert_eq!(ColdkeySwapAnnouncements::::iter().count(), 0); - let mut weight = Weight::zero(); - assert_ok!(SubtensorModule::perform_swap_coldkey( - &old_coldkey, - &new_coldkey, - &mut weight + let swap_cost = SubtensorModule::get_key_swap_cost().to_u64(); + SubtensorModule::add_balance_to_coldkey_account(&who, swap_cost + ed); + assert_eq!(SubtensorModule::get_coldkey_balance(&who), swap_cost + ed); + + assert_ok!(SubtensorModule::announce_coldkey_swap( + RuntimeOrigin::signed(who), + new_coldkey_hash, )); - assert_eq!(SubnetOwner::::get(netuid), new_coldkey); + let delay = ColdkeySwapAnnouncementDelay::::get(); + let now = System::block_number(); + assert_eq!( + ColdkeySwapAnnouncements::::iter().collect::>(), + vec![(who, (now + delay, new_coldkey_hash))] + ); + assert_eq!(SubtensorModule::get_coldkey_balance(&who), ed); + assert_eq!( + last_event(), + RuntimeEvent::SubtensorModule(Event::ColdkeySwapAnnounced { + who, + new_coldkey_hash, + }) + ); }); } -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::swap_coldkey::test_swap_total_coldkey_stake --exact --show-output #[test] -fn test_swap_total_coldkey_stake() { +fn test_announce_coldkey_swap_with_existing_announcement_past_delay_works() { new_test_ext(1).execute_with(|| { - let old_coldkey = U256::from(1); + let who = U256::from(1); let new_coldkey = U256::from(2); - let other_coldkey = U256::from(3); - let hotkey = U256::from(4); - let other_hotkey = U256::from(5); - let stake = DefaultMinStake::::get().to_u64() * 10; - - let netuid = NetUid::from(1u16); - add_network(netuid, 1, 0); - SubtensorModule::add_balance_to_coldkey_account(&old_coldkey, stake * 2 + 1_000); - register_ok_neuron(netuid, hotkey, old_coldkey, 1001000); - register_ok_neuron(netuid, other_hotkey, other_coldkey, 1001000); + let new_coldkey_hash = ::Hashing::hash_of(&new_coldkey); + let new_coldkey_2 = U256::from(3); + let new_coldkey_2_hash = ::Hashing::hash_of(&new_coldkey_2); - let reserve = stake * 10; - mock::setup_reserves(netuid, reserve.into(), reserve.into()); + assert_eq!(ColdkeySwapAnnouncements::::iter().count(), 0); - assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(old_coldkey), - hotkey, - netuid, - stake.into() - )); - assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(old_coldkey), - other_hotkey, - netuid, - stake.into() - )); - let total_stake_before_swap = SubtensorModule::get_total_stake_for_coldkey(&old_coldkey); + let swap_cost = SubtensorModule::get_key_swap_cost().to_u64(); + SubtensorModule::add_balance_to_coldkey_account(&who, 2 * swap_cost); - let mut weight = Weight::zero(); - assert_ok!(SubtensorModule::perform_swap_coldkey( - &old_coldkey, - &new_coldkey, - &mut weight + assert_ok!(SubtensorModule::announce_coldkey_swap( + RuntimeOrigin::signed(who), + new_coldkey_hash, )); + let now = System::block_number(); + let delay = ColdkeySwapAnnouncementDelay::::get(); assert_eq!( - SubtensorModule::get_total_stake_for_coldkey(&old_coldkey), - TaoCurrency::ZERO + ColdkeySwapAnnouncements::::iter().collect::>(), + vec![(who, (now + delay, new_coldkey_hash))] ); + + let reannouncement_delay = ColdkeySwapReannouncementDelay::::get(); + run_to_block(now + delay + reannouncement_delay); + + assert_ok!(SubtensorModule::announce_coldkey_swap( + RuntimeOrigin::signed(who), + new_coldkey_2_hash, + )); + + let now = System::block_number(); assert_eq!( - SubtensorModule::get_total_stake_for_coldkey(&new_coldkey), - total_stake_before_swap + ColdkeySwapAnnouncements::::iter().collect::>(), + vec![(who, (now + delay, new_coldkey_2_hash))] ); }); } -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_coldkey -- test_swap_staking_hotkeys --exact --nocapture #[test] -fn test_swap_staking_hotkeys() { +fn test_announce_coldkey_swap_only_pays_swap_cost_if_no_announcement_exists() { new_test_ext(1).execute_with(|| { - let old_coldkey = U256::from(1); + let who = U256::from(1); let new_coldkey = U256::from(2); - let hotkey = U256::from(3); + let new_coldkey_hash = ::Hashing::hash_of(&new_coldkey); + let new_coldkey_2 = U256::from(3); + let new_coldkey_2_hash = ::Hashing::hash_of(&new_coldkey_2); + let ed = ExistentialDeposit::get(); - StakingHotkeys::::insert(old_coldkey, vec![hotkey]); + let swap_cost = SubtensorModule::get_key_swap_cost().to_u64(); + SubtensorModule::add_balance_to_coldkey_account(&who, swap_cost + ed); + assert_eq!(SubtensorModule::get_coldkey_balance(&who), swap_cost + ed); - let mut weight = Weight::zero(); - assert_ok!(SubtensorModule::perform_swap_coldkey( - &old_coldkey, - &new_coldkey, - &mut weight + assert_ok!(SubtensorModule::announce_coldkey_swap( + RuntimeOrigin::signed(who), + new_coldkey_hash, )); + assert_eq!(SubtensorModule::get_coldkey_balance(&who), ed); + + let now = System::block_number(); + let base_delay = ColdkeySwapAnnouncementDelay::::get(); + let reannouncement_delay = ColdkeySwapReannouncementDelay::::get(); + run_to_block(now + base_delay + reannouncement_delay); - assert!(StakingHotkeys::::get(old_coldkey).is_empty()); - assert_eq!(StakingHotkeys::::get(new_coldkey), vec![hotkey]); + assert_ok!(SubtensorModule::announce_coldkey_swap( + RuntimeOrigin::signed(who), + new_coldkey_2_hash, + )); + assert_eq!(SubtensorModule::get_coldkey_balance(&who), ed); }); } -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_coldkey -- test_swap_hotkey_owners --exact --nocapture #[test] -fn test_swap_hotkey_owners() { +fn test_announce_coldkey_swap_with_bad_origin_fails() { new_test_ext(1).execute_with(|| { - let old_coldkey = U256::from(1); - let new_coldkey = U256::from(2); - let hotkey = U256::from(3); - - Owner::::insert(hotkey, old_coldkey); - OwnedHotkeys::::insert(old_coldkey, vec![hotkey]); + let new_coldkey = U256::from(1); + let new_coldkey_hash = ::Hashing::hash_of(&new_coldkey); - let mut weight = Weight::zero(); - assert_ok!(SubtensorModule::perform_swap_coldkey( - &old_coldkey, - &new_coldkey, - &mut weight - )); + assert_noop!( + SubtensorModule::announce_coldkey_swap(RuntimeOrigin::none(), new_coldkey_hash), + BadOrigin + ); - assert_eq!(Owner::::get(hotkey), new_coldkey); - assert!(OwnedHotkeys::::get(old_coldkey).is_empty()); - assert_eq!(OwnedHotkeys::::get(new_coldkey), vec![hotkey]); + assert_noop!( + SubtensorModule::announce_coldkey_swap(RuntimeOrigin::root(), new_coldkey_hash), + BadOrigin + ); }); } -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_coldkey -- test_transfer_remaining_balance --exact --nocapture + #[test] -fn test_transfer_remaining_balance() { +fn test_announce_coldkey_swap_with_existing_announcement_not_past_delay_fails() { new_test_ext(1).execute_with(|| { - let old_coldkey = U256::from(1); + let who = U256::from(1); let new_coldkey = U256::from(2); - let balance = 100; + let new_coldkey_hash = ::Hashing::hash_of(&new_coldkey); + let new_coldkey_2 = U256::from(3); + let new_coldkey_2_hash = ::Hashing::hash_of(&new_coldkey_2); - SubtensorModule::add_balance_to_coldkey_account(&old_coldkey, balance); + assert_eq!(ColdkeySwapAnnouncements::::iter().count(), 0); - let mut weight = Weight::zero(); - assert_ok!(SubtensorModule::perform_swap_coldkey( - &old_coldkey, - &new_coldkey, - &mut weight + let swap_cost = SubtensorModule::get_key_swap_cost().to_u64(); + let ed = ExistentialDeposit::get(); + SubtensorModule::add_balance_to_coldkey_account(&who, swap_cost + ed); + + assert_ok!(SubtensorModule::announce_coldkey_swap( + RuntimeOrigin::signed(who), + new_coldkey_hash, )); - assert_eq!(SubtensorModule::get_coldkey_balance(&old_coldkey), 0); - assert_eq!(SubtensorModule::get_coldkey_balance(&new_coldkey), balance); + let now = System::block_number(); + let delay = ColdkeySwapAnnouncementDelay::::get(); + assert_eq!( + ColdkeySwapAnnouncements::::iter().collect::>(), + vec![(who, (now + delay, new_coldkey_hash))] + ); + + assert_noop!( + SubtensorModule::announce_coldkey_swap(RuntimeOrigin::signed(who), new_coldkey_2_hash,), + Error::::ColdkeySwapReannouncedTooEarly + ); }); } -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::swap_coldkey::test_swap_with_no_stake --exact --show-output #[test] -fn test_swap_with_no_stake() { +fn test_swap_coldkey_announced_works() { new_test_ext(1).execute_with(|| { - let old_coldkey = U256::from(1); + let who = U256::from(1); let new_coldkey = U256::from(2); + let new_coldkey_hash = ::Hashing::hash_of(&new_coldkey); + let hotkey1 = U256::from(1001); + let hotkey2 = U256::from(1002); + let hotkey3 = U256::from(1003); + let ed = ExistentialDeposit::get(); + let min_stake = DefaultMinStake::::get().to_u64(); + let stake1 = min_stake * 10; + let stake2 = min_stake * 20; + let stake3 = min_stake * 30; + let now = System::block_number(); + + ColdkeySwapAnnouncements::::insert(who, (now, new_coldkey_hash)); + + // Run some blocks for the announcement to be past the delay + let delay = ColdkeySwapAnnouncementDelay::::get() + 1; + run_to_block(now + delay); + + SubtensorModule::add_balance_to_coldkey_account(&who, stake1 + stake2 + stake3 + ed); + + let ( + netuid1, + netuid2, + hotkeys, + hk1_alpha, + hk2_alpha, + hk3_alpha, + total_ck_stake, + identity, + balance_before, + total_stake_before, + ) = comprehensive_setup!( + who, + new_coldkey, + new_coldkey_hash, + stake1, + stake2, + stake3, + hotkey1, + hotkey2, + hotkey3 + ); - let mut weight = Weight::zero(); - assert_ok!(SubtensorModule::perform_swap_coldkey( - &old_coldkey, - &new_coldkey, - &mut weight + assert_ok!(SubtensorModule::swap_coldkey_announced( + ::RuntimeOrigin::signed(who), + new_coldkey )); - assert_eq!( - SubtensorModule::get_total_stake_for_coldkey(&old_coldkey), - TaoCurrency::ZERO - ); - assert_eq!( - SubtensorModule::get_total_stake_for_coldkey(&new_coldkey), - TaoCurrency::ZERO + comprehensive_checks!( + who, + hotkey1, + hotkey2, + hotkey3, + hotkeys, + new_coldkey, + balance_before, + identity, + netuid1, + netuid2, + hk1_alpha, + hk2_alpha, + hk3_alpha, + total_ck_stake, + total_stake_before, + 0_u64 // Charged on announcement ); }); } -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_coldkey -- test_swap_with_multiple_hotkeys --exact --nocapture #[test] -fn test_swap_with_multiple_hotkeys() { +fn test_swap_coldkey_announced_with_bad_origin_fails() { new_test_ext(1).execute_with(|| { - let old_coldkey = U256::from(1); + let who = U256::from(1); let new_coldkey = U256::from(2); - let hotkey1 = U256::from(3); - let hotkey2 = U256::from(4); - OwnedHotkeys::::insert(old_coldkey, vec![hotkey1, hotkey2]); - - let mut weight = Weight::zero(); - assert_ok!(SubtensorModule::perform_swap_coldkey( - &old_coldkey, - &new_coldkey, - &mut weight - )); + assert_noop!( + SubtensorModule::swap_coldkey_announced(RuntimeOrigin::none(), new_coldkey), + BadOrigin + ); - assert!(OwnedHotkeys::::get(old_coldkey).is_empty()); - assert_eq!( - OwnedHotkeys::::get(new_coldkey), - vec![hotkey1, hotkey2] + assert_noop!( + SubtensorModule::swap_coldkey_announced(RuntimeOrigin::root(), new_coldkey), + BadOrigin ); }); } -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_coldkey -- test_swap_with_multiple_subnets --exact --nocapture #[test] -fn test_swap_with_multiple_subnets() { +fn test_swap_coldkey_announced_without_announcement_fails() { new_test_ext(1).execute_with(|| { - let old_coldkey = U256::from(1); + let who = U256::from(1); let new_coldkey = U256::from(2); - let netuid1 = NetUid::from(1); - let netuid2 = NetUid::from(2); - add_network(netuid1, 1, 0); - add_network(netuid2, 1, 0); - SubnetOwner::::insert(netuid1, old_coldkey); - SubnetOwner::::insert(netuid2, old_coldkey); + assert_noop!( + SubtensorModule::swap_coldkey_announced(RuntimeOrigin::signed(who), new_coldkey), + Error::::ColdkeySwapAnnouncementNotFound + ); + }) +} - let mut weight = Weight::zero(); - assert_ok!(SubtensorModule::perform_swap_coldkey( - &old_coldkey, - &new_coldkey, - &mut weight - )); +#[test] +fn test_swap_coldkey_announced_with_mismatched_coldkey_hash_fails() { + new_test_ext(1).execute_with(|| { + let who = U256::from(1); + let new_coldkey = U256::from(2); + let new_coldkey_hash = ::Hashing::hash_of(&new_coldkey); + let other_coldkey = U256::from(3); + let now = System::block_number(); - assert_eq!(SubnetOwner::::get(netuid1), new_coldkey); - assert_eq!(SubnetOwner::::get(netuid2), new_coldkey); - }); + ColdkeySwapAnnouncements::::insert(who, (now, new_coldkey_hash)); + + assert_noop!( + SubtensorModule::swap_coldkey_announced(RuntimeOrigin::signed(who), other_coldkey), + Error::::AnnouncedColdkeyHashDoesNotMatch + ); + }) } -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_coldkey -- test_swap_with_zero_balance --exact --nocapture #[test] -fn test_swap_with_zero_balance() { +fn test_swap_coldkey_announced_too_early_fails() { new_test_ext(1).execute_with(|| { - let old_coldkey = U256::from(1); + let who = U256::from(1); let new_coldkey = U256::from(2); + let new_coldkey_hash = ::Hashing::hash_of(&new_coldkey); - let mut weight = Weight::zero(); - assert_ok!(SubtensorModule::perform_swap_coldkey( - &old_coldkey, - &new_coldkey, - &mut weight - )); + // Now case + let now = System::block_number(); + let delay = ColdkeySwapAnnouncementDelay::::get(); + ColdkeySwapAnnouncements::::insert(who, (now + delay, new_coldkey_hash)); - assert_eq!(Balances::free_balance(old_coldkey), 0); - assert_eq!(Balances::free_balance(new_coldkey), 0); - }); + assert_noop!( + SubtensorModule::swap_coldkey_announced( + ::RuntimeOrigin::signed(who), + new_coldkey + ), + Error::::ColdkeySwapTooEarly + ); + + // Now + delay - 1 case + run_to_block(now + delay - 1); + + assert_noop!( + SubtensorModule::swap_coldkey_announced( + ::RuntimeOrigin::signed(who), + new_coldkey + ), + Error::::ColdkeySwapTooEarly + ); + }) } -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::swap_coldkey::test_swap_idempotency --exact --show-output #[test] -fn test_swap_idempotency() { +fn test_swap_coldkey_announced_with_already_associated_coldkey_fails() { new_test_ext(1).execute_with(|| { - let old_coldkey = U256::from(1); + let who = U256::from(1); let new_coldkey = U256::from(2); + let new_coldkey_hash = ::Hashing::hash_of(&new_coldkey); let hotkey = U256::from(3); - let netuid = NetUid::from(1u16); - let stake = DefaultMinStake::::get().to_u64() * 10; - let reserve = stake * 10; - mock::setup_reserves(netuid, reserve.into(), reserve.into()); + let swap_cost = SubtensorModule::get_key_swap_cost().to_u64(); + let ed = ExistentialDeposit::get(); + SubtensorModule::add_balance_to_coldkey_account(&who, swap_cost + ed); - // Add a network - add_network(netuid, 1, 0); - SubtensorModule::add_balance_to_coldkey_account(&old_coldkey, stake); // Give old coldkey some balance - // Stake to a hotkey - register_ok_neuron(netuid, hotkey, old_coldkey, 1001000); - assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(old_coldkey), - hotkey, - netuid, - stake.into() + assert_ok!(SubtensorModule::announce_coldkey_swap( + RuntimeOrigin::signed(who), + new_coldkey_hash, )); - // Get stake before swap - let stake_before_swap = SubtensorModule::get_total_stake_for_coldkey(&old_coldkey); + let now = System::block_number(); + let delay = ColdkeySwapAnnouncementDelay::::get() + 1; + run_to_block(now + delay); - let mut weight = Weight::zero(); - assert_ok!(SubtensorModule::perform_swap_coldkey( - &old_coldkey, - &new_coldkey, - &mut weight - )); - assert_ok!(SubtensorModule::perform_swap_coldkey( - &old_coldkey, - &new_coldkey, - &mut weight - )); + SubtensorModule::create_account_if_non_existent(&new_coldkey, &hotkey); - assert_eq!( - SubtensorModule::get_total_stake_for_coldkey(&old_coldkey), - TaoCurrency::ZERO - ); - assert_eq!( - SubtensorModule::get_total_stake_for_coldkey(&new_coldkey), - stake_before_swap + assert_noop!( + SubtensorModule::swap_coldkey_announced( + ::RuntimeOrigin::signed(who), + new_coldkey + ), + Error::::ColdKeyAlreadyAssociated ); - }); + }) } -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::swap_coldkey::test_swap_with_max_values --exact --show-output #[test] -fn test_swap_with_max_values() { +fn test_swap_coldkey_announced_with_hotkey_fails() { new_test_ext(1).execute_with(|| { - let old_coldkey = U256::from(1); + let who = U256::from(1); let new_coldkey = U256::from(2); - let old_coldkey2 = U256::from(3); - let new_coldkey2 = U256::from(4); - let hotkey = U256::from(5); - let hotkey2 = U256::from(6); - let other_coldkey = U256::from(7); - let netuid = NetUid::from(1); - let netuid2 = NetUid::from(2); - let stake = 10_000; - let max_stake = 21_000_000_000_000_000; // 21 Million TAO; max possible balance. + let hotkey = U256::from(3); + let hotkey_hash = ::Hashing::hash_of(&hotkey); + let now = System::block_number(); - // Add a network - add_network(netuid, 1, 0); - add_network(netuid2, 1, 0); + ColdkeySwapAnnouncements::::insert(who, (now, hotkey_hash)); - // Register hotkey on each subnet. - // hotkey2 is owned by other_coldkey. - register_ok_neuron(netuid, hotkey, old_coldkey, 1001000); - register_ok_neuron(netuid2, hotkey2, other_coldkey, 1001000); + let now = System::block_number(); + let delay = ColdkeySwapAnnouncementDelay::::get() + 1; + run_to_block(now + delay); - // Give balance to old_coldkey and old_coldkey2. - SubtensorModule::add_balance_to_coldkey_account(&old_coldkey, max_stake + 1_000); - SubtensorModule::add_balance_to_coldkey_account(&old_coldkey2, max_stake + 1_000); + SubtensorModule::create_account_if_non_existent(&new_coldkey, &hotkey); - let reserve = max_stake * 10; - mock::setup_reserves(netuid, reserve.into(), reserve.into()); - mock::setup_reserves(netuid2, reserve.into(), reserve.into()); + assert_noop!( + SubtensorModule::swap_coldkey_announced( + ::RuntimeOrigin::signed(who), + hotkey + ), + Error::::NewColdKeyIsHotkey + ); + }) +} - // Stake to hotkey on each subnet. - assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(old_coldkey), - hotkey, - netuid, - max_stake.into() - )); - let expected_stake1 = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( - &hotkey, +#[test] +fn test_swap_coldkey_works() { + new_test_ext(1000).execute_with(|| { + let old_coldkey = U256::from(1); + let new_coldkey = U256::from(2); + let new_coldkey_hash = ::Hashing::hash_of(&new_coldkey); + let hotkey1 = U256::from(1001); + let hotkey2 = U256::from(1002); + let hotkey3 = U256::from(1003); + let ed = ExistentialDeposit::get(); + let swap_cost = SubtensorModule::get_key_swap_cost(); + let min_stake = DefaultMinStake::::get().to_u64(); + let stake1 = min_stake * 10; + let stake2 = min_stake * 20; + let stake3 = min_stake * 30; + + SubtensorModule::add_balance_to_coldkey_account( &old_coldkey, - netuid, + swap_cost.to_u64() + stake1 + stake2 + stake3 + ed, ); - assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(old_coldkey2), - hotkey2, - netuid2, - max_stake.into() - )); - let expected_stake2 = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( - &hotkey2, - &old_coldkey2, + // Some old announcement and dispute that will be cleared + let now = System::block_number() - 100; + ColdkeySwapAnnouncements::::insert(old_coldkey, (now, new_coldkey_hash)); + ColdkeySwapDisputes::::insert(old_coldkey, now); + + let ( + netuid1, netuid2, + hotkeys, + hk1_alpha, + hk2_alpha, + hk3_alpha, + total_ck_stake, + identity, + balance_before, + total_stake_before, + ) = comprehensive_setup!( + old_coldkey, + new_coldkey, + new_coldkey_hash, + stake1, + stake2, + stake3, + hotkey1, + hotkey2, + hotkey3 ); - let mut weight = Weight::zero(); - assert_ok!(SubtensorModule::perform_swap_coldkey( - &old_coldkey, - &new_coldkey, - &mut weight - )); - assert_ok!(SubtensorModule::perform_swap_coldkey( - &old_coldkey2, - &new_coldkey2, - &mut weight + assert_ok!(SubtensorModule::swap_coldkey( + ::RuntimeOrigin::root(), + old_coldkey, + new_coldkey, + swap_cost, )); - assert_eq!( - SubtensorModule::get_total_stake_for_coldkey(&old_coldkey), - TaoCurrency::ZERO - ); - assert_abs_diff_eq!( - SubtensorModule::get_total_stake_for_coldkey(&new_coldkey), - expected_stake1.to_u64().into(), - epsilon = TaoCurrency::from(expected_stake1.to_u64()) / 1000.into() - ); - assert_eq!( - SubtensorModule::get_total_stake_for_coldkey(&old_coldkey2), - TaoCurrency::ZERO - ); - assert_abs_diff_eq!( - SubtensorModule::get_total_stake_for_coldkey(&new_coldkey2), - expected_stake2.to_u64().into(), - epsilon = TaoCurrency::from(expected_stake2.to_u64()) / 1000.into() + comprehensive_checks!( + old_coldkey, + hotkey1, + hotkey2, + hotkey3, + hotkeys, + new_coldkey, + balance_before, + identity, + netuid1, + netuid2, + hk1_alpha, + hk2_alpha, + hk3_alpha, + total_ck_stake, + total_stake_before, + swap_cost.to_u64() ); + + // Check that the old announcement and dispute are cleared + assert!(!ColdkeySwapAnnouncements::::contains_key(old_coldkey)); + assert!(!ColdkeySwapDisputes::::contains_key(old_coldkey)); }); } -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::swap_coldkey::test_swap_with_non_existent_new_coldkey --exact --show-output #[test] -fn test_swap_with_non_existent_new_coldkey() { +fn test_swap_coldkey_works_with_zero_cost() { new_test_ext(1).execute_with(|| { let old_coldkey = U256::from(1); let new_coldkey = U256::from(2); - let hotkey = U256::from(3); - let stake = DefaultMinStake::::get().to_u64() * 10; - let netuid = NetUid::from(1); + let new_coldkey_hash = ::Hashing::hash_of(&new_coldkey); + let hotkey1 = U256::from(1001); + let hotkey2 = U256::from(1002); + let hotkey3 = U256::from(1003); + let ed = ExistentialDeposit::get(); + let swap_cost = 0u64; + let min_stake = DefaultMinStake::::get().to_u64(); + let stake1 = min_stake * 10; + let stake2 = min_stake * 20; + let stake3 = min_stake * 30; - add_network(netuid, 1, 0); - register_ok_neuron(netuid, hotkey, old_coldkey, 1001000); - // Give old coldkey some balance. - SubtensorModule::add_balance_to_coldkey_account(&old_coldkey, stake + 1_000); + SubtensorModule::add_balance_to_coldkey_account( + &old_coldkey, + stake1 + stake2 + stake3 + ed, + ); - let reserve = stake * 10; - mock::setup_reserves(netuid, reserve.into(), reserve.into()); + let ( + netuid1, + netuid2, + hotkeys, + hk1_alpha, + hk2_alpha, + hk3_alpha, + total_ck_stake, + identity, + balance_before, + total_stake_before, + ) = comprehensive_setup!( + old_coldkey, + new_coldkey, + new_coldkey_hash, + stake1, + stake2, + stake3, + hotkey1, + hotkey2, + hotkey3 + ); - // Stake to hotkey. - assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(old_coldkey), - hotkey, - netuid, - stake.into() + assert_ok!(SubtensorModule::swap_coldkey( + ::RuntimeOrigin::root(), + old_coldkey, + new_coldkey, + swap_cost.into(), )); - let expected_stake = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( - &hotkey, - &old_coldkey, - netuid, + + comprehensive_checks!( + old_coldkey, + hotkey1, + hotkey2, + hotkey3, + hotkeys, + new_coldkey, + balance_before, + identity, + netuid1, + netuid2, + hk1_alpha, + hk2_alpha, + hk3_alpha, + total_ck_stake, + total_stake_before, + swap_cost ); + }); +} - let mut weight = Weight::zero(); - assert_ok!(SubtensorModule::perform_swap_coldkey( - &old_coldkey, - &new_coldkey, - &mut weight - )); +#[test] +fn test_swap_coldkey_with_bad_origin_fails() { + new_test_ext(1).execute_with(|| { + let who = U256::from(1); + let old_coldkey = U256::from(2); + let new_coldkey = U256::from(3); + let swap_cost = SubtensorModule::get_key_swap_cost(); + + assert_noop!( + SubtensorModule::swap_coldkey( + ::RuntimeOrigin::signed(who), + old_coldkey, + new_coldkey, + swap_cost, + ), + BadOrigin + ); + + assert_noop!( + SubtensorModule::swap_coldkey( + ::RuntimeOrigin::none(), + old_coldkey, + new_coldkey, + swap_cost + ), + BadOrigin + ); + }); +} + +#[test] +fn test_swap_coldkey_with_not_enough_balance_to_pay_swap_cost_fails() { + new_test_ext(1).execute_with(|| { + let old_coldkey = U256::from(1); + let new_coldkey = U256::from(2); + let swap_cost = SubtensorModule::get_key_swap_cost(); + + // No balance to pay swap cost + assert_noop!( + SubtensorModule::swap_coldkey( + RuntimeOrigin::root(), + old_coldkey, + new_coldkey, + swap_cost + ), + Error::::NotEnoughBalanceToPaySwapColdKey + ); + + // Needs to preserve ED + let balance = SubtensorModule::get_key_swap_cost().to_u64() + ExistentialDeposit::get() - 1; + SubtensorModule::add_balance_to_coldkey_account(&old_coldkey, balance); + assert_noop!( + SubtensorModule::swap_coldkey( + RuntimeOrigin::root(), + old_coldkey, + new_coldkey, + swap_cost + ), + Error::::NotEnoughBalanceToPaySwapColdKey + ); + }); +} + +#[test] +fn test_do_swap_coldkey_preserves_new_coldkey_identity() { + new_test_ext(1).execute_with(|| { + let who = U256::from(1); + let new_coldkey = U256::from(2); + + let old_identity = ChainIdentityV2 { + name: b"Old identity".to_vec(), + ..Default::default() + }; + IdentitiesV2::::insert(who, old_identity.clone()); + + let new_identity = ChainIdentityV2 { + name: b"New identity".to_vec(), + ..Default::default() + }; + IdentitiesV2::::insert(new_coldkey, new_identity.clone()); + + assert_ok!(SubtensorModule::do_swap_coldkey(&who, &new_coldkey,)); + + // Identity is preserved + assert_eq!(IdentitiesV2::::get(who), Some(old_identity)); + assert_eq!(IdentitiesV2::::get(new_coldkey), Some(new_identity)); + }); +} + +#[test] +fn test_announce_coldkey_swap_with_not_enough_balance_to_pay_swap_cost_fails() { + new_test_ext(1).execute_with(|| { + let who = U256::from(1); + let new_coldkey = U256::from(2); + let new_coldkey_hash = ::Hashing::hash_of(&new_coldkey); + + // No balance to pay swap cost + assert_noop!( + SubtensorModule::announce_coldkey_swap(RuntimeOrigin::signed(who), new_coldkey_hash), + Error::::NotEnoughBalanceToPaySwapColdKey + ); + + // Needs to preserve ED + let balance = SubtensorModule::get_key_swap_cost().to_u64() + ExistentialDeposit::get() - 1; + SubtensorModule::add_balance_to_coldkey_account(&who, balance); + assert_noop!( + SubtensorModule::announce_coldkey_swap(RuntimeOrigin::signed(who), new_coldkey_hash), + Error::::NotEnoughBalanceToPaySwapColdKey + ); + }); +} + +#[test] +fn test_do_swap_coldkey_with_no_stake() { + new_test_ext(1).execute_with(|| { + let old_coldkey = U256::from(1); + let new_coldkey = U256::from(2); + + assert_ok!(SubtensorModule::do_swap_coldkey(&old_coldkey, &new_coldkey)); assert_eq!( SubtensorModule::get_total_stake_for_coldkey(&old_coldkey), TaoCurrency::ZERO ); - - let actual_stake = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( - &hotkey, - &new_coldkey, - netuid, - ); - assert_abs_diff_eq!( - actual_stake, - expected_stake, - epsilon = expected_stake / 1000.into() + assert_eq!( + SubtensorModule::get_total_stake_for_coldkey(&new_coldkey), + TaoCurrency::ZERO ); }); } -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_coldkey -- test_swap_with_max_hotkeys --exact --nocapture #[test] -fn test_swap_with_max_hotkeys() { +fn test_do_swap_coldkey_with_max_values() { new_test_ext(1).execute_with(|| { let old_coldkey = U256::from(1); let new_coldkey = U256::from(2); - let max_hotkeys = 1000; - let hotkeys: Vec = (0..max_hotkeys).map(U256::from).collect(); + let old_coldkey2 = U256::from(3); + let new_coldkey2 = U256::from(4); + let hotkey = U256::from(5); + let hotkey2 = U256::from(6); + let other_coldkey = U256::from(7); + let netuid = NetUid::from(1); + let netuid2 = NetUid::from(2); + let stake = 10_000; + let max_stake = 21_000_000_000_000_000; // 21 Million TAO; max possible balance. + + // Add a network + add_network(netuid, 1, 0); + add_network(netuid2, 1, 0); + + // Register hotkey on each subnet. + // hotkey2 is owned by other_coldkey. + register_ok_neuron(netuid, hotkey, old_coldkey, 1001000); + register_ok_neuron(netuid2, hotkey2, other_coldkey, 1001000); + + // Give balance to old_coldkey and old_coldkey2. + SubtensorModule::add_balance_to_coldkey_account(&old_coldkey, max_stake + 1_000); + SubtensorModule::add_balance_to_coldkey_account(&old_coldkey2, max_stake + 1_000); - OwnedHotkeys::::insert(old_coldkey, hotkeys.clone()); + let reserve = max_stake * 10; + mock::setup_reserves(netuid, reserve.into(), reserve.into()); + mock::setup_reserves(netuid2, reserve.into(), reserve.into()); - let mut weight = Weight::zero(); - assert_ok!(SubtensorModule::perform_swap_coldkey( + // Stake to hotkey on each subnet. + assert_ok!(SubtensorModule::add_stake( + <::RuntimeOrigin>::signed(old_coldkey), + hotkey, + netuid, + max_stake.into() + )); + let expected_stake1 = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( + &hotkey, &old_coldkey, - &new_coldkey, - &mut weight + netuid, + ); + + assert_ok!(SubtensorModule::add_stake( + <::RuntimeOrigin>::signed(old_coldkey2), + hotkey2, + netuid2, + max_stake.into() + )); + let expected_stake2 = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( + &hotkey2, + &old_coldkey2, + netuid2, + ); + + assert_ok!(SubtensorModule::do_swap_coldkey(&old_coldkey, &new_coldkey,)); + assert_ok!(SubtensorModule::do_swap_coldkey( + &old_coldkey2, + &new_coldkey2, )); - assert!(OwnedHotkeys::::get(old_coldkey).is_empty()); - assert_eq!(OwnedHotkeys::::get(new_coldkey), hotkeys); + assert_eq!( + SubtensorModule::get_total_stake_for_coldkey(&old_coldkey), + TaoCurrency::ZERO + ); + assert_abs_diff_eq!( + SubtensorModule::get_total_stake_for_coldkey(&new_coldkey), + expected_stake1.to_u64().into(), + epsilon = TaoCurrency::from(expected_stake1.to_u64()) / 1000.into() + ); + assert_eq!( + SubtensorModule::get_total_stake_for_coldkey(&old_coldkey2), + TaoCurrency::ZERO + ); + assert_abs_diff_eq!( + SubtensorModule::get_total_stake_for_coldkey(&new_coldkey2), + expected_stake2.to_u64().into(), + epsilon = TaoCurrency::from(expected_stake2.to_u64()) / 1000.into() + ); }); } -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_coldkey -- test_swap_effect_on_delegated_stake --exact --nocapture #[test] -fn test_swap_effect_on_delegated_stake() { +fn test_do_swap_coldkey_effect_on_delegated_stake() { new_test_ext(1).execute_with(|| { let subnet_owner_coldkey = U256::from(1001); let subnet_owner_hotkey = U256::from(1002); @@ -552,12 +819,7 @@ fn test_swap_effect_on_delegated_stake() { let coldkey_stake_before = SubtensorModule::get_total_stake_for_coldkey(&old_coldkey); let delegator_stake_before = SubtensorModule::get_total_stake_for_coldkey(&delegator); - let mut weight = Weight::zero(); - assert_ok!(SubtensorModule::perform_swap_coldkey( - &old_coldkey, - &new_coldkey, - &mut weight - )); + assert_ok!(SubtensorModule::do_swap_coldkey(&old_coldkey, &new_coldkey,)); assert_abs_diff_eq!( SubtensorModule::get_total_stake_for_coldkey(&new_coldkey), @@ -577,589 +839,89 @@ fn test_swap_effect_on_delegated_stake() { }); } -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::swap_coldkey::test_swap_concurrent_modifications --exact --show-output #[test] -fn test_swap_concurrent_modifications() { +fn test_swap_delegated_stake_for_coldkey() { new_test_ext(1).execute_with(|| { let old_coldkey = U256::from(1); let new_coldkey = U256::from(2); - let hotkey = U256::from(3); + let other_coldkey = U256::from(3); + let hotkey1 = U256::from(4); + let hotkey2 = U256::from(5); + let stake_amount1 = DefaultMinStake::::get().to_u64() * 10; + let stake_amount2 = DefaultMinStake::::get().to_u64() * 20; let netuid = NetUid::from(1); - let initial_stake = 1_000_000_000_000; - let additional_stake = 500_000_000_000; - let reserve = (initial_stake + additional_stake) * 1000; + // Setup initial state + add_network(netuid, 1, 0); + register_ok_neuron(netuid, hotkey1, other_coldkey, 0); + register_ok_neuron(netuid, hotkey2, other_coldkey, 0); + + let reserve = (stake_amount1 + stake_amount2) * 10; mock::setup_reserves(netuid, reserve.into(), reserve.into()); - // Setup initial state - add_network(netuid, 1, 1); + // Notice hotkey1 and hotkey2 are Owned by other_coldkey + // old_coldkey and new_coldkey therefore delegates stake to them + // === Give old_coldkey some balance === SubtensorModule::add_balance_to_coldkey_account( - &new_coldkey, - initial_stake + additional_stake + 1_000_000, + &old_coldkey, + stake_amount1 + stake_amount2 + 1_000_000, ); - register_ok_neuron(netuid, hotkey, new_coldkey, 1001000); + // === Stake to hotkeys === assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(new_coldkey), - hotkey, + <::RuntimeOrigin>::signed(old_coldkey), + hotkey1, netuid, - initial_stake.into() + stake_amount1.into() )); - - // Verify initial stake - let stake_before_swap = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( - &hotkey, - &new_coldkey, + let expected_stake_alpha1 = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( + &hotkey1, + &old_coldkey, netuid, ); - // Wait some blocks - step_block(10); - - // Simulate concurrent stake addition + let (expected_stake_alpha2, fee) = mock::swap_tao_to_alpha(netuid, stake_amount2.into()); assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(new_coldkey), - hotkey, + <::RuntimeOrigin>::signed(old_coldkey), + hotkey2, netuid, - additional_stake.into() + stake_amount2.into() )); - - let stake_with_additional = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( - &hotkey, - &new_coldkey, + let expected_stake_alpha2 = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( + &hotkey2, + &old_coldkey, netuid, ); + let fee = (expected_stake_alpha2.to_u64() as f64 * 0.003) as u64; - let mut weight = Weight::zero(); - assert_ok!(SubtensorModule::perform_swap_coldkey( + // Record initial values + let initial_total_issuance = SubtensorModule::get_total_issuance(); + let initial_total_stake = SubtensorModule::get_total_stake(); + let coldkey_stake = SubtensorModule::get_total_stake_for_coldkey(&old_coldkey); + let stake_coldkey_hotkey1 = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( + &hotkey1, &old_coldkey, - &new_coldkey, - &mut weight - )); + netuid, + ); + let stake_coldkey_hotkey2 = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( + &hotkey2, + &old_coldkey, + netuid, + ); + let total_hotkey1_stake = SubtensorModule::get_total_stake_for_hotkey(&hotkey1); + let total_hotkey2_stake = SubtensorModule::get_total_stake_for_hotkey(&hotkey2); + + // Perform the swap + assert_ok!(SubtensorModule::do_swap_coldkey(&old_coldkey, &new_coldkey,)); + // Verify stake transfer assert_eq!( SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( - &hotkey, + &hotkey1, &new_coldkey, netuid ), - stake_with_additional - ); - assert!(stake_with_additional > stake_before_swap); - assert!(!Alpha::::contains_key((hotkey, old_coldkey, netuid))); - }); -} - -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_coldkey -- test_swap_with_invalid_subnet_ownership --exact --nocapture -#[test] -fn test_swap_with_invalid_subnet_ownership() { - new_test_ext(1).execute_with(|| { - let old_coldkey = U256::from(1); - let new_coldkey = U256::from(2); - let netuid = NetUid::from(1u16); - - SubnetOwner::::insert(netuid, old_coldkey); - - // Simulate an invalid state where the subnet owner doesn't match the old_coldkey - SubnetOwner::::insert(netuid, U256::from(3)); - - let mut weight = Weight::zero(); - assert_ok!(SubtensorModule::perform_swap_coldkey( - &old_coldkey, - &new_coldkey, - &mut weight - )); - - // The swap should not affect the mismatched subnet ownership - assert_eq!(SubnetOwner::::get(netuid), U256::from(3)); - }); -} - -// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --package pallet-subtensor --lib -- tests::swap_coldkey::test_do_swap_coldkey_success --exact --show-output -#[test] -fn test_do_swap_coldkey_success() { - new_test_ext(1).execute_with(|| { - let old_coldkey = U256::from(1); - let new_coldkey = U256::from(2); - let hotkey1 = U256::from(3); - let hotkey2 = U256::from(4); - let netuid = NetUid::from(1u16); - let stake_amount1 = DefaultMinStake::::get().to_u64() * 10; - let stake_amount2 = DefaultMinStake::::get().to_u64() * 20; - let swap_cost = SubtensorModule::get_key_swap_cost(); - let free_balance_old = 12345 + swap_cost.to_u64(); - - let reserve = (stake_amount1 + stake_amount2) * 10; - mock::setup_reserves(netuid, reserve.into(), reserve.into()); - - // Setup initial state - add_network(netuid, 13, 0); - register_ok_neuron(netuid, hotkey1, old_coldkey, 0); - register_ok_neuron(netuid, hotkey2, old_coldkey, 0); - - // Add balance to old coldkey - SubtensorModule::add_balance_to_coldkey_account( - &old_coldkey, - stake_amount1 + stake_amount2 + free_balance_old, - ); - - // Log initial state - log::info!( - "Initial total stake: {}", - SubtensorModule::get_total_stake() - ); - log::info!( - "Initial old coldkey stake: {}", - SubtensorModule::get_total_stake_for_coldkey(&old_coldkey) - ); - log::info!( - "Initial new coldkey stake: {}", - SubtensorModule::get_total_stake_for_coldkey(&new_coldkey) - ); - - // Add stake to the neurons - assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(old_coldkey), - hotkey1, - netuid, - stake_amount1.into() - )); - assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(old_coldkey), - hotkey2, - netuid, - stake_amount2.into() - )); - - // Insert an Identity - let name: Vec = b"The fourth Coolest Identity".to_vec(); - let identity: ChainIdentityV2 = ChainIdentityV2 { - name: name.clone(), - url: vec![], - github_repo: vec![], - image: vec![], - discord: vec![], - description: vec![], - additional: vec![], - }; - - IdentitiesV2::::insert(old_coldkey, identity.clone()); - - assert!(IdentitiesV2::::get(old_coldkey).is_some()); - assert!(IdentitiesV2::::get(new_coldkey).is_none()); - - // Log state after adding stake - log::info!( - "Total stake after adding: {}", - SubtensorModule::get_total_stake() - ); - log::info!( - "Old coldkey stake after adding: {}", - SubtensorModule::get_total_stake_for_coldkey(&old_coldkey) - ); - log::info!( - "New coldkey stake after adding: {}", - SubtensorModule::get_total_stake_for_coldkey(&new_coldkey) - ); - - // Record total stake before swap - let total_stake_before_swap = SubtensorModule::get_total_stake(); - - let hk1_alpha = Alpha::::get((hotkey1, old_coldkey, netuid)); - let hk2_alpha = Alpha::::get((hotkey2, old_coldkey, netuid)); - let total_ck_stake = SubtensorModule::get_total_stake_for_coldkey(&old_coldkey); - - // Perform the swap - assert_ok!(SubtensorModule::do_swap_coldkey( - // <::RuntimeOrigin>::signed(old_coldkey), - &old_coldkey, - &new_coldkey, - swap_cost - )); - - // Log state after swap - log::info!( - "Total stake after swap: {}", - SubtensorModule::get_total_stake() - ); - log::info!( - "Old coldkey stake after swap: {}", - SubtensorModule::get_total_stake_for_coldkey(&old_coldkey) - ); - log::info!( - "New coldkey stake after swap: {}", - SubtensorModule::get_total_stake_for_coldkey(&new_coldkey) - ); - - // Verify the swap - assert_eq!(Owner::::get(hotkey1), new_coldkey); - assert_eq!(Owner::::get(hotkey2), new_coldkey); - assert_eq!( - SubtensorModule::get_total_stake_for_coldkey(&new_coldkey), - total_ck_stake - ); - assert_eq!( - SubtensorModule::get_total_stake_for_coldkey(&old_coldkey), - TaoCurrency::ZERO - ); - assert_eq!( - Alpha::::get((hotkey1, new_coldkey, netuid)), - hk1_alpha - ); - assert_eq!( - Alpha::::get((hotkey2, new_coldkey, netuid)), - hk2_alpha - ); - assert!(!Alpha::::contains_key((hotkey1, old_coldkey, netuid))); - assert!(!Alpha::::contains_key((hotkey2, old_coldkey, netuid))); - - // Verify OwnedHotkeys - let new_owned_hotkeys = OwnedHotkeys::::get(new_coldkey); - assert!(new_owned_hotkeys.contains(&hotkey1)); - assert!(new_owned_hotkeys.contains(&hotkey2)); - assert_eq!(new_owned_hotkeys.len(), 2); - assert!(!OwnedHotkeys::::contains_key(old_coldkey)); - - // Verify balance transfer - assert_eq!( - SubtensorModule::get_coldkey_balance(&new_coldkey), - free_balance_old - swap_cost.to_u64() - ); - assert_eq!(SubtensorModule::get_coldkey_balance(&old_coldkey), 0); - - // Verify total stake remains unchanged - assert_eq!( - SubtensorModule::get_total_stake(), - total_stake_before_swap, - "Total stake changed unexpectedly" - ); - - // Verify identities were swapped - assert!(IdentitiesV2::::get(old_coldkey).is_none()); - assert!(IdentitiesV2::::get(new_coldkey).is_some()); - assert_eq!( - IdentitiesV2::::get(new_coldkey).expect("Expected an Identity"), - identity - ); - - // Verify event emission - System::assert_last_event( - Event::ColdkeySwapped { - old_coldkey, - new_coldkey, - swap_cost, - } - .into(), - ); - }); -} - -// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --package pallet-subtensor --lib -- tests::swap_coldkey::test_swap_stake_for_coldkey --exact --show-output -#[test] -fn test_swap_stake_for_coldkey() { - new_test_ext(1).execute_with(|| { - let old_coldkey = U256::from(1); - let new_coldkey = U256::from(2); - let hotkey1 = U256::from(3); - let hotkey2 = U256::from(4); - let stake_amount1 = DefaultMinStake::::get().to_u64() * 10; - let stake_amount2 = DefaultMinStake::::get().to_u64() * 20; - let stake_amount3 = DefaultMinStake::::get().to_u64() * 30; - let mut weight = Weight::zero(); - - // Setup initial state - // Add a network - let netuid = NetUid::from(1u16); - add_network(netuid, 1, 0); - - // Register hotkeys - register_ok_neuron(netuid, hotkey1, old_coldkey, 0); - register_ok_neuron(netuid, hotkey2, old_coldkey, 0); - // Give some balance to old coldkey - SubtensorModule::add_balance_to_coldkey_account( - &old_coldkey, - stake_amount1 + stake_amount2 + 1_000_000, - ); - - let reserve = (stake_amount1 + stake_amount2 + stake_amount3) * 10; - mock::setup_reserves(netuid, reserve.into(), reserve.into()); - - // Stake to hotkeys - assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(old_coldkey), - hotkey1, - netuid, - stake_amount1.into() - )); - let expected_stake_alpha1 = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( - &hotkey1, - &old_coldkey, - netuid, - ); - - assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(old_coldkey), - hotkey2, - netuid, - stake_amount2.into() - )); - let expected_stake_alpha2 = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( - &hotkey2, - &old_coldkey, - netuid, - ); - - // Insert existing for same hotkey1 - // give new coldkey some balance - SubtensorModule::add_balance_to_coldkey_account(&new_coldkey, stake_amount3 + 1_000_000); - // Stake to hotkey1 - assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(new_coldkey), - hotkey1, - netuid, - stake_amount3.into() - )); - let expected_stake_alpha3 = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( - &hotkey1, - &new_coldkey, - netuid, - ); - - // Record initial values - let initial_total_issuance = SubtensorModule::get_total_issuance(); - let initial_total_stake = SubtensorModule::get_total_stake(); - let initial_total_stake_for_old_coldkey = - SubtensorModule::get_total_stake_for_coldkey(&old_coldkey); - let initial_total_stake_for_new_coldkey = - SubtensorModule::get_total_stake_for_coldkey(&new_coldkey); - let initial_total_hotkey1_stake = SubtensorModule::get_total_stake_for_hotkey(&hotkey1); - let initial_total_hotkey2_stake = SubtensorModule::get_total_stake_for_hotkey(&hotkey2); - - // Perform the swap - SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight); - - // Verify stake is additive, not replaced - assert_abs_diff_eq!( - SubtensorModule::get_total_stake_for_coldkey(&new_coldkey), - initial_total_stake_for_old_coldkey + initial_total_stake_for_new_coldkey, - epsilon = 2.into() - ); - - // Verify ownership transfer - assert_eq!( - SubtensorModule::get_owned_hotkeys(&new_coldkey), - vec![hotkey1, hotkey2] - ); - assert_eq!(SubtensorModule::get_owned_hotkeys(&old_coldkey), vec![]); - - // Verify stake transfer - assert_eq!( - SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( - &hotkey1, - &new_coldkey, - netuid - ), - expected_stake_alpha1 + expected_stake_alpha3 - ); - assert_eq!( - SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( - &hotkey2, - &new_coldkey, - netuid - ), - expected_stake_alpha2 - ); - assert_eq!( - SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( - &hotkey1, - &old_coldkey, - netuid - ), - AlphaCurrency::ZERO - ); - assert_eq!( - SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( - &hotkey2, - &old_coldkey, - netuid - ), - AlphaCurrency::ZERO - ); - - // Verify TotalHotkeyStake remains unchanged - assert_eq!( - SubtensorModule::get_total_stake_for_hotkey(&hotkey1), - initial_total_hotkey1_stake - ); - assert_eq!( - SubtensorModule::get_total_stake_for_hotkey(&hotkey2), - initial_total_hotkey2_stake - ); - - // Verify total stake and issuance remain unchanged - assert_eq!( - SubtensorModule::get_total_stake(), - initial_total_stake, - "Total stake changed unexpectedly" - ); - assert_eq!( - SubtensorModule::get_total_issuance(), - initial_total_issuance, - "Total issuance changed unexpectedly" - ); - }); -} - -// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --package pallet-subtensor --lib -- tests::swap_coldkey::test_swap_staking_hotkeys_for_coldkey --exact --show-output -#[test] -fn test_swap_staking_hotkeys_for_coldkey() { - new_test_ext(1).execute_with(|| { - let old_coldkey = U256::from(1); - let new_coldkey = U256::from(2); - let other_coldkey = U256::from(3); - let hotkey1 = U256::from(4); - let hotkey2 = U256::from(5); - let stake_amount1 = DefaultMinStake::::get().to_u64() * 10; - let stake_amount2 = DefaultMinStake::::get().to_u64() * 20; - let mut weight = Weight::zero(); - - // Setup initial state - // Add a network - let netuid = NetUid::from(1u16); - add_network(netuid, 1, 0); - // Give some balance to old coldkey - SubtensorModule::add_balance_to_coldkey_account( - &old_coldkey, - stake_amount1 + stake_amount2 + 1_000_000, - ); // Register hotkeys - register_ok_neuron(netuid, hotkey1, old_coldkey, 0); - register_ok_neuron(netuid, hotkey2, other_coldkey, 0); - - let reserve = (stake_amount1 + stake_amount2) * 10; - mock::setup_reserves(netuid, reserve.into(), reserve.into()); - - // Stake to hotkeys - assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(old_coldkey), - hotkey1, - netuid, - stake_amount1.into() - )); - let expected_stake_alpha1 = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( - &hotkey1, - &old_coldkey, - netuid, - ); - - assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(old_coldkey), - hotkey2, - netuid, - stake_amount2.into() - )); - let expected_stake_alpha2 = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( - &hotkey2, - &old_coldkey, - netuid, - ); - - // Perform the swap - SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight); - - // Verify StakingHotkeys transfer - assert_eq!( - StakingHotkeys::::get(new_coldkey), - vec![hotkey1, hotkey2] - ); - assert_eq!(StakingHotkeys::::get(old_coldkey), vec![]); - }); -} - -// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --package pallet-subtensor --lib -- tests::swap_coldkey::test_swap_delegated_stake_for_coldkey --exact --show-output -#[test] -fn test_swap_delegated_stake_for_coldkey() { - new_test_ext(1).execute_with(|| { - let old_coldkey = U256::from(1); - let new_coldkey = U256::from(2); - let other_coldkey = U256::from(3); - let hotkey1 = U256::from(4); - let hotkey2 = U256::from(5); - let stake_amount1 = DefaultMinStake::::get().to_u64() * 10; - let stake_amount2 = DefaultMinStake::::get().to_u64() * 20; - let mut weight = Weight::zero(); - let netuid = NetUid::from(1); - - // Setup initial state - add_network(netuid, 1, 0); - register_ok_neuron(netuid, hotkey1, other_coldkey, 0); - register_ok_neuron(netuid, hotkey2, other_coldkey, 0); - - let reserve = (stake_amount1 + stake_amount2) * 10; - mock::setup_reserves(netuid, reserve.into(), reserve.into()); - - // Notice hotkey1 and hotkey2 are Owned by other_coldkey - // old_coldkey and new_coldkey therefore delegates stake to them - // === Give old_coldkey some balance === - SubtensorModule::add_balance_to_coldkey_account( - &old_coldkey, - stake_amount1 + stake_amount2 + 1_000_000, - ); - - // === Stake to hotkeys === - assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(old_coldkey), - hotkey1, - netuid, - stake_amount1.into() - )); - let expected_stake_alpha1 = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( - &hotkey1, - &old_coldkey, - netuid, - ); - - let (expected_stake_alpha2, fee) = mock::swap_tao_to_alpha(netuid, stake_amount2.into()); - assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(old_coldkey), - hotkey2, - netuid, - stake_amount2.into() - )); - let expected_stake_alpha2 = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( - &hotkey2, - &old_coldkey, - netuid, - ); - let fee = (expected_stake_alpha2.to_u64() as f64 * 0.003) as u64; - - // Record initial values - let initial_total_issuance = SubtensorModule::get_total_issuance(); - let initial_total_stake = SubtensorModule::get_total_stake(); - let coldkey_stake = SubtensorModule::get_total_stake_for_coldkey(&old_coldkey); - let stake_coldkey_hotkey1 = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( - &hotkey1, - &old_coldkey, - netuid, - ); - let stake_coldkey_hotkey2 = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( - &hotkey2, - &old_coldkey, - netuid, - ); - let total_hotkey1_stake = SubtensorModule::get_total_stake_for_hotkey(&hotkey1); - let total_hotkey2_stake = SubtensorModule::get_total_stake_for_hotkey(&hotkey2); - - // Perform the swap - SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight); - - // Verify stake transfer - assert_eq!( - SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( - &hotkey1, - &new_coldkey, - netuid - ), - expected_stake_alpha1 + expected_stake_alpha1 ); assert_eq!( SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( @@ -1220,85 +982,6 @@ fn test_swap_delegated_stake_for_coldkey() { }); } -// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test swap_coldkey -- test_swap_subnet_owner_for_coldkey --exact --nocapture -#[test] -fn test_swap_subnet_owner_for_coldkey() { - new_test_ext(1).execute_with(|| { - let old_coldkey = U256::from(1); - let new_coldkey = U256::from(2); - let netuid1 = NetUid::from(1); - let netuid2 = NetUid::from(2); - let mut weight = Weight::zero(); - - // Initialize SubnetOwner for old_coldkey - add_network(netuid1, 13, 0); - add_network(netuid2, 14, 0); - SubnetOwner::::insert(netuid1, old_coldkey); - SubnetOwner::::insert(netuid2, old_coldkey); - - // Set up TotalNetworks - TotalNetworks::::put(3); - - // Perform the swap - SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight); - - // Verify the swap - assert_eq!(SubnetOwner::::get(netuid1), new_coldkey); - assert_eq!(SubnetOwner::::get(netuid2), new_coldkey); - }); -} - -// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test swap_coldkey -- test_do_swap_coldkey_with_subnet_ownership --exact --nocapture -#[test] -fn test_do_swap_coldkey_with_subnet_ownership() { - new_test_ext(1).execute_with(|| { - let old_coldkey = U256::from(1); - let new_coldkey = U256::from(2); - let hotkey = U256::from(3); - let netuid = NetUid::from(1u16); - let stake_amount = 1000; - let swap_cost = SubtensorModule::get_key_swap_cost().to_u64(); - - // Setup initial state - add_network(netuid, 13, 0); - register_ok_neuron(netuid, hotkey, old_coldkey, 0); - - // Set TotalNetworks because swap relies on it - crate::TotalNetworks::::set(1); - - SubtensorModule::add_balance_to_coldkey_account(&old_coldkey, stake_amount + swap_cost); - SubnetOwner::::insert(netuid, old_coldkey); - - // Populate OwnedHotkeys map - OwnedHotkeys::::insert(old_coldkey, vec![hotkey]); - - // Perform the swap - assert_ok!(SubtensorModule::do_swap_coldkey( - &old_coldkey, - &new_coldkey, - swap_cost.into() - )); - - // Verify subnet ownership transfer - assert_eq!(SubnetOwner::::get(netuid), new_coldkey); - }); -} -// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test swap_coldkey -- test_coldkey_has_associated_hotkeys --exact --nocapture -#[test] -fn test_coldkey_has_associated_hotkeys() { - new_test_ext(1).execute_with(|| { - let coldkey = U256::from(1); - let hotkey = U256::from(2); - let netuid = NetUid::from(1u16); - - // Setup initial state - add_network(netuid, 13, 0); - register_ok_neuron(netuid, hotkey, coldkey, 0); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, 1000); - }); -} - -// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --package pallet-subtensor --lib -- tests::swap_coldkey::test_coldkey_swap_total --exact --show-output #[test] fn test_coldkey_swap_total() { new_test_ext(1).execute_with(|| { @@ -1523,12 +1206,7 @@ fn test_coldkey_swap_total() { SubtensorModule::get_total_stake_for_coldkey(&coldkey), ck_stake ); - let mut weight = Weight::zero(); - assert_ok!(SubtensorModule::perform_swap_coldkey( - &coldkey, - &new_coldkey, - &mut weight - )); + assert_ok!(SubtensorModule::do_swap_coldkey(&coldkey, &new_coldkey,)); assert_eq!( SubtensorModule::get_total_stake_for_coldkey(&new_coldkey), ck_stake @@ -1617,9 +1295,8 @@ fn test_coldkey_swap_total() { }); } -// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --package pallet-subtensor --lib -- tests::swap_coldkey::test_coldkey_delegations --exact --show-output #[test] -fn test_coldkey_delegations() { +fn test_do_swap_coldkey_effect_on_delegations() { new_test_ext(1).execute_with(|| { let new_coldkey = U256::from(0); let owner = U256::from(1); @@ -1656,961 +1333,424 @@ fn test_coldkey_delegations() { )); // Add stake to netuid2 - assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(coldkey), - delegate, - netuid2, - stake.into() - )); - - // Perform the swap - let mut weight = Weight::zero(); - assert_ok!(SubtensorModule::perform_swap_coldkey( - &coldkey, - &new_coldkey, - &mut weight - )); - - // Verify stake was moved for the delegate - let approx_total_stake = TaoCurrency::from(stake * 2 - fee * 2); - assert_abs_diff_eq!( - SubtensorModule::get_total_stake_for_hotkey(&delegate), - approx_total_stake, - epsilon = approx_total_stake / 100.into() - ); - assert_eq!( - SubtensorModule::get_total_stake_for_coldkey(&coldkey), - TaoCurrency::ZERO - ); - assert_abs_diff_eq!( - SubtensorModule::get_total_stake_for_coldkey(&new_coldkey), - approx_total_stake, - epsilon = approx_total_stake / 100.into() - ); - assert_eq!( - expected_stake, - Alpha::::get((delegate, new_coldkey, netuid)) - .to_num::() - .into(), - ); - assert_eq!(Alpha::::get((delegate, coldkey, netuid)), 0); - - assert_eq!( - expected_stake, - Alpha::::get((delegate, new_coldkey, netuid2)) - .to_num::() - .into() - ); - assert_eq!(Alpha::::get((delegate, coldkey, netuid2)), 0); - }); -} - -#[test] -fn test_schedule_swap_coldkey_success() { - new_test_ext(1).execute_with(|| { - // Initialize test accounts - let old_coldkey: U256 = U256::from(1); - let new_coldkey: U256 = U256::from(2); - - let swap_cost = SubtensorModule::get_key_swap_cost(); - - // Add balance to the old coldkey account - SubtensorModule::add_balance_to_coldkey_account(&old_coldkey, swap_cost.to_u64() + 1_000); - - // Schedule the coldkey swap - assert_ok!(SubtensorModule::schedule_swap_coldkey( - <::RuntimeOrigin>::signed(old_coldkey), - new_coldkey - )); - - // Get the current block number - let current_block: u64 = System::block_number(); - - // Calculate the expected execution block (5 days from now) - let expected_execution_block: u64 = current_block + 5 * 24 * 60 * 60 / 12; - - // Check for the SwapScheduled event - System::assert_last_event( - Event::ColdkeySwapScheduled { - old_coldkey, - new_coldkey, - execution_block: expected_execution_block, - swap_cost, - } - .into(), - ); - - // TODO: Add additional checks to ensure the swap is correctly scheduled in the system - // For example, verify that the swap is present in the appropriate storage or scheduler - }); -} - -// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test swap_coldkey -- test_schedule_swap_coldkey_duplicate --exact --nocapture -#[test] -fn test_schedule_swap_coldkey_duplicate() { - new_test_ext(1).execute_with(|| { - let old_coldkey = U256::from(1); - let new_coldkey = U256::from(2); - - let swap_cost = SubtensorModule::get_key_swap_cost(); - - SubtensorModule::add_balance_to_coldkey_account(&old_coldkey, swap_cost.to_u64() + 2_000); - - assert_ok!(SubtensorModule::schedule_swap_coldkey( - <::RuntimeOrigin>::signed(old_coldkey), - new_coldkey - )); - - // Attempt to schedule again - assert_noop!( - SubtensorModule::schedule_swap_coldkey( - <::RuntimeOrigin>::signed(old_coldkey), - new_coldkey - ), - Error::::SwapAlreadyScheduled - ); - }); -} - -// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --package pallet-subtensor --lib -- tests::swap_coldkey::test_schedule_swap_coldkey_execution --exact --show-output --nocapture -#[test] -fn test_schedule_swap_coldkey_execution() { - new_test_ext(1).execute_with(|| { - let old_coldkey = U256::from(1); - let new_coldkey = U256::from(2); - let hotkey = U256::from(3); - let netuid = NetUid::from(1u16); - let stake_amount = DefaultMinStake::::get().to_u64() * 10; - let reserve = stake_amount * 10; - - mock::setup_reserves(netuid, reserve.into(), reserve.into()); - - add_network(netuid, 13, 0); - register_ok_neuron(netuid, hotkey, old_coldkey, 0); - SubtensorModule::add_balance_to_coldkey_account(&old_coldkey, 1000000000000000); - assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(old_coldkey), - hotkey, - netuid, - stake_amount.into() - )); - - // Check initial ownership - assert_eq!( - Owner::::get(hotkey), - old_coldkey, - "Initial ownership check failed" - ); - - let swap_cost = SubtensorModule::get_key_swap_cost(); - - // Schedule the swap - assert_ok!(SubtensorModule::schedule_swap_coldkey( - <::RuntimeOrigin>::signed(old_coldkey), - new_coldkey - )); - - // Get the scheduled execution block - let current_block = System::block_number(); - let execution_block = current_block + ColdkeySwapScheduleDuration::::get(); - - System::assert_last_event( - Event::ColdkeySwapScheduled { - old_coldkey, - new_coldkey, - execution_block, - swap_cost, - } - .into(), - ); - - run_to_block(execution_block - 1); - - let stake_before_swap = SubtensorModule::get_total_stake_for_coldkey(&old_coldkey); - - run_to_block(execution_block); + assert_ok!(SubtensorModule::add_stake( + <::RuntimeOrigin>::signed(coldkey), + delegate, + netuid2, + stake.into() + )); - // Run on_initialize for the execution block - >::on_initialize(execution_block); + // Perform the swap + assert_ok!(SubtensorModule::do_swap_coldkey(&coldkey, &new_coldkey,)); - // Also run Scheduler's on_initialize - as OnInitialize>::on_initialize( - execution_block, + // Verify stake was moved for the delegate + let approx_total_stake = TaoCurrency::from(stake * 2 - fee * 2); + assert_abs_diff_eq!( + SubtensorModule::get_total_stake_for_hotkey(&delegate), + approx_total_stake, + epsilon = approx_total_stake / 100.into() ); - - // Check if the swap has occurred - let new_owner = Owner::::get(hotkey); assert_eq!( - new_owner, new_coldkey, - "Ownership was not updated as expected" + SubtensorModule::get_total_stake_for_coldkey(&coldkey), + TaoCurrency::ZERO ); - - assert_eq!( + assert_abs_diff_eq!( SubtensorModule::get_total_stake_for_coldkey(&new_coldkey), - stake_before_swap, - "Stake was not transferred to new coldkey" + approx_total_stake, + epsilon = approx_total_stake / 100.into() ); assert_eq!( - SubtensorModule::get_total_stake_for_coldkey(&old_coldkey), - TaoCurrency::ZERO, - "Old coldkey still has stake" + expected_stake, + Alpha::::get((delegate, new_coldkey, netuid)) + .to_num::() + .into(), ); + assert_eq!(Alpha::::get((delegate, coldkey, netuid)), 0); - // Check for the SwapExecuted event - System::assert_has_event( - Event::ColdkeySwapped { - old_coldkey, - new_coldkey, - swap_cost, - } - .into(), + assert_eq!( + expected_stake, + Alpha::::get((delegate, new_coldkey, netuid2)) + .to_num::() + .into() ); + assert_eq!(Alpha::::get((delegate, coldkey, netuid2)), 0); }); } -// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test swap_coldkey -- test_direct_swap_coldkey_call_fails --exact --nocapture #[test] -fn test_direct_swap_coldkey_call_fails() { +fn test_dispute_coldkey_swap_works() { new_test_ext(1).execute_with(|| { - let old_coldkey = U256::from(1); + let who = U256::from(1); let new_coldkey = U256::from(2); + let new_coldkey_hash = ::Hashing::hash_of(&new_coldkey); + let now = System::block_number(); - assert_noop!( - SubtensorModule::swap_coldkey( - <::RuntimeOrigin>::signed(old_coldkey), - old_coldkey, - new_coldkey, - TaoCurrency::ZERO - ), - BadOrigin - ); + ColdkeySwapAnnouncements::::insert(who, (now, new_coldkey_hash)); + + assert_ok!(SubtensorModule::dispute_coldkey_swap( + RuntimeOrigin::signed(who) + )); + + assert_eq!(ColdkeySwapDisputes::::get(who), Some(now)); + assert!(matches!( + last_event(), + RuntimeEvent::SubtensorModule(Event::ColdkeySwapDisputed { coldkey: _ }) + )); }); } -// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test swap_coldkey -- test_schedule_swap_coldkey_with_pending_swap --exact --nocapture #[test] -fn test_schedule_swap_coldkey_with_pending_swap() { +fn test_dispute_coldkey_swap_with_bad_origin_fails() { new_test_ext(1).execute_with(|| { - let old_coldkey = U256::from(1); - let new_coldkey1 = U256::from(2); - let new_coldkey2 = U256::from(3); - - let swap_cost = SubtensorModule::get_key_swap_cost(); + let who = U256::from(1); + let new_coldkey = U256::from(2); + let new_coldkey_hash = ::Hashing::hash_of(&new_coldkey); + let now = System::block_number(); - SubtensorModule::add_balance_to_coldkey_account(&old_coldkey, swap_cost.to_u64() + 1_000); + ColdkeySwapAnnouncements::::insert(who, (now, new_coldkey_hash)); - assert_ok!(SubtensorModule::schedule_swap_coldkey( - <::RuntimeOrigin>::signed(old_coldkey), - new_coldkey1 - )); + assert_noop!( + SubtensorModule::dispute_coldkey_swap(RuntimeOrigin::root()), + BadOrigin + ); - // Attempt to schedule another swap before the first one executes assert_noop!( - SubtensorModule::schedule_swap_coldkey( - <::RuntimeOrigin>::signed(old_coldkey), - new_coldkey2 - ), - Error::::SwapAlreadyScheduled + SubtensorModule::dispute_coldkey_swap(RuntimeOrigin::none()), + BadOrigin ); }); } -// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test swap_coldkey -- test_schedule_swap_coldkey_failure_and_reschedule --exact --nocapture #[test] -fn test_schedule_swap_coldkey_failure_and_reschedule() { +fn test_dispute_coldkey_swap_without_announcement_fails() { new_test_ext(1).execute_with(|| { - let old_coldkey = U256::from(1); - let new_coldkey1 = U256::from(2); - let new_coldkey2 = U256::from(3); - - let swap_cost = SubtensorModule::get_key_swap_cost(); - - // Two swaps - SubtensorModule::add_balance_to_coldkey_account( - &old_coldkey, - swap_cost.to_u64() + 1_000 * 2, - ); - - assert_ok!(SubtensorModule::schedule_swap_coldkey( - <::RuntimeOrigin>::signed(old_coldkey), - new_coldkey1 - )); - - let current_block = >::block_number(); - let duration = ColdkeySwapScheduleDuration::::get(); - let when = current_block.saturating_add(duration); - - // Setup first key to fail - // -- will fail if the new coldkey is already a hotkey (has an Owner) - Owner::::insert(new_coldkey1, U256::from(4)); - - // First swap fails - run_to_block(when - 1); - next_block(); - - // Check the failure - next_block(); // Still in the scheduled-swap map - assert!(ColdkeySwapScheduled::::contains_key(old_coldkey)); + let who = U256::from(1); + let new_coldkey = U256::from(2); + let new_coldkey_hash = ::Hashing::hash_of(&new_coldkey); + let now = System::block_number(); - // Try to schedule the second swap assert_noop!( - SubtensorModule::schedule_swap_coldkey( - <::RuntimeOrigin>::signed(old_coldkey), - new_coldkey2 - ), - Error::::SwapAlreadyScheduled + SubtensorModule::dispute_coldkey_swap(RuntimeOrigin::signed(who)), + Error::::ColdkeySwapAnnouncementNotFound ); - - // Wait for correct duration after first swap fails - let fail_duration = ColdkeySwapRescheduleDuration::::get(); - run_to_block(when + fail_duration); - - // Schedule the second swap - assert_ok!(SubtensorModule::schedule_swap_coldkey( - <::RuntimeOrigin>::signed(old_coldkey), - new_coldkey2 - )); - - let current_block = >::block_number(); - let duration = ColdkeySwapScheduleDuration::::get(); - let when = current_block.saturating_add(duration); - run_to_block(when - 1); - next_block(); - - // Check the success - next_block(); // Now in the scheduled-swap map - assert!(!ColdkeySwapScheduled::::contains_key(old_coldkey)); }); } #[test] -fn test_coldkey_swap_delegate_identity_updated() { +fn test_dispute_coldkey_swap_already_disputed_fails() { new_test_ext(1).execute_with(|| { - let old_coldkey = U256::from(1); + let who = U256::from(1); let new_coldkey = U256::from(2); + let new_coldkey_hash = ::Hashing::hash_of(&new_coldkey); + let now = System::block_number(); - let netuid = NetUid::from(1); - let burn_cost = TaoCurrency::from(10); - let tempo = 1; - - SubtensorModule::set_burn(netuid, burn_cost); - add_network(netuid, tempo, 0); - - SubtensorModule::add_balance_to_coldkey_account(&old_coldkey, 100_000_000_000); - mock::setup_reserves(netuid, 1_000_000_000_000.into(), 1_000_000_000_000.into()); - - assert_ok!(SubtensorModule::burned_register( - <::RuntimeOrigin>::signed(old_coldkey), - netuid, - old_coldkey - )); - - let name: Vec = b"The Third Coolest Identity".to_vec(); - let identity: ChainIdentityV2 = ChainIdentityV2 { - name: name.clone(), - url: vec![], - image: vec![], - github_repo: vec![], - discord: vec![], - description: vec![], - additional: vec![], - }; - - IdentitiesV2::::insert(old_coldkey, identity.clone()); - - assert!(IdentitiesV2::::get(old_coldkey).is_some()); - assert!(IdentitiesV2::::get(new_coldkey).is_none()); - - assert_ok!(SubtensorModule::do_swap_coldkey( - &old_coldkey, - &new_coldkey, - burn_cost - )); + ColdkeySwapAnnouncements::::insert(who, (now, new_coldkey_hash)); + ColdkeySwapDisputes::::insert(who, now); - assert!(IdentitiesV2::::get(old_coldkey).is_none()); - assert!(IdentitiesV2::::get(new_coldkey).is_some()); - assert_eq!( - IdentitiesV2::::get(new_coldkey).expect("Expected an Identity"), - identity + assert_noop!( + SubtensorModule::dispute_coldkey_swap(RuntimeOrigin::signed(who)), + Error::::ColdkeySwapAlreadyDisputed ); }); } #[test] -fn test_coldkey_swap_no_identity_no_changes() { +fn test_reset_coldkey_swap_works() { new_test_ext(1).execute_with(|| { - let old_coldkey = U256::from(1); + let who = U256::from(1); let new_coldkey = U256::from(2); + let new_coldkey_hash = ::Hashing::hash_of(&new_coldkey); + let now = System::block_number(); - let netuid = NetUid::from(1); - let burn_cost = TaoCurrency::from(10); - let tempo = 1; - - SubtensorModule::set_burn(netuid, burn_cost); - add_network(netuid, tempo, 0); + ColdkeySwapAnnouncements::::insert(who, (now, new_coldkey_hash)); + ColdkeySwapDisputes::::insert(who, now); - SubtensorModule::add_balance_to_coldkey_account(&old_coldkey, 100_000_000_000); - mock::setup_reserves(netuid, 1_000_000_000_000.into(), 1_000_000_000_000.into()); - - assert_ok!(SubtensorModule::burned_register( - <::RuntimeOrigin>::signed(old_coldkey), - netuid, - old_coldkey + assert_ok!(SubtensorModule::reset_coldkey_swap( + RuntimeOrigin::root(), + who, )); - // Ensure the old coldkey does not have an identity before the swap - assert!(IdentitiesV2::::get(old_coldkey).is_none()); - - // Perform the coldkey swap - assert_ok!(SubtensorModule::do_swap_coldkey( - &old_coldkey, - &new_coldkey, - burn_cost + assert!(!ColdkeySwapAnnouncements::::contains_key(who)); + assert!(!ColdkeySwapDisputes::::contains_key(who)); + assert!(matches!( + last_event(), + RuntimeEvent::SubtensorModule(Event::ColdkeySwapReset { who }) )); - - // Ensure no identities have been changed - assert!(IdentitiesV2::::get(old_coldkey).is_none()); - assert!(IdentitiesV2::::get(new_coldkey).is_none()); }); } #[test] -fn test_coldkey_swap_no_identity_no_changes_newcoldkey_exists() { +fn test_reset_coldkey_swap_with_bad_origin_fails() { new_test_ext(1).execute_with(|| { - let old_coldkey = U256::from(3); - let new_coldkey = U256::from(4); - - let netuid = NetUid::from(1); - let burn_cost = TaoCurrency::from(10); - let tempo = 1; - - SubtensorModule::set_burn(netuid, burn_cost); - add_network(netuid, tempo, 0); - SubtensorModule::add_balance_to_coldkey_account(&old_coldkey, 100_000_000_000); - mock::setup_reserves(netuid, 1_000_000_000_000.into(), 1_000_000_000_000.into()); - - assert_ok!(SubtensorModule::burned_register( - <::RuntimeOrigin>::signed(old_coldkey), - netuid, - old_coldkey - )); - - let name: Vec = b"The Coolest Identity".to_vec(); - let identity: ChainIdentityV2 = ChainIdentityV2 { - name: name.clone(), - url: vec![], - github_repo: vec![], - image: vec![], - discord: vec![], - description: vec![], - additional: vec![], - }; + let who = U256::from(1); + let coldkey = U256::from(2); - IdentitiesV2::::insert(new_coldkey, identity.clone()); - // Ensure the new coldkey does have an identity before the swap - assert!(IdentitiesV2::::get(new_coldkey).is_some()); - assert!(IdentitiesV2::::get(old_coldkey).is_none()); - - // Perform the coldkey swap - assert_ok!(SubtensorModule::do_swap_coldkey( - &old_coldkey, - &new_coldkey, - burn_cost - )); + assert_noop!( + SubtensorModule::reset_coldkey_swap(RuntimeOrigin::signed(who), coldkey), + BadOrigin + ); - // Ensure no identities have been changed - assert!(IdentitiesV2::::get(old_coldkey).is_none()); - assert!(IdentitiesV2::::get(new_coldkey).is_some()); + assert_noop!( + SubtensorModule::reset_coldkey_swap(RuntimeOrigin::none(), coldkey), + BadOrigin + ); }); } -// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test swap_coldkey -- test_cant_schedule_swap_without_enough_to_burn --exact --nocapture #[test] -fn test_cant_schedule_swap_without_enough_to_burn() { +#[allow(deprecated)] +fn test_schedule_swap_coldkey_deprecated() { new_test_ext(1).execute_with(|| { - let old_coldkey = U256::from(3); - let new_coldkey = U256::from(4); - let hotkey = U256::from(5); + let old_coldkey = U256::from(1); + let new_coldkey = U256::from(2); - let burn_cost = SubtensorModule::get_key_swap_cost(); assert_noop!( SubtensorModule::schedule_swap_coldkey( - <::RuntimeOrigin>::signed(old_coldkey), - new_coldkey + <::RuntimeOrigin>::root(), + new_coldkey, ), - Error::::NotEnoughBalanceToPaySwapColdKey + Error::::Deprecated ); }); } -// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --package pallet-subtensor --lib -- tests::swap_coldkey::test_coldkey_in_swap_schedule_prevents_funds_usage --exact --show-output --nocapture -#[test] -fn test_coldkey_in_swap_schedule_prevents_funds_usage() { - // Testing the signed extension validate function - // correctly filters transactions that attempt to use funds - // while a coldkey swap is scheduled. - - new_test_ext(0).execute_with(|| { - let netuid = NetUid::from(1); - let version_key: u64 = 0; - let coldkey = U256::from(0); - let new_coldkey = U256::from(1); - let hotkey: U256 = U256::from(2); // Add the hotkey field - assert_ne!(hotkey, coldkey); // Ensure hotkey is NOT the same as coldkey !!! - - let stake = 100_000_000_000; - let reserve = stake * 100; - - mock::setup_reserves(netuid, reserve.into(), reserve.into()); +#[macro_export] +macro_rules! comprehensive_setup { + ( + $who:expr, + $new_coldkey:expr, + $new_coldkey_hash:expr, + $stake1:expr, + $stake2:expr, + $stake3:expr, + $hotkey1:expr, + $hotkey2:expr, + $hotkey3:expr + ) => {{ + // Setup networks and subnet ownerships + let netuid1 = NetUid::from(1); + let netuid2 = NetUid::from(2); + add_network(netuid1, 1, 0); + add_network(netuid2, 1, 0); + SubnetOwner::::insert(netuid1, $who); + SubnetOwner::::insert(netuid2, $who); + + // Setup reserves + let reserve1 = ($stake1 + $stake3) * 10; + let reserve2 = $stake2 * 10; + mock::setup_reserves(netuid1, reserve1.into(), reserve1.into()); + mock::setup_reserves(netuid2, reserve2.into(), reserve2.into()); + + // Setup auto stake destinations + AutoStakeDestination::::insert($who, netuid1, $hotkey1); + AutoStakeDestination::::insert($who, netuid2, $hotkey2); + AutoStakeDestinationColdkeys::::insert( + $hotkey1, + netuid1, + vec![$who, U256::from(3), U256::from(4)], + ); + AutoStakeDestinationColdkeys::::insert( + $hotkey2, + netuid2, + vec![U256::from(7), U256::from(8), $who], + ); - let who = coldkey; // The coldkey signs this transaction - - // Disallowed transactions are - // - add_stake - // - add_stake_limit - // - swap_stake - // - swap_stake_limit - // - move_stake - // - transfer_stake - // - balances.transfer_all - // - balances.transfer_allow_death - // - balances.transfer_keep_alive - - // Allowed transactions are: - // - remove_stake - // - remove_stake_limit - // others... - - // Create netuid - add_network(netuid, 1, 0); - // Register the hotkey - SubtensorModule::append_neuron(netuid, &hotkey, 0); - crate::Owner::::insert(hotkey, coldkey); + // Setup neurons with stake + register_ok_neuron(netuid1, $hotkey1, $who, 0); + register_ok_neuron(netuid2, $hotkey2, $who, 0); + register_ok_neuron(netuid1, $hotkey3, $who, 0); - SubtensorModule::add_balance_to_coldkey_account(&who, u64::MAX); + let hotkeys = vec![$hotkey1, $hotkey2, $hotkey3]; + assert_eq!(StakingHotkeys::::get($who), hotkeys); + assert_eq!(OwnedHotkeys::::get($who), hotkeys); + assert_eq!(Owner::::get($hotkey1), $who); + assert_eq!(Owner::::get($hotkey2), $who); + assert_eq!(Owner::::get($hotkey3), $who); - // Set the minimum stake to 0. - SubtensorModule::set_stake_threshold(0); - // Add stake to the hotkey assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(who), - hotkey, - netuid, - stake.into() - )); - - // Schedule the coldkey for a swap - assert_ok!(SubtensorModule::schedule_swap_coldkey( - <::RuntimeOrigin>::signed(who), - new_coldkey + <::RuntimeOrigin>::signed($who), + $hotkey1, + netuid1, + $stake1.into() )); - - assert!(ColdkeySwapScheduled::::contains_key(who)); - - // Setup the extension - let info: DispatchInfo = - DispatchInfoOf::<::RuntimeCall>::default(); - let extension = SubtensorTransactionExtension::::new(); - - // Try each call - - // Add stake - let call = RuntimeCall::SubtensorModule(SubtensorCall::add_stake { - hotkey, - netuid, - amount_staked: stake.into(), - }); - let result = extension.validate( - RawOrigin::Signed(who).into(), - &call.clone(), - &info, - 10, - (), - &TxBaseImplication(()), - TransactionSource::External, - ); - // Should fail - assert_eq!( - // Should get an invalid transaction error - result.unwrap_err(), - CustomTransactionError::ColdkeyInSwapSchedule.into() - ); - - // Add stake limit - let call = RuntimeCall::SubtensorModule(SubtensorCall::add_stake_limit { - hotkey, - netuid, - amount_staked: stake.into(), - limit_price: stake.into(), - allow_partial: false, - }); - let result = extension.validate( - RawOrigin::Signed(who).into(), - &call.clone(), - &info, - 10, - (), - &TxBaseImplication(()), - TransactionSource::External, - ); - // Should fail - assert_eq!( - // Should get an invalid transaction error - result.unwrap_err(), - CustomTransactionError::ColdkeyInSwapSchedule.into() - ); - - // Swap stake - let call = RuntimeCall::SubtensorModule(SubtensorCall::swap_stake { - hotkey, - origin_netuid: netuid, - destination_netuid: netuid, - alpha_amount: stake.into(), - }); - let result = extension.validate( - RawOrigin::Signed(who).into(), - &call.clone(), - &info, - 10, - (), - &TxBaseImplication(()), - TransactionSource::External, - ); - // Should fail - assert_eq!( - // Should get an invalid transaction error - result.unwrap_err(), - CustomTransactionError::ColdkeyInSwapSchedule.into() - ); - - // Swap stake limit - let call = RuntimeCall::SubtensorModule(SubtensorCall::swap_stake_limit { - hotkey, - origin_netuid: netuid, - destination_netuid: netuid, - alpha_amount: stake.into(), - limit_price: stake.into(), - allow_partial: false, - }); - let result = extension.validate( - RawOrigin::Signed(who).into(), - &call.clone(), - &info, - 10, - (), - &TxBaseImplication(()), - TransactionSource::External, - ); - // Should fail - assert_eq!( - // Should get an invalid transaction error - result.unwrap_err(), - CustomTransactionError::ColdkeyInSwapSchedule.into() - ); - - // Move stake - let call = RuntimeCall::SubtensorModule(SubtensorCall::move_stake { - origin_hotkey: hotkey, - destination_hotkey: hotkey, - origin_netuid: netuid, - destination_netuid: netuid, - alpha_amount: stake.into(), - }); - let result = extension.validate( - RawOrigin::Signed(who).into(), - &call.clone(), - &info, - 10, - (), - &TxBaseImplication(()), - TransactionSource::External, - ); - // Should fail - assert_eq!( - // Should get an invalid transaction error - result.unwrap_err(), - CustomTransactionError::ColdkeyInSwapSchedule.into() - ); - - // Transfer stake - let call = RuntimeCall::SubtensorModule(SubtensorCall::transfer_stake { - destination_coldkey: new_coldkey, - hotkey, - origin_netuid: netuid, - destination_netuid: netuid, - alpha_amount: stake.into(), - }); - let result = extension.validate( - RawOrigin::Signed(who).into(), - &call.clone(), - &info, - 10, - (), - &TxBaseImplication(()), - TransactionSource::External, - ); - // Should fail - assert_eq!( - // Should get an invalid transaction error - result.unwrap_err(), - CustomTransactionError::ColdkeyInSwapSchedule.into() - ); - - // Transfer all - let call = RuntimeCall::Balances(BalancesCall::transfer_all { - dest: new_coldkey, - keep_alive: false, - }); - let result = extension.validate( - RawOrigin::Signed(who).into(), - &call.clone(), - &info, - 10, - (), - &TxBaseImplication(()), - TransactionSource::External, - ); - // Should fail - assert_eq!( - // Should get an invalid transaction error - result.unwrap_err(), - CustomTransactionError::ColdkeyInSwapSchedule.into() - ); - - // Transfer keep alive - let call = RuntimeCall::Balances(BalancesCall::transfer_keep_alive { - dest: new_coldkey, - value: 100_000_000_000, - }); - let result = extension.validate( - RawOrigin::Signed(who).into(), - &call.clone(), - &info, - 10, - (), - &TxBaseImplication(()), - TransactionSource::External, - ); - // Should fail - assert_eq!( - // Should get an invalid transaction error - result.unwrap_err(), - CustomTransactionError::ColdkeyInSwapSchedule.into() - ); - - // Transfer allow death - let call = RuntimeCall::Balances(BalancesCall::transfer_allow_death { - dest: new_coldkey, - value: 100_000_000_000, - }); - let result = extension.validate( - RawOrigin::Signed(who).into(), - &call.clone(), - &info, - 10, - (), - &TxBaseImplication(()), - TransactionSource::External, - ); - // Should fail - assert_eq!( - // Should get an invalid transaction error - result.unwrap_err(), - CustomTransactionError::ColdkeyInSwapSchedule.into() - ); - - // Burned register - let call = RuntimeCall::SubtensorModule(SubtensorCall::burned_register { netuid, hotkey }); - let result = extension.validate( - RawOrigin::Signed(who).into(), - &call.clone(), - &info, - 10, - (), - &TxBaseImplication(()), - TransactionSource::External, - ); - // Should fail - assert_eq!( - // Should get an invalid transaction error - result.unwrap_err(), - CustomTransactionError::ColdkeyInSwapSchedule.into() - ); - - remove_stake_rate_limit_for_tests(&hotkey, &coldkey, netuid); - - // Remove stake - let call = RuntimeCall::SubtensorModule(SubtensorCall::remove_stake { - hotkey, - netuid, - amount_unstaked: (DefaultMinStake::::get().to_u64() * 2).into(), - }); - let result = extension.validate( - RawOrigin::Signed(who).into(), - &call.clone(), - &info, - 10, - (), - &TxBaseImplication(()), - TransactionSource::External, - ); - // Should fail - assert_eq!( - // Should get an invalid transaction error - result.unwrap_err(), - CustomTransactionError::ColdkeyInSwapSchedule.into() - ); - - // Remove stake limit - let call = RuntimeCall::SubtensorModule(SubtensorCall::remove_stake_limit { - hotkey, - netuid, - amount_unstaked: (DefaultMinStake::::get().to_u64() * 2).into(), - limit_price: 123456789.into(), // should be low enough - allow_partial: true, - }); - let result = extension.validate( - RawOrigin::Signed(who).into(), - &call.clone(), - &info, - 10, - (), - &TxBaseImplication(()), - TransactionSource::External, - ); - // Should fail - assert_eq!( - // Should get an invalid transaction error - result.unwrap_err(), - CustomTransactionError::ColdkeyInSwapSchedule.into() - ); - - // Schedule swap should succeed - let call = RuntimeCall::SubtensorModule(SubtensorCall::schedule_swap_coldkey { - new_coldkey: hotkey, - }); - let result = extension.validate( - RawOrigin::Signed(who).into(), - &call.clone(), - &info, - 10, - (), - &TxBaseImplication(()), - TransactionSource::External, - ); - // Should be ok - assert_ok!(result); - }); -} - -// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --package pallet-subtensor --lib -- tests::swap_coldkey::test_coldkey_in_swap_schedule_prevents_critical_calls --exact --show-output --nocapture -#[test] -fn test_coldkey_in_swap_schedule_prevents_critical_calls() { - // Testing the signed extension validate function - // correctly filters transactions that are critical - // while a coldkey swap is scheduled. - - new_test_ext(0).execute_with(|| { - let netuid = NetUid::from(1); - let version_key: u64 = 0; - let coldkey = U256::from(0); - let new_coldkey = U256::from(1); - let hotkey: U256 = U256::from(2); // Add the hotkey field - assert_ne!(hotkey, coldkey); // Ensure hotkey is NOT the same as coldkey !!! - let stake = 100_000_000_000; - let reserve = stake * 10; - - mock::setup_reserves(netuid, reserve.into(), reserve.into()); - - let who = coldkey; // The coldkey signs this transaction - - // Disallowed transactions are - // - dissolve_network - - // Create netuid - add_network(netuid, 1, 0); - // Register the hotkey - SubtensorModule::append_neuron(netuid, &hotkey, 0); - crate::Owner::::insert(hotkey, coldkey); - - SubtensorModule::add_balance_to_coldkey_account(&who, u64::MAX); - - // Set the minimum stake to 0. - SubtensorModule::set_stake_threshold(0); - // Add stake to the hotkey assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(who), - hotkey, - netuid, - stake.into() + <::RuntimeOrigin>::signed($who), + $hotkey2, + netuid2, + $stake2.into() )); + assert_ok!(SubtensorModule::add_stake( + <::RuntimeOrigin>::signed($who), + $hotkey3, + netuid1, + $stake3.into() + )); + let hk1_alpha = + SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(&$hotkey1, &$who, netuid1); + let hk2_alpha = + SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(&$hotkey2, &$who, netuid2); + let hk3_alpha = + SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(&$hotkey3, &$who, netuid1); + let total_ck_stake = SubtensorModule::get_total_stake_for_coldkey(&$who); + + // Setup identity + let identity = ChainIdentityV2::default(); + IdentitiesV2::::insert($who, identity.clone()); + assert_eq!(IdentitiesV2::::get($who), Some(identity.clone())); + assert!(IdentitiesV2::::get($new_coldkey).is_none()); + + let balance_before = SubtensorModule::get_coldkey_balance(&$who); + let total_stake_before = SubtensorModule::get_total_stake(); + + ( + netuid1, + netuid2, + hotkeys, + hk1_alpha, + hk2_alpha, + hk3_alpha, + total_ck_stake, + identity, + balance_before, + total_stake_before, + ) + }}; +} - // Schedule the coldkey for a swap - assert_ok!(SubtensorModule::schedule_swap_coldkey( - <::RuntimeOrigin>::signed(who), - new_coldkey - )); +#[macro_export] +macro_rules! comprehensive_checks { + ( + $who:expr, + $hotkey1:expr, + $hotkey2:expr, + $hotkey3:expr, + $hotkeys:expr, + $new_coldkey:expr, + $balance_before:expr, + $identity:expr, + $netuid1:expr, + $netuid2:expr, + $hk1_alpha:expr, + $hk2_alpha:expr, + $hk3_alpha:expr, + $total_ck_stake:expr, + $total_stake_before:expr, + $swap_cost:expr + ) => { + // Ensure the announcement has been consumed + assert!(!ColdkeySwapAnnouncements::::contains_key($who)); - assert!(ColdkeySwapScheduled::::contains_key(who)); + // Ensure the cost has been withdrawn from the old coldkey and recycled + let balance_after = SubtensorModule::get_coldkey_balance(&$who); + let ed = ExistentialDeposit::get(); + assert_eq!($balance_before - $swap_cost, balance_after + ed); - // Setup the extension - let info: DispatchInfo = - DispatchInfoOf::<::RuntimeCall>::default(); - let extension = SubtensorTransactionExtension::::new(); + // Ensure the identity is correctly swapped + assert!(IdentitiesV2::::get($who).is_none()); + assert_eq!(IdentitiesV2::::get($new_coldkey), Some($identity)); - // Try each call + // Ensure the subnet ownerships are correctly swapped + assert_eq!(SubnetOwner::::get($netuid1), $new_coldkey); + assert_eq!(SubnetOwner::::get($netuid2), $new_coldkey); - // Dissolve network - let call = - RuntimeCall::SubtensorModule(SubtensorCall::dissolve_network { netuid, coldkey }); - let result = extension.validate( - RawOrigin::Signed(who).into(), - &call.clone(), - &info, - 10, - (), - &TxBaseImplication(()), - TransactionSource::External, + // Ensure the auto stake destinations are correctly swapped + assert!(AutoStakeDestination::::get($who, $netuid1).is_none()); + assert!(AutoStakeDestination::::get($who, $netuid2).is_none()); + assert_eq!( + AutoStakeDestination::::get($new_coldkey, $netuid1), + Some($hotkey1) ); - // Should fail assert_eq!( - // Should get an invalid transaction error - result.unwrap_err(), - CustomTransactionError::ColdkeyInSwapSchedule.into() + AutoStakeDestination::::get($new_coldkey, $netuid2), + Some($hotkey2) + ); + assert_eq!( + AutoStakeDestinationColdkeys::::get($hotkey1, $netuid1), + vec![U256::from(3), U256::from(4), $new_coldkey] + ); + assert_eq!( + AutoStakeDestinationColdkeys::::get($hotkey2, $netuid2), + vec![U256::from(7), U256::from(8), $new_coldkey] ); - }); -} -#[test] -fn test_swap_auto_stake_destination_coldkeys() { - new_test_ext(1).execute_with(|| { - let old_coldkey = U256::from(1); - let new_coldkey = U256::from(2); - let hotkey = U256::from(3); - let netuid = NetUid::from(1u16); - let coldkeys = vec![U256::from(4), U256::from(5), old_coldkey]; + // Ensure the coldkey stake is correctly swapped + assert_eq!( + SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(&$hotkey1, &$who, $netuid1), + 0.into(), + ); + assert_eq!( + SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(&$hotkey2, &$who, $netuid2), + 0.into(), + ); + assert_eq!( + SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(&$hotkey3, &$who, $netuid1), + 0.into(), + ); + assert_eq!( + SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( + &$hotkey1, + &$new_coldkey, + $netuid1 + ), + $hk1_alpha + ); + assert_eq!( + SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( + &$hotkey2, + &$new_coldkey, + $netuid2 + ), + $hk2_alpha + ); + assert_eq!( + SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( + &$hotkey3, + &$new_coldkey, + $netuid1 + ), + $hk3_alpha + ); + assert_eq!( + SubtensorModule::get_total_stake_for_coldkey(&$who), + TaoCurrency::ZERO + ); + assert_eq!( + SubtensorModule::get_total_stake_for_coldkey(&$new_coldkey), + $total_ck_stake, + ); - add_network(netuid, 1, 0); - AutoStakeDestinationColdkeys::::insert(hotkey, netuid, coldkeys.clone()); - AutoStakeDestination::::insert(old_coldkey, netuid, hotkey); + // Ensure the staking hotkeys are correctly swapped + assert!(StakingHotkeys::::get($who).is_empty()); + assert_eq!(StakingHotkeys::::get($new_coldkey), $hotkeys); - let mut weight = Weight::zero(); - assert_ok!(SubtensorModule::perform_swap_coldkey( - &old_coldkey, - &new_coldkey, - &mut weight - )); + // Ensure the hotkey ownership is correctly swapped + assert!(OwnedHotkeys::::get($who).is_empty()); + assert_eq!(OwnedHotkeys::::get($new_coldkey), $hotkeys); + assert_eq!(Owner::::get($hotkey1), $new_coldkey); + assert_eq!(Owner::::get($hotkey2), $new_coldkey); + assert_eq!(Owner::::get($hotkey3), $new_coldkey); - let new_coldkeys = AutoStakeDestinationColdkeys::::get(hotkey, netuid); - assert!(new_coldkeys.contains(&new_coldkey)); - assert!(!new_coldkeys.contains(&old_coldkey)); + // Ensure the remaining balance is transferred to the new coldkey + assert_eq!(SubtensorModule::get_coldkey_balance(&$who), 0); assert_eq!( - AutoStakeDestination::::try_get(old_coldkey, netuid), - Err(()) + SubtensorModule::get_coldkey_balance(&$new_coldkey), + ExistentialDeposit::get() ); + + // Ensure total stake is unchanged assert_eq!( - AutoStakeDestination::::try_get(new_coldkey, netuid), - Ok(hotkey) + SubtensorModule::get_total_stake(), + $total_stake_before, + "Total stake changed unexpectedly" ); - }); + + // Verify event emission + System::assert_last_event( + Event::ColdkeySwapped { + old_coldkey: $who, + new_coldkey: $new_coldkey, + } + .into(), + ); + }; } diff --git a/pallets/subtensor/src/tests/voting_power.rs b/pallets/subtensor/src/tests/voting_power.rs new file mode 100644 index 0000000000..63418fb6a9 --- /dev/null +++ b/pallets/subtensor/src/tests/voting_power.rs @@ -0,0 +1,760 @@ +#![allow(unused, clippy::indexing_slicing, clippy::panic, clippy::unwrap_used)] + +use alloc::collections::BTreeMap; +use frame_support::weights::Weight; +use frame_support::{assert_err, assert_noop, assert_ok}; +use frame_system::RawOrigin; +use sp_core::U256; +use subtensor_runtime_common::NetUid; + +use super::mock; +use super::mock::*; +use crate::epoch::run_epoch::EpochTerms; +use crate::utils::voting_power::{ + MAX_VOTING_POWER_EMA_ALPHA, VOTING_POWER_DISABLE_GRACE_PERIOD_BLOCKS, +}; +use crate::*; + +// ============================================ +// === Test Helpers === +// ============================================ + +const DEFAULT_STAKE_AMOUNT: u64 = 1_000_000_000_000; // 1 million RAO + +/// Build epoch output from current state for testing voting power updates. +fn build_mock_epoch_output(netuid: NetUid) -> BTreeMap { + let n = SubtensorModule::get_subnetwork_n(netuid); + let validator_permits = ValidatorPermit::::get(netuid); + + let mut output = BTreeMap::new(); + for uid in 0..n { + if let Ok(hotkey) = SubtensorModule::get_hotkey_for_net_and_uid(netuid, uid) { + let has_permit = validator_permits + .get(uid as usize) + .copied() + .unwrap_or(false); + let stake = SubtensorModule::get_stake_for_hotkey_on_subnet(&hotkey, netuid).to_u64(); + output.insert( + hotkey, + EpochTerms { + uid: uid as usize, + new_validator_permit: has_permit, + stake: stake.into(), + ..Default::default() + }, + ); + } + } + output +} + +/// Test fixture containing common test setup data +struct VotingPowerTestFixture { + hotkey: U256, + coldkey: U256, + netuid: NetUid, +} + +impl VotingPowerTestFixture { + /// Create a basic fixture with a dynamic network + fn new() -> Self { + let hotkey = U256::from(1); + let coldkey = U256::from(2); + let netuid = add_dynamic_network(&hotkey, &coldkey); + Self { + hotkey, + coldkey, + netuid, + } + } + + /// Setup reserves and add balance to coldkey for staking + fn setup_for_staking(&self) { + self.setup_for_staking_with_amount(DEFAULT_STAKE_AMOUNT); + } + + /// Setup reserves and add balance with custom amount + #[allow(clippy::arithmetic_side_effects)] + fn setup_for_staking_with_amount(&self, amount: u64) { + mock::setup_reserves(self.netuid, (amount * 100).into(), (amount * 100).into()); + SubtensorModule::add_balance_to_coldkey_account(&self.coldkey, amount * 10); + } + + /// Enable voting power tracking for the subnet + fn enable_tracking(&self) { + assert_ok!(SubtensorModule::enable_voting_power_tracking( + RuntimeOrigin::signed(self.coldkey), + self.netuid + )); + } + + /// Add stake from coldkey to hotkey + fn add_stake(&self, amount: u64) { + assert_ok!(SubtensorModule::add_stake( + RuntimeOrigin::signed(self.coldkey), + self.hotkey, + self.netuid, + amount.into() + )); + } + + /// Set validator permit for the hotkey (uid 0) + fn set_validator_permit(&self, has_permit: bool) { + ValidatorPermit::::insert(self.netuid, vec![has_permit]); + } + + /// Run voting power update for N epochs + fn run_epochs(&self, n: u32) { + for _ in 0..n { + let epoch_output = build_mock_epoch_output(self.netuid); + SubtensorModule::update_voting_power_for_subnet(self.netuid, &epoch_output); + } + } + + /// Get current voting power for the hotkey + fn get_voting_power(&self) -> u64 { + SubtensorModule::get_voting_power(self.netuid, &self.hotkey) + } + + /// Full setup: reserves, balance, tracking enabled, stake added, validator permit + fn setup_full(&self) { + self.setup_for_staking(); + self.enable_tracking(); + self.add_stake(DEFAULT_STAKE_AMOUNT); + self.set_validator_permit(true); + } +} + +// ============================================ +// === Test Enable/Disable Voting Power === +// ============================================ + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::voting_power::test_enable_voting_power_tracking --exact --nocapture +#[test] +fn test_enable_voting_power_tracking() { + new_test_ext(1).execute_with(|| { + let f = VotingPowerTestFixture::new(); + + // Initially disabled + assert!(!SubtensorModule::get_voting_power_tracking_enabled( + f.netuid + )); + + // Enable tracking (subnet owner can do this) + f.enable_tracking(); + + // Now enabled + assert!(SubtensorModule::get_voting_power_tracking_enabled(f.netuid)); + assert_eq!( + SubtensorModule::get_voting_power_disable_at_block(f.netuid), + 0 + ); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::voting_power::test_enable_voting_power_tracking_root_can_enable --exact --nocapture +#[test] +fn test_enable_voting_power_tracking_root_can_enable() { + new_test_ext(1).execute_with(|| { + let f = VotingPowerTestFixture::new(); + + // Root can enable + assert_ok!(SubtensorModule::enable_voting_power_tracking( + RuntimeOrigin::root(), + f.netuid + )); + + assert!(SubtensorModule::get_voting_power_tracking_enabled(f.netuid)); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::voting_power::test_disable_voting_power_tracking_schedules_disable --exact --nocapture +#[test] +fn test_disable_voting_power_tracking_schedules_disable() { + new_test_ext(1).execute_with(|| { + let f = VotingPowerTestFixture::new(); + f.enable_tracking(); + + let current_block = SubtensorModule::get_current_block_as_u64(); + + // Schedule disable + assert_ok!(SubtensorModule::disable_voting_power_tracking( + RuntimeOrigin::signed(f.coldkey), + f.netuid + )); + + // Still enabled, but scheduled for disable + assert!(SubtensorModule::get_voting_power_tracking_enabled(f.netuid)); + let disable_at = SubtensorModule::get_voting_power_disable_at_block(f.netuid); + assert_eq!( + disable_at, + current_block + VOTING_POWER_DISABLE_GRACE_PERIOD_BLOCKS + ); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::voting_power::test_disable_voting_power_tracking_fails_when_not_enabled --exact --nocapture +#[test] +fn test_disable_voting_power_tracking_fails_when_not_enabled() { + new_test_ext(1).execute_with(|| { + let f = VotingPowerTestFixture::new(); + + // Try to disable when not enabled + assert_noop!( + SubtensorModule::disable_voting_power_tracking( + RuntimeOrigin::signed(f.coldkey), + f.netuid + ), + Error::::VotingPowerTrackingNotEnabled + ); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::voting_power::test_enable_voting_power_tracking_non_owner_fails --exact --nocapture +#[test] +fn test_enable_voting_power_tracking_non_owner_fails() { + new_test_ext(1).execute_with(|| { + let f = VotingPowerTestFixture::new(); + let random_account = U256::from(999); + + // Non-owner cannot enable (returns BadOrigin) + assert_noop!( + SubtensorModule::enable_voting_power_tracking( + RuntimeOrigin::signed(random_account), + f.netuid + ), + sp_runtime::DispatchError::BadOrigin + ); + + // Should still be disabled + assert!(!SubtensorModule::get_voting_power_tracking_enabled( + f.netuid + )); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::voting_power::test_disable_voting_power_tracking_non_owner_fails --exact --nocapture +#[test] +fn test_disable_voting_power_tracking_non_owner_fails() { + new_test_ext(1).execute_with(|| { + let f = VotingPowerTestFixture::new(); + let random_account = U256::from(999); + f.enable_tracking(); + + // Non-owner cannot disable (returns BadOrigin) + assert_noop!( + SubtensorModule::disable_voting_power_tracking( + RuntimeOrigin::signed(random_account), + f.netuid + ), + sp_runtime::DispatchError::BadOrigin + ); + + // Should still be enabled with no disable scheduled + assert!(SubtensorModule::get_voting_power_tracking_enabled(f.netuid)); + assert_eq!( + SubtensorModule::get_voting_power_disable_at_block(f.netuid), + 0 + ); + }); +} + +// ============================================ +// === Test EMA Alpha === +// ============================================ + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::voting_power::test_set_voting_power_ema_alpha --exact --nocapture +#[test] +fn test_set_voting_power_ema_alpha() { + new_test_ext(1).execute_with(|| { + let f = VotingPowerTestFixture::new(); + + // Get default alpha + let default_alpha = SubtensorModule::get_voting_power_ema_alpha(f.netuid); + assert_eq!(default_alpha, 3_570_000_000_000_000); // 0.00357 * 10^18 = 2 weeks e-folding + + // Set new alpha (only root can do this) + let new_alpha: u64 = 500_000_000_000_000_000; // 0.5 * 10^18 + assert_ok!(SubtensorModule::sudo_set_voting_power_ema_alpha( + RuntimeOrigin::root(), + f.netuid, + new_alpha + )); + + assert_eq!( + SubtensorModule::get_voting_power_ema_alpha(f.netuid), + new_alpha + ); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::voting_power::test_set_voting_power_ema_alpha_fails_above_one --exact --nocapture +#[test] +fn test_set_voting_power_ema_alpha_fails_above_one() { + new_test_ext(1).execute_with(|| { + let f = VotingPowerTestFixture::new(); + + // Try to set alpha > 1.0 (> 10^18) + let invalid_alpha: u64 = MAX_VOTING_POWER_EMA_ALPHA + 1; + assert_noop!( + SubtensorModule::sudo_set_voting_power_ema_alpha( + RuntimeOrigin::root(), + f.netuid, + invalid_alpha + ), + Error::::InvalidVotingPowerEmaAlpha + ); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::voting_power::test_set_voting_power_ema_alpha_non_root_fails --exact --nocapture +#[test] +fn test_set_voting_power_ema_alpha_non_root_fails() { + new_test_ext(1).execute_with(|| { + let f = VotingPowerTestFixture::new(); + + // Non-root cannot set alpha + assert_noop!( + SubtensorModule::sudo_set_voting_power_ema_alpha( + RuntimeOrigin::signed(f.coldkey), + f.netuid, + 500_000_000_000_000_000 + ), + sp_runtime::DispatchError::BadOrigin + ); + }); +} + +// ============================================ +// === Test EMA Calculation === +// ============================================ + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::voting_power::test_voting_power_ema_calculation --exact --nocapture +#[test] +fn test_voting_power_ema_calculation() { + new_test_ext(1).execute_with(|| { + let f = VotingPowerTestFixture::new(); + f.setup_full(); + + // Initially voting power is 0 + assert_eq!(f.get_voting_power(), 0); + + // Run epoch to update voting power + f.run_epochs(1); + + // Voting power should now be > 0 (but less than full stake due to EMA starting from 0) + let voting_power_after_first_epoch = f.get_voting_power(); + assert!(voting_power_after_first_epoch > 0); + + // Run more epochs - voting power should increase towards stake + f.run_epochs(10); + + let voting_power_after_many_epochs = f.get_voting_power(); + assert!(voting_power_after_many_epochs > voting_power_after_first_epoch); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::voting_power::test_voting_power_cleared_when_deregistered --exact --nocapture +#[test] +fn test_voting_power_cleared_when_deregistered() { + new_test_ext(1).execute_with(|| { + let f = VotingPowerTestFixture::new(); + f.setup_full(); + + // Run epochs to build up voting power + f.run_epochs(10); + + let voting_power_before = f.get_voting_power(); + assert!(voting_power_before > 0, "Voting power should be built up"); + + // Deregister the hotkey (simulate by removing from IsNetworkMember) + IsNetworkMember::::remove(f.hotkey, f.netuid); + + // Run epoch - voting power should be cleared for deregistered hotkey + f.run_epochs(1); + + // Should be removed from storage immediately when deregistered + assert_eq!(f.get_voting_power(), 0); + assert!( + !VotingPower::::contains_key(f.netuid, f.hotkey), + "Entry should be removed when hotkey is deregistered" + ); + }); +} + +// ============================================ +// === Test Validators Only === +// ============================================ + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::voting_power::test_only_validators_get_voting_power --exact --nocapture +#[test] +fn test_only_validators_get_voting_power() { + new_test_ext(1).execute_with(|| { + let validator_hotkey = U256::from(1); + let miner_hotkey = U256::from(2); + let coldkey = U256::from(3); + + let netuid = add_dynamic_network(&validator_hotkey, &coldkey); + + mock::setup_reserves( + netuid, + (DEFAULT_STAKE_AMOUNT * 100).into(), + (DEFAULT_STAKE_AMOUNT * 100).into(), + ); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, DEFAULT_STAKE_AMOUNT * 20); + + // Register miner + register_ok_neuron(netuid, miner_hotkey, coldkey, 0); + + // Enable voting power tracking + assert_ok!(SubtensorModule::enable_voting_power_tracking( + RuntimeOrigin::signed(coldkey), + netuid + )); + + // Add stake to both + assert_ok!(SubtensorModule::add_stake( + RuntimeOrigin::signed(coldkey), + validator_hotkey, + netuid, + DEFAULT_STAKE_AMOUNT.into() + )); + assert_ok!(SubtensorModule::add_stake( + RuntimeOrigin::signed(coldkey), + miner_hotkey, + netuid, + DEFAULT_STAKE_AMOUNT.into() + )); + + // Set validator permit: uid 0 (validator) has permit, uid 1 (miner) does not + ValidatorPermit::::insert(netuid, vec![true, false]); + + // Run epoch + let epoch_output = build_mock_epoch_output(netuid); + SubtensorModule::update_voting_power_for_subnet(netuid, &epoch_output); + + // Only validator should have voting power + assert!(SubtensorModule::get_voting_power(netuid, &validator_hotkey) > 0); + assert_eq!(SubtensorModule::get_voting_power(netuid, &miner_hotkey), 0); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::voting_power::test_miner_voting_power_removed_when_loses_vpermit --exact --nocapture +#[test] +fn test_miner_voting_power_removed_when_loses_vpermit() { + new_test_ext(1).execute_with(|| { + let f = VotingPowerTestFixture::new(); + f.setup_full(); + + // Run epochs to build voting power + f.run_epochs(10); + + let voting_power_before = f.get_voting_power(); + assert!(voting_power_before > 0); + + // Remove validator permit (now they're a miner) + f.set_validator_permit(false); + + // Run epoch - voting power should be removed + f.run_epochs(1); + + assert_eq!(f.get_voting_power(), 0); + }); +} + +// ============================================ +// === Test Hotkey Swap === +// ============================================ + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::voting_power::test_voting_power_transfers_on_hotkey_swap --exact --nocapture +#[test] +fn test_voting_power_transfers_on_hotkey_swap() { + new_test_ext(1).execute_with(|| { + let f = VotingPowerTestFixture::new(); + let new_hotkey = U256::from(99); + let voting_power_value = 5_000_000_000_000_u64; + + // Set some voting power for the old hotkey + VotingPower::::insert(f.netuid, f.hotkey, voting_power_value); + + // Verify old hotkey has voting power + assert_eq!(f.get_voting_power(), voting_power_value); + assert_eq!(SubtensorModule::get_voting_power(f.netuid, &new_hotkey), 0); + + // Perform hotkey swap for this subnet + SubtensorModule::swap_voting_power_for_hotkey(&f.hotkey, &new_hotkey, f.netuid); + + // Old hotkey should have 0, new hotkey should have the voting power + assert_eq!(f.get_voting_power(), 0); + assert_eq!( + SubtensorModule::get_voting_power(f.netuid, &new_hotkey), + voting_power_value + ); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::voting_power::test_voting_power_swap_adds_to_existing --exact --nocapture +#[test] +fn test_voting_power_swap_adds_to_existing() { + new_test_ext(1).execute_with(|| { + let f = VotingPowerTestFixture::new(); + let new_hotkey = U256::from(99); + let old_voting_power = 5_000_000_000_000_u64; + let new_existing_voting_power = 2_000_000_000_000_u64; + + // Set voting power for both hotkeys + VotingPower::::insert(f.netuid, f.hotkey, old_voting_power); + VotingPower::::insert(f.netuid, new_hotkey, new_existing_voting_power); + + // Perform swap + SubtensorModule::swap_voting_power_for_hotkey(&f.hotkey, &new_hotkey, f.netuid); + + // New hotkey should have combined voting power + assert_eq!(f.get_voting_power(), 0); + assert_eq!( + SubtensorModule::get_voting_power(f.netuid, &new_hotkey), + old_voting_power + new_existing_voting_power + ); + }); +} + +// ============================================ +// === Test Threshold Logic === +// ============================================ +// Tests the rule: Only remove voting power entry if it decayed FROM above threshold TO below. +// New validators building up from 0 should NOT be removed even if below threshold. + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::voting_power::test_voting_power_not_removed_if_never_above_threshold --exact --nocapture +#[test] +fn test_voting_power_not_removed_if_never_above_threshold() { + new_test_ext(1).execute_with(|| { + let f = VotingPowerTestFixture::new(); + f.setup_full(); + + // Get the threshold + let min_stake = SubtensorModule::get_stake_threshold(); + + // Set voting power directly to a value below threshold (simulating building up) + // This is below threshold but was never above it + let below_threshold = min_stake.saturating_sub(1); + VotingPower::::insert(f.netuid, f.hotkey, below_threshold); + + // Run epoch + f.run_epochs(1); + + // Key assertion: Entry should NOT be removed because previous_ema was below threshold + // The removal rule only triggers when previous_ema >= threshold and new_ema < threshold + let voting_power = f.get_voting_power(); + assert!( + voting_power > 0, + "Voting power should still exist - it was never above threshold" + ); + assert!( + VotingPower::::contains_key(f.netuid, f.hotkey), + "Entry should exist - it was never above threshold so shouldn't be removed" + ); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::voting_power::test_voting_power_not_removed_with_small_dip_below_threshold --exact --nocapture +#[test] +fn test_voting_power_not_removed_with_small_dip_below_threshold() { + new_test_ext(1).execute_with(|| { + let f = VotingPowerTestFixture::new(); + f.setup_for_staking(); + f.enable_tracking(); + f.set_validator_permit(true); + + let min_stake = SubtensorModule::get_stake_threshold(); + + // Set voting power above threshold (validator was established) + let above_threshold = min_stake + 100; + VotingPower::::insert(f.netuid, f.hotkey, above_threshold); + + // Simulate a small dip: new EMA drops to 95% of threshold (within 10% buffer) + // This is above the removal threshold (90%) so should NOT be removed + let small_dip = min_stake * 95 / 100; + VotingPower::::insert(f.netuid, f.hotkey, small_dip); + + // Manually trigger the removal check by setting previous to above threshold + // and running with stake that would produce EMA in the buffer zone + VotingPower::::insert(f.netuid, f.hotkey, above_threshold); + + // Build epoch output with stake that will produce EMA around 95% of threshold + let mut epoch_output = build_mock_epoch_output(f.netuid); + if let Some(terms) = epoch_output.get_mut(&f.hotkey) { + terms.stake = small_dip.into(); // Stake drops but stays in buffer zone + } + + SubtensorModule::update_voting_power_for_subnet(f.netuid, &epoch_output); + + // Should NOT be removed - dip is within hysteresis buffer + assert!( + VotingPower::::contains_key(f.netuid, f.hotkey), + "Entry should exist - small dip within 10% buffer should not trigger removal" + ); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::voting_power::test_voting_power_removed_with_significant_drop_below_threshold --exact --nocapture +#[test] +fn test_voting_power_removed_with_significant_drop_below_threshold() { + new_test_ext(1).execute_with(|| { + let f = VotingPowerTestFixture::new(); + f.enable_tracking(); + + // Use explicit values since get_stake_threshold() may return 0 in tests + let min_stake: u64 = 1_000_000_000; + StakeThreshold::::put(min_stake); + + // Set voting power above threshold (validator was established) + VotingPower::::insert(f.netuid, f.hotkey, min_stake); + + // Set alpha to 100% so new_ema = current_stake directly (for testing removal) + VotingPowerEmaAlpha::::insert(f.netuid, MAX_VOTING_POWER_EMA_ALPHA); + + // Build epoch output manually with stake = 0 and validator permit = true + let mut epoch_output = BTreeMap::new(); + epoch_output.insert( + f.hotkey, + EpochTerms { + uid: 0, + new_validator_permit: true, + stake: 0.into(), // Complete unstake + ..Default::default() + }, + ); + + // With alpha = 1.0: new_ema = 1.0 * 0 + 0 * previous = 0 + // 0 < removal_threshold (90% of min_stake = 900M) AND previous (1B) >= min_stake (1B) + // Should trigger removal + SubtensorModule::update_voting_power_for_subnet(f.netuid, &epoch_output); + + assert!( + !VotingPower::::contains_key(f.netuid, f.hotkey), + "Entry should be removed - stake dropped to 0 with alpha=1.0" + ); + }); +} + +// ============================================ +// === Test Tracking Not Active === +// ============================================ + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::voting_power::test_voting_power_not_updated_when_disabled --exact --nocapture +#[test] +fn test_voting_power_not_updated_when_disabled() { + new_test_ext(1).execute_with(|| { + let f = VotingPowerTestFixture::new(); + f.setup_for_staking(); + // DON'T enable voting power tracking + f.add_stake(DEFAULT_STAKE_AMOUNT); + f.set_validator_permit(true); + + // Run epoch + f.run_epochs(1); + + // Voting power should still be 0 since tracking is disabled + assert_eq!(f.get_voting_power(), 0); + }); +} + +// ============================================ +// === Test Re-enable After Disable === +// ============================================ + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::voting_power::test_reenable_voting_power_clears_disable_schedule --exact --nocapture +#[test] +fn test_reenable_voting_power_clears_disable_schedule() { + new_test_ext(1).execute_with(|| { + let f = VotingPowerTestFixture::new(); + f.enable_tracking(); + + // Schedule disable + assert_ok!(SubtensorModule::disable_voting_power_tracking( + RuntimeOrigin::signed(f.coldkey), + f.netuid + )); + + assert!(SubtensorModule::get_voting_power_disable_at_block(f.netuid) > 0); + + // Re-enable should clear the disable schedule + f.enable_tracking(); + + assert!(SubtensorModule::get_voting_power_tracking_enabled(f.netuid)); + assert_eq!( + SubtensorModule::get_voting_power_disable_at_block(f.netuid), + 0 + ); + }); +} + +// ============================================ +// === Test Grace Period Finalization === +// ============================================ + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::voting_power::test_voting_power_finalized_after_grace_period --exact --nocapture +#[test] +fn test_voting_power_finalized_after_grace_period() { + new_test_ext(1).execute_with(|| { + let f = VotingPowerTestFixture::new(); + f.setup_full(); + + // Build up voting power + f.run_epochs(10); + + let voting_power_before = f.get_voting_power(); + assert!(voting_power_before > 0); + + // Schedule disable + assert_ok!(SubtensorModule::disable_voting_power_tracking( + RuntimeOrigin::signed(f.coldkey), + f.netuid + )); + + let disable_at = SubtensorModule::get_voting_power_disable_at_block(f.netuid); + + // Advance block past grace period (time travel!) + System::set_block_number(disable_at + 1); + + // Run epoch - should finalize disable + f.run_epochs(1); + + // Tracking should be disabled and all entries cleared + assert!(!SubtensorModule::get_voting_power_tracking_enabled( + f.netuid + )); + assert_eq!( + SubtensorModule::get_voting_power_disable_at_block(f.netuid), + 0 + ); + assert_eq!(f.get_voting_power(), 0); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::voting_power::test_voting_power_continues_during_grace_period --exact --nocapture +#[test] +fn test_voting_power_continues_during_grace_period() { + new_test_ext(1).execute_with(|| { + let f = VotingPowerTestFixture::new(); + f.setup_full(); + + // Schedule disable + assert_ok!(SubtensorModule::disable_voting_power_tracking( + RuntimeOrigin::signed(f.coldkey), + f.netuid + )); + + let disable_at = SubtensorModule::get_voting_power_disable_at_block(f.netuid); + + // Set block to middle of grace period (time travel!) + System::set_block_number(disable_at - 1000); + + // Run epoch - should still update voting power during grace period + f.run_epochs(1); + + // Tracking should still be enabled and voting power should exist + assert!(SubtensorModule::get_voting_power_tracking_enabled(f.netuid)); + assert!(f.get_voting_power() > 0); + }); +} diff --git a/pallets/subtensor/src/tests/weights.rs b/pallets/subtensor/src/tests/weights.rs index 20ace5ee0d..2c64b23d32 100644 --- a/pallets/subtensor/src/tests/weights.rs +++ b/pallets/subtensor/src/tests/weights.rs @@ -34,7 +34,7 @@ use w3f_bls::EngineBLS; use super::mock; use super::mock::*; use crate::coinbase::reveal_commits::{LegacyWeightsTlockPayload, WeightsTlockPayload}; -use crate::transaction_extension::SubtensorTransactionExtension; +use crate::extensions::SubtensorTransactionExtension; use crate::*; /*************************** pub fn set_weights() tests diff --git a/pallets/subtensor/src/utils/misc.rs b/pallets/subtensor/src/utils/misc.rs index 10fc0535f0..609e43cf63 100644 --- a/pallets/subtensor/src/utils/misc.rs +++ b/pallets/subtensor/src/utils/misc.rs @@ -808,19 +808,14 @@ impl Pallet { TransferToggle::::get(netuid) } - /// Set the duration for coldkey swap - /// - /// # Arguments - /// - /// * `duration` - The blocks for coldkey swap execution. - /// - /// # Effects - /// - /// * Update the ColdkeySwapScheduleDuration storage. - /// * Emits a ColdkeySwapScheduleDurationSet evnet. - pub fn set_coldkey_swap_schedule_duration(duration: BlockNumberFor) { - ColdkeySwapScheduleDuration::::set(duration); - Self::deposit_event(Event::ColdkeySwapScheduleDurationSet(duration)); + pub fn set_coldkey_swap_announcement_delay(duration: BlockNumberFor) { + ColdkeySwapAnnouncementDelay::::set(duration); + Self::deposit_event(Event::ColdkeySwapAnnouncementDelaySet(duration)); + } + + pub fn set_coldkey_swap_reannouncement_delay(duration: BlockNumberFor) { + ColdkeySwapReannouncementDelay::::set(duration); + Self::deposit_event(Event::ColdkeySwapReannouncementDelaySet(duration)); } /// Set the duration for dissolve network diff --git a/pallets/subtensor/src/utils/mod.rs b/pallets/subtensor/src/utils/mod.rs index 3eb8439959..a91875da59 100644 --- a/pallets/subtensor/src/utils/mod.rs +++ b/pallets/subtensor/src/utils/mod.rs @@ -5,3 +5,4 @@ pub mod misc; pub mod rate_limiting; #[cfg(feature = "try-runtime")] pub mod try_state; +pub mod voting_power; diff --git a/pallets/subtensor/src/utils/rate_limiting.rs b/pallets/subtensor/src/utils/rate_limiting.rs index 85f58cfc64..0649b3b9e3 100644 --- a/pallets/subtensor/src/utils/rate_limiting.rs +++ b/pallets/subtensor/src/utils/rate_limiting.rs @@ -16,6 +16,7 @@ pub enum TransactionType { MechanismCountUpdate, MechanismEmission, MaxUidsTrimming, + AddStakeBurn, } impl TransactionType { @@ -44,6 +45,7 @@ impl TransactionType { (Tempo::::get(netuid) as u64).saturating_mul(epochs) } Self::SetSNOwnerHotkey => DefaultSetSNOwnerHotkeyRateLimit::::get(), + Self::AddStakeBurn => Tempo::::get(netuid) as u64, _ => self.rate_limit::(), } @@ -141,6 +143,7 @@ impl From for u16 { TransactionType::MechanismCountUpdate => 7, TransactionType::MechanismEmission => 8, TransactionType::MaxUidsTrimming => 9, + TransactionType::AddStakeBurn => 10, } } } @@ -158,6 +161,7 @@ impl From for TransactionType { 7 => TransactionType::MechanismCountUpdate, 8 => TransactionType::MechanismEmission, 9 => TransactionType::MaxUidsTrimming, + 10 => TransactionType::AddStakeBurn, _ => TransactionType::Unknown, } } diff --git a/pallets/subtensor/src/utils/voting_power.rs b/pallets/subtensor/src/utils/voting_power.rs new file mode 100644 index 0000000000..55437f8885 --- /dev/null +++ b/pallets/subtensor/src/utils/voting_power.rs @@ -0,0 +1,280 @@ +use super::*; +use crate::epoch::run_epoch::EpochTerms; +use alloc::collections::BTreeMap; +use subtensor_runtime_common::{AlphaCurrency, NetUid}; + +/// 14 days in blocks (assuming ~12 second blocks) +/// 14 * 24 * 60 * 60 / 12 = 100800 blocks +pub const VOTING_POWER_DISABLE_GRACE_PERIOD_BLOCKS: u64 = 100800; + +/// Maximum alpha value (1.0 represented as u64 with 18 decimals) +pub const MAX_VOTING_POWER_EMA_ALPHA: u64 = 1_000_000_000_000_000_000; + +impl Pallet { + // ======================== + // === Getters === + // ======================== + + /// Get voting power for a hotkey on a subnet. + /// Returns 0 if not found or tracking disabled. + pub fn get_voting_power(netuid: NetUid, hotkey: &T::AccountId) -> u64 { + VotingPower::::get(netuid, hotkey) + } + + /// Check if voting power tracking is enabled for a subnet. + pub fn get_voting_power_tracking_enabled(netuid: NetUid) -> bool { + VotingPowerTrackingEnabled::::get(netuid) + } + + /// Get the block at which voting power tracking will be disabled. + /// Returns 0 if not scheduled for disabling. + pub fn get_voting_power_disable_at_block(netuid: NetUid) -> u64 { + VotingPowerDisableAtBlock::::get(netuid) + } + + /// Get the EMA alpha value for voting power calculation on a subnet. + pub fn get_voting_power_ema_alpha(netuid: NetUid) -> u64 { + VotingPowerEmaAlpha::::get(netuid) + } + + // ======================== + // === Extrinsic Handlers === + // ======================== + + /// Enable voting power tracking for a subnet. + pub fn do_enable_voting_power_tracking(netuid: NetUid) -> DispatchResult { + // Enable tracking + VotingPowerTrackingEnabled::::insert(netuid, true); + + // Clear any scheduled disable + VotingPowerDisableAtBlock::::remove(netuid); + + // Emit event + Self::deposit_event(Event::VotingPowerTrackingEnabled { netuid }); + + log::info!("VotingPower tracking enabled for netuid {netuid:?}"); + + Ok(()) + } + + /// Schedule disabling of voting power tracking for a subnet. + /// Tracking will continue for 14 days, then automatically disable. + pub fn do_disable_voting_power_tracking(netuid: NetUid) -> DispatchResult { + // Check if tracking is enabled + ensure!( + Self::get_voting_power_tracking_enabled(netuid), + Error::::VotingPowerTrackingNotEnabled + ); + + // Calculate the block at which tracking will be disabled + let current_block = Self::get_current_block_as_u64(); + let disable_at_block = + current_block.saturating_add(VOTING_POWER_DISABLE_GRACE_PERIOD_BLOCKS); + + // Schedule disable + VotingPowerDisableAtBlock::::insert(netuid, disable_at_block); + + // Emit event + Self::deposit_event(Event::VotingPowerTrackingDisableScheduled { + netuid, + disable_at_block, + }); + + log::info!( + "VotingPower tracking scheduled to disable at block {disable_at_block:?} for netuid {netuid:?}" + ); + + Ok(()) + } + + /// Set the EMA alpha value for voting power calculation on a subnet. + pub fn do_set_voting_power_ema_alpha(netuid: NetUid, alpha: u64) -> DispatchResult { + // Validate alpha (must be <= 1.0, represented as 10^18) + ensure!( + alpha <= MAX_VOTING_POWER_EMA_ALPHA, + Error::::InvalidVotingPowerEmaAlpha + ); + + // Set the alpha + VotingPowerEmaAlpha::::insert(netuid, alpha); + + // Emit event + Self::deposit_event(Event::VotingPowerEmaAlphaSet { netuid, alpha }); + + log::info!("VotingPower EMA alpha set to {alpha:?} for netuid {netuid:?}"); + + Ok(()) + } + + // ======================== + // === Epoch Processing === + // ======================== + + /// Update voting power for all validators on a subnet using pre-calculated epoch terms. + pub fn update_voting_power_for_subnet( + netuid: NetUid, + epoch_output: &BTreeMap, + ) { + // Early exit if tracking not enabled + if !Self::get_voting_power_tracking_enabled(netuid) { + return; + } + + // Check if past grace period and should finalize disable + let disable_at = Self::get_voting_power_disable_at_block(netuid); + if disable_at > 0 { + let current_block = Self::get_current_block_as_u64(); + if current_block >= disable_at { + Self::finalize_voting_power_disable(netuid); + return; + } + // Still in grace period - continue updating + } + + // Get the EMA alpha value for this subnet + let alpha = Self::get_voting_power_ema_alpha(netuid); + + // Get minimum stake threshold for validator permit + let min_stake = Self::get_stake_threshold(); + + // Iterate over epoch output using pre-calculated values + for (hotkey, terms) in epoch_output.iter() { + // Only validators (with vpermit) get voting power, not miners + if terms.new_validator_permit { + // Use the subnet-specific stake from epoch calculation + Self::update_voting_power_for_hotkey(netuid, hotkey, terms.stake, alpha, min_stake); + } else { + // Miner without vpermit - remove any existing voting power + VotingPower::::remove(netuid, hotkey); + } + } + + // Remove voting power for any hotkeys that are no longer registered on this subnet + Self::clear_voting_power_for_deregistered_hotkeys(netuid); + + log::trace!("VotingPower updated for validators on netuid {netuid:?}"); + } + + /// Clear voting power for hotkeys that are no longer registered on the subnet. + fn clear_voting_power_for_deregistered_hotkeys(netuid: NetUid) { + // Collect hotkeys to remove (can't mutate while iterating) + let hotkeys_to_remove: Vec = VotingPower::::iter_prefix(netuid) + .filter_map(|(hotkey, _)| { + // If the hotkey is not a network member, it's deregistered + if !IsNetworkMember::::get(&hotkey, netuid) { + Some(hotkey) + } else { + None + } + }) + .collect(); + + // Remove voting power for deregistered hotkeys + for hotkey in hotkeys_to_remove { + VotingPower::::remove(netuid, &hotkey); + log::trace!( + "VotingPower removed for deregistered hotkey {hotkey:?} on netuid {netuid:?}" + ); + } + } + + /// Update voting power EMA for a single hotkey using subnet-specific stake. + fn update_voting_power_for_hotkey( + netuid: NetUid, + hotkey: &T::AccountId, + current_stake: AlphaCurrency, + alpha: u64, + min_stake: u64, + ) { + // Get previous EMA value + let previous_ema = VotingPower::::get(netuid, hotkey); + + // Calculate new EMA value + // new_ema = alpha * current_stake + (1 - alpha) * previous_ema + // All values use 18 decimal precision for alpha (alpha is in range [0, 10^18]) + let new_ema = Self::calculate_voting_power_ema(current_stake.to_u64(), previous_ema, alpha); + + // Only remove if they previously had voting power ABOVE threshold and decayed below. + // This allows new validators to build up voting power from 0 without being removed. + if new_ema < min_stake && previous_ema >= min_stake { + // Was above threshold, now decayed below - remove + VotingPower::::remove(netuid, hotkey); + log::trace!( + "VotingPower removed for hotkey {hotkey:?} on netuid {netuid:?} (decayed below removal threshold: {new_ema:?} < {min_stake:?})" + ); + } else if new_ema > 0 { + // Update voting power (building up or maintaining) + VotingPower::::insert(netuid, hotkey, new_ema); + log::trace!( + "VotingPower updated for hotkey {hotkey:?} on netuid {netuid:?}: {previous_ema:?} -> {new_ema:?}" + ); + } + // If new_ema == 0 do nothing + } + + /// Calculate EMA for voting power. + /// new_ema = alpha * current_stake + (1 - alpha) * previous_ema + /// Alpha is in 18 decimal precision (10^18 = 1.0) + fn calculate_voting_power_ema(current_stake: u64, previous_ema: u64, alpha: u64) -> u64 { + // Use u128 for intermediate calculations to avoid overflow + let alpha_128 = alpha as u128; + let one_minus_alpha = (MAX_VOTING_POWER_EMA_ALPHA as u128).saturating_sub(alpha_128); + let current_128 = current_stake as u128; + let previous_128 = previous_ema as u128; + + // new_ema = (alpha * current_stake + (1 - alpha) * previous_ema) / 10^18 + let numerator = alpha_128 + .saturating_mul(current_128) + .saturating_add(one_minus_alpha.saturating_mul(previous_128)); + + let result = numerator + .checked_div(MAX_VOTING_POWER_EMA_ALPHA as u128) + .unwrap_or(0); + + // Safely convert back to u64, saturating at u64::MAX + result.min(u64::MAX as u128) as u64 + } + + /// Finalize the disabling of voting power tracking. + /// Clears all VotingPower entries for the subnet. + fn finalize_voting_power_disable(netuid: NetUid) { + // Clear all VotingPower entries for this subnet + let _ = VotingPower::::clear_prefix(netuid, u32::MAX, None); + + // Disable tracking + VotingPowerTrackingEnabled::::insert(netuid, false); + + // Clear disable schedule + VotingPowerDisableAtBlock::::remove(netuid); + + // Emit event + Self::deposit_event(Event::VotingPowerTrackingDisabled { netuid }); + + log::info!("VotingPower tracking disabled and entries cleared for netuid {netuid:?}"); + } + + // ======================== + // === Hotkey Swap === + // ======================== + + /// Transfer voting power from old hotkey to new hotkey during swap. + pub fn swap_voting_power_for_hotkey( + old_hotkey: &T::AccountId, + new_hotkey: &T::AccountId, + netuid: NetUid, + ) { + // Get voting power from old hotkey + let voting_power = VotingPower::::take(netuid, old_hotkey); + + // Transfer to new hotkey if non-zero + if voting_power > 0 { + // Add to any existing voting power on new hotkey (in case new hotkey already has some) + let existing = VotingPower::::get(netuid, new_hotkey); + VotingPower::::insert(netuid, new_hotkey, voting_power.saturating_add(existing)); + + log::trace!( + "VotingPower transferred from {old_hotkey:?} to {new_hotkey:?} on netuid {netuid:?}: {voting_power:?}" + ); + } + } +} diff --git a/pallets/swap-interface/src/lib.rs b/pallets/swap-interface/src/lib.rs index 19af1303c1..76e149b4b7 100644 --- a/pallets/swap-interface/src/lib.rs +++ b/pallets/swap-interface/src/lib.rs @@ -61,7 +61,8 @@ where fn default_price_limit() -> C; } -#[freeze_struct("d3d0b124fe5a97c8")] +/// Externally used swap result (for RPC) +#[freeze_struct("58ff42da64adce1a")] #[derive(Decode, Encode, PartialEq, Eq, Clone, Debug, TypeInfo)] pub struct SwapResult where @@ -71,6 +72,7 @@ where pub amount_paid_in: PaidIn, pub amount_paid_out: PaidOut, pub fee_paid: PaidIn, + pub fee_to_block_author: PaidIn, } impl SwapResult diff --git a/pallets/swap/src/mock.rs b/pallets/swap/src/mock.rs index aacdf90835..bb671e4762 100644 --- a/pallets/swap/src/mock.rs +++ b/pallets/swap/src/mock.rs @@ -2,12 +2,12 @@ use core::num::NonZeroU64; -use frame_support::construct_runtime; use frame_support::pallet_prelude::*; use frame_support::{ PalletId, parameter_types, traits::{ConstU32, Everything}, }; +use frame_support::{construct_runtime, derive_impl}; use frame_system::{self as system}; use sp_core::H256; use sp_runtime::{ @@ -46,11 +46,9 @@ parameter_types! { pub const SS58Prefix: u8 = 42; } +#[derive_impl(frame_system::config_preludes::TestDefaultConfig)] impl system::Config for Test { type BaseCallFilter = Everything; - type BlockWeights = (); - type BlockLength = (); - type DbWeight = (); type RuntimeOrigin = RuntimeOrigin; type RuntimeCall = RuntimeCall; type Hash = H256; @@ -59,24 +57,11 @@ impl system::Config for Test { type Lookup = IdentityLookup; type RuntimeEvent = RuntimeEvent; type BlockHashCount = BlockHashCount; - type Version = (); type PalletInfo = PalletInfo; - type AccountData = (); - type OnNewAccount = (); - type OnKilledAccount = (); - type SystemWeightInfo = (); type SS58Prefix = SS58Prefix; - type OnSetCode = (); type MaxConsumers = ConstU32<16>; type Nonce = u64; type Block = Block; - type RuntimeTask = (); - type SingleBlockMigrations = (); - type MultiBlockMigrator = (); - type PreInherents = (); - type PostInherents = (); - type PostTransactions = (); - type ExtensionsWeightInfo = (); } parameter_types! { @@ -124,6 +109,7 @@ pub type GetAlphaForTao = subtensor_swap_interface::GetAlphaForTao; pub(crate) trait GlobalFeeInfo: Currency { + #[allow(dead_code)] fn global_fee(&self, netuid: NetUid) -> U64F64; } diff --git a/pallets/swap/src/pallet/impls.rs b/pallets/swap/src/pallet/impls.rs index 6ec02879bf..38830ec688 100644 --- a/pallets/swap/src/pallet/impls.rs +++ b/pallets/swap/src/pallet/impls.rs @@ -302,6 +302,7 @@ impl Pallet { let mut iteration_counter: u16 = 0; let mut in_acc = Order::PaidIn::ZERO; let mut fee_acc = Order::PaidIn::ZERO; + let mut fee_to_block_author_acc = Order::PaidIn::ZERO; log::trace!("======== Start Swap ========"); log::trace!("Amount Remaining: {amount_remaining}"); @@ -326,6 +327,8 @@ impl Pallet { in_acc = in_acc.saturating_add(swap_result.delta_in); fee_acc = fee_acc.saturating_add(swap_result.fee_paid); + fee_to_block_author_acc = + fee_to_block_author_acc.saturating_add(swap_result.fee_to_block_author); amount_remaining = amount_remaining.saturating_sub(swap_result.amount_to_take); amount_paid_out = amount_paid_out.saturating_add(swap_result.delta_out); @@ -353,6 +356,7 @@ impl Pallet { amount_paid_in: in_acc, amount_paid_out, fee_paid: fee_acc, + fee_to_block_author: fee_to_block_author_acc, }) } @@ -1101,6 +1105,7 @@ impl SwapHandler for Pallet { amount_paid_in: actual_amount, amount_paid_out: actual_amount.to_u64().into(), fee_paid: 0.into(), + fee_to_block_author: 0.into(), }) } } diff --git a/pallets/swap/src/pallet/mod.rs b/pallets/swap/src/pallet/mod.rs index b55df77fee..73f0833d5d 100644 --- a/pallets/swap/src/pallet/mod.rs +++ b/pallets/swap/src/pallet/mod.rs @@ -3,6 +3,7 @@ use core::ops::Neg; use frame_support::{PalletId, pallet_prelude::*, traits::Get}; use frame_system::pallet_prelude::*; +use sp_arithmetic::Perbill; use substrate_fixed::types::U64F64; use subtensor_runtime_common::{ AlphaCurrency, BalanceOps, Currency, CurrencyReserve, NetUid, SubnetInfo, TaoCurrency, @@ -78,6 +79,13 @@ mod pallet { 33 // ~0.05 % } + /// Fee split between pool and block builder. + /// Pool receives the portion returned by this function + #[pallet::type_value] + pub fn DefaultFeeSplit() -> Perbill { + Perbill::zero() + } + /// The fee rate applied to swaps per subnet, normalized value between 0 and u16::MAX #[pallet::storage] pub type FeeRate = StorageMap<_, Twox64Concat, NetUid, u16, ValueQuery, DefaultFeeRate>; diff --git a/pallets/swap/src/pallet/swap_step.rs b/pallets/swap/src/pallet/swap_step.rs index 6791835b1a..52215e79b5 100644 --- a/pallets/swap/src/pallet/swap_step.rs +++ b/pallets/swap/src/pallet/swap_step.rs @@ -1,5 +1,6 @@ use core::marker::PhantomData; +use frame_support::{ensure, traits::Get}; use safe_math::*; use substrate_fixed::types::{I64F64, U64F64}; use subtensor_runtime_common::{AlphaCurrency, Currency, NetUid, TaoCurrency}; @@ -186,14 +187,33 @@ where /// Process a single step of a swap fn process_swap(&self) -> Result, Error> { - // Hold the fees - Self::add_fees( - self.netuid, - Pallet::::current_liquidity_safe(self.netuid), - self.fee, - ); let delta_out = Self::convert_deltas(self.netuid, self.delta_in); - // log::trace!("\tDelta Out : {delta_out:?}"); + log::trace!("\tDelta Out : {delta_out}"); + + let mut fee_to_block_author = 0.into(); + if self.delta_in > 0.into() { + ensure!(delta_out > 0.into(), Error::::ReservesTooLow); + + // Split fees according to DefaultFeeSplit between liquidity pool and + // validators. In case we want just to forward 100% of fees to the block + // author, it can be done this way: + // ``` + // fee_to_block_author = self.fee; + // ``` + let fee_split = DefaultFeeSplit::get(); + let lp_fee: PaidIn = fee_split.mul_floor(self.fee.to_u64()).into(); + + // Hold the reserve portion of fees + if !lp_fee.is_zero() { + Self::add_fees( + self.netuid, + Pallet::::current_liquidity_safe(self.netuid), + lp_fee, + ); + } + + fee_to_block_author = self.fee.saturating_sub(lp_fee); + } if self.action == SwapStepAction::Crossing { let mut tick = Ticks::::get(self.netuid, self.edge_tick).unwrap_or_default(); @@ -218,6 +238,7 @@ where fee_paid: self.fee, delta_in: self.delta_in, delta_out, + fee_to_block_author, }) } @@ -553,6 +574,7 @@ where pub(crate) fee_paid: PaidIn, pub(crate) delta_in: PaidIn, pub(crate) delta_out: PaidOut, + pub(crate) fee_to_block_author: PaidIn, } #[derive(Clone, Copy, Debug, PartialEq)] diff --git a/pallets/swap/src/pallet/tests.rs b/pallets/swap/src/pallet/tests.rs index cd18e665cd..727e65c95a 100644 --- a/pallets/swap/src/pallet/tests.rs +++ b/pallets/swap/src/pallet/tests.rs @@ -679,8 +679,10 @@ fn test_modify_position_basic() { alpha / 10, epsilon = alpha / 1000 ); - assert!(modify_result.fee_tao > TaoCurrency::ZERO); - assert_eq!(modify_result.fee_alpha, AlphaCurrency::ZERO); + + // Block author may get all fees + // assert!(modify_result.fee_tao > TaoCurrency::ZERO); + // assert_eq!(modify_result.fee_alpha, AlphaCurrency::ZERO); // Liquidity position is reduced assert_eq!( @@ -814,11 +816,13 @@ fn test_swap_basic() { let expected_fee = (liquidity as f64 * fee_rate) as u64; // Global fees should be updated - let actual_global_fee = (order.amount().global_fee(netuid).to_num::() - * (liquidity_before as f64)) as u64; + // let actual_global_fee = (order.amount().global_fee(netuid).to_num::() + // * (liquidity_before as f64)) as u64; assert!((swap_result.fee_paid.to_u64() as i64 - expected_fee as i64).abs() <= 1); - assert!((actual_global_fee as i64 - expected_fee as i64).abs() <= 1); + + // All fees go to block builder + // assert!((actual_global_fee as i64 - expected_fee as i64).abs() <= 1); // Tick fees should be updated @@ -1024,23 +1028,23 @@ fn test_swap_single_position() { expected_liquidity_gross_high, ); - // Expected fee amount - let fee_rate = FeeRate::::get(netuid) as f64 / u16::MAX as f64; - let expected_fee = (order_liquidity - order_liquidity / (1.0 + fee_rate)) as u64; + // Expected fee amount - do not test, all fees go to block builder + // let fee_rate = FeeRate::::get(netuid) as f64 / u16::MAX as f64; + // let expected_fee = (order_liquidity - order_liquidity / (1.0 + fee_rate)) as u64; - // // Global fees should be updated - let actual_global_fee = ($order_t::with_amount(0) - .amount() - .global_fee(netuid) - .to_num::() - * (liquidity_before as f64)) as u64; + // // // Global fees should be updated + // let actual_global_fee = ($order_t::with_amount(0) + // .amount() + // .global_fee(netuid) + // .to_num::() + // * (liquidity_before as f64)) as u64; - assert_abs_diff_eq!( - swap_result.fee_paid.to_u64(), - expected_fee, - epsilon = expected_fee / 10 - ); - assert_abs_diff_eq!(actual_global_fee, expected_fee, epsilon = expected_fee / 10); + // assert_abs_diff_eq!( + // swap_result.fee_paid.to_u64(), + // expected_fee, + // epsilon = expected_fee / 10 + // ); + // assert_abs_diff_eq!(actual_global_fee, expected_fee, epsilon = expected_fee / 10); // Tick fees should be updated @@ -1464,70 +1468,71 @@ fn test_convert_deltas() { // }); // } -/// Test correctness of swap fees: -/// - Fees are distribued to (concentrated) liquidity providers -/// -#[test] -fn test_swap_fee_correctness() { - new_test_ext().execute_with(|| { - let min_price = tick_to_price(TickIndex::MIN); - let max_price = tick_to_price(TickIndex::MAX); - let netuid = NetUid::from(1); - - // Provide very spread liquidity at the range from min to max that matches protocol liquidity - let liquidity = 2_000_000_000_000_u64; // 1x of protocol liquidity - - assert_ok!(Pallet::::maybe_initialize_v3(netuid)); - - // Calculate ticks - let tick_low = price_to_tick(min_price); - let tick_high = price_to_tick(max_price); +// This test is pointless: All fees go to block author +// Test correctness of swap fees: +// - Fees are distribued to (concentrated) liquidity providers +// +// #[test] +// fn test_swap_fee_correctness() { +// new_test_ext().execute_with(|| { +// let min_price = tick_to_price(TickIndex::MIN); +// let max_price = tick_to_price(TickIndex::MAX); +// let netuid = NetUid::from(1); - // Add user liquidity - let (position_id, _tao, _alpha) = Pallet::::do_add_liquidity( - netuid, - &OK_COLDKEY_ACCOUNT_ID, - &OK_HOTKEY_ACCOUNT_ID, - tick_low, - tick_high, - liquidity, - ) - .unwrap(); +// // Provide very spread liquidity at the range from min to max that matches protocol liquidity +// let liquidity = 2_000_000_000_000_u64; // 1x of protocol liquidity - // Swap buy and swap sell - Pallet::::do_swap( - netuid, - GetAlphaForTao::with_amount(liquidity / 10), - u64::MAX.into(), - false, - false, - ) - .unwrap(); - Pallet::::do_swap( - netuid, - GetTaoForAlpha::with_amount(liquidity / 10), - 0_u64.into(), - false, - false, - ) - .unwrap(); +// assert_ok!(Pallet::::maybe_initialize_v3(netuid)); - // Get user position - let mut position = - Positions::::get((netuid, OK_COLDKEY_ACCOUNT_ID, position_id)).unwrap(); - assert_eq!(position.liquidity, liquidity); - assert_eq!(position.tick_low, tick_low); - assert_eq!(position.tick_high, tick_high); +// // Calculate ticks +// let tick_low = price_to_tick(min_price); +// let tick_high = price_to_tick(max_price); - // Check that 50% of fees were credited to the position - let fee_rate = FeeRate::::get(NetUid::from(netuid)) as f64 / u16::MAX as f64; - let (actual_fee_tao, actual_fee_alpha) = position.collect_fees(); - let expected_fee = (fee_rate * (liquidity / 10) as f64 * 0.5) as u64; +// // Add user liquidity +// let (position_id, _tao, _alpha) = Pallet::::do_add_liquidity( +// netuid, +// &OK_COLDKEY_ACCOUNT_ID, +// &OK_HOTKEY_ACCOUNT_ID, +// tick_low, +// tick_high, +// liquidity, +// ) +// .unwrap(); - assert_abs_diff_eq!(actual_fee_tao, expected_fee, epsilon = 1,); - assert_abs_diff_eq!(actual_fee_alpha, expected_fee, epsilon = 1,); - }); -} +// // Swap buy and swap sell +// Pallet::::do_swap( +// netuid, +// GetAlphaForTao::with_amount(liquidity / 10), +// u64::MAX.into(), +// false, +// false, +// ) +// .unwrap(); +// Pallet::::do_swap( +// netuid, +// GetTaoForAlpha::with_amount(liquidity / 10), +// 0_u64.into(), +// false, +// false, +// ) +// .unwrap(); + +// // Get user position +// let mut position = +// Positions::::get((netuid, OK_COLDKEY_ACCOUNT_ID, position_id)).unwrap(); +// assert_eq!(position.liquidity, liquidity); +// assert_eq!(position.tick_low, tick_low); +// assert_eq!(position.tick_high, tick_high); + +// // Check that 50% of fees were credited to the position +// let fee_rate = FeeRate::::get(NetUid::from(netuid)) as f64 / u16::MAX as f64; +// let (actual_fee_tao, actual_fee_alpha) = position.collect_fees(); +// let expected_fee = (fee_rate * (liquidity / 10) as f64 * 0.5) as u64; + +// assert_abs_diff_eq!(actual_fee_tao, expected_fee, epsilon = 1,); +// assert_abs_diff_eq!(actual_fee_alpha, expected_fee, epsilon = 1,); +// }); +// } #[test] fn test_current_liquidity_updates() { @@ -1694,123 +1699,124 @@ fn test_new_lp_doesnt_get_old_fees() { }); } -fn bbox(t: U64F64, a: U64F64, b: U64F64) -> U64F64 { - if t < a { - a - } else if t > b { - b - } else { - t - } -} +// fn bbox(t: U64F64, a: U64F64, b: U64F64) -> U64F64 { +// if t < a { +// a +// } else if t > b { +// b +// } else { +// t +// } +// } -fn print_current_price(netuid: NetUid) { - let current_sqrt_price = AlphaSqrtPrice::::get(netuid).to_num::(); - let current_price = current_sqrt_price * current_sqrt_price; - log::trace!("Current price: {current_price:.6}"); -} +// fn print_current_price(netuid: NetUid) { +// let current_sqrt_price = AlphaSqrtPrice::::get(netuid).to_num::(); +// let current_price = current_sqrt_price * current_sqrt_price; +// log::trace!("Current price: {current_price:.6}"); +// } -/// RUST_LOG=pallet_subtensor_swap=trace cargo test --package pallet-subtensor-swap --lib -- pallet::tests::test_wrapping_fees --exact --show-output --nocapture -#[test] -fn test_wrapping_fees() { - new_test_ext().execute_with(|| { - let netuid = NetUid::from(WRAPPING_FEES_NETUID); - let position_1_low_price = 0.20; - let position_1_high_price = 0.255; - let position_2_low_price = 0.255; - let position_2_high_price = 0.257; - assert_ok!(Pallet::::maybe_initialize_v3(netuid)); +// All fees go to block builder +// RUST_LOG=pallet_subtensor_swap=trace cargo test --package pallet-subtensor-swap --lib -- pallet::tests::test_wrapping_fees --exact --show-output --nocapture +// #[test] +// fn test_wrapping_fees() { +// new_test_ext().execute_with(|| { +// let netuid = NetUid::from(WRAPPING_FEES_NETUID); +// let position_1_low_price = 0.20; +// let position_1_high_price = 0.255; +// let position_2_low_price = 0.255; +// let position_2_high_price = 0.257; +// assert_ok!(Pallet::::maybe_initialize_v3(netuid)); - Pallet::::do_add_liquidity( - netuid, - &OK_COLDKEY_ACCOUNT_ID_RICH, - &OK_COLDKEY_ACCOUNT_ID_RICH, - price_to_tick(position_1_low_price), - price_to_tick(position_1_high_price), - 1_000_000_000_u64, - ) - .unwrap(); +// Pallet::::do_add_liquidity( +// netuid, +// &OK_COLDKEY_ACCOUNT_ID_RICH, +// &OK_COLDKEY_ACCOUNT_ID_RICH, +// price_to_tick(position_1_low_price), +// price_to_tick(position_1_high_price), +// 1_000_000_000_u64, +// ) +// .unwrap(); - print_current_price(netuid); +// print_current_price(netuid); - let order = GetTaoForAlpha::with_amount(800_000_000); - let sqrt_limit_price = SqrtPrice::from_num(0.000001); - Pallet::::do_swap(netuid, order, sqrt_limit_price, false, false).unwrap(); +// let order = GetTaoForAlpha::with_amount(800_000_000); +// let sqrt_limit_price = SqrtPrice::from_num(0.000001); +// Pallet::::do_swap(netuid, order, sqrt_limit_price, false, false).unwrap(); - let order = GetAlphaForTao::with_amount(1_850_000_000); - let sqrt_limit_price = SqrtPrice::from_num(1_000_000.0); +// let order = GetAlphaForTao::with_amount(1_850_000_000); +// let sqrt_limit_price = SqrtPrice::from_num(1_000_000.0); - print_current_price(netuid); +// print_current_price(netuid); - Pallet::::do_swap(netuid, order, sqrt_limit_price, false, false).unwrap(); +// Pallet::::do_swap(netuid, order, sqrt_limit_price, false, false).unwrap(); - print_current_price(netuid); +// print_current_price(netuid); - let add_liquidity_result = Pallet::::do_add_liquidity( - netuid, - &OK_COLDKEY_ACCOUNT_ID_RICH, - &OK_COLDKEY_ACCOUNT_ID_RICH, - price_to_tick(position_2_low_price), - price_to_tick(position_2_high_price), - 1_000_000_000_u64, - ) - .unwrap(); +// let add_liquidity_result = Pallet::::do_add_liquidity( +// netuid, +// &OK_COLDKEY_ACCOUNT_ID_RICH, +// &OK_COLDKEY_ACCOUNT_ID_RICH, +// price_to_tick(position_2_low_price), +// price_to_tick(position_2_high_price), +// 1_000_000_000_u64, +// ) +// .unwrap(); - let order = GetTaoForAlpha::with_amount(1_800_000_000); - let sqrt_limit_price = SqrtPrice::from_num(0.000001); +// let order = GetTaoForAlpha::with_amount(1_800_000_000); +// let sqrt_limit_price = SqrtPrice::from_num(0.000001); - let initial_sqrt_price = AlphaSqrtPrice::::get(netuid); - Pallet::::do_swap(netuid, order, sqrt_limit_price, false, false).unwrap(); - let final_sqrt_price = AlphaSqrtPrice::::get(netuid); +// let initial_sqrt_price = AlphaSqrtPrice::::get(netuid); +// Pallet::::do_swap(netuid, order, sqrt_limit_price, false, false).unwrap(); +// let final_sqrt_price = AlphaSqrtPrice::::get(netuid); - print_current_price(netuid); +// print_current_price(netuid); - let mut position = - Positions::::get((netuid, &OK_COLDKEY_ACCOUNT_ID_RICH, add_liquidity_result.0)) - .unwrap(); +// let mut position = +// Positions::::get((netuid, &OK_COLDKEY_ACCOUNT_ID_RICH, add_liquidity_result.0)) +// .unwrap(); - let initial_box_price = bbox( - initial_sqrt_price, - position.tick_low.try_to_sqrt_price().unwrap(), - position.tick_high.try_to_sqrt_price().unwrap(), - ); +// let initial_box_price = bbox( +// initial_sqrt_price, +// position.tick_low.try_to_sqrt_price().unwrap(), +// position.tick_high.try_to_sqrt_price().unwrap(), +// ); - let final_box_price = bbox( - final_sqrt_price, - position.tick_low.try_to_sqrt_price().unwrap(), - position.tick_high.try_to_sqrt_price().unwrap(), - ); +// let final_box_price = bbox( +// final_sqrt_price, +// position.tick_low.try_to_sqrt_price().unwrap(), +// position.tick_high.try_to_sqrt_price().unwrap(), +// ); - let fee_rate = FeeRate::::get(netuid) as f64 / u16::MAX as f64; +// let fee_rate = FeeRate::::get(netuid) as f64 / u16::MAX as f64; - log::trace!("fee_rate: {fee_rate:.6}"); - log::trace!("position.liquidity: {}", position.liquidity); - log::trace!( - "initial_box_price: {:.6}", - initial_box_price.to_num::() - ); - log::trace!("final_box_price: {:.6}", final_box_price.to_num::()); +// log::trace!("fee_rate: {fee_rate:.6}"); +// log::trace!("position.liquidity: {}", position.liquidity); +// log::trace!( +// "initial_box_price: {:.6}", +// initial_box_price.to_num::() +// ); +// log::trace!("final_box_price: {:.6}", final_box_price.to_num::()); - let expected_fee_tao = ((fee_rate / (1.0 - fee_rate)) - * (position.liquidity as f64) - * (final_box_price.to_num::() - initial_box_price.to_num::())) - as u64; +// let expected_fee_tao = ((fee_rate / (1.0 - fee_rate)) +// * (position.liquidity as f64) +// * (final_box_price.to_num::() - initial_box_price.to_num::())) +// as u64; - let expected_fee_alpha = ((fee_rate / (1.0 - fee_rate)) - * (position.liquidity as f64) - * ((1.0 / final_box_price.to_num::()) - (1.0 / initial_box_price.to_num::()))) - as u64; +// let expected_fee_alpha = ((fee_rate / (1.0 - fee_rate)) +// * (position.liquidity as f64) +// * ((1.0 / final_box_price.to_num::()) - (1.0 / initial_box_price.to_num::()))) +// as u64; - log::trace!("Expected ALPHA fee: {:.6}", expected_fee_alpha as f64); +// log::trace!("Expected ALPHA fee: {:.6}", expected_fee_alpha as f64); - let (fee_tao, fee_alpha) = position.collect_fees(); +// let (fee_tao, fee_alpha) = position.collect_fees(); - log::trace!("Collected fees: TAO: {fee_tao}, ALPHA: {fee_alpha}"); +// log::trace!("Collected fees: TAO: {fee_tao}, ALPHA: {fee_alpha}"); - assert_abs_diff_eq!(fee_tao, expected_fee_tao, epsilon = 1); - assert_abs_diff_eq!(fee_alpha, expected_fee_alpha, epsilon = 1); - }); -} +// assert_abs_diff_eq!(fee_tao, expected_fee_tao, epsilon = 1); +// assert_abs_diff_eq!(fee_alpha, expected_fee_alpha, epsilon = 1); +// }); +// } /// Test that price moves less with provided liquidity /// cargo test --package pallet-subtensor-swap --lib -- pallet::tests::test_less_price_movement --exact --show-output diff --git a/pallets/transaction-fee/src/lib.rs b/pallets/transaction-fee/src/lib.rs index fc2a16a409..fe1eb43ce8 100644 --- a/pallets/transaction-fee/src/lib.rs +++ b/pallets/transaction-fee/src/lib.rs @@ -31,7 +31,7 @@ use core::marker::PhantomData; use smallvec::smallvec; use sp_std::vec::Vec; use substrate_fixed::types::U96F32; -use subtensor_runtime_common::{Balance, Currency, NetUid}; +use subtensor_runtime_common::{AuthorshipInfo, Balance, NetUid}; // Tests #[cfg(test)] @@ -47,7 +47,7 @@ impl WeightToFeePolynomial for LinearWeightToFee { fn polynomial() -> WeightToFeeCoefficients { let coefficient = WeightToFeeCoefficient { coeff_integer: 0, - coeff_frac: Perbill::from_parts(50_000), // 0.05 unit per weight + coeff_frac: Perbill::from_parts(500_000), // 0.5 unit per weight negative: false, degree: 1, }; @@ -95,6 +95,7 @@ where T: frame_system::Config, T: pallet_subtensor::Config, T: pallet_balances::Config, + T: AuthorshipInfo>, { fn on_nonzero_unbalanced( imbalance: FungibleImbalance< @@ -103,11 +104,18 @@ where IncreaseIssuance, pallet_balances::Pallet>, >, ) { - let ti_before = pallet_subtensor::TotalIssuance::::get(); - pallet_subtensor::TotalIssuance::::put( - ti_before.saturating_sub(imbalance.peek().into()), - ); - drop(imbalance); + if let Some(author) = T::author() { + // Pay block author instead of burning. + // One of these is the right call depending on your exact fungible API: + // let _ = pallet_balances::Pallet::::resolve(&author, imbalance); + // or: let _ = pallet_balances::Pallet::::deposit(&author, imbalance.peek(), Precision::BestEffort); + // + // Prefer "resolve" (moves the actual imbalance) if available: + let _ = as Balanced<_>>::resolve(&author, imbalance); + } else { + // Fallback: if no author, burn (or just drop). + drop(imbalance); + } } } diff --git a/pallets/transaction-fee/src/tests/mock.rs b/pallets/transaction-fee/src/tests/mock.rs index 3bad4a275f..e4572bbfea 100644 --- a/pallets/transaction-fee/src/tests/mock.rs +++ b/pallets/transaction-fee/src/tests/mock.rs @@ -21,7 +21,7 @@ use sp_runtime::{ }; use sp_std::cmp::Ordering; use sp_weights::Weight; -pub use subtensor_runtime_common::{AlphaCurrency, Currency, NetUid, TaoCurrency}; +pub use subtensor_runtime_common::{AlphaCurrency, AuthorshipInfo, Currency, NetUid, TaoCurrency}; use subtensor_swap_interface::{Order, SwapHandler}; use crate::SubtensorTxFeeHandler; @@ -29,10 +29,7 @@ use pallet_transaction_payment::{ConstFeeMultiplier, Multiplier}; pub const TAO: u64 = 1_000_000_000; -pub type Block = sp_runtime::generic::Block< - sp_runtime::generic::Header, - UncheckedExtrinsic, ->; +type Block = frame_system::mocking::MockBlock; // Configure a mock runtime to test the pallet. frame_support::construct_runtime!( @@ -139,6 +136,22 @@ impl pallet_transaction_payment::Config for Test { type WeightInfo = pallet_transaction_payment::weights::SubstrateWeight; } +pub struct MockAuthorshipProvider; + +pub const MOCK_BLOCK_BUILDER: u64 = 12345u64; + +impl AuthorshipInfo for MockAuthorshipProvider { + fn author() -> Option { + Some(U256::from(MOCK_BLOCK_BUILDER)) + } +} + +impl AuthorshipInfo for Test { + fn author() -> Option { + Some(U256::from(MOCK_BLOCK_BUILDER)) + } +} + parameter_types! { pub const InitialMinAllowedWeights: u16 = 0; pub const InitialEmissionValue: u16 = 0; @@ -196,17 +209,14 @@ parameter_types! { pub const InitialNetworkMinLockCost: u64 = 100_000_000_000; pub const InitialSubnetOwnerCut: u16 = 0; // 0%. 100% of rewards go to validators + miners. pub const InitialNetworkLockReductionInterval: u64 = 2; // 2 blocks. - // pub const InitialSubnetLimit: u16 = 10; // (DEPRECATED) pub const InitialNetworkRateLimit: u64 = 0; pub const InitialKeySwapCost: u64 = 1_000_000_000; pub const InitialAlphaHigh: u16 = 58982; // Represents 0.9 as per the production default pub const InitialAlphaLow: u16 = 45875; // Represents 0.7 as per the production default pub const InitialLiquidAlphaOn: bool = false; // Default value for LiquidAlphaOn pub const InitialYuma3On: bool = false; // Default value for Yuma3On - // pub const InitialHotkeyEmissionTempo: u64 = 1; // (DEPRECATED) - // pub const InitialNetworkMaxStake: u64 = u64::MAX; // (DEPRECATED) - pub const InitialColdkeySwapScheduleDuration: u64 = 5 * 24 * 60 * 60 / 12; // 5 days - pub const InitialColdkeySwapRescheduleDuration: u64 = 24 * 60 * 60 / 12; // 1 day + pub const InitialColdkeySwapAnnouncementDelay: u64 = 50; + pub const InitialColdkeySwapReannouncementDelay: u64 = 10; pub const InitialDissolveNetworkScheduleDuration: u64 = 5 * 24 * 60 * 60 / 12; // 5 days pub const InitialTaoWeight: u64 = u64::MAX/10; // 10% global weight. pub const InitialEmaPriceHalvingPeriod: u64 = 201_600_u64; // 4 weeks @@ -275,8 +285,8 @@ impl pallet_subtensor::Config for Test { type LiquidAlphaOn = InitialLiquidAlphaOn; type Yuma3On = InitialYuma3On; type Preimages = (); - type InitialColdkeySwapScheduleDuration = InitialColdkeySwapScheduleDuration; - type InitialColdkeySwapRescheduleDuration = InitialColdkeySwapRescheduleDuration; + type InitialColdkeySwapAnnouncementDelay = InitialColdkeySwapAnnouncementDelay; + type InitialColdkeySwapReannouncementDelay = InitialColdkeySwapReannouncementDelay; type InitialDissolveNetworkScheduleDuration = InitialDissolveNetworkScheduleDuration; type InitialTaoWeight = InitialTaoWeight; type InitialEmaPriceHalvingPeriod = InitialEmaPriceHalvingPeriod; @@ -290,6 +300,7 @@ impl pallet_subtensor::Config for Test { type MaxImmuneUidsPercentage = MaxImmuneUidsPercentage; type CommitmentsInterface = CommitmentsI; type EvmKeyAssociateRateLimit = EvmKeyAssociateRateLimit; + type AuthorshipProvider = MockAuthorshipProvider; } parameter_types! { @@ -522,7 +533,12 @@ where pallet_transaction_payment::ChargeTransactionPayment::::from(0), ); - Some(UncheckedExtrinsic::new_signed(call, nonce, (), extra)) + Some(UncheckedExtrinsic::new_signed( + call, + nonce.into(), + (), + extra, + )) } } @@ -629,6 +645,38 @@ pub(crate) fn swap_alpha_to_tao(netuid: NetUid, alpha: AlphaCurrency) -> (u64, u swap_alpha_to_tao_ext(netuid, alpha, false) } +pub(crate) fn swap_tao_to_alpha_ext( + netuid: NetUid, + tao: TaoCurrency, + drop_fees: bool, +) -> (u64, u64) { + if netuid.is_root() { + return (tao.into(), 0); + } + + let order = GetAlphaForTao::::with_amount(tao); + let result = ::SwapInterface::swap( + netuid.into(), + order, + ::SwapInterface::max_price(), + drop_fees, + true, + ); + + assert_ok!(&result); + + let result = result.unwrap(); + + // we don't want to have silent 0 comparisons in tests + assert!(!result.amount_paid_out.is_zero()); + + (result.amount_paid_out.to_u64(), result.fee_paid.to_u64()) +} + +pub(crate) fn swap_tao_to_alpha(netuid: NetUid, tao: TaoCurrency) -> (u64, u64) { + swap_tao_to_alpha_ext(netuid, tao, false) +} + #[allow(dead_code)] pub fn add_network(netuid: NetUid, tempo: u16) { SubtensorModule::init_new_network(netuid, tempo); diff --git a/pallets/transaction-fee/src/tests/mod.rs b/pallets/transaction-fee/src/tests/mod.rs index b6697e87f0..fa501b899f 100644 --- a/pallets/transaction-fee/src/tests/mod.rs +++ b/pallets/transaction-fee/src/tests/mod.rs @@ -1209,3 +1209,55 @@ fn test_recycle_alpha_fees_alpha() { assert!(actual_alpha_fee > 0.into()); }); } + +// cargo test --package subtensor-transaction-fee --lib -- tests::test_add_stake_fees_go_to_block_builder --exact --show-output +#[test] +fn test_add_stake_fees_go_to_block_builder() { + new_test_ext().execute_with(|| { + // Portion of swap fees that should go to the block builder + let block_builder_fee_portion = 1.; + + // Get the block builder balance + let block_builder = U256::from(MOCK_BLOCK_BUILDER); + let block_builder_balance_before = Balances::free_balance(block_builder); + + let stake_amount = TAO; + let sn = setup_subnets(1, 1); + + // Simulate add stake to get the expected TAO fee + let (_, swap_fee) = mock::swap_tao_to_alpha(sn.subnets[0].netuid, stake_amount.into()); + + SubtensorModule::add_balance_to_coldkey_account(&sn.coldkey, stake_amount * 10_u64); + remove_stake_rate_limit_for_tests(&sn.hotkeys[0], &sn.coldkey, sn.subnets[0].netuid); + + // Stake + let balance_before = Balances::free_balance(sn.coldkey); + let call = RuntimeCall::SubtensorModule(pallet_subtensor::Call::add_stake { + hotkey: sn.hotkeys[0], + netuid: sn.subnets[0].netuid, + amount_staked: stake_amount.into(), + }); + + // Dispatch the extrinsic with ChargeTransactionPayment extension + let info = call.get_dispatch_info(); + let ext = pallet_transaction_payment::ChargeTransactionPayment::::from(0); + assert_ok!(ext.dispatch_transaction( + RuntimeOrigin::signed(sn.coldkey).into(), + call, + &info, + 0, + 0, + )); + + let final_balance = Balances::free_balance(sn.coldkey); + let actual_tao_fee = balance_before - stake_amount - final_balance; + assert!(actual_tao_fee > 0); + + // Expect that block builder balance has increased by both the swap fee and the transaction fee + let expected_block_builder_swap_reward = swap_fee as f64 * block_builder_fee_portion; + let expected_tx_fee = 0.000136; // Use very low value for less test flakiness + let block_builder_balance_after = Balances::free_balance(block_builder); + let actual_reward = block_builder_balance_after - block_builder_balance_before; + assert!(actual_reward as f64 >= expected_block_builder_swap_reward + expected_tx_fee); + }); +} diff --git a/precompiles/Cargo.toml b/precompiles/Cargo.toml index 400e1caa9f..be1824cf91 100644 --- a/precompiles/Cargo.toml +++ b/precompiles/Cargo.toml @@ -38,6 +38,7 @@ pallet-subtensor-swap.workspace = true pallet-admin-utils.workspace = true subtensor-swap-interface.workspace = true pallet-crowdloan.workspace = true +pallet-shield.workspace = true [lints] workspace = true @@ -63,6 +64,7 @@ std = [ "pallet-subtensor-proxy/std", "pallet-subtensor-swap/std", "pallet-subtensor/std", + "pallet-shield/std", "precompile-utils/std", "scale-info/std", "sp-core/std", diff --git a/precompiles/src/balance_transfer.rs b/precompiles/src/balance_transfer.rs index c1cdab6ca5..d8d10970a3 100644 --- a/precompiles/src/balance_transfer.rs +++ b/precompiles/src/balance_transfer.rs @@ -10,7 +10,7 @@ use sp_runtime::traits::{AsSystemOriginSigner, Dispatchable, StaticLookup, Uniqu use crate::{PrecompileExt, PrecompileHandleExt}; -pub(crate) struct BalanceTransferPrecompile(PhantomData); +pub struct BalanceTransferPrecompile(PhantomData); impl PrecompileExt for BalanceTransferPrecompile where @@ -18,6 +18,8 @@ where + pallet_balances::Config + pallet_evm::Config + pallet_subtensor::Config + + pallet_shield::Config + + pallet_subtensor_proxy::Config + Send + Sync + scale_info::TypeInfo, @@ -26,7 +28,9 @@ where ::RuntimeCall: GetDispatchInfo + Dispatchable + IsSubType> - + IsSubType>, + + IsSubType> + + IsSubType> + + IsSubType>, ::RuntimeCall: From> + GetDispatchInfo + Dispatchable, @@ -43,6 +47,8 @@ where + pallet_balances::Config + pallet_evm::Config + pallet_subtensor::Config + + pallet_shield::Config + + pallet_subtensor_proxy::Config + Send + Sync + scale_info::TypeInfo, @@ -51,7 +57,9 @@ where ::RuntimeCall: GetDispatchInfo + Dispatchable + IsSubType> - + IsSubType>, + + IsSubType> + + IsSubType> + + IsSubType>, ::RuntimeCall: From> + GetDispatchInfo + Dispatchable, diff --git a/precompiles/src/crowdloan.rs b/precompiles/src/crowdloan.rs index f0971015d9..c9926dfe3b 100644 --- a/precompiles/src/crowdloan.rs +++ b/precompiles/src/crowdloan.rs @@ -25,6 +25,8 @@ where + pallet_evm::Config + pallet_proxy::Config + pallet_subtensor::Config + + pallet_shield::Config + + pallet_subtensor_proxy::Config + Send + Sync + scale_info::TypeInfo, @@ -34,7 +36,9 @@ where + GetDispatchInfo + Dispatchable + IsSubType> - + IsSubType>, + + IsSubType> + + IsSubType> + + IsSubType>, ::AddressMapping: AddressMapping, { const INDEX: u64 = 2057; @@ -49,6 +53,8 @@ where + pallet_evm::Config + pallet_proxy::Config + pallet_subtensor::Config + + pallet_shield::Config + + pallet_subtensor_proxy::Config + Send + Sync + scale_info::TypeInfo, @@ -58,7 +64,9 @@ where + GetDispatchInfo + Dispatchable + IsSubType> - + IsSubType>, + + IsSubType> + + IsSubType> + + IsSubType>, ::RuntimeCall: From> + GetDispatchInfo + Dispatchable, diff --git a/precompiles/src/ed25519.rs b/precompiles/src/ed25519.rs index 1ea581bd35..dbfe032cdf 100644 --- a/precompiles/src/ed25519.rs +++ b/precompiles/src/ed25519.rs @@ -8,7 +8,7 @@ use fp_evm::{ExitError, ExitSucceed, LinearCostPrecompile, PrecompileFailure}; use crate::{PrecompileExt, parse_slice}; -pub(crate) struct Ed25519Verify(PhantomData); +pub struct Ed25519Verify(PhantomData); impl PrecompileExt for Ed25519Verify where diff --git a/precompiles/src/extensions.rs b/precompiles/src/extensions.rs index 5d73a75f9b..4a7c418c86 100644 --- a/precompiles/src/extensions.rs +++ b/precompiles/src/extensions.rs @@ -10,7 +10,7 @@ use pallet_evm::{ AddressMapping, BalanceConverter, EvmBalance, ExitError, GasWeightMapping, Precompile, PrecompileFailure, PrecompileHandle, PrecompileResult, }; -use pallet_subtensor::transaction_extension::SubtensorTransactionExtension; +use pallet_subtensor::SubtensorTransactionExtension; use precompile_utils::EvmResult; use scale_info::TypeInfo; use sp_core::{H160, U256, blake2_256}; @@ -23,6 +23,7 @@ use sp_runtime::{ transaction_validity::{TransactionSource, TransactionValidityError}, }; use sp_std::vec::Vec; +use subtensor_runtime_common::with_evm_context; pub(crate) trait PrecompileHandleExt: PrecompileHandle { fn caller_account_id(&self) -> R::AccountId @@ -58,6 +59,8 @@ pub(crate) trait PrecompileHandleExt: PrecompileHandle { + pallet_balances::Config + pallet_evm::Config + pallet_subtensor::Config + + pallet_shield::Config + + pallet_subtensor_proxy::Config + Send + Sync + TypeInfo, @@ -65,7 +68,9 @@ pub(crate) trait PrecompileHandleExt: PrecompileHandle { ::RuntimeCall: GetDispatchInfo + Dispatchable + IsSubType> - + IsSubType>, + + IsSubType> + + IsSubType> + + IsSubType>, ::RuntimeOrigin: From> + AsSystemOriginSigner + Clone, { @@ -109,7 +114,7 @@ pub(crate) trait PrecompileHandleExt: PrecompileHandle { .prepare(val, &origin, &call, &info, 0) .map_err(extension_error)?; - match call.dispatch(origin) { + match with_evm_context(|| call.dispatch(origin)) { Ok(mut post_info) => { post_info.set_extension_weight(&info); let result: DispatchResult = Ok(()); @@ -182,7 +187,7 @@ fn extension_error(err: TransactionValidityError) -> PrecompileFailure { impl PrecompileHandleExt for T where T: PrecompileHandle {} -pub(crate) trait PrecompileExt>: Precompile { +pub trait PrecompileExt>: Precompile { const INDEX: u64; // ss58 public key i.e., the contract sends funds it received to the destination address from diff --git a/precompiles/src/leasing.rs b/precompiles/src/leasing.rs index 01a8db4354..732e687c6f 100644 --- a/precompiles/src/leasing.rs +++ b/precompiles/src/leasing.rs @@ -26,6 +26,8 @@ where + pallet_evm::Config + pallet_subtensor::Config + pallet_crowdloan::Config + + pallet_shield::Config + + pallet_subtensor_proxy::Config + Send + Sync + scale_info::TypeInfo, @@ -36,7 +38,9 @@ where + GetDispatchInfo + Dispatchable + IsSubType> - + IsSubType>, + + IsSubType> + + IsSubType> + + IsSubType>, ::AddressMapping: AddressMapping, { const INDEX: u64 = 2058; @@ -50,6 +54,8 @@ where + pallet_evm::Config + pallet_subtensor::Config + pallet_crowdloan::Config + + pallet_shield::Config + + pallet_subtensor_proxy::Config + Send + Sync + scale_info::TypeInfo, @@ -60,7 +66,9 @@ where + GetDispatchInfo + Dispatchable + IsSubType> - + IsSubType>, + + IsSubType> + + IsSubType> + + IsSubType>, ::AddressMapping: AddressMapping, { #[precompile::public("getLease(uint32)")] diff --git a/precompiles/src/lib.rs b/precompiles/src/lib.rs index 864119d89f..a824ac39d4 100644 --- a/precompiles/src/lib.rs +++ b/precompiles/src/lib.rs @@ -10,6 +10,7 @@ use frame_support::{ dispatch::{DispatchInfo, GetDispatchInfo, PostDispatchInfo}, pallet_prelude::Decode, }; +use pallet_admin_utils::PrecompileEnum; use pallet_evm::{ AddressMapping, IsPrecompileResult, Precompile, PrecompileHandle, PrecompileResult, PrecompileSet, @@ -24,23 +25,24 @@ use sp_core::{H160, U256, crypto::ByteArray}; use sp_runtime::traits::{AsSystemOriginSigner, Dispatchable, StaticLookup}; use subtensor_runtime_common::ProxyType; -use pallet_admin_utils::PrecompileEnum; - -use crate::address_mapping::*; -use crate::alpha::*; -use crate::balance_transfer::*; -use crate::crowdloan::*; -use crate::ed25519::*; use crate::extensions::*; -use crate::leasing::*; -use crate::metagraph::*; -use crate::neuron::*; -use crate::proxy::*; -use crate::sr25519::*; -use crate::staking::*; -use crate::storage_query::*; -use crate::subnet::*; -use crate::uid_lookup::*; + +pub use address_mapping::AddressMappingPrecompile; +pub use alpha::AlphaPrecompile; +pub use balance_transfer::BalanceTransferPrecompile; +pub use crowdloan::CrowdloanPrecompile; +pub use ed25519::Ed25519Verify; +pub use extensions::PrecompileExt; +pub use leasing::LeasingPrecompile; +pub use metagraph::MetagraphPrecompile; +pub use neuron::NeuronPrecompile; +pub use proxy::ProxyPrecompile; +pub use sr25519::Sr25519Verify; +pub use staking::{StakingPrecompile, StakingPrecompileV2}; +pub use storage_query::StorageQueryPrecompile; +pub use subnet::SubnetPrecompile; +pub use uid_lookup::UidLookupPrecompile; +pub use voting_power::VotingPowerPrecompile; mod address_mapping; mod alpha; @@ -57,6 +59,7 @@ mod staking; mod storage_query; mod subnet; mod uid_lookup; +mod voting_power; pub struct Precompiles(PhantomData); @@ -70,6 +73,8 @@ where + pallet_subtensor_swap::Config + pallet_proxy::Config + pallet_crowdloan::Config + + pallet_shield::Config + + pallet_subtensor_proxy::Config + Send + Sync + scale_info::TypeInfo, @@ -83,7 +88,9 @@ where + GetDispatchInfo + Dispatchable + IsSubType> - + IsSubType>, + + IsSubType> + + IsSubType> + + IsSubType>, ::AddressMapping: AddressMapping, ::Balance: TryFrom, <::Lookup as StaticLookup>::Source: From, @@ -103,6 +110,8 @@ where + pallet_subtensor_swap::Config + pallet_proxy::Config + pallet_crowdloan::Config + + pallet_shield::Config + + pallet_subtensor_proxy::Config + Send + Sync + scale_info::TypeInfo, @@ -116,7 +125,9 @@ where + GetDispatchInfo + Dispatchable + IsSubType> - + IsSubType>, + + IsSubType> + + IsSubType> + + IsSubType>, ::AddressMapping: AddressMapping, ::Balance: TryFrom, <::Lookup as StaticLookup>::Source: From, @@ -125,7 +136,7 @@ where Self(Default::default()) } - pub fn used_addresses() -> [H160; 26] { + pub fn used_addresses() -> [H160; 27] { [ hash(1), hash(2), @@ -151,6 +162,7 @@ where hash(AlphaPrecompile::::INDEX), hash(CrowdloanPrecompile::::INDEX), hash(LeasingPrecompile::::INDEX), + hash(VotingPowerPrecompile::::INDEX), hash(ProxyPrecompile::::INDEX), hash(AddressMappingPrecompile::::INDEX), ] @@ -166,6 +178,8 @@ where + pallet_subtensor_swap::Config + pallet_proxy::Config + pallet_crowdloan::Config + + pallet_shield::Config + + pallet_subtensor_proxy::Config + Send + Sync + scale_info::TypeInfo, @@ -180,6 +194,8 @@ where + Dispatchable + IsSubType> + IsSubType> + + IsSubType> + + IsSubType> + Decode, <::RuntimeCall as Dispatchable>::RuntimeOrigin: From>>, @@ -245,6 +261,9 @@ where a if a == hash(LeasingPrecompile::::INDEX) => { LeasingPrecompile::::try_execute::(handle, PrecompileEnum::Leasing) } + a if a == hash(VotingPowerPrecompile::::INDEX) => { + VotingPowerPrecompile::::try_execute::(handle, PrecompileEnum::VotingPower) + } a if a == hash(ProxyPrecompile::::INDEX) => { ProxyPrecompile::::try_execute::(handle, PrecompileEnum::Proxy) } diff --git a/precompiles/src/neuron.rs b/precompiles/src/neuron.rs index 0b998b3c07..e2602c0246 100644 --- a/precompiles/src/neuron.rs +++ b/precompiles/src/neuron.rs @@ -19,6 +19,8 @@ where + pallet_balances::Config + pallet_evm::Config + pallet_subtensor::Config + + pallet_shield::Config + + pallet_subtensor_proxy::Config + Send + Sync + scale_info::TypeInfo, @@ -28,7 +30,9 @@ where + GetDispatchInfo + Dispatchable + IsSubType> - + IsSubType>, + + IsSubType> + + IsSubType> + + IsSubType>, ::AddressMapping: AddressMapping, { const INDEX: u64 = 2052; @@ -41,6 +45,8 @@ where + pallet_balances::Config + pallet_evm::Config + pallet_subtensor::Config + + pallet_shield::Config + + pallet_subtensor_proxy::Config + Send + Sync + scale_info::TypeInfo, @@ -50,7 +56,9 @@ where + GetDispatchInfo + Dispatchable + IsSubType> - + IsSubType>, + + IsSubType> + + IsSubType> + + IsSubType>, ::AddressMapping: AddressMapping, { #[precompile::public("setWeights(uint16,uint16[],uint16[],uint64)")] diff --git a/precompiles/src/proxy.rs b/precompiles/src/proxy.rs index 5139477f00..3312b67194 100644 --- a/precompiles/src/proxy.rs +++ b/precompiles/src/proxy.rs @@ -30,6 +30,8 @@ where + pallet_evm::Config + pallet_subtensor::Config + pallet_proxy::Config + + pallet_shield::Config + + pallet_subtensor_proxy::Config + Send + Sync + scale_info::TypeInfo, @@ -41,7 +43,9 @@ where + GetDispatchInfo + Dispatchable + IsSubType> - + IsSubType>, + + IsSubType> + + IsSubType> + + IsSubType>, ::AddressMapping: AddressMapping, <::Lookup as StaticLookup>::Source: From, { @@ -56,6 +60,8 @@ where + pallet_evm::Config + pallet_subtensor::Config + pallet_proxy::Config + + pallet_shield::Config + + pallet_subtensor_proxy::Config + Send + Sync + scale_info::TypeInfo, @@ -67,7 +73,9 @@ where + GetDispatchInfo + Dispatchable + IsSubType> - + IsSubType>, + + IsSubType> + + IsSubType> + + IsSubType>, <::Lookup as StaticLookup>::Source: From, { #[precompile::public("createPureProxy(uint8,uint32,uint16)")] diff --git a/precompiles/src/sr25519.rs b/precompiles/src/sr25519.rs index 6c6245d8f0..054948d524 100644 --- a/precompiles/src/sr25519.rs +++ b/precompiles/src/sr25519.rs @@ -9,7 +9,7 @@ use fp_evm::{ExitError, ExitSucceed, LinearCostPrecompile, PrecompileFailure}; use crate::{PrecompileExt, parse_slice}; -pub(crate) struct Sr25519Verify(PhantomData); +pub struct Sr25519Verify(PhantomData); impl PrecompileExt for Sr25519Verify where diff --git a/precompiles/src/staking.rs b/precompiles/src/staking.rs index 9cc2a2aaa4..c276c32e60 100644 --- a/precompiles/src/staking.rs +++ b/precompiles/src/staking.rs @@ -48,7 +48,7 @@ use crate::{PrecompileExt, PrecompileHandleExt}; // to stop supporting both precompiles. // // All the future extensions should happen in StakingPrecompileV2. -pub(crate) struct StakingPrecompileV2(PhantomData); +pub struct StakingPrecompileV2(PhantomData); impl PrecompileExt for StakingPrecompileV2 where @@ -57,6 +57,8 @@ where + pallet_evm::Config + pallet_subtensor::Config + pallet_proxy::Config + + pallet_shield::Config + + pallet_subtensor_proxy::Config + Send + Sync + scale_info::TypeInfo, @@ -67,7 +69,9 @@ where + GetDispatchInfo + Dispatchable + IsSubType> - + IsSubType>, + + IsSubType> + + IsSubType> + + IsSubType>, ::AddressMapping: AddressMapping, <::Lookup as StaticLookup>::Source: From, { @@ -82,6 +86,8 @@ where + pallet_evm::Config + pallet_subtensor::Config + pallet_proxy::Config + + pallet_shield::Config + + pallet_subtensor_proxy::Config + Send + Sync + scale_info::TypeInfo, @@ -92,7 +98,9 @@ where + GetDispatchInfo + Dispatchable + IsSubType> - + IsSubType>, + + IsSubType> + + IsSubType> + + IsSubType>, ::AddressMapping: AddressMapping, <::Lookup as StaticLookup>::Source: From, { @@ -442,7 +450,7 @@ where } // Deprecated, exists for backward compatibility. -pub(crate) struct StakingPrecompile(PhantomData); +pub struct StakingPrecompile(PhantomData); impl PrecompileExt for StakingPrecompile where @@ -451,6 +459,8 @@ where + pallet_subtensor::Config + pallet_proxy::Config + pallet_balances::Config + + pallet_shield::Config + + pallet_subtensor_proxy::Config + Send + Sync + scale_info::TypeInfo, @@ -462,7 +472,9 @@ where + GetDispatchInfo + Dispatchable + IsSubType> - + IsSubType>, + + IsSubType> + + IsSubType> + + IsSubType>, ::AddressMapping: AddressMapping, ::Balance: TryFrom, <::Lookup as StaticLookup>::Source: From, @@ -478,6 +490,8 @@ where + pallet_subtensor::Config + pallet_proxy::Config + pallet_balances::Config + + pallet_shield::Config + + pallet_subtensor_proxy::Config + Send + Sync + scale_info::TypeInfo, @@ -489,7 +503,9 @@ where + GetDispatchInfo + Dispatchable + IsSubType> - + IsSubType>, + + IsSubType> + + IsSubType> + + IsSubType>, ::AddressMapping: AddressMapping, ::Balance: TryFrom, <::Lookup as StaticLookup>::Source: From, diff --git a/precompiles/src/storage_query.rs b/precompiles/src/storage_query.rs index 3022fff36b..796d1c8f04 100644 --- a/precompiles/src/storage_query.rs +++ b/precompiles/src/storage_query.rs @@ -62,7 +62,7 @@ const AUTHORIZED_PREFIXES: [[u8; 16]; 10] = [ use crate::PrecompileExt; -pub(crate) struct StorageQueryPrecompile(PhantomData); +pub struct StorageQueryPrecompile(PhantomData); impl PrecompileExt for StorageQueryPrecompile where diff --git a/precompiles/src/subnet.rs b/precompiles/src/subnet.rs index 4df373c116..9d1e24cc1e 100644 --- a/precompiles/src/subnet.rs +++ b/precompiles/src/subnet.rs @@ -22,6 +22,8 @@ where + pallet_evm::Config + pallet_subtensor::Config + pallet_admin_utils::Config + + pallet_shield::Config + + pallet_subtensor_proxy::Config + Send + Sync + scale_info::TypeInfo, @@ -32,7 +34,9 @@ where + GetDispatchInfo + Dispatchable + IsSubType> - + IsSubType>, + + IsSubType> + + IsSubType> + + IsSubType>, ::AddressMapping: AddressMapping, { const INDEX: u64 = 2051; @@ -45,7 +49,9 @@ where + pallet_balances::Config + pallet_evm::Config + pallet_subtensor::Config + + pallet_shield::Config + pallet_admin_utils::Config + + pallet_subtensor_proxy::Config + Send + Sync + scale_info::TypeInfo, @@ -56,7 +62,9 @@ where + GetDispatchInfo + Dispatchable + IsSubType> - + IsSubType>, + + IsSubType> + + IsSubType> + + IsSubType>, ::AddressMapping: AddressMapping, { #[precompile::public("registerNetwork(bytes32)")] diff --git a/precompiles/src/uid_lookup.rs b/precompiles/src/uid_lookup.rs index be8c803b45..b791b96786 100644 --- a/precompiles/src/uid_lookup.rs +++ b/precompiles/src/uid_lookup.rs @@ -8,7 +8,7 @@ use sp_std::vec::Vec; use crate::PrecompileExt; -pub(crate) struct UidLookupPrecompile(PhantomData); +pub struct UidLookupPrecompile(PhantomData); impl PrecompileExt for UidLookupPrecompile where diff --git a/precompiles/src/voting_power.rs b/precompiles/src/voting_power.rs new file mode 100644 index 0000000000..74e1731b6e --- /dev/null +++ b/precompiles/src/voting_power.rs @@ -0,0 +1,131 @@ +use core::marker::PhantomData; + +use fp_evm::PrecompileHandle; +use precompile_utils::EvmResult; +use sp_core::{ByteArray, H256, U256}; +use subtensor_runtime_common::NetUid; + +use crate::PrecompileExt; + +/// VotingPower precompile for smart contract access to validator voting power. +/// +/// This precompile allows smart contracts to query voting power for validators, +/// enabling on-chain governance decisions like slashing and spending. +pub struct VotingPowerPrecompile(PhantomData); + +impl PrecompileExt for VotingPowerPrecompile +where + R: frame_system::Config + pallet_subtensor::Config, + R::AccountId: From<[u8; 32]> + ByteArray, +{ + const INDEX: u64 = 2061; +} + +#[precompile_utils::precompile] +impl VotingPowerPrecompile +where + R: frame_system::Config + pallet_subtensor::Config, + R::AccountId: From<[u8; 32]>, +{ + /// Get voting power for a hotkey on a subnet. + /// + /// Returns the EMA of stake for the hotkey, which represents its voting power. + /// Returns 0 if: + /// - The hotkey has no voting power entry + /// - Voting power tracking is not enabled for the subnet + /// - The hotkey is not registered on the subnet + /// + /// # Arguments + /// * `netuid` - The subnet identifier (u16) + /// * `hotkey` - The hotkey account ID (bytes32) + /// + /// # Returns + /// * `u256` - The voting power value (in RAO, same precision as stake) + #[precompile::public("getVotingPower(uint16,bytes32)")] + #[precompile::view] + fn get_voting_power( + _: &mut impl PrecompileHandle, + netuid: u16, + hotkey: H256, + ) -> EvmResult { + let hotkey = R::AccountId::from(hotkey.0); + let voting_power = pallet_subtensor::VotingPower::::get(NetUid::from(netuid), &hotkey); + Ok(U256::from(voting_power)) + } + + /// Check if voting power tracking is enabled for a subnet. + /// + /// # Arguments + /// * `netuid` - The subnet identifier (u16) + /// + /// # Returns + /// * `bool` - True if voting power tracking is enabled + #[precompile::public("isVotingPowerTrackingEnabled(uint16)")] + #[precompile::view] + fn is_voting_power_tracking_enabled( + _: &mut impl PrecompileHandle, + netuid: u16, + ) -> EvmResult { + Ok(pallet_subtensor::VotingPowerTrackingEnabled::::get( + NetUid::from(netuid), + )) + } + + /// Get the block at which voting power tracking will be disabled. + /// + /// Returns 0 if not scheduled for disabling. + /// When non-zero, tracking continues until this block, then stops. + /// + /// # Arguments + /// * `netuid` - The subnet identifier (u16) + /// + /// # Returns + /// * `u64` - The block number at which tracking will be disabled (0 if not scheduled) + #[precompile::public("getVotingPowerDisableAtBlock(uint16)")] + #[precompile::view] + fn get_voting_power_disable_at_block( + _: &mut impl PrecompileHandle, + netuid: u16, + ) -> EvmResult { + Ok(pallet_subtensor::VotingPowerDisableAtBlock::::get( + NetUid::from(netuid), + )) + } + + /// Get the EMA alpha value for voting power calculation on a subnet. + /// + /// Alpha is stored with 18 decimal precision (1.0 = 10^18). + /// Higher alpha = faster response to stake changes. + /// + /// # Arguments + /// * `netuid` - The subnet identifier (u16) + /// + /// # Returns + /// * `u64` - The alpha value (with 18 decimal precision) + #[precompile::public("getVotingPowerEmaAlpha(uint16)")] + #[precompile::view] + fn get_voting_power_ema_alpha(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { + Ok(pallet_subtensor::VotingPowerEmaAlpha::::get( + NetUid::from(netuid), + )) + } + + /// Get total voting power for a subnet. + /// + /// Returns the sum of all voting power for all validators on the subnet. + /// Useful for calculating voting thresholds (e.g., 51% quorum). + /// + /// # Arguments + /// * `netuid` - The subnet identifier (u16) + /// + /// # Returns + /// * `u256` - The total voting power across all validators + #[precompile::public("getTotalVotingPower(uint16)")] + #[precompile::view] + fn get_total_voting_power(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { + let total: u64 = pallet_subtensor::VotingPower::::iter_prefix(NetUid::from(netuid)) + .map(|(_, voting_power)| voting_power) + .fold(0u64, |acc, vp| acc.saturating_add(vp)); + Ok(U256::from(total)) + } +} diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index b3aced2160..623846de12 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -158,6 +158,7 @@ ethereum.workspace = true frame-metadata.workspace = true sp-io.workspace = true sp-tracing.workspace = true +precompile-utils = { workspace = true, features = ["testing"] } [build-dependencies] substrate-wasm-builder = { workspace = true, optional = true } diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 919468c1ef..41a00e3f64 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -71,7 +71,7 @@ use sp_std::prelude::*; use sp_version::NativeVersion; use sp_version::RuntimeVersion; use subtensor_precompiles::Precompiles; -use subtensor_runtime_common::{AlphaCurrency, TaoCurrency, time::*, *}; +use subtensor_runtime_common::{AlphaCurrency, AuthorshipInfo, TaoCurrency, time::*, *}; use subtensor_swap_interface::{Order, SwapHandler}; // A few exports that help ease life for downstream crates. @@ -177,8 +177,7 @@ impl frame_system::offchain::CreateSignedTransaction pallet_transaction_payment::ChargeTransactionPayment::::from(0), ), SudoTransactionExtension::::new(), - pallet_subtensor::transaction_extension::SubtensorTransactionExtension::::new( - ), + pallet_subtensor::SubtensorTransactionExtension::::new(), pallet_drand::drand_priority::DrandPriority::::new(), frame_metadata_hash_extension::CheckMetadataHash::::new(true), ); @@ -241,7 +240,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: 377, + spec_version: 385, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1, @@ -354,6 +353,7 @@ impl frame_system::Config for Runtime { type PostInherents = (); type PostTransactions = (); type ExtensionsWeightInfo = frame_system::SubstrateExtensionsWeight; + type DispatchGuard = pallet_subtensor::CheckColdkeySwap; } impl pallet_insecure_randomness_collective_flip::Config for Runtime {} @@ -491,6 +491,34 @@ impl pallet_balances::Config for Runtime { type DoneSlashHandler = (); } +// Implement AuthorshipInfo trait for Runtime to satisfy pallet transaction +// fee OnUnbalanced trait bounds +pub struct BlockAuthorFromAura(core::marker::PhantomData); + +impl> BlockAuthorFromAura { + pub fn get_block_author() -> Option { + let binding = frame_system::Pallet::::digest(); + let digest_logs = binding.logs(); + let author_index = F::find_author(digest_logs.iter().filter_map(|d| d.as_pre_runtime()))?; + let authority_id = pallet_aura::Authorities::::get() + .get(author_index as usize)? + .clone(); + Some(AccountId32::new(authority_id.to_raw_vec().try_into().ok()?)) + } +} + +impl AuthorshipInfo for Runtime { + fn author() -> Option { + BlockAuthorFromAura::::get_block_author() + } +} + +impl> AuthorshipInfo for BlockAuthorFromAura { + fn author() -> Option { + Self::get_block_author() + } +} + parameter_types! { pub const OperationalFeeMultiplier: u8 = 5; pub FeeMultiplier: Multiplier = Multiplier::one(); @@ -1001,7 +1029,7 @@ parameter_types! { pub const SubtensorInitialRho: u16 = 10; pub const SubtensorInitialAlphaSigmoidSteepness: i16 = 1000; pub const SubtensorInitialKappa: u16 = 32_767; // 0.5 = 65535/2 - pub const SubtensorInitialMaxAllowedUids: u16 = 4096; + pub const SubtensorInitialMaxAllowedUids: u16 = 256; pub const SubtensorInitialIssuance: u64 = 0; pub const SubtensorInitialMinAllowedWeights: u16 = 1024; pub const SubtensorInitialEmissionValue: u16 = 0; @@ -1043,7 +1071,6 @@ parameter_types! { pub const SubtensorInitialMinAllowedUids: u16 = 64; pub const SubtensorInitialMinLockCost: u64 = 1_000_000_000_000; // 1000 TAO pub const SubtensorInitialSubnetOwnerCut: u16 = 11_796; // 18 percent - // pub const SubtensorInitialSubnetLimit: u16 = 12; // (DEPRECATED) pub const SubtensorInitialNetworkLockReductionInterval: u64 = 14 * 7200; pub const SubtensorInitialNetworkRateLimit: u64 = 7200; pub const SubtensorInitialKeySwapCost: u64 = 100_000_000; // 0.1 TAO @@ -1051,9 +1078,8 @@ parameter_types! { pub const InitialAlphaLow: u16 = 45875; // Represents 0.7 as per the production default pub const InitialLiquidAlphaOn: bool = false; // Default value for LiquidAlphaOn pub const InitialYuma3On: bool = false; // Default value for Yuma3On - // pub const SubtensorInitialNetworkMaxStake: u64 = u64::MAX; // (DEPRECATED) - pub const InitialColdkeySwapScheduleDuration: BlockNumber = 5 * 24 * 60 * 60 / 12; // 5 days - pub const InitialColdkeySwapRescheduleDuration: BlockNumber = 24 * 60 * 60 / 12; // 1 day + pub const InitialColdkeySwapAnnouncementDelay: BlockNumber = prod_or_fast!(5 * 24 * 60 * 60 / 12, 50); // 5 days + pub const InitialColdkeySwapReannouncementDelay: BlockNumber = prod_or_fast!(24 * 60 * 60 / 12, 10); // 1 day pub const InitialDissolveNetworkScheduleDuration: BlockNumber = 5 * 24 * 60 * 60 / 12; // 5 days pub const SubtensorInitialTaoWeight: u64 = 971_718_665_099_567_868; // 0.05267697438728329% tao weight. pub const InitialEmaPriceHalvingPeriod: u64 = 201_600_u64; // 4 weeks @@ -1124,8 +1150,8 @@ impl pallet_subtensor::Config for Runtime { type Yuma3On = InitialYuma3On; type InitialTaoWeight = SubtensorInitialTaoWeight; type Preimages = Preimage; - type InitialColdkeySwapScheduleDuration = InitialColdkeySwapScheduleDuration; - type InitialColdkeySwapRescheduleDuration = InitialColdkeySwapRescheduleDuration; + type InitialColdkeySwapAnnouncementDelay = InitialColdkeySwapAnnouncementDelay; + type InitialColdkeySwapReannouncementDelay = InitialColdkeySwapReannouncementDelay; type InitialDissolveNetworkScheduleDuration = InitialDissolveNetworkScheduleDuration; type InitialEmaPriceHalvingPeriod = InitialEmaPriceHalvingPeriod; type InitialStartCallDelay = InitialStartCallDelay; @@ -1138,6 +1164,7 @@ impl pallet_subtensor::Config for Runtime { type MaxImmuneUidsPercentage = MaxImmuneUidsPercentage; type CommitmentsInterface = CommitmentsI; type EvmKeyAssociateRateLimit = EvmKeyAssociateRateLimit; + type AuthorshipProvider = BlockAuthorFromAura; } parameter_types! { @@ -1618,7 +1645,7 @@ pub type TransactionExtensions = ( frame_system::CheckWeight, ChargeTransactionPaymentWrapper, SudoTransactionExtension, - pallet_subtensor::transaction_extension::SubtensorTransactionExtension, + pallet_subtensor::SubtensorTransactionExtension, pallet_drand::drand_priority::DrandPriority, frame_metadata_hash_extension::CheckMetadataHash, ); @@ -1671,6 +1698,7 @@ mod benches { [pallet_crowdloan, Crowdloan] [pallet_subtensor_swap, Swap] [pallet_shield, MevShield] + [pallet_subtensor_proxy, Proxy] ); } @@ -2509,6 +2537,7 @@ impl_runtime_apis! { fn sim_swap_tao_for_alpha(netuid: NetUid, tao: TaoCurrency) -> SimSwapResult { let order = pallet_subtensor::GetAlphaForTao::::with_amount(tao); + // fee_to_block_author is included in sr.fee_paid, so it is absent in this calculation pallet_subtensor_swap::Pallet::::sim_swap( netuid.into(), order, @@ -2531,6 +2560,7 @@ impl_runtime_apis! { fn sim_swap_alpha_for_tao(netuid: NetUid, alpha: AlphaCurrency) -> SimSwapResult { let order = pallet_subtensor::GetTaoForAlpha::::with_amount(alpha); + // fee_to_block_author is included in sr.fee_paid, so it is absent in this calculation pallet_subtensor_swap::Pallet::::sim_swap( netuid.into(), order, diff --git a/runtime/src/transaction_payment_wrapper.rs b/runtime/src/transaction_payment_wrapper.rs index 96d7f3609b..7973c44caf 100644 --- a/runtime/src/transaction_payment_wrapper.rs +++ b/runtime/src/transaction_payment_wrapper.rs @@ -3,18 +3,28 @@ use codec::{Decode, DecodeWithMemTracking, Encode}; use frame_election_provider_support::private::sp_arithmetic::traits::SaturatedConversion; use frame_support::dispatch::{DispatchClass, DispatchInfo, PostDispatchInfo}; use frame_support::pallet_prelude::TypeInfo; +use frame_support::traits::{Get, IsSubType, IsType}; +use pallet_subtensor_proxy as pallet_proxy; +use pallet_subtensor_utility as pallet_utility; use pallet_transaction_payment::{ChargeTransactionPayment, Config, Pre, Val}; use sp_runtime::DispatchResult; use sp_runtime::traits::{ - DispatchInfoOf, DispatchOriginOf, Dispatchable, Implication, PostDispatchInfoOf, - TransactionExtension, TransactionExtensionMetadata, ValidateResult, + AsSystemOriginSigner, DispatchInfoOf, DispatchOriginOf, Dispatchable, Implication, + PostDispatchInfoOf, StaticLookup, TransactionExtension, TransactionExtensionMetadata, + ValidateResult, }; use sp_runtime::transaction_validity::{ TransactionPriority, TransactionSource, TransactionValidity, TransactionValidityError, }; +use sp_std::boxed::Box; use sp_std::vec::Vec; use subtensor_macros::freeze_struct; +type RuntimeCallOf = ::RuntimeCall; +type RuntimeOriginOf = ::RuntimeOrigin; +type AccountIdOf = ::AccountId; +type LookupOf = ::Lookup; + #[freeze_struct("5f10cb9db06873c0")] #[derive(Encode, Decode, DecodeWithMemTracking, Clone, Eq, PartialEq, TypeInfo)] #[scale_info(skip_type_params(T))] @@ -41,64 +51,206 @@ impl ChargeTransactionPaymentWrapper { } } -impl TransactionExtension for ChargeTransactionPaymentWrapper +impl ChargeTransactionPaymentWrapper where - T::RuntimeCall: Dispatchable, + RuntimeCallOf: IsSubType> + IsSubType>, + RuntimeOriginOf: AsSystemOriginSigner> + Clone, +{ + /// Extract (real, delegate, inner_call) from a `proxy` call. + /// `signer` is used as the delegate since it is implicit (the caller). + /// `proxy_announced` is intentionally not handled here; fee propagation + /// only applies to `proxy` calls to keep the logic simple. + fn extract_proxy_parts<'a>( + call: &'a RuntimeCallOf, + signer: &AccountIdOf, + ) -> Option<( + AccountIdOf, + AccountIdOf, + &'a Box<::RuntimeCall>, + )> { + match call.is_sub_type()? { + pallet_proxy::Call::proxy { real, call, .. } => { + let real = LookupOf::::lookup(real.clone()).ok()?; + Some((real, signer.clone(), call)) + } + _ => None, + } + } + + /// Determine who should pay the transaction fee for a proxy call. + /// + /// Follows the RealPaysFee chain up to 2 levels deep: + /// - Case 1: `proxy(real=A, call)` → A pays if `RealPaysFee` + /// - Case 2: `proxy(real=B, proxy(real=A, call))` → A pays if both + /// `RealPaysFee` and `RealPaysFee` are set; B pays if only the former. + /// - Case 3: `proxy(real=B, batch([proxy(real=A, ..), ..]))` → A pays if + /// `RealPaysFee`, all batch items are proxy calls with the same real A, + /// and `RealPaysFee` is set; B pays if only the first condition holds. + /// + /// Returns `None` if the signer should pay (no RealPaysFee opt-in). + fn extract_real_fee_payer( + call: &RuntimeCallOf, + origin: &RuntimeOriginOf, + ) -> Option> { + let signer = origin.as_system_origin_signer()?; + let (outer_real, delegate, inner_call) = Self::extract_proxy_parts(call, signer)?; + + // Check if the outer real account has opted in to pay for the delegate. + if !pallet_proxy::Pallet::::is_real_pays_fee(&outer_real, &delegate) { + return None; + } + + // outer_real pays. Try to push the fee deeper into nested proxy structures. + let inner_call: &RuntimeCallOf = (*inner_call).as_ref().into_ref(); + + // Case 2: inner call is another proxy call. + if let Some(inner_payer) = Self::extract_inner_proxy_payer(inner_call, &outer_real) { + return Some(inner_payer); + } + + // Case 3: inner call is a batch of proxy calls with the same real. + if let Some(batch_payer) = Self::extract_batch_proxy_payer(inner_call, &outer_real) { + return Some(batch_payer); + } + + // Case 1: simple proxy, outer_real pays. + Some(outer_real) + } + + /// Check if an inner call is a proxy call where the inner real has opted in to pay. + /// `outer_real` is used as the implicit delegate for `proxy` calls. + fn extract_inner_proxy_payer( + inner_call: &RuntimeCallOf, + outer_real: &AccountIdOf, + ) -> Option> { + let (inner_real, inner_delegate, _call) = + Self::extract_proxy_parts(inner_call, outer_real)?; + + if pallet_proxy::Pallet::::is_real_pays_fee(&inner_real, &inner_delegate) { + Some(inner_real) + } else { + None + } + } + + /// Check if an inner call is a batch where ALL items are proxy calls with the same real + /// account, and that real account has opted in to pay. + /// `outer_real` is used as the implicit delegate for `proxy` calls within the batch. + fn extract_batch_proxy_payer( + inner_call: &RuntimeCallOf, + outer_real: &AccountIdOf, + ) -> Option> { + let calls: &Vec<::RuntimeCall> = + match inner_call.is_sub_type()? { + pallet_utility::Call::batch { calls } + | pallet_utility::Call::batch_all { calls } + | pallet_utility::Call::force_batch { calls } => calls, + _ => return None, + }; + + if calls.is_empty() { + return None; + } + + let mut common_real: Option> = None; + + for call in calls.iter() { + let call_ref: &RuntimeCallOf = call.into_ref(); + let (inner_real, inner_delegate, _) = Self::extract_proxy_parts(call_ref, outer_real)?; + + match &common_real { + None => { + // Check RealPaysFee once on the first item and memoize. For `proxy` + // calls the delegate is always `outer_real`, so a single read covers + // the entire batch; for `proxy_announced` it uses the explicit delegate. + if !pallet_proxy::Pallet::::is_real_pays_fee(&inner_real, &inner_delegate) { + return None; + } + common_real = Some(inner_real); + } + // All items must share the same real account. + Some(existing) if *existing != inner_real => return None, + _ => {} + } + } + + common_real + } +} + +impl + TransactionExtension> for ChargeTransactionPaymentWrapper +where + RuntimeCallOf: Dispatchable + + IsSubType> + + IsSubType>, + RuntimeOriginOf: AsSystemOriginSigner> + + Clone + + From>>, { const IDENTIFIER: &'static str = "ChargeTransactionPaymentWrapper"; type Implicit = (); type Val = Val; type Pre = Pre; - fn weight(&self, call: &T::RuntimeCall) -> Weight { - self.charge_transaction_payment.weight(call) + fn weight(&self, call: &RuntimeCallOf) -> Weight { + // Account for up to 3 storage reads in the worst-case fee payer resolution + // (outer is_real_pays_fee + inner/batch is_real_pays_fee + margin). + self.charge_transaction_payment + .weight(call) + .saturating_add(T::DbWeight::get().reads(3)) } fn validate( &self, - origin: DispatchOriginOf, - call: &T::RuntimeCall, - info: &DispatchInfoOf, + origin: DispatchOriginOf>, + call: &RuntimeCallOf, + info: &DispatchInfoOf>, len: usize, self_implicit: Self::Implicit, inherited_implication: &impl Implication, source: TransactionSource, - ) -> ValidateResult { - let inner_validate = self.charge_transaction_payment.validate( - origin, + ) -> ValidateResult> { + let overridden_priority = { + let base: TransactionPriority = match info.class { + DispatchClass::Normal => NORMAL_DISPATCH_BASE_PRIORITY, + DispatchClass::Mandatory => NORMAL_DISPATCH_BASE_PRIORITY, + DispatchClass::Operational => OPERATIONAL_DISPATCH_PRIORITY, + }; + base.saturated_into::() + }; + + // If a real account opted in to pay fees, create a synthetic origin for fee validation. + // Otherwise, the signer pays as usual. + let fee_origin = if let Some(real) = Self::extract_real_fee_payer(call, &origin) { + frame_system::RawOrigin::Signed(real).into() + } else { + origin.clone() + }; + + let (mut valid_transaction, val, _fee_origin) = self.charge_transaction_payment.validate( + fee_origin, call, info, len, self_implicit, inherited_implication, source, - ); - - match inner_validate { - Ok((mut valid_transaction, val, origin)) => { - let overridden_priority = { - let base: TransactionPriority = match info.class { - DispatchClass::Normal => NORMAL_DISPATCH_BASE_PRIORITY, - DispatchClass::Mandatory => NORMAL_DISPATCH_BASE_PRIORITY, - DispatchClass::Operational => OPERATIONAL_DISPATCH_PRIORITY, - }; - base.saturated_into::() - }; - - valid_transaction.priority = overridden_priority; - - Ok((valid_transaction, val, origin)) - } - Err(err) => Err(err), - } + )?; + + valid_transaction.priority = overridden_priority; + + // Always return the original origin so the actual signer remains + // the origin for dispatch and all subsequent extensions. + Ok((valid_transaction, val, origin)) } fn prepare( self, val: Self::Val, - origin: &DispatchOriginOf, - call: &T::RuntimeCall, - info: &DispatchInfoOf, + origin: &DispatchOriginOf>, + call: &RuntimeCallOf, + info: &DispatchInfoOf>, len: usize, ) -> Result { self.charge_transaction_payment @@ -109,8 +261,8 @@ where } fn post_dispatch_details( pre: Self::Pre, - info: &DispatchInfoOf, - post_info: &PostDispatchInfoOf, + info: &DispatchInfoOf>, + post_info: &PostDispatchInfoOf>, len: usize, result: &DispatchResult, ) -> Result { @@ -119,8 +271,8 @@ where fn post_dispatch( pre: Self::Pre, - info: &DispatchInfoOf, - post_info: &mut PostDispatchInfoOf, + info: &DispatchInfoOf>, + post_info: &mut PostDispatchInfoOf>, len: usize, result: &DispatchResult, ) -> Result<(), TransactionValidityError> { @@ -128,24 +280,24 @@ where } fn bare_validate( - call: &T::RuntimeCall, - info: &DispatchInfoOf, + call: &RuntimeCallOf, + info: &DispatchInfoOf>, len: usize, ) -> TransactionValidity { ChargeTransactionPayment::::bare_validate(call, info, len) } fn bare_validate_and_prepare( - call: &T::RuntimeCall, - info: &DispatchInfoOf, + call: &RuntimeCallOf, + info: &DispatchInfoOf>, len: usize, ) -> Result<(), TransactionValidityError> { ChargeTransactionPayment::::bare_validate_and_prepare(call, info, len) } fn bare_post_dispatch( - info: &DispatchInfoOf, - post_info: &mut PostDispatchInfoOf, + info: &DispatchInfoOf>, + post_info: &mut PostDispatchInfoOf>, len: usize, result: &DispatchResult, ) -> Result<(), TransactionValidityError> { diff --git a/runtime/tests/precompiles.rs b/runtime/tests/precompiles.rs new file mode 100644 index 0000000000..dcd7b3f3b9 --- /dev/null +++ b/runtime/tests/precompiles.rs @@ -0,0 +1,219 @@ +#![allow(clippy::unwrap_used)] +#![allow(clippy::expect_used)] + +use core::iter::IntoIterator; +use std::collections::BTreeSet; + +use fp_evm::{Context, ExitError, PrecompileFailure, PrecompileResult}; +use node_subtensor_runtime::{BuildStorage, Runtime, RuntimeGenesisConfig, System}; +use pallet_evm::{AddressMapping, BalanceConverter, PrecompileSet}; +use precompile_utils::testing::{MockHandle, PrecompileTesterExt}; +use sp_core::{H160, H256, U256}; +use sp_runtime::traits::Hash; +use subtensor_precompiles::{ + AddressMappingPrecompile, BalanceTransferPrecompile, PrecompileExt, Precompiles, +}; + +type AccountId = ::AccountId; + +fn new_test_ext() -> sp_io::TestExternalities { + let mut ext: sp_io::TestExternalities = RuntimeGenesisConfig::default() + .build_storage() + .unwrap() + .into(); + ext.execute_with(|| System::set_block_number(1)); + ext +} + +fn execute_precompile( + precompiles: &Precompiles, + precompile_address: H160, + caller: H160, + input: Vec, + apparent_value: U256, +) -> Option { + let mut handle = MockHandle::new( + precompile_address, + Context { + address: precompile_address, + caller, + apparent_value, + }, + ); + handle.input = input; + precompiles.execute(&mut handle) +} + +fn evm_apparent_value_from_substrate(amount: u64) -> U256 { + ::BalanceConverter::into_evm_balance(amount.into()) + .expect("runtime balance conversion should work for test amount") + .into() +} + +fn addr_from_index(index: u64) -> H160 { + H160::from_low_u64_be(index) +} + +#[test] +fn precompile_registry_addresses_are_unique() { + new_test_ext().execute_with(|| { + let addresses = Precompiles::::used_addresses(); + let unique: BTreeSet<_> = IntoIterator::into_iter(addresses).collect(); + assert_eq!(unique.len(), addresses.len()); + }); +} + +mod address_mapping { + use super::*; + + fn address_mapping_call_data(target: H160) -> Vec { + // Solidity selector for addressMapping(address). + let selector = sp_io::hashing::keccak_256(b"addressMapping(address)"); + let mut input = Vec::with_capacity(4 + 32); + // First 4 bytes of keccak256(function_signature): ABI function selector. + input.extend_from_slice(&selector[..4]); + // Left-pad the 20-byte address argument to a 32-byte ABI word. + input.extend_from_slice(&[0u8; 12]); + // The 20-byte address payload (right-aligned in the 32-byte ABI word). + input.extend_from_slice(target.as_bytes()); + input + } + + #[test] + fn address_mapping_precompile_returns_runtime_address_mapping() { + new_test_ext().execute_with(|| { + let precompiles = Precompiles::::new(); + + let caller = addr_from_index(1); + let target_address = addr_from_index(0x1234); + let input = address_mapping_call_data(target_address); + + let mapped_account = + ::AddressMapping::into_account_id(target_address); + let expected_output: [u8; 32] = mapped_account.into(); + + let precompile_addr = addr_from_index(AddressMappingPrecompile::::INDEX); + precompiles + .prepare_test(caller, precompile_addr, input) + .with_static_call(true) + .execute_returns_raw(expected_output.to_vec()); + }); + } +} + +mod balance_transfer { + use super::*; + + fn balance_transfer_call_data(target: H256) -> Vec { + // Solidity selector for transfer(bytes32). + let selector = sp_io::hashing::keccak_256(b"transfer(bytes32)"); + let mut input = Vec::with_capacity(4 + 32); + input.extend_from_slice(&selector[..4]); + input.extend_from_slice(target.as_bytes()); + input + } + + #[test] + fn balance_transfer_precompile_transfers_balance() { + new_test_ext().execute_with(|| { + let precompiles = Precompiles::::new(); + let precompile_addr = addr_from_index(BalanceTransferPrecompile::::INDEX); + let dispatch_account: AccountId = BalanceTransferPrecompile::::account_id(); + let destination_raw = H256::repeat_byte(7); + let destination_account: AccountId = destination_raw.0.into(); + + let amount = 123_456; + pallet_subtensor::Pallet::::add_balance_to_coldkey_account( + &dispatch_account, + (amount * 2).into(), + ); + + let source_balance_before = + pallet_balances::Pallet::::free_balance(&dispatch_account); + let destination_balance_before = + pallet_balances::Pallet::::free_balance(&destination_account); + + let result = execute_precompile( + &precompiles, + precompile_addr, + addr_from_index(1), + balance_transfer_call_data(destination_raw), + evm_apparent_value_from_substrate(amount), + ); + let precompile_result = + result.expect("expected precompile transfer call to be routed to a precompile"); + precompile_result.expect("expected successful precompile transfer dispatch"); + + let source_balance_after = + pallet_balances::Pallet::::free_balance(&dispatch_account); + let destination_balance_after = + pallet_balances::Pallet::::free_balance(&destination_account); + + assert_eq!(source_balance_after, source_balance_before - amount); + assert_eq!( + destination_balance_after, + destination_balance_before + amount + ); + }); + } + + #[test] + fn balance_transfer_precompile_respects_dispatch_guard_policy() { + new_test_ext().execute_with(|| { + let precompiles = Precompiles::::new(); + let precompile_addr = addr_from_index(BalanceTransferPrecompile::::INDEX); + let dispatch_account: AccountId = BalanceTransferPrecompile::::account_id(); + let destination_raw = H256::repeat_byte(8); + let destination_account: AccountId = destination_raw.0.into(); + + let amount = 100; + pallet_subtensor::Pallet::::add_balance_to_coldkey_account( + &dispatch_account, + 1_000_000_u64.into(), + ); + + // Activate coldkey-swap guard for precompile dispatch account. + let replacement_coldkey = AccountId::from([9u8; 32]); + let replacement_hash = + ::Hashing::hash_of(&replacement_coldkey); + pallet_subtensor::ColdkeySwapAnnouncements::::insert( + &dispatch_account, + (System::block_number(), replacement_hash), + ); + + let source_balance_before = + pallet_balances::Pallet::::free_balance(&dispatch_account); + let destination_balance_before = + pallet_balances::Pallet::::free_balance(&destination_account); + + let result = execute_precompile( + &precompiles, + precompile_addr, + addr_from_index(1), + balance_transfer_call_data(destination_raw), + evm_apparent_value_from_substrate(amount), + ); + let precompile_result = + result.expect("expected precompile transfer call to be routed to a precompile"); + let failure = precompile_result + .expect_err("expected transaction extension rejection on precompile dispatch"); + let message = match failure { + PrecompileFailure::Error { + exit_status: ExitError::Other(message), + } => message, + other => panic!("unexpected precompile failure: {other:?}"), + }; + assert!( + message.contains("dispatch execution failed: ColdkeySwapAnnounced"), + "unexpected precompile failure: {message}" + ); + + let source_balance_after = + pallet_balances::Pallet::::free_balance(&dispatch_account); + let destination_balance_after = + pallet_balances::Pallet::::free_balance(&destination_account); + assert_eq!(source_balance_after, source_balance_before); + assert_eq!(destination_balance_after, destination_balance_before); + }); + } +} diff --git a/runtime/tests/transaction_payment_wrapper.rs b/runtime/tests/transaction_payment_wrapper.rs new file mode 100644 index 0000000000..639e8b3576 --- /dev/null +++ b/runtime/tests/transaction_payment_wrapper.rs @@ -0,0 +1,463 @@ +#![allow(clippy::unwrap_used)] + +use frame_support::{ + assert_ok, + dispatch::{DispatchClass, DispatchInfo, GetDispatchInfo}, +}; +use node_subtensor_runtime::{ + BuildStorage, NORMAL_DISPATCH_BASE_PRIORITY, OPERATIONAL_DISPATCH_PRIORITY, Proxy, Runtime, + RuntimeCall, RuntimeGenesisConfig, RuntimeOrigin, System, SystemCall, + transaction_payment_wrapper, +}; +use pallet_subtensor_proxy as pallet_proxy; +use pallet_subtensor_utility as pallet_utility; +use pallet_transaction_payment::{ChargeTransactionPayment, Val}; +use sp_runtime::traits::{TransactionExtension, TxBaseImplication}; +use sp_runtime::transaction_validity::{ + TransactionSource, TransactionValidityError, ValidTransaction, +}; +use subtensor_runtime_common::{AccountId, ProxyType}; + +const SIGNER: [u8; 32] = [1_u8; 32]; +const REAL_A: [u8; 32] = [2_u8; 32]; +const REAL_B: [u8; 32] = [3_u8; 32]; +const OTHER: [u8; 32] = [4_u8; 32]; +const BALANCE: u64 = 1_000_000_000_000; + +fn new_test_ext() -> sp_io::TestExternalities { + sp_tracing::try_init_simple(); + let mut ext: sp_io::TestExternalities = RuntimeGenesisConfig { + balances: pallet_balances::GenesisConfig { + balances: vec![ + (AccountId::from(SIGNER), BALANCE), + (AccountId::from(REAL_A), BALANCE), + (AccountId::from(REAL_B), BALANCE), + (AccountId::from(OTHER), BALANCE), + ], + dev_accounts: None, + }, + ..Default::default() + } + .build_storage() + .unwrap() + .into(); + ext.execute_with(|| System::set_block_number(1)); + ext +} + +fn signer() -> AccountId { + AccountId::from(SIGNER) +} +fn real_a() -> AccountId { + AccountId::from(REAL_A) +} +fn real_b() -> AccountId { + AccountId::from(REAL_B) +} +fn other() -> AccountId { + AccountId::from(OTHER) +} + +// -- Call builders -- + +fn call_remark() -> RuntimeCall { + RuntimeCall::System(SystemCall::remark { + remark: vec![1, 2, 3], + }) +} + +fn proxy_call(real: AccountId, inner: RuntimeCall) -> RuntimeCall { + RuntimeCall::Proxy(pallet_proxy::Call::proxy { + real: real.into(), + force_proxy_type: None, + call: Box::new(inner), + }) +} + +fn proxy_announced_call(delegate: AccountId, real: AccountId, inner: RuntimeCall) -> RuntimeCall { + RuntimeCall::Proxy(pallet_proxy::Call::proxy_announced { + delegate: delegate.into(), + real: real.into(), + force_proxy_type: None, + call: Box::new(inner), + }) +} + +fn batch_call(calls: Vec) -> RuntimeCall { + RuntimeCall::Utility(pallet_utility::Call::batch { calls }) +} + +fn batch_all_call(calls: Vec) -> RuntimeCall { + RuntimeCall::Utility(pallet_utility::Call::batch_all { calls }) +} + +fn force_batch_call(calls: Vec) -> RuntimeCall { + RuntimeCall::Utility(pallet_utility::Call::force_batch { calls }) +} + +// -- Setup helpers -- + +fn add_proxy(real: &AccountId, delegate: &AccountId) { + assert_ok!(Proxy::add_proxy( + RuntimeOrigin::signed(real.clone()), + delegate.clone().into(), + ProxyType::Any, + 0, + )); +} + +fn enable_real_pays_fee(real: &AccountId, delegate: &AccountId) { + assert_ok!(Proxy::set_real_pays_fee( + RuntimeOrigin::signed(real.clone()), + delegate.clone().into(), + true, + )); +} + +// -- Validate helpers -- + +fn validate_call( + origin: RuntimeOrigin, + call: &RuntimeCall, +) -> Result<(ValidTransaction, Val), TransactionValidityError> { + validate_call_with_info(origin, call, &call.get_dispatch_info()) +} + +fn validate_call_with_info( + origin: RuntimeOrigin, + call: &RuntimeCall, + info: &DispatchInfo, +) -> Result<(ValidTransaction, Val), TransactionValidityError> { + let ext = transaction_payment_wrapper::ChargeTransactionPaymentWrapper::::new( + ChargeTransactionPayment::from(0u64), + ); + let (valid_tx, val, _origin) = ext.validate( + origin, + call, + info, + 100, + (), + &TxBaseImplication(()), + TransactionSource::External, + )?; + Ok((valid_tx, val)) +} + +/// Extract the fee payer from the validate result. +fn fee_payer(val: &Val) -> AccountId { + match val { + Val::Charge { who, .. } => who.clone(), + _ => panic!("expected Val::Charge"), + } +} + +// ============================================================ +// Case 0: Non-proxy calls +// ============================================================ + +#[test] +fn non_proxy_call_charges_signer() { + new_test_ext().execute_with(|| { + let call = call_remark(); + let (_valid_tx, val) = validate_call(RuntimeOrigin::signed(signer()), &call).unwrap(); + assert_eq!(fee_payer(&val), signer()); + }); +} + +// ============================================================ +// Case 1: Simple proxy (1 level) +// ============================================================ + +#[test] +fn simple_proxy_charges_real_when_opted_in() { + new_test_ext().execute_with(|| { + add_proxy(&real_a(), &signer()); + enable_real_pays_fee(&real_a(), &signer()); + + let call = proxy_call(real_a(), call_remark()); + let (_valid_tx, val) = validate_call(RuntimeOrigin::signed(signer()), &call).unwrap(); + assert_eq!(fee_payer(&val), real_a()); + }); +} + +#[test] +fn simple_proxy_charges_signer_when_not_opted_in() { + new_test_ext().execute_with(|| { + add_proxy(&real_a(), &signer()); + // No enable_real_pays_fee + + let call = proxy_call(real_a(), call_remark()); + let (_valid_tx, val) = validate_call(RuntimeOrigin::signed(signer()), &call).unwrap(); + assert_eq!(fee_payer(&val), signer()); + }); +} + +#[test] +fn proxy_announced_always_charges_signer() { + new_test_ext().execute_with(|| { + add_proxy(&real_a(), &real_b()); + enable_real_pays_fee(&real_a(), &real_b()); + + // Fee propagation intentionally ignores proxy_announced; signer always pays. + let call = proxy_announced_call(real_b(), real_a(), call_remark()); + let (_valid_tx, val) = validate_call(RuntimeOrigin::signed(signer()), &call).unwrap(); + assert_eq!(fee_payer(&val), signer()); + }); +} + +// ============================================================ +// Case 2: Nested proxy (2 levels) +// ============================================================ + +#[test] +fn nested_proxy_charges_inner_real_when_both_opted_in() { + new_test_ext().execute_with(|| { + // Chain: signer → real_b → real_a + add_proxy(&real_b(), &signer()); + enable_real_pays_fee(&real_b(), &signer()); + add_proxy(&real_a(), &real_b()); + enable_real_pays_fee(&real_a(), &real_b()); + + let call = proxy_call(real_b(), proxy_call(real_a(), call_remark())); + let (_valid_tx, val) = validate_call(RuntimeOrigin::signed(signer()), &call).unwrap(); + assert_eq!(fee_payer(&val), real_a()); + }); +} + +#[test] +fn nested_proxy_charges_outer_real_when_only_outer_opted_in() { + new_test_ext().execute_with(|| { + add_proxy(&real_b(), &signer()); + enable_real_pays_fee(&real_b(), &signer()); + add_proxy(&real_a(), &real_b()); + // No enable_real_pays_fee for A→B + + let call = proxy_call(real_b(), proxy_call(real_a(), call_remark())); + let (_valid_tx, val) = validate_call(RuntimeOrigin::signed(signer()), &call).unwrap(); + assert_eq!(fee_payer(&val), real_b()); + }); +} + +#[test] +fn nested_proxy_charges_signer_when_neither_opted_in() { + new_test_ext().execute_with(|| { + add_proxy(&real_b(), &signer()); + add_proxy(&real_a(), &real_b()); + // No enable_real_pays_fee at all + + let call = proxy_call(real_b(), proxy_call(real_a(), call_remark())); + let (_valid_tx, val) = validate_call(RuntimeOrigin::signed(signer()), &call).unwrap(); + assert_eq!(fee_payer(&val), signer()); + }); +} + +#[test] +fn nested_proxy_charges_signer_when_only_inner_opted_in() { + new_test_ext().execute_with(|| { + add_proxy(&real_b(), &signer()); + // No enable_real_pays_fee for B→signer + add_proxy(&real_a(), &real_b()); + enable_real_pays_fee(&real_a(), &real_b()); + + let call = proxy_call(real_b(), proxy_call(real_a(), call_remark())); + let (_valid_tx, val) = validate_call(RuntimeOrigin::signed(signer()), &call).unwrap(); + // Outer RealPaysFee not set → signer pays (inner opt-in is irrelevant) + assert_eq!(fee_payer(&val), signer()); + }); +} + +// ============================================================ +// Case 3: Batch of proxy calls +// ============================================================ + +#[test] +fn batch_charges_inner_real_when_all_opted_in() { + new_test_ext().execute_with(|| { + add_proxy(&real_b(), &signer()); + enable_real_pays_fee(&real_b(), &signer()); + add_proxy(&real_a(), &real_b()); + enable_real_pays_fee(&real_a(), &real_b()); + + let batch = batch_call(vec![ + proxy_call(real_a(), call_remark()), + proxy_call(real_a(), call_remark()), + ]); + let call = proxy_call(real_b(), batch); + let (_valid_tx, val) = validate_call(RuntimeOrigin::signed(signer()), &call).unwrap(); + assert_eq!(fee_payer(&val), real_a()); + }); +} + +#[test] +fn batch_all_charges_inner_real_when_all_opted_in() { + new_test_ext().execute_with(|| { + add_proxy(&real_b(), &signer()); + enable_real_pays_fee(&real_b(), &signer()); + add_proxy(&real_a(), &real_b()); + enable_real_pays_fee(&real_a(), &real_b()); + + let batch = batch_all_call(vec![ + proxy_call(real_a(), call_remark()), + proxy_call(real_a(), call_remark()), + ]); + let call = proxy_call(real_b(), batch); + let (_valid_tx, val) = validate_call(RuntimeOrigin::signed(signer()), &call).unwrap(); + assert_eq!(fee_payer(&val), real_a()); + }); +} + +#[test] +fn force_batch_charges_inner_real_when_all_opted_in() { + new_test_ext().execute_with(|| { + add_proxy(&real_b(), &signer()); + enable_real_pays_fee(&real_b(), &signer()); + add_proxy(&real_a(), &real_b()); + enable_real_pays_fee(&real_a(), &real_b()); + + let batch = force_batch_call(vec![ + proxy_call(real_a(), call_remark()), + proxy_call(real_a(), call_remark()), + ]); + let call = proxy_call(real_b(), batch); + let (_valid_tx, val) = validate_call(RuntimeOrigin::signed(signer()), &call).unwrap(); + assert_eq!(fee_payer(&val), real_a()); + }); +} + +#[test] +fn batch_charges_outer_real_when_only_outer_opted_in() { + new_test_ext().execute_with(|| { + add_proxy(&real_b(), &signer()); + enable_real_pays_fee(&real_b(), &signer()); + add_proxy(&real_a(), &real_b()); + // No enable_real_pays_fee for A→B + + let batch = batch_call(vec![ + proxy_call(real_a(), call_remark()), + proxy_call(real_a(), call_remark()), + ]); + let call = proxy_call(real_b(), batch); + let (_valid_tx, val) = validate_call(RuntimeOrigin::signed(signer()), &call).unwrap(); + assert_eq!(fee_payer(&val), real_b()); + }); +} + +#[test] +fn batch_charges_outer_real_when_mixed_inner_reals() { + new_test_ext().execute_with(|| { + add_proxy(&real_b(), &signer()); + enable_real_pays_fee(&real_b(), &signer()); + add_proxy(&real_a(), &real_b()); + enable_real_pays_fee(&real_a(), &real_b()); + add_proxy(&other(), &real_b()); + enable_real_pays_fee(&other(), &real_b()); + + // Different inner reals → can't push deeper + let batch = batch_call(vec![ + proxy_call(real_a(), call_remark()), + proxy_call(other(), call_remark()), + ]); + let call = proxy_call(real_b(), batch); + let (_valid_tx, val) = validate_call(RuntimeOrigin::signed(signer()), &call).unwrap(); + assert_eq!(fee_payer(&val), real_b()); + }); +} + +#[test] +fn batch_charges_outer_real_when_non_proxy_in_batch() { + new_test_ext().execute_with(|| { + add_proxy(&real_b(), &signer()); + enable_real_pays_fee(&real_b(), &signer()); + + // Batch contains a non-proxy call → extract_proxy_parts fails + let batch = batch_call(vec![proxy_call(real_a(), call_remark()), call_remark()]); + let call = proxy_call(real_b(), batch); + let (_valid_tx, val) = validate_call(RuntimeOrigin::signed(signer()), &call).unwrap(); + assert_eq!(fee_payer(&val), real_b()); + }); +} + +#[test] +fn batch_charges_outer_real_when_empty() { + new_test_ext().execute_with(|| { + add_proxy(&real_b(), &signer()); + enable_real_pays_fee(&real_b(), &signer()); + + let batch = batch_call(vec![]); + let call = proxy_call(real_b(), batch); + let (_valid_tx, val) = validate_call(RuntimeOrigin::signed(signer()), &call).unwrap(); + assert_eq!(fee_payer(&val), real_b()); + }); +} + +#[test] +fn batch_charges_outer_real_when_inner_real_not_opted_in() { + new_test_ext().execute_with(|| { + add_proxy(&real_b(), &signer()); + enable_real_pays_fee(&real_b(), &signer()); + add_proxy(&real_a(), &real_b()); + // real_a has NOT opted in to pay for real_b + + // Even with same real in all batch items, if RealPaysFee not set → outer_real pays + let batch = batch_call(vec![ + proxy_call(real_a(), call_remark()), + proxy_call(real_a(), call_remark()), + ]); + let call = proxy_call(real_b(), batch); + let (_valid_tx, val) = validate_call(RuntimeOrigin::signed(signer()), &call).unwrap(); + assert_eq!(fee_payer(&val), real_b()); + }); +} + +// ============================================================ +// Priority override +// ============================================================ + +#[test] +fn priority_override_normal_dispatch() { + new_test_ext().execute_with(|| { + let call = call_remark(); + let (valid_tx, _val) = validate_call(RuntimeOrigin::signed(signer()), &call).unwrap(); + assert_eq!(valid_tx.priority, NORMAL_DISPATCH_BASE_PRIORITY); + }); +} + +#[test] +fn priority_override_operational_dispatch() { + new_test_ext().execute_with(|| { + let call = call_remark(); + let mut info = call.get_dispatch_info(); + info.class = DispatchClass::Operational; + + let (valid_tx, _val) = + validate_call_with_info(RuntimeOrigin::signed(signer()), &call, &info).unwrap(); + assert_eq!(valid_tx.priority, OPERATIONAL_DISPATCH_PRIORITY); + }); +} + +#[test] +fn priority_override_mandatory_dispatch() { + new_test_ext().execute_with(|| { + let call = call_remark(); + let mut info = call.get_dispatch_info(); + info.class = DispatchClass::Mandatory; + + let (valid_tx, _val) = + validate_call_with_info(RuntimeOrigin::signed(signer()), &call, &info).unwrap(); + // Mandatory uses the same base as Normal + assert_eq!(valid_tx.priority, NORMAL_DISPATCH_BASE_PRIORITY); + }); +} + +#[test] +fn priority_override_applies_with_real_pays_fee() { + new_test_ext().execute_with(|| { + add_proxy(&real_a(), &signer()); + enable_real_pays_fee(&real_a(), &signer()); + + let call = proxy_call(real_a(), call_remark()); + let (valid_tx, _val) = validate_call(RuntimeOrigin::signed(signer()), &call).unwrap(); + // Priority override should still apply when real pays fee + assert_eq!(valid_tx.priority, NORMAL_DISPATCH_BASE_PRIORITY); + }); +} diff --git a/scripts/update-deps-to-path.sh b/scripts/update-deps-to-path.sh new file mode 100755 index 0000000000..a1eab9b99c --- /dev/null +++ b/scripts/update-deps-to-path.sh @@ -0,0 +1,90 @@ +#!/bin/zsh +# update-deps-to-path.sh goal is to replace git dependencies with path dependencies +# in the target Cargo.toml file. +# +# The script will scan the source repos for packages and build a mapping of package name to path. +# It will then process the target Cargo.toml file line by line and replace git dependencies with path dependencies. +# +# The script will output the new Cargo.toml file to stdout. +# +# The script will exit with a non-zero status if the target Cargo.toml file is not found. +# Usage: ./scripts/update-deps-to-path.sh ./Cargo.toml ./polkadot-sdk-otf ../frontier-otf > Cargo.toml.new + +set -e + +TARGET_TOML="${1:?Usage: $0 [source-repo-2] ...}" +shift + +if [[ $# -eq 0 ]]; then + echo "Error: At least one source repo path required" >&2 + exit 1 +fi + +# Build package name -> path mapping from all source repos +typeset -A PKG_PATHS + +for SOURCE_PATH in "$@"; do + SOURCE_PATH="$(cd "$SOURCE_PATH" && pwd)" + echo "Scanning $SOURCE_PATH for packages..." >&2 + + for cargo_toml in $(find "$SOURCE_PATH" -name "Cargo.toml" -type f 2>/dev/null); do + pkg_name=$(yq -p toml -o yaml '.package.name // ""' "$cargo_toml" 2>/dev/null | tr -d '"') + + if [[ -n "$pkg_name" && "$pkg_name" != "null" ]]; then + pkg_dir="$(dirname "$cargo_toml")" + PKG_PATHS[$pkg_name]="$pkg_dir" + echo " Found: $pkg_name" >&2 + fi + done +done + +echo "Found ${#PKG_PATHS[@]} total packages" >&2 +echo "" >&2 + +# Process target Cargo.toml line by line +echo "Updating dependencies in $TARGET_TOML..." >&2 + +while IFS= read -r line; do + # Check if this line has a git dependency + if [[ "$line" =~ ^([a-zA-Z0-9_-]+|\"[^\"]+\")\ *=\ *\{.*git\ *=\ *\" ]]; then + # Extract package name (handle both quoted and unquoted) + dep_name=$(echo "$line" | sed -E 's/^"?([a-zA-Z0-9_-]+)"? *=.*/\1/') + + # Check for package alias + if [[ "$line" =~ package\ *=\ *\"([^\"]+)\" ]]; then + lookup_name="${match[1]}" + else + lookup_name="$dep_name" + fi + + # Check if we have this package + if [[ -n "${PKG_PATHS[$lookup_name]}" ]]; then + pkg_path="${PKG_PATHS[$lookup_name]}" + echo " $dep_name -> $pkg_path" >&2 + + # Extract features/default-features/package if present + extras="" + if [[ "$line" =~ default-features\ *=\ *false ]]; then + extras="$extras, default-features = false" + fi + if [[ "$line" =~ package\ *=\ *\"([^\"]+)\" ]]; then + extras="$extras, package = \"${match[1]}\"" + fi + if [[ "$line" =~ features\ *=\ *\[([^\]]*)\] ]]; then + extras="$extras, features = [${match[1]}]" + fi + + # Output new line with just path + echo "${dep_name} = { path = \"${pkg_path}\"${extras} }" + else + # Package not found in sources, keep original + echo "$line" + fi + else + # Not a git dependency, keep as-is + echo "$line" + fi +done < "$TARGET_TOML" + +echo "" >&2 +echo "Done!" >&2