diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml new file mode 100644 index 0000000000..959a86bdeb --- /dev/null +++ b/.github/workflows/e2e.yml @@ -0,0 +1,148 @@ +name: E2E Tests + +on: + pull_request: + + workflow_dispatch: + inputs: + verbose: + description: "Output more information when triggered manually" + required: false + default: "" + +env: + CARGO_TERM_COLOR: always + +permissions: + contents: read + +jobs: + # Build the node binary in both variants and share as artifacts. + build: + runs-on: [self-hosted, type-ccx33] + timeout-minutes: 60 + strategy: + matrix: + include: + - variant: release + flags: "" + - variant: fast + flags: "--features fast-runtime" + env: + RUST_BACKTRACE: full + steps: + - name: Check-out repository + uses: actions/checkout@v4 + + - name: Install system dependencies + run: | + sudo DEBIAN_FRONTEND=noninteractive NEEDRESTART_MODE=a apt-get update + sudo DEBIAN_FRONTEND=noninteractive NEEDRESTART_MODE=a apt-get install -y --no-install-recommends \ + -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" \ + build-essential clang curl git make libssl-dev llvm libudev-dev protobuf-compiler pkg-config + + - name: Install Rust + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + + - name: Utilize Shared Rust Cache + uses: Swatinem/rust-cache@v2 + with: + key: e2e-${{ matrix.variant }} + cache-on-failure: true + + - name: Build node-subtensor (${{ matrix.variant }}) + run: cargo build --profile release ${{ matrix.flags }} -p node-subtensor + + - name: Upload binary + uses: actions/upload-artifact@v4 + with: + name: node-subtensor-${{ matrix.variant }} + path: target/release/node-subtensor + if-no-files-found: error + + # Discover e2e packages that have a "test" script. + discover: + runs-on: ubuntu-latest + outputs: + packages: ${{ steps.find.outputs.packages }} + steps: + - name: Check-out repository + uses: actions/checkout@v4 + with: + sparse-checkout: e2e + + - name: Find testable packages + id: find + working-directory: e2e + run: | + packages=$( + find . -maxdepth 2 -name package.json -not -path './node_modules/*' \ + | while read -r pkg; do + name=$(jq -r '.name // empty' "$pkg") + has_test=$(jq -r '.scripts.test // empty' "$pkg") + if [ -n "$has_test" ] && [ -n "$name" ]; then + echo "$name" + fi + done \ + | jq -R -s -c 'split("\n") | map(select(. != ""))' + ) + echo "packages=$packages" >> "$GITHUB_OUTPUT" + echo "Discovered packages: $packages" + + # Run each e2e package's tests in parallel. + test: + needs: [build, discover] + if: ${{ needs.discover.outputs.packages != '[]' }} + runs-on: [self-hosted, type-ccx33] + timeout-minutes: 30 + strategy: + fail-fast: false + matrix: + package: ${{ fromJson(needs.discover.outputs.packages) }} + name: "e2e: ${{ matrix.package }}" + steps: + - name: Check-out repository + uses: actions/checkout@v4 + + - name: Download release binary + uses: actions/download-artifact@v4 + with: + name: node-subtensor-release + path: target/release + + - name: Download fast binary + uses: actions/download-artifact@v4 + with: + name: node-subtensor-fast + path: target/fast + + - name: Make binaries executable + run: chmod +x target/release/node-subtensor target/fast/node-subtensor + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version-file: e2e/.nvmrc + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: 10 + + - name: Bootstrap papi types + working-directory: e2e + run: ./bootstrap_types.sh --skip-build + + - name: Install e2e dependencies + working-directory: e2e + run: pnpm install --frozen-lockfile + + - name: Run tests + working-directory: e2e + env: + # Use fast-runtime binary for staking package, release binary for others + # Path is relative to package directory (e2e//) + BINARY_PATH: ${{ matrix.package == 'e2e-staking' && '../../target/fast/node-subtensor' || '../../target/release/node-subtensor' }} + run: pnpm --filter ${{ matrix.package }} test diff --git a/.gitignore b/.gitignore index 3f20eb58e2..91993ddf2d 100644 --- a/.gitignore +++ b/.gitignore @@ -50,3 +50,6 @@ scripts/specs/local.json # Node modules node_modules + +# Claude Code configuration +.claude \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 0b2a387c2b..7bdb24a9d3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -54,7 +54,7 @@ checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", "cipher 0.4.4", - "cpufeatures", + "cpufeatures 0.2.17", ] [[package]] @@ -1056,7 +1056,7 @@ checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" [[package]] name = "assets-common" version = "0.22.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" 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=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" 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=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" 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=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" 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=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" 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=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" 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=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" 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=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" 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=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" 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=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" 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=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" 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=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" 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=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "bp-header-chain", "bp-messages", @@ -2106,7 +2106,18 @@ checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" dependencies = [ "cfg-if", "cipher 0.4.4", - "cpufeatures", + "cpufeatures 0.2.17", +] + +[[package]] +name = "chacha20" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "rand_core 0.10.0", ] [[package]] @@ -2116,7 +2127,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" dependencies = [ "aead", - "chacha20", + "chacha20 0.9.1", "cipher 0.4.4", "poly1305", "zeroize", @@ -2337,7 +2348,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6407bff74dea37e0fa3dc1c1c974e5d46405f0c987bf9997a0762adce71eda6" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "proptest", "serde_core", ] @@ -2363,7 +2374,7 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" dependencies = [ - "getrandom 0.2.16", + "getrandom 0.2.17", "once_cell", "tiny-keccak", ] @@ -2475,6 +2486,15 @@ dependencies = [ "libc", ] +[[package]] +name = "cpufeatures" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +dependencies = [ + "libc", +] + [[package]] name = "cranelift-bforest" version = "0.95.1" @@ -2569,7 +2589,7 @@ dependencies = [ "itertools 0.10.5", "log", "smallvec", - "wasmparser", + "wasmparser 0.102.0", "wasmtime-types", ] @@ -2722,7 +2742,7 @@ dependencies = [ [[package]] name = "cumulus-client-bootnodes" version = "0.2.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "array-bytes 6.2.3", "async-channel 1.9.0", @@ -2748,7 +2768,7 @@ dependencies = [ [[package]] name = "cumulus-client-cli" version = "0.24.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "clap", "parity-scale-codec", @@ -2765,7 +2785,7 @@ dependencies = [ [[package]] name = "cumulus-client-collator" version = "0.24.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "cumulus-client-consensus-common", "cumulus-client-network", @@ -2788,7 +2808,7 @@ dependencies = [ [[package]] name = "cumulus-client-consensus-aura" version = "0.24.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "async-trait", "cumulus-client-collator", @@ -2835,7 +2855,7 @@ dependencies = [ [[package]] name = "cumulus-client-consensus-common" version = "0.24.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "async-trait", "cumulus-client-pov-recovery", @@ -2867,7 +2887,7 @@ dependencies = [ [[package]] name = "cumulus-client-consensus-proposer" version = "0.20.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "anyhow", "async-trait", @@ -2882,7 +2902,7 @@ dependencies = [ [[package]] name = "cumulus-client-consensus-relay-chain" version = "0.24.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "async-trait", "cumulus-client-consensus-common", @@ -2905,7 +2925,7 @@ dependencies = [ [[package]] name = "cumulus-client-network" version = "0.24.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "async-trait", "cumulus-relay-chain-interface", @@ -2932,7 +2952,7 @@ dependencies = [ [[package]] name = "cumulus-client-parachain-inherent" version = "0.18.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "async-trait", "cumulus-primitives-core", @@ -2942,7 +2962,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=71629fd93b6c12a362a5cfb6331accef9b2b2b61)", + "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee)", "sp-inherents", "sp-runtime", "sp-state-machine", @@ -2953,7 +2973,7 @@ dependencies = [ [[package]] name = "cumulus-client-pov-recovery" version = "0.24.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "async-trait", "cumulus-primitives-core", @@ -2981,7 +3001,7 @@ dependencies = [ [[package]] name = "cumulus-client-service" version = "0.25.1" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "async-channel 1.9.0", "cumulus-client-cli", @@ -3021,7 +3041,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-aura-ext" version = "0.21.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "cumulus-pallet-parachain-system", "frame-support", @@ -3038,7 +3058,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-dmp-queue" version = "0.21.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "cumulus-primitives-core", "frame-benchmarking", @@ -3055,7 +3075,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-parachain-system" version = "0.21.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "bytes", "cumulus-pallet-parachain-system-proc-macro", @@ -3092,7 +3112,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-parachain-system-proc-macro" version = "0.6.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "proc-macro-crate 3.4.0", "proc-macro2", @@ -3103,7 +3123,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-session-benchmarking" version = "22.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-support", @@ -3116,7 +3136,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-solo-to-para" version = "0.21.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "cumulus-pallet-parachain-system", "frame-support", @@ -3131,7 +3151,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-weight-reclaim" version = "0.3.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "cumulus-primitives-storage-weight-reclaim", "derive-where", @@ -3150,7 +3170,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-xcm" version = "0.20.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -3165,7 +3185,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-xcmp-queue" version = "0.21.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "approx", "bounded-collections 0.2.4", @@ -3190,7 +3210,7 @@ dependencies = [ [[package]] name = "cumulus-ping" version = "0.21.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "cumulus-pallet-xcm", "cumulus-primitives-core", @@ -3205,7 +3225,7 @@ dependencies = [ [[package]] name = "cumulus-primitives-aura" version = "0.18.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "sp-api", "sp-consensus-aura", @@ -3214,7 +3234,7 @@ dependencies = [ [[package]] name = "cumulus-primitives-core" version = "0.19.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "parity-scale-codec", "polkadot-core-primitives", @@ -3231,7 +3251,7 @@ dependencies = [ [[package]] name = "cumulus-primitives-parachain-inherent" version = "0.19.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "async-trait", "cumulus-primitives-core", @@ -3245,7 +3265,7 @@ dependencies = [ [[package]] name = "cumulus-primitives-proof-size-hostfunction" version = "0.13.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "sp-externalities", "sp-runtime-interface", @@ -3255,7 +3275,7 @@ dependencies = [ [[package]] name = "cumulus-primitives-storage-weight-reclaim" version = "12.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "cumulus-primitives-core", "cumulus-primitives-proof-size-hostfunction", @@ -3272,7 +3292,7 @@ dependencies = [ [[package]] name = "cumulus-primitives-utility" version = "0.21.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -3289,7 +3309,7 @@ dependencies = [ [[package]] name = "cumulus-relay-chain-inprocess-interface" version = "0.25.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "async-channel 1.9.0", "async-trait", @@ -3317,7 +3337,7 @@ dependencies = [ [[package]] name = "cumulus-relay-chain-interface" version = "0.24.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "async-trait", "cumulus-primitives-core", @@ -3337,7 +3357,7 @@ dependencies = [ [[package]] name = "cumulus-relay-chain-minimal-node" version = "0.25.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "array-bytes 6.2.3", "async-channel 1.9.0", @@ -3373,7 +3393,7 @@ dependencies = [ [[package]] name = "cumulus-relay-chain-rpc-interface" version = "0.24.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "async-trait", "cumulus-primitives-core", @@ -3414,7 +3434,7 @@ dependencies = [ [[package]] name = "cumulus-relay-chain-streams" version = "0.2.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "cumulus-relay-chain-interface", "futures", @@ -3428,7 +3448,7 @@ dependencies = [ [[package]] name = "cumulus-test-relay-sproof-builder" version = "0.20.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "cumulus-primitives-core", "parity-scale-codec", @@ -3445,7 +3465,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "curve25519-dalek-derive", "digest 0.10.7", "fiat-crypto", @@ -4210,7 +4230,7 @@ dependencies = [ [[package]] name = "ethereum-standards" version = "0.1.1" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "alloy-core", ] @@ -4427,7 +4447,7 @@ dependencies = [ [[package]] name = "fc-api" version = "1.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" +source = "git+https://github.com/opentensor/frontier?rev=a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710#a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710" dependencies = [ "async-trait", "fp-storage", @@ -4439,7 +4459,7 @@ dependencies = [ [[package]] name = "fc-aura" version = "1.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" +source = "git+https://github.com/opentensor/frontier?rev=a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710#a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710" dependencies = [ "fc-rpc", "fp-storage", @@ -4455,7 +4475,7 @@ dependencies = [ [[package]] name = "fc-babe" version = "1.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" +source = "git+https://github.com/opentensor/frontier?rev=a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710#a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710" dependencies = [ "fc-rpc", "sc-client-api", @@ -4471,7 +4491,7 @@ dependencies = [ [[package]] name = "fc-consensus" version = "2.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" +source = "git+https://github.com/opentensor/frontier?rev=a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710#a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710" dependencies = [ "async-trait", "fp-consensus", @@ -4487,7 +4507,7 @@ dependencies = [ [[package]] name = "fc-db" version = "2.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" +source = "git+https://github.com/opentensor/frontier?rev=a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710#a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710" dependencies = [ "async-trait", "ethereum", @@ -4517,7 +4537,7 @@ dependencies = [ [[package]] name = "fc-mapping-sync" version = "2.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" +source = "git+https://github.com/opentensor/frontier?rev=a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710#a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710" dependencies = [ "fc-db", "fc-storage", @@ -4540,7 +4560,7 @@ dependencies = [ [[package]] name = "fc-rpc" version = "2.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" +source = "git+https://github.com/opentensor/frontier?rev=a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710#a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710" dependencies = [ "ethereum", "ethereum-types", @@ -4591,7 +4611,7 @@ dependencies = [ [[package]] name = "fc-rpc-core" version = "1.1.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" +source = "git+https://github.com/opentensor/frontier?rev=a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710#a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710" dependencies = [ "ethereum", "ethereum-types", @@ -4600,13 +4620,13 @@ dependencies = [ "rustc-hex", "serde", "serde_json", - "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61)", + "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee)", ] [[package]] name = "fc-storage" version = "1.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" +source = "git+https://github.com/opentensor/frontier?rev=a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710#a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710" dependencies = [ "ethereum", "ethereum-types", @@ -4771,7 +4791,7 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "fork-tree" version = "13.0.1" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "parity-scale-codec", ] @@ -4798,7 +4818,7 @@ dependencies = [ [[package]] name = "fp-account" version = "1.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" +source = "git+https://github.com/opentensor/frontier?rev=a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710#a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710" dependencies = [ "hex", "impl-serde", @@ -4816,7 +4836,7 @@ dependencies = [ [[package]] name = "fp-consensus" version = "2.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" +source = "git+https://github.com/opentensor/frontier?rev=a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710#a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710" dependencies = [ "ethereum", "parity-scale-codec", @@ -4827,7 +4847,7 @@ dependencies = [ [[package]] name = "fp-ethereum" version = "1.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" +source = "git+https://github.com/opentensor/frontier?rev=a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710#a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710" dependencies = [ "ethereum", "ethereum-types", @@ -4839,7 +4859,7 @@ dependencies = [ [[package]] name = "fp-evm" version = "3.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" +source = "git+https://github.com/opentensor/frontier?rev=a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710#a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710" dependencies = [ "environmental", "evm", @@ -4855,7 +4875,7 @@ dependencies = [ [[package]] name = "fp-rpc" version = "3.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" +source = "git+https://github.com/opentensor/frontier?rev=a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710#a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710" dependencies = [ "ethereum", "ethereum-types", @@ -4871,7 +4891,7 @@ dependencies = [ [[package]] name = "fp-self-contained" version = "1.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" +source = "git+https://github.com/opentensor/frontier?rev=a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710#a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710" dependencies = [ "frame-support", "parity-scale-codec", @@ -4883,7 +4903,7 @@ dependencies = [ [[package]] name = "fp-storage" version = "2.0.0" -source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" +source = "git+https://github.com/opentensor/frontier?rev=a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710#a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710" dependencies = [ "parity-scale-codec", "serde", @@ -4898,7 +4918,7 @@ checksum = "28dd6caf6059519a65843af8fe2a3ae298b14b80179855aeb4adc2c1934ee619" [[package]] name = "frame-benchmarking" version = "41.0.1" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-support", "frame-support-procedural", @@ -4922,7 +4942,7 @@ dependencies = [ [[package]] name = "frame-benchmarking-cli" version = "49.1.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "Inflector", "array-bytes 6.2.3", @@ -4987,7 +5007,7 @@ dependencies = [ [[package]] name = "frame-benchmarking-pallet-pov" version = "31.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-support", @@ -5015,7 +5035,7 @@ dependencies = [ [[package]] name = "frame-election-provider-solution-type" version = "16.1.1" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "proc-macro-crate 3.4.0", "proc-macro2", @@ -5026,7 +5046,7 @@ dependencies = [ [[package]] name = "frame-election-provider-support" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-election-provider-solution-type", "frame-support", @@ -5043,7 +5063,7 @@ dependencies = [ [[package]] name = "frame-executive" version = "41.0.1" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "aquamarine", "frame-support", @@ -5096,7 +5116,7 @@ dependencies = [ [[package]] name = "frame-metadata-hash-extension" version = "0.9.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "array-bytes 6.2.3", "const-hex", @@ -5112,7 +5132,7 @@ dependencies = [ [[package]] name = "frame-storage-access-test-runtime" version = "0.2.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "cumulus-pallet-parachain-system", "parity-scale-codec", @@ -5126,7 +5146,7 @@ dependencies = [ [[package]] name = "frame-support" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "aquamarine", "array-bytes 6.2.3", @@ -5167,7 +5187,7 @@ dependencies = [ [[package]] name = "frame-support-procedural" version = "34.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "Inflector", "cfg-expr", @@ -5180,7 +5200,7 @@ dependencies = [ "proc-macro-warning", "proc-macro2", "quote", - "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61)", + "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee)", "syn 2.0.106", ] @@ -5200,7 +5220,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools" version = "13.0.1" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-support-procedural-tools-derive 12.0.0", "proc-macro-crate 3.4.0", @@ -5223,7 +5243,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools-derive" version = "12.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "proc-macro2", "quote", @@ -5233,7 +5253,7 @@ dependencies = [ [[package]] name = "frame-system" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "cfg-if", "docify", @@ -5252,7 +5272,7 @@ dependencies = [ [[package]] name = "frame-system-benchmarking" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-support", @@ -5266,7 +5286,7 @@ dependencies = [ [[package]] name = "frame-system-rpc-runtime-api" version = "37.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "docify", "parity-scale-codec", @@ -5276,7 +5296,7 @@ dependencies = [ [[package]] name = "frame-try-runtime" version = "0.47.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-support", "parity-scale-codec", @@ -5516,9 +5536,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ "cfg-if", "js-sys", @@ -5541,6 +5561,20 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "getrandom" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139ef39800118c7683f2fd3c98c1b23c09ae076556b435f8e9064ae108aaeeec" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "rand_core 0.10.0", + "wasip2", + "wasip3", +] + [[package]] name = "getrandom_or_panic" version = "0.0.3" @@ -6237,6 +6271,12 @@ dependencies = [ "zerovec", ] +[[package]] +name = "id-arena" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" + [[package]] name = "ident_case" version = "1.0.1" @@ -6764,7 +6804,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" dependencies = [ - "cpufeatures", + "cpufeatures 0.2.17", ] [[package]] @@ -6862,6 +6902,12 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" +[[package]] +name = "leb128fmt" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" + [[package]] name = "libc" version = "0.2.176" @@ -6894,7 +6940,7 @@ dependencies = [ "either", "futures", "futures-timer", - "getrandom 0.2.16", + "getrandom 0.2.17", "libp2p-allow-block-list", "libp2p-connection-limits", "libp2p-core", @@ -7820,20 +7866,21 @@ dependencies = [ [[package]] name = "ml-kem" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97befee0c869cb56f3118f49d0f9bb68c9e3f380dec23c1100aedc4ec3ba239a" +checksum = "dcaee19a45f916d98f24a551cc9a2cdae705a040e66f3cbc4f3a282ea6a2e982" dependencies = [ "hybrid-array", "kem", "rand_core 0.6.4", "sha3", + "zeroize", ] [[package]] name = "mmr-gadget" version = "46.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "futures", "log", @@ -7852,7 +7899,7 @@ dependencies = [ [[package]] name = "mmr-rpc" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "jsonrpsee", "parity-scale-codec", @@ -8202,10 +8249,7 @@ checksum = "43794a0ace135be66a25d3ae77d41b91615fb68ae937f904090203e81f755b65" name = "node-subtensor" version = "4.0.0-dev" dependencies = [ - "anyhow", "async-trait", - "blake2 0.10.6", - "chacha20poly1305", "clap", "fc-api", "fc-aura", @@ -8225,11 +8269,9 @@ dependencies = [ "frame-system-rpc-runtime-api", "futures", "hex", - "hkdf", "jsonrpsee", "log", "memmap2 0.9.8", - "ml-kem", "node-subtensor-runtime", "num-traits", "pallet-commitments", @@ -8241,10 +8283,7 @@ dependencies = [ "pallet-transaction-payment", "pallet-transaction-payment-rpc", "pallet-transaction-payment-rpc-runtime-api", - "parity-scale-codec", "polkadot-sdk", - "rand 0.8.5", - "rand_core 0.9.3", "sc-basic-authorship", "sc-chain-spec", "sc-chain-spec-derive", @@ -8272,7 +8311,6 @@ dependencies = [ "sc-transaction-pool-api", "serde", "serde_json", - "sha2 0.10.9", "sp-api", "sp-block-builder", "sp-blockchain", @@ -8292,6 +8330,8 @@ dependencies = [ "sp-session", "sp-timestamp", "sp-transaction-pool", + "stc-shield", + "stp-shield", "substrate-build-script-utils", "substrate-frame-rpc-system", "substrate-prometheus-endpoint", @@ -8300,7 +8340,6 @@ dependencies = [ "subtensor-macros", "subtensor-runtime-common", "tokio", - "x25519-dalek", ] [[package]] @@ -8323,7 +8362,6 @@ dependencies = [ "frame-system-benchmarking", "frame-system-rpc-runtime-api", "frame-try-runtime", - "getrandom 0.2.16", "hex", "log", "pallet-admin-utils", @@ -8376,6 +8414,7 @@ dependencies = [ "polkadot-runtime-common", "precompile-utils", "rand_chacha 0.3.1", + "safe-math", "scale-info", "serde_json", "sha2 0.10.9", @@ -8401,6 +8440,8 @@ dependencies = [ "sp-tracing", "sp-transaction-pool", "sp-version", + "sp-weights", + "stp-shield", "substrate-fixed", "substrate-wasm-builder", "subtensor-chain-extensions", @@ -8801,7 +8842,7 @@ dependencies = [ [[package]] name = "pallet-alliance" version = "40.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "array-bytes 6.2.3", "frame-benchmarking", @@ -8813,7 +8854,7 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-core", - "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61)", + "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee)", "sp-io", "sp-runtime", ] @@ -8821,7 +8862,7 @@ dependencies = [ [[package]] name = "pallet-asset-conversion" version = "23.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-support", @@ -8839,7 +8880,7 @@ dependencies = [ [[package]] name = "pallet-asset-conversion-ops" version = "0.9.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-support", @@ -8857,7 +8898,7 @@ dependencies = [ [[package]] name = "pallet-asset-conversion-tx-payment" version = "23.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-support", @@ -8872,7 +8913,7 @@ dependencies = [ [[package]] name = "pallet-asset-rate" version = "20.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-support", @@ -8886,7 +8927,7 @@ dependencies = [ [[package]] name = "pallet-asset-rewards" version = "0.3.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-support", @@ -8904,7 +8945,7 @@ dependencies = [ [[package]] name = "pallet-asset-tx-payment" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-support", @@ -8920,7 +8961,7 @@ dependencies = [ [[package]] name = "pallet-assets" version = "43.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "ethereum-standards", "frame-benchmarking", @@ -8938,7 +8979,7 @@ dependencies = [ [[package]] name = "pallet-assets-freezer" version = "0.8.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "log", "pallet-assets", @@ -8950,7 +8991,7 @@ dependencies = [ [[package]] name = "pallet-assets-holder" version = "0.3.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-support", @@ -8965,7 +9006,7 @@ dependencies = [ [[package]] name = "pallet-atomic-swap" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "parity-scale-codec", "polkadot-sdk-frame", @@ -8975,7 +9016,7 @@ dependencies = [ [[package]] name = "pallet-aura" version = "40.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-support", "frame-system", @@ -8991,7 +9032,7 @@ dependencies = [ [[package]] name = "pallet-authority-discovery" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-support", "frame-system", @@ -9006,7 +9047,7 @@ dependencies = [ [[package]] name = "pallet-authorship" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-support", "frame-system", @@ -9019,7 +9060,7 @@ dependencies = [ [[package]] name = "pallet-babe" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-support", @@ -9042,7 +9083,7 @@ dependencies = [ [[package]] name = "pallet-bags-list" version = "40.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "aquamarine", "docify", @@ -9063,7 +9104,7 @@ dependencies = [ [[package]] name = "pallet-balances" version = "42.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "docify", "frame-benchmarking", @@ -9079,7 +9120,7 @@ dependencies = [ [[package]] name = "pallet-base-fee" version = "1.0.0" -source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" +source = "git+https://github.com/opentensor/frontier?rev=a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710#a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710" dependencies = [ "fp-evm", "frame-support", @@ -9093,7 +9134,7 @@ dependencies = [ [[package]] name = "pallet-beefy" version = "42.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-support", "frame-system", @@ -9112,7 +9153,7 @@ dependencies = [ [[package]] name = "pallet-beefy-mmr" version = "42.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "array-bytes 6.2.3", "binary-merkle-tree", @@ -9137,7 +9178,7 @@ dependencies = [ [[package]] name = "pallet-bounties" version = "40.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-support", @@ -9154,7 +9195,7 @@ dependencies = [ [[package]] name = "pallet-bridge-grandpa" version = "0.21.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "bp-header-chain", "bp-runtime", @@ -9173,7 +9214,7 @@ dependencies = [ [[package]] name = "pallet-bridge-messages" version = "0.21.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "bp-header-chain", "bp-messages", @@ -9192,7 +9233,7 @@ dependencies = [ [[package]] name = "pallet-bridge-parachains" version = "0.21.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "bp-header-chain", "bp-parachains", @@ -9212,7 +9253,7 @@ dependencies = [ [[package]] name = "pallet-bridge-relayers" version = "0.21.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "bp-header-chain", "bp-messages", @@ -9235,7 +9276,7 @@ dependencies = [ [[package]] name = "pallet-broker" version = "0.20.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "bitvec", "frame-benchmarking", @@ -9253,7 +9294,7 @@ dependencies = [ [[package]] name = "pallet-child-bounties" version = "40.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-support", @@ -9271,7 +9312,7 @@ dependencies = [ [[package]] name = "pallet-collator-selection" version = "22.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-support", @@ -9290,7 +9331,7 @@ dependencies = [ [[package]] name = "pallet-collective" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "docify", "frame-benchmarking", @@ -9307,7 +9348,7 @@ dependencies = [ [[package]] name = "pallet-collective-content" version = "0.19.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-support", @@ -9348,7 +9389,7 @@ dependencies = [ [[package]] name = "pallet-contracts" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "environmental", "frame-benchmarking", @@ -9379,7 +9420,7 @@ dependencies = [ [[package]] name = "pallet-contracts-mock-network" version = "18.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-support", "frame-system", @@ -9410,7 +9451,7 @@ dependencies = [ [[package]] name = "pallet-contracts-proc-macro" version = "23.0.3" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "proc-macro2", "quote", @@ -9420,7 +9461,7 @@ dependencies = [ [[package]] name = "pallet-contracts-uapi" version = "14.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "bitflags 1.3.2", "parity-scale-codec", @@ -9431,7 +9472,7 @@ dependencies = [ [[package]] name = "pallet-conviction-voting" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "assert_matches", "frame-benchmarking", @@ -9447,7 +9488,7 @@ dependencies = [ [[package]] name = "pallet-core-fellowship" version = "25.0.1" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-support", @@ -9479,12 +9520,13 @@ dependencies = [ "sp-runtime", "sp-std", "subtensor-macros", + "subtensor-runtime-common", ] [[package]] name = "pallet-delegated-staking" version = "8.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-support", "frame-system", @@ -9499,7 +9541,7 @@ dependencies = [ [[package]] name = "pallet-democracy" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-support", @@ -9516,7 +9558,7 @@ dependencies = [ [[package]] name = "pallet-dev-mode" version = "23.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-support", "frame-system", @@ -9565,7 +9607,7 @@ dependencies = [ [[package]] name = "pallet-dummy-dim" version = "0.2.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-support", @@ -9583,7 +9625,7 @@ dependencies = [ [[package]] name = "pallet-election-provider-multi-block" version = "0.2.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -9604,7 +9646,7 @@ dependencies = [ [[package]] name = "pallet-election-provider-multi-phase" version = "40.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -9625,7 +9667,7 @@ dependencies = [ [[package]] name = "pallet-election-provider-support-benchmarking" version = "40.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -9638,7 +9680,7 @@ dependencies = [ [[package]] name = "pallet-elections-phragmen" version = "42.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-support", @@ -9656,7 +9698,7 @@ dependencies = [ [[package]] name = "pallet-ethereum" version = "4.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" +source = "git+https://github.com/opentensor/frontier?rev=a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710#a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710" dependencies = [ "ethereum", "ethereum-types", @@ -9679,7 +9721,7 @@ dependencies = [ [[package]] name = "pallet-evm" version = "6.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" +source = "git+https://github.com/opentensor/frontier?rev=a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710#a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710" dependencies = [ "cumulus-primitives-storage-weight-reclaim", "environmental", @@ -9704,7 +9746,7 @@ dependencies = [ [[package]] name = "pallet-evm-chain-id" version = "1.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" +source = "git+https://github.com/opentensor/frontier?rev=a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710#a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710" dependencies = [ "frame-support", "frame-system", @@ -9715,7 +9757,7 @@ dependencies = [ [[package]] name = "pallet-evm-precompile-bn128" version = "2.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" +source = "git+https://github.com/opentensor/frontier?rev=a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710#a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710" dependencies = [ "fp-evm", "sp-core", @@ -9725,7 +9767,7 @@ dependencies = [ [[package]] name = "pallet-evm-precompile-dispatch" version = "2.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" +source = "git+https://github.com/opentensor/frontier?rev=a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710#a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710" dependencies = [ "fp-evm", "frame-support", @@ -9737,7 +9779,7 @@ dependencies = [ [[package]] name = "pallet-evm-precompile-modexp" version = "2.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" +source = "git+https://github.com/opentensor/frontier?rev=a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710#a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710" dependencies = [ "fp-evm", "num", @@ -9746,7 +9788,7 @@ dependencies = [ [[package]] name = "pallet-evm-precompile-sha3fips" version = "2.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" +source = "git+https://github.com/opentensor/frontier?rev=a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710#a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710" dependencies = [ "fp-evm", "tiny-keccak", @@ -9755,7 +9797,7 @@ dependencies = [ [[package]] name = "pallet-evm-precompile-simple" version = "2.0.0-dev" -source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" +source = "git+https://github.com/opentensor/frontier?rev=a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710#a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710" dependencies = [ "fp-evm", "ripemd", @@ -9765,7 +9807,7 @@ dependencies = [ [[package]] name = "pallet-fast-unstake" version = "40.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "docify", "frame-benchmarking", @@ -9783,7 +9825,7 @@ dependencies = [ [[package]] name = "pallet-glutton" version = "27.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "blake2 0.10.6", "frame-benchmarking", @@ -9801,7 +9843,7 @@ dependencies = [ [[package]] name = "pallet-grandpa" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-support", @@ -9823,7 +9865,7 @@ dependencies = [ [[package]] name = "pallet-hotfix-sufficients" version = "1.0.0" -source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" +source = "git+https://github.com/opentensor/frontier?rev=a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710#a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710" dependencies = [ "frame-benchmarking", "frame-support", @@ -9838,7 +9880,7 @@ dependencies = [ [[package]] name = "pallet-identity" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "enumflags2", "frame-benchmarking", @@ -9854,7 +9896,7 @@ dependencies = [ [[package]] name = "pallet-im-online" version = "40.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-support", @@ -9873,7 +9915,7 @@ dependencies = [ [[package]] name = "pallet-indices" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-support", @@ -9888,7 +9930,7 @@ dependencies = [ [[package]] name = "pallet-insecure-randomness-collective-flip" version = "29.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "parity-scale-codec", "polkadot-sdk-frame", @@ -9899,7 +9941,7 @@ dependencies = [ [[package]] name = "pallet-lottery" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-support", @@ -9912,7 +9954,7 @@ dependencies = [ [[package]] name = "pallet-membership" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-support", @@ -9928,7 +9970,7 @@ dependencies = [ [[package]] name = "pallet-message-queue" version = "44.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "environmental", "frame-benchmarking", @@ -9947,7 +9989,7 @@ dependencies = [ [[package]] name = "pallet-meta-tx" version = "0.3.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "docify", "frame-benchmarking", @@ -9965,7 +10007,7 @@ dependencies = [ [[package]] name = "pallet-migrations" version = "11.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "docify", "frame-benchmarking", @@ -9984,7 +10026,7 @@ dependencies = [ [[package]] name = "pallet-mixnet" version = "0.17.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "log", "parity-scale-codec", @@ -9998,7 +10040,7 @@ dependencies = [ [[package]] name = "pallet-mmr" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "log", "parity-scale-codec", @@ -10010,7 +10052,7 @@ dependencies = [ [[package]] name = "pallet-multisig" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "log", "parity-scale-codec", @@ -10021,7 +10063,7 @@ dependencies = [ [[package]] name = "pallet-nft-fractionalization" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "log", "pallet-assets", @@ -10034,7 +10076,7 @@ dependencies = [ [[package]] name = "pallet-nfts" version = "35.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "enumflags2", "frame-benchmarking", @@ -10051,7 +10093,7 @@ dependencies = [ [[package]] name = "pallet-nis" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "parity-scale-codec", "polkadot-sdk-frame", @@ -10061,7 +10103,7 @@ dependencies = [ [[package]] name = "pallet-node-authorization" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "log", "parity-scale-codec", @@ -10072,7 +10114,7 @@ dependencies = [ [[package]] name = "pallet-nomination-pools" version = "39.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-support", "frame-system", @@ -10090,7 +10132,7 @@ dependencies = [ [[package]] name = "pallet-nomination-pools-benchmarking" version = "39.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -10110,7 +10152,7 @@ dependencies = [ [[package]] name = "pallet-nomination-pools-runtime-api" version = "37.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "pallet-nomination-pools", "parity-scale-codec", @@ -10120,7 +10162,7 @@ dependencies = [ [[package]] name = "pallet-offences" version = "40.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-support", "frame-system", @@ -10135,7 +10177,7 @@ dependencies = [ [[package]] name = "pallet-offences-benchmarking" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -10158,7 +10200,7 @@ dependencies = [ [[package]] name = "pallet-origin-restriction" version = "0.2.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-support", @@ -10176,7 +10218,7 @@ dependencies = [ [[package]] name = "pallet-paged-list" version = "0.19.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "docify", "parity-scale-codec", @@ -10187,7 +10229,7 @@ dependencies = [ [[package]] name = "pallet-parameters" version = "0.12.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "docify", "frame-benchmarking", @@ -10204,7 +10246,7 @@ dependencies = [ [[package]] name = "pallet-people" version = "0.2.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-support", @@ -10222,7 +10264,7 @@ dependencies = [ [[package]] name = "pallet-preimage" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-support", @@ -10238,7 +10280,7 @@ dependencies = [ [[package]] name = "pallet-proxy" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "parity-scale-codec", "polkadot-sdk-frame", @@ -10248,7 +10290,7 @@ dependencies = [ [[package]] name = "pallet-ranked-collective" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-support", @@ -10266,7 +10308,7 @@ dependencies = [ [[package]] name = "pallet-recovery" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "parity-scale-codec", "polkadot-sdk-frame", @@ -10276,7 +10318,7 @@ dependencies = [ [[package]] name = "pallet-referenda" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "assert_matches", "frame-benchmarking", @@ -10311,7 +10353,7 @@ dependencies = [ [[package]] name = "pallet-remark" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-support", @@ -10326,7 +10368,7 @@ dependencies = [ [[package]] name = "pallet-revive" version = "0.7.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "alloy-core", "derive_more 0.99.20", @@ -10372,7 +10414,7 @@ dependencies = [ [[package]] name = "pallet-revive-fixtures" version = "0.4.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "anyhow", "cargo_metadata", @@ -10386,7 +10428,7 @@ dependencies = [ [[package]] name = "pallet-revive-proc-macro" version = "0.3.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "proc-macro2", "quote", @@ -10396,7 +10438,7 @@ dependencies = [ [[package]] name = "pallet-revive-uapi" version = "0.5.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "bitflags 1.3.2", "pallet-revive-proc-macro", @@ -10408,7 +10450,7 @@ dependencies = [ [[package]] name = "pallet-root-offences" version = "38.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-support", "frame-system", @@ -10424,7 +10466,7 @@ dependencies = [ [[package]] name = "pallet-root-testing" version = "17.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-support", "frame-system", @@ -10437,7 +10479,7 @@ dependencies = [ [[package]] name = "pallet-safe-mode" version = "22.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "docify", "pallet-balances", @@ -10451,7 +10493,7 @@ dependencies = [ [[package]] name = "pallet-salary" version = "26.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "log", "pallet-ranked-collective", @@ -10463,7 +10505,7 @@ dependencies = [ [[package]] name = "pallet-scheduler" version = "42.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "docify", "frame-benchmarking", @@ -10480,7 +10522,7 @@ dependencies = [ [[package]] name = "pallet-scored-pool" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-support", "frame-system", @@ -10493,7 +10535,7 @@ dependencies = [ [[package]] name = "pallet-session" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-support", "frame-system", @@ -10514,7 +10556,7 @@ dependencies = [ [[package]] name = "pallet-session-benchmarking" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-support", @@ -10531,26 +10573,36 @@ dependencies = [ name = "pallet-shield" version = "0.0.1" dependencies = [ + "chacha20poly1305", "frame-benchmarking", "frame-support", "frame-system", + "log", + "ml-kem", "pallet-aura", + "pallet-subtensor-utility", "pallet-timestamp", "parity-scale-codec", + "rand_chacha 0.3.1", "scale-info", "sp-consensus-aura", "sp-core", + "sp-inherents", "sp-io", + "sp-keystore", "sp-runtime", "sp-std", "sp-weights", + "stc-shield", + "stp-shield", "subtensor-macros", + "subtensor-runtime-common", ] [[package]] name = "pallet-skip-feeless-payment" version = "16.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-support", "frame-system", @@ -10562,7 +10614,7 @@ dependencies = [ [[package]] name = "pallet-society" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-support", @@ -10579,7 +10631,7 @@ dependencies = [ [[package]] name = "pallet-staking" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -10601,7 +10653,7 @@ dependencies = [ [[package]] name = "pallet-staking-async" version = "0.2.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -10624,7 +10676,7 @@ dependencies = [ [[package]] name = "pallet-staking-async-ah-client" version = "0.2.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-support", "frame-system", @@ -10643,7 +10695,7 @@ dependencies = [ [[package]] name = "pallet-staking-async-rc-client" version = "0.2.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-support", "frame-system", @@ -10660,7 +10712,7 @@ dependencies = [ [[package]] name = "pallet-staking-reward-curve" version = "12.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "proc-macro-crate 3.4.0", "proc-macro2", @@ -10671,7 +10723,7 @@ dependencies = [ [[package]] name = "pallet-staking-reward-fn" version = "23.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "log", "sp-arithmetic", @@ -10680,7 +10732,7 @@ dependencies = [ [[package]] name = "pallet-staking-runtime-api" version = "27.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "parity-scale-codec", "sp-api", @@ -10690,7 +10742,7 @@ dependencies = [ [[package]] name = "pallet-state-trie-migration" version = "46.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-support", @@ -10706,7 +10758,7 @@ dependencies = [ [[package]] name = "pallet-statement" version = "23.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-support", "frame-system", @@ -10746,11 +10798,10 @@ dependencies = [ "pallet-subtensor-proxy", "pallet-subtensor-swap", "pallet-subtensor-utility", - "pallet-timestamp", "pallet-transaction-payment", "parity-scale-codec", "polkadot-runtime-common", - "rand 0.8.5", + "rand 0.10.0", "rand_chacha 0.3.1", "safe-math", "scale-info", @@ -10758,7 +10809,6 @@ dependencies = [ "serde_json", "sha2 0.10.9", "share-pool", - "sp-consensus-aura", "sp-core", "sp-io", "sp-keyring", @@ -10867,7 +10917,7 @@ dependencies = [ [[package]] name = "pallet-sudo" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "docify", "frame-benchmarking", @@ -10882,7 +10932,7 @@ dependencies = [ [[package]] name = "pallet-timestamp" version = "40.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "docify", "frame-benchmarking", @@ -10900,7 +10950,7 @@ dependencies = [ [[package]] name = "pallet-tips" version = "40.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-support", @@ -10918,7 +10968,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-support", @@ -10933,7 +10983,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc" version = "44.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "jsonrpsee", "pallet-transaction-payment-rpc-runtime-api", @@ -10949,7 +10999,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc-runtime-api" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "pallet-transaction-payment", "parity-scale-codec", @@ -10961,7 +11011,7 @@ dependencies = [ [[package]] name = "pallet-transaction-storage" version = "40.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "array-bytes 6.2.3", "frame-benchmarking", @@ -10980,7 +11030,7 @@ dependencies = [ [[package]] name = "pallet-treasury" version = "40.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "docify", "frame-benchmarking", @@ -10999,7 +11049,7 @@ dependencies = [ [[package]] name = "pallet-tx-pause" version = "22.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "docify", "parity-scale-codec", @@ -11010,7 +11060,7 @@ dependencies = [ [[package]] name = "pallet-uniques" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-support", @@ -11024,7 +11074,7 @@ dependencies = [ [[package]] name = "pallet-utility" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-support", @@ -11039,7 +11089,7 @@ dependencies = [ [[package]] name = "pallet-verify-signature" version = "0.4.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-support", @@ -11054,7 +11104,7 @@ dependencies = [ [[package]] name = "pallet-vesting" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-support", @@ -11068,7 +11118,7 @@ dependencies = [ [[package]] name = "pallet-whitelist" version = "40.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "parity-scale-codec", "polkadot-sdk-frame", @@ -11078,7 +11128,7 @@ dependencies = [ [[package]] name = "pallet-xcm" version = "20.1.3" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "bounded-collections 0.2.4", "frame-benchmarking", @@ -11104,7 +11154,7 @@ dependencies = [ [[package]] name = "pallet-xcm-benchmarks" version = "21.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-benchmarking", "frame-support", @@ -11121,7 +11171,7 @@ dependencies = [ [[package]] name = "pallet-xcm-bridge-hub" version = "0.17.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "bp-messages", "bp-runtime", @@ -11143,7 +11193,7 @@ dependencies = [ [[package]] name = "pallet-xcm-bridge-hub-router" version = "0.19.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "bp-xcm-bridge-hub-router", "frame-benchmarking", @@ -11163,7 +11213,7 @@ dependencies = [ [[package]] name = "parachains-common" version = "22.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "cumulus-primitives-core", "cumulus-primitives-utility", @@ -11502,7 +11552,7 @@ checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "polkadot-approval-distribution" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "futures", "futures-timer", @@ -11520,7 +11570,7 @@ dependencies = [ [[package]] name = "polkadot-availability-bitfield-distribution" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "futures", "futures-timer", @@ -11535,7 +11585,7 @@ dependencies = [ [[package]] name = "polkadot-availability-distribution" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "fatality", "futures", @@ -11558,7 +11608,7 @@ dependencies = [ [[package]] name = "polkadot-availability-recovery" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "async-trait", "fatality", @@ -11591,7 +11641,7 @@ dependencies = [ [[package]] name = "polkadot-cli" version = "25.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "clap", "frame-benchmarking-cli", @@ -11615,7 +11665,7 @@ dependencies = [ [[package]] name = "polkadot-collator-protocol" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "bitvec", "fatality", @@ -11638,7 +11688,7 @@ dependencies = [ [[package]] name = "polkadot-core-primitives" version = "18.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "parity-scale-codec", "scale-info", @@ -11649,7 +11699,7 @@ dependencies = [ [[package]] name = "polkadot-dispute-distribution" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "fatality", "futures", @@ -11671,7 +11721,7 @@ dependencies = [ [[package]] name = "polkadot-erasure-coding" version = "20.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "parity-scale-codec", "polkadot-node-primitives", @@ -11685,7 +11735,7 @@ dependencies = [ [[package]] name = "polkadot-gossip-support" version = "24.0.1" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "futures", "futures-timer", @@ -11698,7 +11748,7 @@ dependencies = [ "sc-network", "sp-application-crypto", "sp-core", - "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61)", + "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee)", "sp-keystore", "tracing-gum", ] @@ -11706,7 +11756,7 @@ dependencies = [ [[package]] name = "polkadot-network-bridge" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "always-assert", "async-trait", @@ -11729,7 +11779,7 @@ dependencies = [ [[package]] name = "polkadot-node-collation-generation" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "futures", "parity-scale-codec", @@ -11747,7 +11797,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-approval-voting" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "async-trait", "bitvec", @@ -11779,7 +11829,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-approval-voting-parallel" version = "0.7.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "async-trait", "futures", @@ -11803,7 +11853,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-av-store" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "bitvec", "futures", @@ -11822,7 +11872,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-backing" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "bitvec", "fatality", @@ -11843,7 +11893,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-bitfield-signing" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "futures", "polkadot-node-subsystem", @@ -11858,7 +11908,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-candidate-validation" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "async-trait", "futures", @@ -11880,7 +11930,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-chain-api" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "futures", "polkadot-node-metrics", @@ -11894,7 +11944,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-chain-selection" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "futures", "futures-timer", @@ -11910,7 +11960,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-dispute-coordinator" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "fatality", "futures", @@ -11928,7 +11978,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-parachains-inherent" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "async-trait", "futures", @@ -11945,7 +11995,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-prospective-parachains" version = "23.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "fatality", "futures", @@ -11959,7 +12009,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-provisioner" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "bitvec", "fatality", @@ -11976,7 +12026,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-pvf" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "always-assert", "array-bytes 6.2.3", @@ -12004,7 +12054,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-pvf-checker" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "futures", "polkadot-node-subsystem", @@ -12017,7 +12067,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-pvf-common" version = "20.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "cpu-time", "futures", @@ -12032,7 +12082,7 @@ dependencies = [ "sc-executor-wasmtime", "seccompiler", "sp-core", - "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61)", + "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee)", "sp-externalities", "sp-io", "sp-tracing", @@ -12043,7 +12093,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-runtime-api" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "futures", "polkadot-node-metrics", @@ -12058,7 +12108,7 @@ dependencies = [ [[package]] name = "polkadot-node-metrics" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "bs58", "futures", @@ -12075,7 +12125,7 @@ dependencies = [ [[package]] name = "polkadot-node-network-protocol" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "async-channel 1.9.0", "async-trait", @@ -12100,7 +12150,7 @@ dependencies = [ [[package]] name = "polkadot-node-primitives" version = "20.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "bitvec", "bounded-vec", @@ -12124,7 +12174,7 @@ dependencies = [ [[package]] name = "polkadot-node-subsystem" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "polkadot-node-subsystem-types", "polkadot-overseer", @@ -12133,7 +12183,7 @@ dependencies = [ [[package]] name = "polkadot-node-subsystem-types" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "async-trait", "derive_more 0.99.20", @@ -12161,7 +12211,7 @@ dependencies = [ [[package]] name = "polkadot-node-subsystem-util" version = "24.0.1" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "fatality", "futures", @@ -12192,7 +12242,7 @@ dependencies = [ [[package]] name = "polkadot-omni-node-lib" version = "0.7.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "async-trait", "clap", @@ -12278,7 +12328,7 @@ dependencies = [ [[package]] name = "polkadot-overseer" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "async-trait", "futures", @@ -12298,7 +12348,7 @@ dependencies = [ [[package]] name = "polkadot-parachain-primitives" version = "17.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "bounded-collections 0.2.4", "derive_more 0.99.20", @@ -12314,7 +12364,7 @@ dependencies = [ [[package]] name = "polkadot-primitives" version = "19.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "bitvec", "bounded-collections 0.2.4", @@ -12343,7 +12393,7 @@ dependencies = [ [[package]] name = "polkadot-rpc" version = "25.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "jsonrpsee", "mmr-rpc", @@ -12376,7 +12426,7 @@ dependencies = [ [[package]] name = "polkadot-runtime-common" version = "20.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "bitvec", "frame-benchmarking", @@ -12426,7 +12476,7 @@ dependencies = [ [[package]] name = "polkadot-runtime-metrics" version = "21.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "bs58", "frame-benchmarking", @@ -12438,7 +12488,7 @@ dependencies = [ [[package]] name = "polkadot-runtime-parachains" version = "20.0.2" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "bitflags 1.3.2", "bitvec", @@ -12486,7 +12536,7 @@ dependencies = [ [[package]] name = "polkadot-sdk" version = "2506.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "assets-common", "bridge-hub-common", @@ -12644,7 +12694,7 @@ dependencies = [ [[package]] name = "polkadot-sdk-frame" version = "0.10.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "docify", "frame-benchmarking", @@ -12679,7 +12729,7 @@ dependencies = [ [[package]] name = "polkadot-service" version = "25.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "async-trait", "frame-benchmarking", @@ -12787,7 +12837,7 @@ dependencies = [ [[package]] name = "polkadot-statement-distribution" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "bitvec", "fatality", @@ -12807,7 +12857,7 @@ dependencies = [ [[package]] name = "polkadot-statement-table" version = "20.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "parity-scale-codec", "polkadot-primitives", @@ -13021,7 +13071,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" dependencies = [ - "cpufeatures", + "cpufeatures 0.2.17", "opaque-debug 0.3.1", "universal-hash", ] @@ -13033,7 +13083,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "opaque-debug 0.3.1", "universal-hash", ] @@ -13080,7 +13130,7 @@ dependencies = [ [[package]] name = "precompile-utils" version = "0.1.0" -source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" +source = "git+https://github.com/opentensor/frontier?rev=a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710#a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710" dependencies = [ "derive_more 1.0.0", "environmental", @@ -13109,14 +13159,14 @@ dependencies = [ [[package]] name = "precompile-utils-macro" version = "0.1.0" -source = "git+https://github.com/opentensor/frontier?rev=b51a81bb3f2a94eabaafcde40eab6a91accf3f36#b51a81bb3f2a94eabaafcde40eab6a91accf3f36" +source = "git+https://github.com/opentensor/frontier?rev=a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710#a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710" dependencies = [ "case", "num_enum", "prettyplease", "proc-macro2", "quote", - "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61)", + "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee)", "syn 2.0.106", ] @@ -13298,7 +13348,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61)", + "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee)", "syn 2.0.106", ] @@ -13585,6 +13635,17 @@ dependencies = [ "serde", ] +[[package]] +name = "rand" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc266eb313df6c5c09c1c7b1fbe2510961e5bcd3add930c1e31f7ed9da0feff8" +dependencies = [ + "chacha20 0.10.0", + "getrandom 0.4.1", + "rand_core 0.10.0", +] + [[package]] name = "rand_chacha" version = "0.3.1" @@ -13611,7 +13672,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.16", + "getrandom 0.2.17", ] [[package]] @@ -13624,6 +13685,12 @@ dependencies = [ "serde", ] +[[package]] +name = "rand_core" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c8d0fd677905edcbeedbf2edb6494d676f0e98d54d5cf9bda0b061cb8fb8aba" + [[package]] name = "rand_distr" version = "0.4.3" @@ -13723,7 +13790,7 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ - "getrandom 0.2.16", + "getrandom 0.2.17", "libredox", "thiserror 1.0.69", ] @@ -13868,7 +13935,7 @@ checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", - "getrandom 0.2.16", + "getrandom 0.2.17", "libc", "untrusted 0.9.0", "windows-sys 0.52.0", @@ -13928,7 +13995,7 @@ dependencies = [ [[package]] name = "rococo-runtime" version = "24.0.1" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "binary-merkle-tree", "bitvec", @@ -14026,7 +14093,7 @@ dependencies = [ [[package]] name = "rococo-runtime-constants" version = "21.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-support", "polkadot-primitives", @@ -14422,7 +14489,7 @@ dependencies = [ [[package]] name = "sc-allocator" version = "32.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "log", "sp-core", @@ -14433,7 +14500,7 @@ dependencies = [ [[package]] name = "sc-authority-discovery" version = "0.51.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "async-trait", "futures", @@ -14464,7 +14531,7 @@ dependencies = [ [[package]] name = "sc-basic-authorship" version = "0.50.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "futures", "log", @@ -14479,13 +14546,14 @@ dependencies = [ "sp-core", "sp-inherents", "sp-runtime", + "stp-shield", "substrate-prometheus-endpoint", ] [[package]] name = "sc-block-builder" version = "0.45.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "parity-scale-codec", "sp-api", @@ -14500,7 +14568,7 @@ dependencies = [ [[package]] name = "sc-chain-spec" version = "44.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "array-bytes 6.2.3", "clap", @@ -14516,7 +14584,7 @@ dependencies = [ "serde_json", "sp-blockchain", "sp-core", - "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61)", + "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee)", "sp-genesis-builder", "sp-io", "sp-runtime", @@ -14527,7 +14595,7 @@ dependencies = [ [[package]] name = "sc-chain-spec-derive" version = "12.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "proc-macro-crate 3.4.0", "proc-macro2", @@ -14538,7 +14606,7 @@ dependencies = [ [[package]] name = "sc-cli" version = "0.53.1" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "array-bytes 6.2.3", "chrono", @@ -14580,7 +14648,7 @@ dependencies = [ [[package]] name = "sc-client-api" version = "40.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "fnv", "futures", @@ -14606,7 +14674,7 @@ dependencies = [ [[package]] name = "sc-client-db" version = "0.47.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "hash-db", "kvdb", @@ -14634,7 +14702,7 @@ dependencies = [ [[package]] name = "sc-consensus" version = "0.50.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "async-trait", "futures", @@ -14657,7 +14725,7 @@ dependencies = [ [[package]] name = "sc-consensus-aura" version = "0.51.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "async-trait", "futures", @@ -14686,7 +14754,7 @@ dependencies = [ [[package]] name = "sc-consensus-babe" version = "0.51.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "async-trait", "fork-tree", @@ -14711,7 +14779,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=71629fd93b6c12a362a5cfb6331accef9b2b2b61)", + "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee)", "sp-inherents", "sp-keystore", "sp-runtime", @@ -14722,7 +14790,7 @@ dependencies = [ [[package]] name = "sc-consensus-babe-rpc" version = "0.51.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "futures", "jsonrpsee", @@ -14744,7 +14812,7 @@ dependencies = [ [[package]] name = "sc-consensus-beefy" version = "30.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "array-bytes 6.2.3", "async-channel 1.9.0", @@ -14778,7 +14846,7 @@ dependencies = [ [[package]] name = "sc-consensus-beefy-rpc" version = "30.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "futures", "jsonrpsee", @@ -14798,7 +14866,7 @@ dependencies = [ [[package]] name = "sc-consensus-epochs" version = "0.50.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "fork-tree", "parity-scale-codec", @@ -14811,7 +14879,7 @@ dependencies = [ [[package]] name = "sc-consensus-grandpa" version = "0.36.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "ahash", "array-bytes 6.2.3", @@ -14845,7 +14913,7 @@ dependencies = [ "sp-consensus", "sp-consensus-grandpa", "sp-core", - "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61)", + "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee)", "sp-keystore", "sp-runtime", "substrate-prometheus-endpoint", @@ -14855,7 +14923,7 @@ dependencies = [ [[package]] name = "sc-consensus-grandpa-rpc" version = "0.36.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "finality-grandpa", "futures", @@ -14875,7 +14943,7 @@ dependencies = [ [[package]] name = "sc-consensus-manual-seal" version = "0.52.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "assert_matches", "async-trait", @@ -14910,7 +14978,7 @@ dependencies = [ [[package]] name = "sc-consensus-slots" version = "0.50.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "async-trait", "futures", @@ -14933,7 +15001,7 @@ dependencies = [ [[package]] name = "sc-executor" version = "0.43.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "parity-scale-codec", "parking_lot 0.12.5", @@ -14956,7 +15024,7 @@ dependencies = [ [[package]] name = "sc-executor-common" version = "0.39.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "polkavm 0.24.0", "sc-allocator", @@ -14969,7 +15037,7 @@ dependencies = [ [[package]] name = "sc-executor-polkavm" version = "0.36.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "log", "polkavm 0.24.0", @@ -14980,7 +15048,7 @@ dependencies = [ [[package]] name = "sc-executor-wasmtime" version = "0.39.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "anyhow", "log", @@ -14996,7 +15064,7 @@ dependencies = [ [[package]] name = "sc-informant" version = "0.50.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "console", "futures", @@ -15012,7 +15080,7 @@ dependencies = [ [[package]] name = "sc-keystore" version = "36.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "array-bytes 6.2.3", "parking_lot 0.12.5", @@ -15026,7 +15094,7 @@ dependencies = [ [[package]] name = "sc-mixnet" version = "0.21.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "array-bytes 6.2.3", "arrayvec 0.7.6", @@ -15054,7 +15122,7 @@ dependencies = [ [[package]] name = "sc-network" version = "0.51.1" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "array-bytes 6.2.3", "async-channel 1.9.0", @@ -15104,7 +15172,7 @@ dependencies = [ [[package]] name = "sc-network-common" version = "0.49.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "bitflags 1.3.2", "parity-scale-codec", @@ -15114,7 +15182,7 @@ dependencies = [ [[package]] name = "sc-network-gossip" version = "0.51.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "ahash", "futures", @@ -15133,7 +15201,7 @@ dependencies = [ [[package]] name = "sc-network-light" version = "0.50.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "array-bytes 6.2.3", "async-channel 1.9.0", @@ -15154,7 +15222,7 @@ dependencies = [ [[package]] name = "sc-network-statement" version = "0.33.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "array-bytes 6.2.3", "async-channel 1.9.0", @@ -15174,7 +15242,7 @@ dependencies = [ [[package]] name = "sc-network-sync" version = "0.50.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "array-bytes 6.2.3", "async-channel 1.9.0", @@ -15209,7 +15277,7 @@ dependencies = [ [[package]] name = "sc-network-transactions" version = "0.50.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "array-bytes 6.2.3", "futures", @@ -15228,7 +15296,7 @@ dependencies = [ [[package]] name = "sc-network-types" version = "0.17.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "bs58", "bytes", @@ -15249,7 +15317,7 @@ dependencies = [ [[package]] name = "sc-offchain" version = "46.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "bytes", "fnv", @@ -15283,7 +15351,7 @@ dependencies = [ [[package]] name = "sc-proposer-metrics" version = "0.20.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "log", "substrate-prometheus-endpoint", @@ -15292,7 +15360,7 @@ dependencies = [ [[package]] name = "sc-rpc" version = "46.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "futures", "jsonrpsee", @@ -15324,7 +15392,7 @@ dependencies = [ [[package]] name = "sc-rpc-api" version = "0.50.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "jsonrpsee", "parity-scale-codec", @@ -15344,7 +15412,7 @@ dependencies = [ [[package]] name = "sc-rpc-server" version = "23.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "dyn-clone", "forwarded-header-value", @@ -15368,7 +15436,7 @@ dependencies = [ [[package]] name = "sc-rpc-spec-v2" version = "0.51.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "array-bytes 6.2.3", "futures", @@ -15401,13 +15469,13 @@ dependencies = [ [[package]] name = "sc-runtime-utilities" version = "0.3.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" 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=71629fd93b6c12a362a5cfb6331accef9b2b2b61)", + "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee)", "sp-state-machine", "sp-wasm-interface", "thiserror 1.0.69", @@ -15416,7 +15484,7 @@ dependencies = [ [[package]] name = "sc-service" version = "0.52.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "async-trait", "directories", @@ -15480,7 +15548,7 @@ dependencies = [ [[package]] name = "sc-state-db" version = "0.39.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "log", "parity-scale-codec", @@ -15491,7 +15559,7 @@ dependencies = [ [[package]] name = "sc-statement-store" version = "22.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "log", "parity-db", @@ -15510,7 +15578,7 @@ dependencies = [ [[package]] name = "sc-storage-monitor" version = "0.25.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "clap", "fs4", @@ -15523,7 +15591,7 @@ dependencies = [ [[package]] name = "sc-sync-state-rpc" version = "0.51.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "jsonrpsee", "parity-scale-codec", @@ -15542,7 +15610,7 @@ dependencies = [ [[package]] name = "sc-sysinfo" version = "43.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "derive_more 0.99.20", "futures", @@ -15555,14 +15623,14 @@ dependencies = [ "serde", "serde_json", "sp-core", - "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61)", + "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee)", "sp-io", ] [[package]] name = "sc-telemetry" version = "29.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "chrono", "futures", @@ -15581,7 +15649,7 @@ dependencies = [ [[package]] name = "sc-tracing" version = "40.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "chrono", "console", @@ -15609,7 +15677,7 @@ dependencies = [ [[package]] name = "sc-tracing-proc-macro" version = "11.1.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "proc-macro-crate 3.4.0", "proc-macro2", @@ -15620,7 +15688,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool" version = "40.1.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "async-trait", "futures", @@ -15637,7 +15705,7 @@ dependencies = [ "sp-api", "sp-blockchain", "sp-core", - "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61)", + "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee)", "sp-runtime", "sp-tracing", "sp-transaction-pool", @@ -15651,7 +15719,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool-api" version = "40.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "async-trait", "futures", @@ -15668,7 +15736,7 @@ dependencies = [ [[package]] name = "sc-utils" version = "19.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "async-channel 1.9.0", "futures", @@ -16208,7 +16276,7 @@ checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" dependencies = [ "block-buffer 0.9.0", "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "digest 0.9.0", "opaque-debug 0.3.1", ] @@ -16220,7 +16288,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "digest 0.10.7", ] @@ -16232,7 +16300,7 @@ checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" dependencies = [ "block-buffer 0.9.0", "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "digest 0.9.0", "opaque-debug 0.3.1", ] @@ -16244,7 +16312,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "digest 0.10.7", ] @@ -16386,7 +16454,7 @@ checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" [[package]] name = "slot-range-helper" version = "18.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "enumn", "parity-scale-codec", @@ -16456,7 +16524,7 @@ dependencies = [ "bip39", "blake2-rfc", "bs58", - "chacha20", + "chacha20 0.9.1", "crossbeam-queue", "derive_more 0.99.20", "ed25519-zebra", @@ -16510,7 +16578,7 @@ dependencies = [ "bip39", "blake2-rfc", "bs58", - "chacha20", + "chacha20 0.9.1", "crossbeam-queue", "derive_more 0.99.20", "ed25519-zebra", @@ -16649,7 +16717,7 @@ dependencies = [ [[package]] name = "snowbridge-core" version = "0.14.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "bp-relayers", "frame-support", @@ -16733,7 +16801,7 @@ dependencies = [ [[package]] name = "sp-api" version = "37.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "docify", "hash-db", @@ -16755,7 +16823,7 @@ dependencies = [ [[package]] name = "sp-api-proc-macro" version = "23.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "Inflector", "blake2 0.10.6", @@ -16769,7 +16837,7 @@ dependencies = [ [[package]] name = "sp-application-crypto" version = "41.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "parity-scale-codec", "scale-info", @@ -16781,7 +16849,7 @@ dependencies = [ [[package]] name = "sp-arithmetic" version = "27.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "docify", "integer-sqrt", @@ -16795,7 +16863,7 @@ dependencies = [ [[package]] name = "sp-authority-discovery" version = "37.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "parity-scale-codec", "scale-info", @@ -16807,7 +16875,7 @@ dependencies = [ [[package]] name = "sp-block-builder" version = "37.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "sp-api", "sp-inherents", @@ -16817,7 +16885,7 @@ dependencies = [ [[package]] name = "sp-blockchain" version = "40.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "futures", "parity-scale-codec", @@ -16836,7 +16904,7 @@ dependencies = [ [[package]] name = "sp-consensus" version = "0.43.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "async-trait", "futures", @@ -16850,7 +16918,7 @@ dependencies = [ [[package]] name = "sp-consensus-aura" version = "0.43.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "async-trait", "parity-scale-codec", @@ -16866,7 +16934,7 @@ dependencies = [ [[package]] name = "sp-consensus-babe" version = "0.43.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "async-trait", "parity-scale-codec", @@ -16884,7 +16952,7 @@ dependencies = [ [[package]] name = "sp-consensus-beefy" version = "25.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "parity-scale-codec", "scale-info", @@ -16892,7 +16960,7 @@ dependencies = [ "sp-api", "sp-application-crypto", "sp-core", - "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61)", + "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee)", "sp-io", "sp-keystore", "sp-mmr-primitives", @@ -16904,7 +16972,7 @@ dependencies = [ [[package]] name = "sp-consensus-grandpa" version = "24.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "finality-grandpa", "log", @@ -16921,7 +16989,7 @@ dependencies = [ [[package]] name = "sp-consensus-slots" version = "0.43.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "parity-scale-codec", "scale-info", @@ -16932,7 +17000,7 @@ dependencies = [ [[package]] name = "sp-core" version = "37.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "ark-vrf", "array-bytes 6.2.3", @@ -16963,7 +17031,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=71629fd93b6c12a362a5cfb6331accef9b2b2b61)", + "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee)", "sp-debug-derive", "sp-externalities", "sp-runtime-interface", @@ -16980,7 +17048,7 @@ dependencies = [ [[package]] name = "sp-crypto-ec-utils" version = "0.16.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "ark-bls12-377", "ark-bls12-377-ext", @@ -17014,7 +17082,7 @@ dependencies = [ [[package]] name = "sp-crypto-hashing" version = "0.1.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "blake2b_simd", "byteorder", @@ -17027,17 +17095,17 @@ dependencies = [ [[package]] name = "sp-crypto-hashing-proc-macro" version = "0.1.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "quote", - "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61)", + "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee)", "syn 2.0.106", ] [[package]] name = "sp-database" version = "10.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "kvdb", "parking_lot 0.12.5", @@ -17046,7 +17114,7 @@ dependencies = [ [[package]] name = "sp-debug-derive" version = "14.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "proc-macro2", "quote", @@ -17056,7 +17124,7 @@ dependencies = [ [[package]] name = "sp-externalities" version = "0.30.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "environmental", "parity-scale-codec", @@ -17066,7 +17134,7 @@ dependencies = [ [[package]] name = "sp-genesis-builder" version = "0.18.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "parity-scale-codec", "scale-info", @@ -17078,7 +17146,7 @@ dependencies = [ [[package]] name = "sp-inherents" version = "37.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "async-trait", "impl-trait-for-tuples", @@ -17091,7 +17159,7 @@ dependencies = [ [[package]] name = "sp-io" version = "41.0.1" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "bytes", "docify", @@ -17103,7 +17171,7 @@ dependencies = [ "rustversion", "secp256k1 0.28.2", "sp-core", - "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61)", + "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee)", "sp-externalities", "sp-keystore", "sp-runtime-interface", @@ -17117,7 +17185,7 @@ dependencies = [ [[package]] name = "sp-keyring" version = "42.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "sp-core", "sp-runtime", @@ -17127,7 +17195,7 @@ dependencies = [ [[package]] name = "sp-keystore" version = "0.43.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "parity-scale-codec", "parking_lot 0.12.5", @@ -17138,7 +17206,7 @@ dependencies = [ [[package]] name = "sp-maybe-compressed-blob" version = "11.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "thiserror 1.0.69", "zstd 0.12.4", @@ -17147,7 +17215,7 @@ dependencies = [ [[package]] name = "sp-metadata-ir" version = "0.11.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-metadata 23.0.0", "parity-scale-codec", @@ -17157,7 +17225,7 @@ dependencies = [ [[package]] name = "sp-mixnet" version = "0.15.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "parity-scale-codec", "scale-info", @@ -17168,7 +17236,7 @@ dependencies = [ [[package]] name = "sp-mmr-primitives" version = "37.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "log", "parity-scale-codec", @@ -17185,7 +17253,7 @@ dependencies = [ [[package]] name = "sp-npos-elections" version = "37.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "parity-scale-codec", "scale-info", @@ -17198,7 +17266,7 @@ dependencies = [ [[package]] name = "sp-offchain" version = "37.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "sp-api", "sp-core", @@ -17208,7 +17276,7 @@ dependencies = [ [[package]] name = "sp-panic-handler" version = "13.0.2" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "backtrace", "regex", @@ -17217,7 +17285,7 @@ dependencies = [ [[package]] name = "sp-rpc" version = "35.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "rustc-hash 1.1.0", "serde", @@ -17227,7 +17295,7 @@ dependencies = [ [[package]] name = "sp-runtime" version = "42.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "binary-merkle-tree", "docify", @@ -17256,7 +17324,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface" version = "30.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "bytes", "impl-trait-for-tuples", @@ -17275,7 +17343,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" version = "19.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "Inflector", "expander", @@ -17288,7 +17356,7 @@ dependencies = [ [[package]] name = "sp-session" version = "39.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "parity-scale-codec", "scale-info", @@ -17302,7 +17370,7 @@ dependencies = [ [[package]] name = "sp-staking" version = "39.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", @@ -17315,7 +17383,7 @@ dependencies = [ [[package]] name = "sp-state-machine" version = "0.46.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "hash-db", "log", @@ -17335,7 +17403,7 @@ dependencies = [ [[package]] name = "sp-statement-store" version = "21.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "aes-gcm", "curve25519-dalek", @@ -17348,7 +17416,7 @@ dependencies = [ "sp-api", "sp-application-crypto", "sp-core", - "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61)", + "sp-crypto-hashing 0.1.0 (git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee)", "sp-externalities", "sp-runtime", "sp-runtime-interface", @@ -17359,12 +17427,12 @@ dependencies = [ [[package]] name = "sp-std" version = "14.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" [[package]] name = "sp-storage" version = "22.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "impl-serde", "parity-scale-codec", @@ -17376,7 +17444,7 @@ dependencies = [ [[package]] name = "sp-timestamp" version = "37.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "async-trait", "parity-scale-codec", @@ -17388,7 +17456,7 @@ dependencies = [ [[package]] name = "sp-tracing" version = "17.1.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "parity-scale-codec", "tracing", @@ -17399,7 +17467,7 @@ dependencies = [ [[package]] name = "sp-transaction-pool" version = "37.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "sp-api", "sp-runtime", @@ -17408,7 +17476,7 @@ dependencies = [ [[package]] name = "sp-transaction-storage-proof" version = "37.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "async-trait", "parity-scale-codec", @@ -17422,7 +17490,7 @@ dependencies = [ [[package]] name = "sp-trie" version = "40.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "ahash", "foldhash 0.1.5", @@ -17447,7 +17515,7 @@ dependencies = [ [[package]] name = "sp-version" version = "40.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "impl-serde", "parity-scale-codec", @@ -17464,7 +17532,7 @@ dependencies = [ [[package]] name = "sp-version-proc-macro" version = "15.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "parity-scale-codec", "proc-macro-warning", @@ -17476,7 +17544,7 @@ dependencies = [ [[package]] name = "sp-wasm-interface" version = "22.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "anyhow", "impl-trait-for-tuples", @@ -17488,7 +17556,7 @@ dependencies = [ [[package]] name = "sp-weights" version = "32.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "bounded-collections 0.2.4", "parity-scale-codec", @@ -17662,7 +17730,7 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "staging-chain-spec-builder" version = "12.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "clap", "docify", @@ -17675,7 +17743,7 @@ dependencies = [ [[package]] name = "staging-node-inspect" version = "0.29.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "clap", "parity-scale-codec", @@ -17693,7 +17761,7 @@ dependencies = [ [[package]] name = "staging-parachain-info" version = "0.21.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -17706,7 +17774,7 @@ dependencies = [ [[package]] name = "staging-xcm" version = "17.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "array-bytes 6.2.3", "bounded-collections 0.2.4", @@ -17727,7 +17795,7 @@ dependencies = [ [[package]] name = "staging-xcm-builder" version = "21.1.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "environmental", "frame-support", @@ -17751,7 +17819,7 @@ dependencies = [ [[package]] name = "staging-xcm-executor" version = "20.0.1" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "environmental", "frame-benchmarking", @@ -17802,6 +17870,39 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "stc-shield" +version = "0.1.0" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" +dependencies = [ + "anyhow", + "async-trait", + "futures", + "hex", + "log", + "ml-kem", + "parity-scale-codec", + "rand 0.8.5", + "sc-client-api", + "sc-service", + "sp-consensus", + "sp-inherents", + "sp-runtime", + "stp-shield", +] + +[[package]] +name = "stp-shield" +version = "0.1.0" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" +dependencies = [ + "parity-scale-codec", + "scale-info", + "sp-api", + "sp-inherents", + "sp-runtime", +] + [[package]] name = "string-interner" version = "0.17.0" @@ -17863,7 +17964,7 @@ dependencies = [ [[package]] name = "substrate-bip39" version = "0.6.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "hmac 0.12.1", "pbkdf2", @@ -17888,7 +17989,7 @@ dependencies = [ [[package]] name = "substrate-build-script-utils" version = "11.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" [[package]] name = "substrate-fixed" @@ -17904,7 +18005,7 @@ dependencies = [ [[package]] name = "substrate-frame-rpc-system" version = "45.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "docify", "frame-system-rpc-runtime-api", @@ -17924,7 +18025,7 @@ dependencies = [ [[package]] name = "substrate-prometheus-endpoint" version = "0.17.6" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "http-body-util", "hyper 1.7.0", @@ -17938,7 +18039,7 @@ dependencies = [ [[package]] name = "substrate-state-trie-migration-rpc" version = "44.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "jsonrpsee", "parity-scale-codec", @@ -17965,7 +18066,7 @@ dependencies = [ [[package]] name = "substrate-wasm-builder" version = "27.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "array-bytes 6.2.3", "build-helper", @@ -18118,11 +18219,14 @@ dependencies = [ "approx", "environmental", "frame-support", + "num-traits", "parity-scale-codec", "polkadot-runtime-common", "scale-info", "serde", + "sp-arithmetic", "sp-core", + "sp-rpc", "sp-runtime", "substrate-fixed", "subtensor-macros", @@ -18996,7 +19100,7 @@ dependencies = [ [[package]] name = "tracing-gum" version = "20.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "coarsetime", "polkadot-primitives", @@ -19007,7 +19111,7 @@ dependencies = [ [[package]] name = "tracing-gum-proc-macro" version = "5.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "expander", "proc-macro-crate 3.4.0", @@ -19478,7 +19582,16 @@ version = "1.0.1+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" dependencies = [ - "wit-bindgen", + "wit-bindgen 0.46.0", +] + +[[package]] +name = "wasip3" +version = "0.4.0+wasi-0.3.0-rc-2026-01-06" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" +dependencies = [ + "wit-bindgen 0.51.0", ] [[package]] @@ -19562,6 +19675,16 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "wasm-encoder" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" +dependencies = [ + "leb128fmt", + "wasmparser 0.244.0", +] + [[package]] name = "wasm-instrument" version = "0.4.0" @@ -19571,6 +19694,18 @@ dependencies = [ "parity-wasm", ] +[[package]] +name = "wasm-metadata" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" +dependencies = [ + "anyhow", + "indexmap 2.11.4", + "wasm-encoder", + "wasmparser 0.244.0", +] + [[package]] name = "wasm-opt" version = "0.116.1" @@ -19707,6 +19842,18 @@ dependencies = [ "url", ] +[[package]] +name = "wasmparser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" +dependencies = [ + "bitflags 2.9.4", + "hashbrown 0.15.5", + "indexmap 2.11.4", + "semver 1.0.27", +] + [[package]] name = "wasmparser-nostd" version = "0.100.2" @@ -19735,7 +19882,7 @@ dependencies = [ "rayon", "serde", "target-lexicon", - "wasmparser", + "wasmparser 0.102.0", "wasmtime-cache", "wasmtime-cranelift", "wasmtime-environ", @@ -19790,7 +19937,7 @@ dependencies = [ "object 0.30.4", "target-lexicon", "thiserror 1.0.69", - "wasmparser", + "wasmparser 0.102.0", "wasmtime-cranelift-shared", "wasmtime-environ", ] @@ -19825,7 +19972,7 @@ dependencies = [ "serde", "target-lexicon", "thiserror 1.0.69", - "wasmparser", + "wasmparser 0.102.0", "wasmtime-types", ] @@ -19908,7 +20055,7 @@ dependencies = [ "cranelift-entity", "serde", "thiserror 1.0.69", - "wasmparser", + "wasmparser 0.102.0", ] [[package]] @@ -19958,7 +20105,7 @@ checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "westend-runtime" version = "24.0.1" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "binary-merkle-tree", "bitvec", @@ -20065,7 +20212,7 @@ dependencies = [ [[package]] name = "westend-runtime-constants" version = "21.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-support", "polkadot-primitives", @@ -20554,6 +20701,94 @@ version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" +[[package]] +name = "wit-bindgen" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +dependencies = [ + "wit-bindgen-rust-macro", +] + +[[package]] +name = "wit-bindgen-core" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" +dependencies = [ + "anyhow", + "heck 0.5.0", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" +dependencies = [ + "anyhow", + "heck 0.5.0", + "indexmap 2.11.4", + "prettyplease", + "syn 2.0.106", + "wasm-metadata", + "wit-bindgen-core", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" +dependencies = [ + "anyhow", + "prettyplease", + "proc-macro2", + "quote", + "syn 2.0.106", + "wit-bindgen-core", + "wit-bindgen-rust", +] + +[[package]] +name = "wit-component" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" +dependencies = [ + "anyhow", + "bitflags 2.9.4", + "indexmap 2.11.4", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser 0.244.0", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" +dependencies = [ + "anyhow", + "id-arena", + "indexmap 2.11.4", + "log", + "semver 1.0.27", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser 0.244.0", +] + [[package]] name = "writeable" version = "0.6.1" @@ -20618,7 +20853,7 @@ dependencies = [ [[package]] name = "xcm-procedural" version = "11.0.2" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "Inflector", "proc-macro2", @@ -20629,7 +20864,7 @@ dependencies = [ [[package]] name = "xcm-runtime-apis" version = "0.8.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-support", "parity-scale-codec", @@ -20643,7 +20878,7 @@ dependencies = [ [[package]] name = "xcm-simulator" version = "21.0.0" -source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=71629fd93b6c12a362a5cfb6331accef9b2b2b61#71629fd93b6c12a362a5cfb6331accef9b2b2b61" +source = "git+https://github.com/opentensor/polkadot-sdk.git?rev=fb1dd20df37710800aa284ac49bb26193d5539ee#fb1dd20df37710800aa284ac49bb26193d5539ee" dependencies = [ "frame-support", "frame-system", diff --git a/Cargo.toml b/Cargo.toml index 32bcacf4c3..0d95b9a054 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,6 +39,9 @@ resolver = "2" [workspace.package] edition = "2024" +[workspace.lints.rust] +unexpected_cfgs = { level = "allow", check-cfg = ['cfg(substrate_runtime)'] } + [workspace.lints.clippy] arithmetic-side-effects = "deny" expect-used = "deny" @@ -70,6 +73,8 @@ subtensor-runtime-common = { default-features = false, path = "common" } subtensor-swap-interface = { default-features = false, path = "pallets/swap-interface" } subtensor-transaction-fee = { default-features = false, path = "pallets/transaction-fee" } subtensor-chain-extensions = { default-features = false, path = "chain-extensions" } +stp-shield = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +stc-shield = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } ed25519-dalek = { version = "2.1.0", default-features = false } async-trait = "0.1" @@ -85,7 +90,7 @@ libsecp256k1 = { version = "0.7.2", default-features = false } log = { version = "0.4.21", default-features = false } memmap2 = "0.9.8" ndarray = { version = "0.16.1", default-features = false } -rand = "0.8.5" +rand = { version = "0.10.0", default-features = false } scale-info = { version = "2.11.2", default-features = false } serde = { version = "1.0.214", default-features = false } serde-tuple-vec-map = { version = "1.0.1", default-features = false } @@ -119,159 +124,160 @@ 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 } +tokio = { version = "1.38", 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 = { package = "polkadot-sdk-frame", git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +frame-support = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +frame-system = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +frame-executive = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +frame-system-rpc-runtime-api = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +frame-system-benchmarking = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +frame-try-runtime = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +frame-benchmarking = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +frame-benchmarking-cli = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +frame-metadata-hash-extension = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", 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/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 } +pallet-babe = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +pallet-aura = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +pallet-balances = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +pallet-grandpa = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +pallet-insecure-randomness-collective-flip = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +pallet-multisig = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +pallet-preimage = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +pallet-safe-mode = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +pallet-scheduler = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +pallet-sudo = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +pallet-timestamp = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +pallet-transaction-payment = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +pallet-transaction-payment-rpc = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +pallet-root-testing = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +pallet-contracts = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } # NPoS -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 } +frame-election-provider-support = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +pallet-authority-discovery = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +pallet-authorship = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +pallet-bags-list = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +pallet-election-provider-multi-phase = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +pallet-fast-unstake = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +pallet-nomination-pools = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +pallet-nomination-pools-runtime-api = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +pallet-session = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +pallet-staking = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +pallet-staking-runtime-api = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +pallet-staking-reward-fn = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +pallet-staking-reward-curve = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +pallet-offences = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", 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 } +sc-basic-authorship = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sc-cli = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sc-client-api = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sc-consensus = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sc-consensus-aura = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sc-consensus-babe = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sc-consensus-babe-rpc = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sc-consensus-grandpa = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sc-consensus-grandpa-rpc = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sc-consensus-epochs = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sc-chain-spec-derive = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sc-chain-spec = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sc-consensus-slots = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sc-executor = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sc-keystore = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sc-network = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sc-offchain = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sc-rpc = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sc-rpc-api = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sc-service = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sc-telemetry = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sc-transaction-pool = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sc-transaction-pool-api = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sc-consensus-manual-seal = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sc-network-sync = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", 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 } +sp-api = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sp-authority-discovery = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sp-arithmetic = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sp-block-builder = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sp-blockchain = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sp-staking = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sp-consensus = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sp-consensus-aura = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sp-consensus-babe = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sp-consensus-slots = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sp-npos-elections = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sp-consensus-grandpa = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sp-genesis-builder = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sp-core = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sp-inherents = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sp-io = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sp-keyring = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sp-offchain = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sp-rpc = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sp-runtime = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sp-session = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sp-std = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sp-storage = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sp-timestamp = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sp-tracing = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sp-transaction-pool = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sp-version = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sp-weights = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sp-crypto-hashing = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sp-application-crypto = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sp-debug-derive = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sp-externalities = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sp-runtime-interface = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } -substrate-build-script-utils = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +substrate-build-script-utils = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", 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/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 } +substrate-frame-rpc-system = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +substrate-wasm-builder = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +substrate-prometheus-endpoint = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } -polkadot-sdk = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +polkadot-sdk = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } -runtime-common = { package = "polkadot-runtime-common", git = "https://github.com/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +runtime-common = { package = "polkadot-runtime-common", git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } # Frontier -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 } +fp-evm = { git = "https://github.com/opentensor/frontier", rev = "a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710", default-features = false } +fp-rpc = { git = "https://github.com/opentensor/frontier", rev = "a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710", default-features = false } +fp-self-contained = { git = "https://github.com/opentensor/frontier", rev = "a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710", default-features = false } +fp-account = { git = "https://github.com/opentensor/frontier", rev = "a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710", default-features = false } +fc-storage = { git = "https://github.com/opentensor/frontier", rev = "a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710", default-features = false } +fc-db = { git = "https://github.com/opentensor/frontier", rev = "a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710", default-features = false } +fc-consensus = { git = "https://github.com/opentensor/frontier", rev = "a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710", default-features = false } +fp-consensus = { git = "https://github.com/opentensor/frontier", rev = "a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710", default-features = false } +fp-dynamic-fee = { git = "https://github.com/opentensor/frontier", rev = "a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710", default-features = false } +fc-api = { git = "https://github.com/opentensor/frontier", rev = "a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710", default-features = false } +fc-rpc = { git = "https://github.com/opentensor/frontier", rev = "a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710", default-features = false } +fc-rpc-core = { git = "https://github.com/opentensor/frontier", rev = "a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710", default-features = false } +fc-aura = { git = "https://github.com/opentensor/frontier", rev = "a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710", default-features = false } +fc-babe = { git = "https://github.com/opentensor/frontier", rev = "a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710", default-features = false } +fc-mapping-sync = { git = "https://github.com/opentensor/frontier", rev = "a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710", default-features = false } +precompile-utils = { git = "https://github.com/opentensor/frontier", rev = "a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710", default-features = false } # Frontier FRAME -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 } +pallet-base-fee = { git = "https://github.com/opentensor/frontier", rev = "a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710", default-features = false } +pallet-dynamic-fee = { git = "https://github.com/opentensor/frontier", rev = "a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710", default-features = false } +pallet-ethereum = { git = "https://github.com/opentensor/frontier", rev = "a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710", default-features = false } +pallet-evm = { git = "https://github.com/opentensor/frontier", rev = "a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710", default-features = false } +pallet-evm-precompile-dispatch = { git = "https://github.com/opentensor/frontier", rev = "a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710", default-features = false } +pallet-evm-chain-id = { git = "https://github.com/opentensor/frontier", rev = "a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710", default-features = false } +pallet-evm-precompile-modexp = { git = "https://github.com/opentensor/frontier", rev = "a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710", default-features = false } +pallet-evm-precompile-sha3fips = { git = "https://github.com/opentensor/frontier", rev = "a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710", default-features = false } +pallet-evm-precompile-simple = { git = "https://github.com/opentensor/frontier", rev = "a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710", default-features = false } +pallet-evm-precompile-bn128 = { git = "https://github.com/opentensor/frontier", rev = "a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710", default-features = false } +pallet-hotfix-sufficients = { git = "https://github.com/opentensor/frontier", rev = "a1aa78ca4a0b9ca21324cdc555ccbfa56a16f710", default-features = false } #DRAND pallet-drand = { path = "pallets/drand", 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/opentensor/polkadot-sdk.git", rev = "71629fd93b6c12a362a5cfb6331accef9b2b2b61", default-features = false } +sp-crypto-ec-utils = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", default-features = false } +sp-keystore = { git = "https://github.com/opentensor/polkadot-sdk.git", rev = "fb1dd20df37710800aa284ac49bb26193d5539ee", 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 } @@ -286,7 +292,9 @@ rand_chacha = { version = "0.3.1", default-features = false } tle = { git = "https://github.com/ideal-lab5/timelock", rev = "5416406cfd32799e31e1795393d4916894de4468", default-features = false } pallet-shield = { path = "pallets/shield", default-features = false } -ml-kem = { version = "0.2.0", default-features = true } +ml-kem = { version = "0.2.2", default-features = false } +chacha20poly1305 = { version = "0.10", default-features = false } +blake2 = "0.10.6" # Primitives @@ -306,4 +314,4 @@ default = [] pow-faucet = [] [patch.crates-io] -w3f-bls = { git = "https://github.com/opentensor/bls", branch = "fix-no-std" } \ No newline at end of file +w3f-bls = { git = "https://github.com/opentensor/bls", branch = "fix-no-std" } diff --git a/chain-extensions/src/lib.rs b/chain-extensions/src/lib.rs index eaaee70d27..14ea23d9c8 100644 --- a/chain-extensions/src/lib.rs +++ b/chain-extensions/src/lib.rs @@ -19,7 +19,7 @@ use pallet_subtensor_proxy::WeightInfo; use sp_runtime::{DispatchError, Weight, traits::StaticLookup}; use sp_std::marker::PhantomData; use substrate_fixed::types::U96F32; -use subtensor_runtime_common::{AlphaCurrency, NetUid, ProxyType, TaoCurrency}; +use subtensor_runtime_common::{AlphaBalance, NetUid, ProxyType, TaoBalance}; use subtensor_swap_interface::SwapHandler; #[derive(DebugNoBound)] @@ -97,7 +97,7 @@ where env.charge_weight(weight)?; - let (hotkey, netuid, amount_staked): (T::AccountId, NetUid, TaoCurrency) = env + let (hotkey, netuid, amount_staked): (T::AccountId, NetUid, TaoBalance) = env .read_as() .map_err(|_| DispatchError::Other("Failed to decode input parameters"))?; @@ -123,7 +123,7 @@ where env.charge_weight(weight)?; - let (hotkey, netuid, amount_unstaked): (T::AccountId, NetUid, AlphaCurrency) = env + let (hotkey, netuid, amount_unstaked): (T::AccountId, NetUid, AlphaBalance) = env .read_as() .map_err(|_| DispatchError::Other("Failed to decode input parameters"))?; @@ -203,7 +203,7 @@ where origin_netuid, destination_netuid, alpha_amount, - ): (T::AccountId, T::AccountId, NetUid, NetUid, AlphaCurrency) = env + ): (T::AccountId, T::AccountId, NetUid, NetUid, AlphaBalance) = env .read_as() .map_err(|_| DispatchError::Other("Failed to decode input parameters"))?; @@ -236,7 +236,7 @@ where T::AccountId, NetUid, NetUid, - AlphaCurrency, + AlphaBalance, ) = env .read_as() .map_err(|_| DispatchError::Other("Failed to decode input parameters"))?; @@ -269,7 +269,7 @@ where T::AccountId, NetUid, NetUid, - AlphaCurrency, + AlphaBalance, ) = env .read_as() .map_err(|_| DispatchError::Other("Failed to decode input parameters"))?; @@ -300,8 +300,8 @@ where let (hotkey, netuid, amount_staked, limit_price, allow_partial): ( T::AccountId, NetUid, - TaoCurrency, - TaoCurrency, + TaoBalance, + TaoBalance, bool, ) = env .read_as() @@ -334,8 +334,8 @@ where let (hotkey, netuid, amount_unstaked, limit_price, allow_partial): ( T::AccountId, NetUid, - AlphaCurrency, - TaoCurrency, + AlphaBalance, + TaoBalance, bool, ) = env .read_as() @@ -372,16 +372,9 @@ where alpha_amount, limit_price, allow_partial, - ): ( - T::AccountId, - NetUid, - NetUid, - AlphaCurrency, - TaoCurrency, - bool, - ) = env - .read_as() - .map_err(|_| DispatchError::Other("Failed to decode input parameters"))?; + ): (T::AccountId, NetUid, NetUid, AlphaBalance, TaoBalance, bool) = + env.read_as() + .map_err(|_| DispatchError::Other("Failed to decode input parameters"))?; let call_result = pallet_subtensor::Pallet::::swap_stake_limit( RawOrigin::Signed(env.caller()).into(), @@ -408,9 +401,9 @@ where env.charge_weight(weight)?; - let (hotkey, netuid, limit_price): (T::AccountId, NetUid, Option) = - env.read_as() - .map_err(|_| DispatchError::Other("Failed to decode input parameters"))?; + let (hotkey, netuid, limit_price): (T::AccountId, NetUid, Option) = env + .read_as() + .map_err(|_| DispatchError::Other("Failed to decode input parameters"))?; let call_result = pallet_subtensor::Pallet::::remove_stake_full_limit( RawOrigin::Signed(env.caller()).into(), diff --git a/chain-extensions/src/mock.rs b/chain-extensions/src/mock.rs index 45c7811adb..46ea71fc39 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, AuthorshipInfo, NetUid, TaoCurrency}; +use subtensor_runtime_common::{AlphaBalance, AuthorshipInfo, NetUid, TaoBalance}; type Block = frame_system::mocking::MockBlock; @@ -57,7 +57,7 @@ pub type AccountId = U256; // Balance of an account. #[allow(dead_code)] -pub type Balance = u64; +pub type Balance = TaoBalance; // An index to a block. #[allow(dead_code)] @@ -75,7 +75,7 @@ pub struct WeightToBalance; impl Convert for WeightToBalance { fn convert(weight: Weight) -> Balance { - weight.ref_time() + weight.ref_time().into() } } @@ -223,7 +223,7 @@ impl system::Config for Test { type BlockHashCount = BlockHashCount; type Version = (); type PalletInfo = PalletInfo; - type AccountData = pallet_balances::AccountData; + type AccountData = pallet_balances::AccountData; type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); @@ -241,9 +241,9 @@ parameter_types! { parameter_types! { pub ContractsSchedule: pallet_contracts::Schedule = Default::default(); - pub const ContractsDepositPerByte: Balance = 1; - pub const ContractsDepositPerItem: Balance = 10; - pub const ContractsDefaultDepositLimit: Balance = 1_000_000_000; + pub const ContractsDepositPerByte: Balance = TaoBalance::new(1); + pub const ContractsDepositPerItem: Balance = TaoBalance::new(10); + pub const ContractsDefaultDepositLimit: Balance = TaoBalance::new(1_000_000_000); pub const ContractsCodeHashLockupDepositPercent: Perbill = Perbill::from_percent(0); pub const ContractsMaxDelegateDependencies: u32 = 32; pub const ContractsMaxCodeLen: u32 = 120_000; @@ -254,12 +254,12 @@ parameter_types! { } parameter_types! { - pub const ProxyDepositBase: Balance = 1; - pub const ProxyDepositFactor: Balance = 1; + pub const ProxyDepositBase: Balance = TaoBalance::new(1); + pub const ProxyDepositFactor: Balance = TaoBalance::new(1); pub const MaxProxies: u32 = 32; pub const MaxPending: u32 = 32; - pub const AnnouncementDepositBase: Balance = 1; - pub const AnnouncementDepositFactor: Balance = 1; + pub const AnnouncementDepositBase: Balance = TaoBalance::new(1); + pub const AnnouncementDepositFactor: Balance = TaoBalance::new(1); } pub struct MockAuthorshipProvider; @@ -277,8 +277,8 @@ parameter_types! { Weight::from_parts(2_000_000_000_000, u64::MAX), Perbill::from_percent(75), ); - pub const ExistentialDeposit: Balance = 1; - pub const TransactionByteFee: Balance = 100; + pub const ExistentialDeposit: Balance = TaoBalance::new(1); + pub const TransactionByteFee: Balance = TaoBalance::new(100); pub const SDebug:u64 = 1; pub const InitialRho: u16 = 30; pub const InitialAlphaSigmoidSteepness: i16 = 1000; @@ -306,8 +306,8 @@ parameter_types! { pub const InitialBurn: u64 = 0; pub const InitialMinBurn: u64 = 500_000; pub const InitialMaxBurn: u64 = 1_000_000_000; - pub const MinBurnUpperBound: TaoCurrency = TaoCurrency::new(1_000_000_000); // 1 TAO - pub const MaxBurnLowerBound: TaoCurrency = TaoCurrency::new(100_000_000); // 0.1 TAO + pub const MinBurnUpperBound: TaoBalance = TaoBalance::new(1_000_000_000); // 1 TAO + pub const MaxBurnLowerBound: TaoBalance = TaoBalance::new(100_000_000); // 0.1 TAO pub const InitialValidatorPruneLen: u64 = 0; pub const InitialScalingLawPower: u16 = 50; pub const InitialMaxAllowedValidators: u16 = 100; @@ -339,7 +339,7 @@ parameter_types! { pub const InitialTaoWeight: u64 = 0; // 100% global weight. pub const InitialEmaPriceHalvingPeriod: u64 = 201_600_u64; // 4 weeks pub const InitialStartCallDelay: u64 = 7 * 24 * 60 * 60 / 12; // Default as 7 days - pub const InitialKeySwapOnSubnetCost: u64 = 10_000_000; + pub const InitialKeySwapOnSubnetCost: TaoBalance = TaoBalance::new(10_000_000); pub const HotkeySwapOnSubnetInterval: u64 = 15; // 15 block, should be bigger than subnet number, then trigger clean up for all subnets pub const MaxContributorsPerLeaseToRemove: u32 = 3; pub const LeaseDividendsDistributionInterval: u32 = 100; @@ -486,8 +486,8 @@ impl pallet_utility::Config for Test { parameter_types! { pub const PreimageMaxSize: u32 = 4096 * 1024; - pub const PreimageBaseDeposit: Balance = 1; - pub const PreimageByteDeposit: Balance = 1; + pub const PreimageBaseDeposit: Balance = TaoBalance::new(1); + pub const PreimageByteDeposit: Balance = TaoBalance::new(1); } impl pallet_preimage::Config for Test { @@ -701,7 +701,7 @@ pub(crate) fn remove_stake_rate_limit_for_tests(hotkey: &U256, coldkey: &U256, n } #[allow(dead_code)] -pub(crate) fn setup_reserves(netuid: NetUid, tao: TaoCurrency, alpha: AlphaCurrency) { +pub(crate) fn setup_reserves(netuid: NetUid, tao: TaoBalance, alpha: AlphaBalance) { SubnetTAO::::set(netuid, tao); SubnetAlphaIn::::set(netuid, alpha); } diff --git a/chain-extensions/src/tests.rs b/chain-extensions/src/tests.rs index bd6f46c8ab..b8956e8659 100644 --- a/chain-extensions/src/tests.rs +++ b/chain-extensions/src/tests.rs @@ -3,6 +3,7 @@ use super::{SubtensorChainExtension, SubtensorExtensionEnv, mock}; use crate::types::{FunctionId, Output}; use codec::{Decode, Encode}; +use frame_support::pallet_prelude::Zero; use frame_support::{assert_ok, weights::Weight}; use frame_system::RawOrigin; use pallet_contracts::chain_extension::RetVal; @@ -11,7 +12,7 @@ use sp_core::Get; use sp_core::U256; use sp_runtime::DispatchError; use substrate_fixed::types::U96F32; -use subtensor_runtime_common::{AlphaCurrency, Currency as CurrencyTrait, NetUid, TaoCurrency}; +use subtensor_runtime_common::{AlphaBalance, NetUid, TaoBalance, Token}; use subtensor_swap_interface::SwapHandler; type AccountId = ::AccountId; @@ -82,15 +83,15 @@ fn remove_stake_full_limit_success_with_limit_price() { let netuid = mock::add_dynamic_network(&owner_hotkey, &owner_coldkey); mock::setup_reserves( netuid, - TaoCurrency::from(130_000_000_000), - AlphaCurrency::from(110_000_000_000), + TaoBalance::from(130_000_000_000_u64), + AlphaBalance::from(110_000_000_000_u64), ); mock::register_ok_neuron(netuid, hotkey, coldkey, 0); pallet_subtensor::Pallet::::add_balance_to_coldkey_account( &coldkey, - stake_amount_raw + 1_000_000_000, + TaoBalance::from(stake_amount_raw + 1_000_000_000), ); assert_ok!(pallet_subtensor::Pallet::::add_stake( @@ -111,7 +112,7 @@ fn remove_stake_full_limit_success_with_limit_price() { let mut env = MockEnv::new( FunctionId::RemoveStakeFullLimitV1, coldkey, - (hotkey, netuid, Option::::None).encode(), + (hotkey, netuid, Option::::None).encode(), ) .with_expected_weight(expected_weight); @@ -140,20 +141,20 @@ fn swap_stake_limit_with_tight_price_returns_slippage_error() { let coldkey = U256::from(5701); let hotkey = U256::from(5702); - let stake_alpha = AlphaCurrency::from(150_000_000_000u64); + let stake_alpha = AlphaBalance::from(150_000_000_000u64); let netuid_a = mock::add_dynamic_network(&owner_hotkey_a, &owner_coldkey_a); let netuid_b = mock::add_dynamic_network(&owner_hotkey_b, &owner_coldkey_b); mock::setup_reserves( netuid_a, - TaoCurrency::from(150_000_000_000), - AlphaCurrency::from(110_000_000_000), + TaoBalance::from(150_000_000_000_u64), + AlphaBalance::from(110_000_000_000_u64), ); mock::setup_reserves( netuid_b, - TaoCurrency::from(120_000_000_000), - AlphaCurrency::from(90_000_000_000), + TaoBalance::from(120_000_000_000_u64), + AlphaBalance::from(90_000_000_000_u64), ); mock::register_ok_neuron(netuid_a, hotkey, coldkey, 0); @@ -177,8 +178,8 @@ fn swap_stake_limit_with_tight_price_returns_slippage_error() { &hotkey, &coldkey, netuid_b, ); - let alpha_to_swap: AlphaCurrency = (alpha_origin_before.to_u64() / 8).into(); - let limit_price: TaoCurrency = 100u64.into(); + let alpha_to_swap: AlphaBalance = (alpha_origin_before.to_u64() / 8).into(); + let limit_price: TaoBalance = 100u64.into(); let expected_weight = Weight::from_parts(411_500_000, 0) .saturating_add(::DbWeight::get().reads(35)) @@ -221,15 +222,15 @@ fn remove_stake_limit_success_respects_price_limit() { let netuid = mock::add_dynamic_network(&owner_hotkey, &owner_coldkey); mock::setup_reserves( netuid, - TaoCurrency::from(120_000_000_000), - AlphaCurrency::from(100_000_000_000), + TaoBalance::from(120_000_000_000_u64), + AlphaBalance::from(100_000_000_000_u64), ); mock::register_ok_neuron(netuid, hotkey, coldkey, 0); pallet_subtensor::Pallet::::add_balance_to_coldkey_account( &coldkey, - stake_amount_raw + 1_000_000_000, + TaoBalance::from(stake_amount_raw + 1_000_000_000), ); assert_ok!(pallet_subtensor::Pallet::::add_stake( @@ -251,9 +252,9 @@ fn remove_stake_limit_success_respects_price_limit() { netuid.into(), ); let limit_price_value = (current_price.to_num::() * 990_000_000f64).round() as u64; - let limit_price: TaoCurrency = limit_price_value.into(); + let limit_price: TaoBalance = limit_price_value.into(); - let alpha_to_unstake: AlphaCurrency = (alpha_before.to_u64() / 2).into(); + let alpha_to_unstake: AlphaBalance = (alpha_before.to_u64() / 2).into(); let expected_weight = Weight::from_parts(377_400_000, 0) .saturating_add(::DbWeight::get().reads(28)) @@ -291,21 +292,21 @@ fn add_stake_limit_success_executes_within_price_guard() { let coldkey = U256::from(5501); let hotkey = U256::from(5502); let amount_raw: u64 = 900_000_000_000; - let limit_price: TaoCurrency = 24_000_000_000u64.into(); + let limit_price: TaoBalance = 24_000_000_000u64.into(); let netuid = mock::add_dynamic_network(&owner_hotkey, &owner_coldkey); mock::setup_reserves( netuid, - TaoCurrency::from(150_000_000_000), - AlphaCurrency::from(100_000_000_000), + TaoBalance::from(150_000_000_000_u64), + AlphaBalance::from(100_000_000_000_u64), ); mock::register_ok_neuron(netuid, hotkey, coldkey, 0); pallet_subtensor::Pallet::::add_balance_to_coldkey_account( &coldkey, - amount_raw + 1_000_000_000, + (amount_raw + 1_000_000_000).into(), ); let stake_before = @@ -324,7 +325,7 @@ fn add_stake_limit_success_executes_within_price_guard() { ( hotkey, netuid, - TaoCurrency::from(amount_raw), + TaoBalance::from(amount_raw), limit_price, true, ) @@ -343,7 +344,7 @@ fn add_stake_limit_success_executes_within_price_guard() { let balance_after = pallet_subtensor::Pallet::::get_coldkey_balance(&coldkey); assert!(stake_after > stake_before); - assert!(stake_after > AlphaCurrency::ZERO); + assert!(stake_after > AlphaBalance::ZERO); assert!(balance_after < balance_before); }); } @@ -367,12 +368,12 @@ fn swap_stake_success_moves_between_subnets() { mock::setup_reserves( netuid_a, stake_amount_raw.saturating_mul(18).into(), - AlphaCurrency::from(stake_amount_raw.saturating_mul(30)), + AlphaBalance::from(stake_amount_raw.saturating_mul(30)), ); mock::setup_reserves( netuid_b, stake_amount_raw.saturating_mul(20).into(), - AlphaCurrency::from(stake_amount_raw.saturating_mul(28)), + AlphaBalance::from(stake_amount_raw.saturating_mul(28)), ); mock::register_ok_neuron(netuid_a, hotkey, coldkey, 0); @@ -380,7 +381,7 @@ fn swap_stake_success_moves_between_subnets() { pallet_subtensor::Pallet::::add_balance_to_coldkey_account( &coldkey, - stake_amount_raw + 1_000_000_000, + (stake_amount_raw + 1_000_000_000).into(), ); assert_ok!(pallet_subtensor::Pallet::::add_stake( @@ -400,7 +401,7 @@ fn swap_stake_success_moves_between_subnets() { pallet_subtensor::Pallet::::get_stake_for_hotkey_and_coldkey_on_subnet( &hotkey, &coldkey, netuid_b, ); - let alpha_to_swap: AlphaCurrency = (alpha_origin_before.to_u64() / 3).into(); + let alpha_to_swap: AlphaBalance = (alpha_origin_before.to_u64() / 3).into(); let expected_weight = Weight::from_parts(351_300_000, 0) .saturating_add(::DbWeight::get().reads(35)) @@ -450,14 +451,14 @@ fn transfer_stake_success_moves_between_coldkeys() { mock::setup_reserves( netuid, stake_amount_raw.saturating_mul(15).into(), - AlphaCurrency::from(stake_amount_raw.saturating_mul(25)), + AlphaBalance::from(stake_amount_raw.saturating_mul(25)), ); mock::register_ok_neuron(netuid, hotkey, origin_coldkey, 0); pallet_subtensor::Pallet::::add_balance_to_coldkey_account( &origin_coldkey, - stake_amount_raw + 1_000_000_000, + (stake_amount_raw + 1_000_000_000).into(), ); assert_ok!(pallet_subtensor::Pallet::::add_stake( @@ -475,7 +476,7 @@ fn transfer_stake_success_moves_between_coldkeys() { &origin_coldkey, netuid, ); - let alpha_to_transfer: AlphaCurrency = (alpha_before.to_u64() / 3).into(); + let alpha_to_transfer: AlphaBalance = (alpha_before.to_u64() / 3).into(); let expected_weight = Weight::from_parts(160_300_000, 0) .saturating_add(::DbWeight::get().reads(13)) @@ -533,7 +534,7 @@ fn move_stake_success_moves_alpha_between_hotkeys() { mock::setup_reserves( netuid, stake_amount_raw.saturating_mul(15).into(), - AlphaCurrency::from(stake_amount_raw.saturating_mul(25)), + AlphaBalance::from(stake_amount_raw.saturating_mul(25)), ); mock::register_ok_neuron(netuid, origin_hotkey, coldkey, 0); @@ -541,7 +542,7 @@ fn move_stake_success_moves_alpha_between_hotkeys() { pallet_subtensor::Pallet::::add_balance_to_coldkey_account( &coldkey, - stake_amount_raw + 1_000_000_000, + (stake_amount_raw + 1_000_000_000).into(), ); assert_ok!(pallet_subtensor::Pallet::::add_stake( @@ -559,7 +560,7 @@ fn move_stake_success_moves_alpha_between_hotkeys() { &coldkey, netuid, ); - let alpha_to_move: AlphaCurrency = (alpha_before.to_u64() / 2).into(); + let alpha_to_move: AlphaBalance = (alpha_before.to_u64() / 2).into(); let expected_weight = Weight::from_parts(164_300_000, 0) .saturating_add(::DbWeight::get().reads(15)) @@ -615,13 +616,13 @@ fn unstake_all_alpha_success_moves_stake_to_root() { mock::setup_reserves( netuid, stake_amount_raw.saturating_mul(20).into(), - AlphaCurrency::from(stake_amount_raw.saturating_mul(30)), + AlphaBalance::from(stake_amount_raw.saturating_mul(30)), ); mock::register_ok_neuron(netuid, hotkey, coldkey, 0); pallet_subtensor::Pallet::::add_balance_to_coldkey_account( &coldkey, - stake_amount_raw + 1_000_000_000, + (stake_amount_raw + 1_000_000_000).into(), ); assert_ok!(pallet_subtensor::Pallet::::add_stake( @@ -648,7 +649,7 @@ fn unstake_all_alpha_success_moves_stake_to_root() { pallet_subtensor::Pallet::::get_stake_for_hotkey_and_coldkey_on_subnet( &hotkey, &coldkey, netuid, ); - assert!(subnet_alpha <= AlphaCurrency::from(1_000)); + assert!(subnet_alpha <= AlphaBalance::from(1_000)); let root_alpha = pallet_subtensor::Pallet::::get_stake_for_hotkey_and_coldkey_on_subnet( @@ -656,7 +657,7 @@ fn unstake_all_alpha_success_moves_stake_to_root() { &coldkey, NetUid::ROOT, ); - assert!(root_alpha > AlphaCurrency::ZERO); + assert!(root_alpha > AlphaBalance::ZERO); }); } @@ -668,7 +669,7 @@ fn add_proxy_success_creates_proxy_relationship() { pallet_subtensor::Pallet::::add_balance_to_coldkey_account( &delegator, - 1_000_000_000, + 1_000_000_000.into(), ); assert_eq!( @@ -706,7 +707,7 @@ fn remove_proxy_success_removes_proxy_relationship() { pallet_subtensor::Pallet::::add_balance_to_coldkey_account( &delegator, - 1_000_000_000, + 1_000_000_000.into(), ); let mut add_env = MockEnv::new(FunctionId::AddProxyV1, delegator, delegate.encode()); @@ -831,18 +832,19 @@ fn add_stake_success_updates_stake_and_returns_success_code() { let hotkey = U256::from(202); let min_stake = DefaultMinStake::::get(); let amount_raw = min_stake.to_u64().saturating_mul(10); - let amount: TaoCurrency = amount_raw.into(); + let amount: TaoBalance = amount_raw.into(); let netuid = mock::add_dynamic_network(&owner_hotkey, &owner_coldkey); mock::setup_reserves( netuid, (amount_raw * 1_000_000).into(), - AlphaCurrency::from(amount_raw * 10_000_000), + AlphaBalance::from(amount_raw * 10_000_000), ); mock::register_ok_neuron(netuid, hotkey, coldkey, 0); pallet_subtensor::Pallet::::add_balance_to_coldkey_account( - &coldkey, amount_raw, + &coldkey, + amount_raw.into(), ); assert!( @@ -867,7 +869,7 @@ fn add_stake_success_updates_stake_and_returns_success_code() { let total_stake = pallet_subtensor::Pallet::::get_total_stake_for_hotkey(&hotkey); - assert!(total_stake > TaoCurrency::ZERO); + assert!(total_stake > TaoBalance::ZERO); }); } @@ -882,7 +884,7 @@ fn remove_stake_with_no_stake_returns_amount_too_low() { mock::register_ok_neuron(netuid, hotkey, coldkey, 0); let min_stake = DefaultMinStake::::get(); - let amount: AlphaCurrency = AlphaCurrency::from(min_stake.to_u64()); + let amount: AlphaBalance = AlphaBalance::from(min_stake.to_u64()); let expected_weight = Weight::from_parts(196_800_000, 0) .saturating_add(::DbWeight::get().reads(19)) @@ -924,13 +926,13 @@ fn unstake_all_success_unstakes_balance() { mock::setup_reserves( netuid, stake_amount_raw.saturating_mul(10).into(), - AlphaCurrency::from(stake_amount_raw.saturating_mul(20)), + AlphaBalance::from(stake_amount_raw.saturating_mul(20)), ); mock::register_ok_neuron(netuid, hotkey, coldkey, 0); pallet_subtensor::Pallet::::add_balance_to_coldkey_account( &coldkey, - stake_amount_raw + 1_000_000_000, + (stake_amount_raw + 1_000_000_000).into(), ); assert_ok!(pallet_subtensor::Pallet::::add_stake( @@ -959,7 +961,7 @@ fn unstake_all_success_unstakes_balance() { pallet_subtensor::Pallet::::get_stake_for_hotkey_and_coldkey_on_subnet( &hotkey, &coldkey, netuid, ); - assert!(remaining_alpha <= AlphaCurrency::from(1_000)); + assert!(remaining_alpha <= AlphaBalance::from(1_000)); let post_balance = pallet_subtensor::Pallet::::get_coldkey_balance(&coldkey); assert!(post_balance > pre_balance); @@ -976,8 +978,8 @@ fn get_alpha_price_returns_encoded_price() { let netuid = mock::add_dynamic_network(&owner_hotkey, &owner_coldkey); // Set up reserves to establish a price - let tao_reserve = TaoCurrency::from(150_000_000_000u64); - let alpha_reserve = AlphaCurrency::from(100_000_000_000u64); + let tao_reserve = TaoBalance::from(150_000_000_000u64); + let alpha_reserve = AlphaBalance::from(100_000_000_000u64); mock::setup_reserves(netuid, tao_reserve, alpha_reserve); // Get expected price from swap handler diff --git a/common/Cargo.toml b/common/Cargo.toml index 732b0cc5b1..9fa9bd1856 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -14,10 +14,13 @@ targets = ["x86_64-unknown-linux-gnu"] codec = { workspace = true, features = ["derive"] } environmental.workspace = true frame-support.workspace = true +num-traits = { workspace = true, features = ["libm"] } scale-info.workspace = true serde.workspace = true +sp-arithmetic.workspace = true sp-core.workspace = true sp-runtime.workspace = true +sp-rpc = { workspace = true, optional = true } substrate-fixed.workspace = true subtensor-macros.workspace = true runtime-common.workspace = true @@ -30,14 +33,22 @@ workspace = true default = ["std"] approx = ["dep:approx"] fast-runtime = [] +runtime-benchmarks = [ + "frame-support/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", + "runtime-common/runtime-benchmarks", +] std = [ "codec/std", "environmental/std", "frame-support/std", + "num-traits/std", "scale-info/std", "serde/std", + "sp-arithmetic/std", "sp-core/std", "sp-runtime/std", + "sp-rpc", "substrate-fixed/std", - "runtime-common/std" + "runtime-common/std", ] diff --git a/common/src/currency.rs b/common/src/currency.rs index 48826b1933..8a39086d37 100644 --- a/common/src/currency.rs +++ b/common/src/currency.rs @@ -1,5 +1,8 @@ use core::fmt::{self, Display, Formatter}; -use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign}; +use core::ops::{ + Add, AddAssign, BitAnd, BitOr, BitXor, Div, DivAssign, Mul, MulAssign, Not, Rem, RemAssign, + Shl, Shr, Sub, SubAssign, +}; #[cfg(feature = "approx")] use approx::AbsDiffEq; @@ -12,7 +15,20 @@ use serde::{Deserialize, Serialize}; use substrate_fixed::traits::{Fixed, ToFixed}; use subtensor_macros::freeze_struct; -#[freeze_struct("40205476b6d995b2")] +pub use num_traits::{ + CheckedShl, CheckedShr, FromPrimitive, Num, NumCast, NumOps, PrimInt, Saturating, Signed, + ToPrimitive, Unsigned, checked_pow, +}; +use sp_arithmetic::per_things::Rounding; +use sp_arithmetic::rational::MultiplyRational; +use sp_arithmetic::traits::{ + Bounded, CheckedAdd, CheckedDiv, CheckedMul, CheckedNeg, CheckedRem, CheckedSub, One, Zero, +}; + +#[cfg(feature = "std")] +use sp_rpc::number::NumberOrHex; + +#[freeze_struct("3ad2c79c0e81406d")] #[repr(transparent)] #[derive( Deserialize, @@ -31,9 +47,9 @@ use subtensor_macros::freeze_struct; PartialOrd, RuntimeDebug, )] -pub struct AlphaCurrency(u64); +pub struct AlphaBalance(u64); -#[freeze_struct("4d1bcb31c40c2594")] +#[freeze_struct("5f0d6c02f3ac2c1")] #[repr(transparent)] #[derive( Deserialize, @@ -52,7 +68,7 @@ pub struct AlphaCurrency(u64); PartialOrd, RuntimeDebug, )] -pub struct TaoCurrency(u64); +pub struct TaoBalance(u64); // implements traits required by the Currency trait (ToFixed + Into + From) and CompactAs, // TypeInfo and Display. It expects a wrapper structure for u64 (CurrencyT(u64)). @@ -107,6 +123,25 @@ macro_rules! impl_currency_reqs { } } + impl From for $currency_type { + fn from(value: u32) -> Self { + Self(value as u64) + } + } + + // TODO: This is a lossy conversion, maybe it should use try_from + impl From for $currency_type { + fn from(value: i32) -> Self { + Self(value.unsigned_abs().into()) + } + } + + impl From for $currency_type { + fn from(value: u8) -> Self { + Self(value as u64) + } + } + impl ToFixed for $currency_type { fn to_fixed(self) -> F { self.0.to_fixed() @@ -127,6 +162,21 @@ macro_rules! impl_currency_reqs { self.0.overflowing_to_fixed() } } + + impl Zero for $currency_type { + fn zero() -> Self { + Self(0) + } + fn is_zero(&self) -> bool { + Into::::into(*self) == 0 + } + } + + impl One for $currency_type { + fn one() -> Self { + Self(1) + } + } }; } @@ -176,6 +226,17 @@ macro_rules! impl_arithmetic_operators { } } + impl Rem for $currency_type { + type Output = Self; + + #[allow(clippy::arithmetic_side_effects)] + fn rem(self, rhs: Self) -> Self::Output { + let lhs_u64: u64 = self.into(); + let rhs_u64: u64 = rhs.into(); + (lhs_u64 % rhs_u64).into() + } + } + impl AddAssign for $currency_type { #[allow(clippy::arithmetic_side_effects)] fn add_assign(&mut self, rhs: Self) { @@ -217,26 +278,42 @@ macro_rules! impl_approx { } fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool { - u64::abs_diff_eq(&u64::from(*self), &u64::from(*other), epsilon.into()) + u64::abs_diff_eq( + &Into::::into(*self), + &Into::::into(*other), + epsilon.into(), + ) } fn abs_diff_ne(&self, other: &Self, epsilon: Self::Epsilon) -> bool { - u64::abs_diff_ne(&u64::from(*self), &u64::from(*other), epsilon.into()) + u64::abs_diff_ne( + &Into::::into(*self), + &Into::::into(*other), + epsilon.into(), + ) } } }; } -pub trait Currency: - ToFixed + Into + From + Clone + Copy + Eq + Ord + PartialEq + PartialOrd + Display +pub trait Token: + ToFixed + + Into + + From + + Clone + + Copy + + Eq + + NumOps + + Ord + + PartialEq + + PartialOrd + + Display + + Zero + + One { const MAX: Self; const ZERO: Self; - fn is_zero(&self) -> bool { - Into::::into(*self) == 0 - } - fn to_u64(&self) -> u64 { (*self).into() } @@ -259,20 +336,380 @@ pub trait Currency: } } -impl_arithmetic_operators!(AlphaCurrency); -impl_approx!(AlphaCurrency); -impl_currency_reqs!(AlphaCurrency); +impl_arithmetic_operators!(AlphaBalance); +impl_approx!(AlphaBalance); +impl_currency_reqs!(AlphaBalance); -impl_arithmetic_operators!(TaoCurrency); -impl_approx!(TaoCurrency); -impl_currency_reqs!(TaoCurrency); +impl_arithmetic_operators!(TaoBalance); +impl_approx!(TaoBalance); +impl_currency_reqs!(TaoBalance); -impl Currency for AlphaCurrency { +impl Token for AlphaBalance { const MAX: Self = Self(u64::MAX); const ZERO: Self = Self(0); } -impl Currency for TaoCurrency { +impl Token for TaoBalance { const MAX: Self = Self(u64::MAX); const ZERO: Self = Self(0); } + +// // Required explicitly by the bound +// impl From for TaoBalance { +// fn from(x: u32) -> Self { Self(x as u64) } +// } + +impl Bounded for TaoBalance { + fn min_value() -> Self { + Self(u64::MIN) + } + fn max_value() -> Self { + Self(u64::MAX) + } +} + +impl Saturating for TaoBalance { + fn saturating_add(self, rhs: Self) -> Self { + Self(self.0.saturating_add(rhs.0)) + } + fn saturating_sub(self, rhs: Self) -> Self { + Self(self.0.saturating_sub(rhs.0)) + } +} + +////////////////// + +impl CheckedNeg for TaoBalance { + fn checked_neg(&self) -> Option { + Some(*self) + } +} + +impl CheckedRem for TaoBalance { + fn checked_rem(&self, rhs: &Self) -> Option { + let lhs_u64: u64 = (*self).into(); + let rhs_u64: u64 = (*rhs).into(); + lhs_u64.checked_rem(rhs_u64).map(Into::into) + } +} + +impl Shl for TaoBalance { + type Output = Self; + + #[allow(clippy::arithmetic_side_effects)] + fn shl(self, rhs: u32) -> Self::Output { + let lhs: u64 = self.into(); + // Define semantics: saturate to 0 on oversized shift (instead of panic). + // Alternatively, you could debug_assert! and return 0 in release. + let shifted = lhs.checked_shl(rhs).unwrap_or(0); + shifted.into() + } +} + +impl Shr for TaoBalance { + type Output = Self; + + #[allow(clippy::arithmetic_side_effects)] + fn shr(self, rhs: u32) -> Self::Output { + let lhs: u64 = self.into(); + let shifted = lhs.checked_shr(rhs).unwrap_or(0); + shifted.into() + } +} + +impl Shl for TaoBalance { + type Output = Self; + + #[allow(clippy::arithmetic_side_effects)] + fn shl(self, rhs: usize) -> Self::Output { + let lhs: u64 = self.into(); + // Define semantics: saturate to 0 on oversized shift (instead of panic). + // Alternatively, you could debug_assert! and return 0 in release. + let shifted = lhs.checked_shl(rhs as u32).unwrap_or(0); + shifted.into() + } +} + +impl Shr for TaoBalance { + type Output = Self; + + #[allow(clippy::arithmetic_side_effects)] + fn shr(self, rhs: usize) -> Self::Output { + let lhs: u64 = self.into(); + let shifted = lhs.checked_shr(rhs as u32).unwrap_or(0); + shifted.into() + } +} + +impl Not for TaoBalance { + type Output = Self; + fn not(self) -> Self { + Self(!self.0) + } +} +impl BitAnd for TaoBalance { + type Output = Self; + fn bitand(self, rhs: Self) -> Self { + Self(self.0 & rhs.0) + } +} +impl BitOr for TaoBalance { + type Output = Self; + fn bitor(self, rhs: Self) -> Self { + Self(self.0 | rhs.0) + } +} + +impl BitXor for TaoBalance { + type Output = Self; + fn bitxor(self, rhs: Self) -> Self { + Self(self.0 ^ rhs.0) + } +} + +impl CheckedAdd for TaoBalance { + fn checked_add(&self, rhs: &Self) -> Option { + self.0.checked_add(rhs.0).map(Self) + } +} +impl CheckedSub for TaoBalance { + fn checked_sub(&self, rhs: &Self) -> Option { + self.0.checked_sub(rhs.0).map(Self) + } +} + +impl CheckedMul for TaoBalance { + fn checked_mul(&self, rhs: &Self) -> Option { + self.0.checked_mul(rhs.0).map(Self) + } +} + +impl CheckedDiv for TaoBalance { + fn checked_div(&self, rhs: &Self) -> Option { + self.0.checked_div(rhs.0).map(Self) + } +} + +#[allow(clippy::arithmetic_side_effects)] +impl CheckedShl for TaoBalance { + fn checked_shl(&self, rhs: u32) -> Option { + // Validate first (so we can return None), then use the operator as requested. + let lhs: u64 = (*self).into(); + lhs.checked_shl(rhs)?; + Some((*self) << rhs) + } +} + +#[allow(clippy::arithmetic_side_effects)] +impl CheckedShr for TaoBalance { + fn checked_shr(&self, rhs: u32) -> Option { + let lhs: u64 = (*self).into(); + lhs.checked_shr(rhs)?; + Some((*self) >> rhs) + } +} + +impl RemAssign for TaoBalance { + #[allow(clippy::arithmetic_side_effects)] + fn rem_assign(&mut self, rhs: Self) { + *self = *self % rhs; + } +} + +impl PrimInt for TaoBalance { + fn count_ones(self) -> u32 { + self.0.count_ones() + } + fn count_zeros(self) -> u32 { + self.0.count_zeros() + } + fn leading_zeros(self) -> u32 { + self.0.leading_zeros() + } + fn trailing_zeros(self) -> u32 { + self.0.trailing_zeros() + } + fn rotate_left(self, n: u32) -> Self { + Self(self.0.rotate_left(n)) + } + fn rotate_right(self, n: u32) -> Self { + Self(self.0.rotate_right(n)) + } + fn signed_shl(self, n: u32) -> Self { + // For unsigned integers, num_traits defines signed_shl/shr as normal shifts. + Self(self.0.wrapping_shl(n)) + } + fn signed_shr(self, n: u32) -> Self { + Self(self.0.wrapping_shr(n)) + } + fn unsigned_shl(self, n: u32) -> Self { + Self(self.0.wrapping_shl(n)) + } + fn unsigned_shr(self, n: u32) -> Self { + Self(self.0.wrapping_shr(n)) + } + fn swap_bytes(self) -> Self { + Self(self.0.swap_bytes()) + } + fn from_be(x: Self) -> Self { + Self(u64::from_be(x.0)) + } + fn from_le(x: Self) -> Self { + Self(u64::from_le(x.0)) + } + fn to_be(self) -> Self { + Self(self.0.to_be()) + } + fn to_le(self) -> Self { + Self(self.0.to_le()) + } + fn pow(self, exp: u32) -> Self { + Self(self.0.pow(exp)) + } +} + +impl Unsigned for TaoBalance {} + +impl Num for TaoBalance { + type FromStrRadixErr = ::FromStrRadixErr; + + fn from_str_radix(s: &str, radix: u32) -> Result { + u64::from_str_radix(s, radix).map(Self) + } +} + +impl NumCast for TaoBalance { + fn from(n: T) -> Option { + n.to_u64().map(Self) + } +} + +impl ToPrimitive for TaoBalance { + fn to_i64(&self) -> Option { + self.0.to_i64() + } + fn to_u64(&self) -> Option { + Some(self.0) + } + fn to_u128(&self) -> Option { + Some(self.0 as u128) + } + fn to_usize(&self) -> Option { + self.0.to_usize() + } +} + +impl FromPrimitive for TaoBalance { + fn from_u64(n: u64) -> Option { + Some(Self(n)) + } + fn from_u128(n: u128) -> Option { + if n <= u64::MAX as u128 { + Some(Self(n as u64)) + } else { + None + } + } + fn from_usize(n: usize) -> Option { + Some(Self(n as u64)) + } + fn from_i64(n: i64) -> Option { + if n >= 0 { Some(Self(n as u64)) } else { None } + } +} + +impl MultiplyRational for TaoBalance { + fn multiply_rational(self, n: Self, d: Self, r: Rounding) -> Option { + let a: u64 = self.into(); + let n: u64 = n.into(); + let d: u64 = d.into(); + a.multiply_rational(n, d, r).map(Into::into) + } +} + +impl From for TaoBalance { + fn from(x: u16) -> Self { + TaoBalance(x as u64) + } +} +impl From for TaoBalance { + fn from(n: u128) -> Self { + if n <= u64::MAX as u128 { + Self(n as u64) + } else { + Self(u64::MAX) + } + } +} +impl From for TaoBalance { + fn from(n: usize) -> Self { + Self(n as u64) + } +} +impl From for TaoBalance { + fn from(n: sp_core::U256) -> Self { + if let Ok(n_u64) = n.try_into() { + Self(n_u64) + } else { + Self(u64::MAX) + } + } +} + +#[allow(clippy::from_over_into)] +impl Into for TaoBalance { + fn into(self) -> usize { + self.0 as usize + } +} + +#[allow(clippy::from_over_into)] +impl Into for TaoBalance { + fn into(self) -> u128 { + self.0 as u128 + } +} + +#[allow(clippy::from_over_into)] +impl Into for TaoBalance { + fn into(self) -> u32 { + self.0 as u32 + } +} + +#[allow(clippy::from_over_into)] +impl Into for TaoBalance { + fn into(self) -> u16 { + self.0 as u16 + } +} + +#[allow(clippy::from_over_into)] +impl Into for TaoBalance { + fn into(self) -> u8 { + self.0 as u8 + } +} + +#[allow(clippy::from_over_into)] +impl Into for TaoBalance { + fn into(self) -> sp_core::U256 { + sp_core::U256::from(self.0) + } +} + +#[allow(clippy::from_over_into)] +#[cfg(feature = "std")] +impl Into for TaoBalance { + fn into(self) -> NumberOrHex { + NumberOrHex::Number(self.0) + } +} + +pub struct ConstTao; + +impl Get for ConstTao { + fn get() -> TaoBalance { + TaoBalance::new(N) + } +} diff --git a/common/src/lib.rs b/common/src/lib.rs index a63b92779a..a143c27824 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -16,12 +16,14 @@ use subtensor_macros::freeze_struct; pub use currency::*; pub use evm_context::*; +pub use transaction_error::*; mod currency; mod evm_context; +mod transaction_error; /// Balance of an account. -pub type Balance = u64; +pub type Balance = TaoBalance; /// An index to a block. pub type BlockNumber = u32; @@ -42,7 +44,8 @@ pub type Hash = sp_core::H256; pub type Nonce = u32; /// Transfers below SMALL_TRANSFER_LIMIT are considered small transfers -pub const SMALL_TRANSFER_LIMIT: Balance = 500_000_000; // 0.5 TAO +pub const SMALL_TRANSFER_LIMIT: Balance = TaoBalance::new(500_000_000); // 0.5 TAO +pub const SMALL_ALPHA_TRANSFER_LIMIT: AlphaBalance = AlphaBalance::new(500_000_000); // 0.5 Alpha #[freeze_struct("c972489bff40ae48")] #[repr(transparent)] @@ -234,32 +237,29 @@ pub trait SubnetInfo { fn hotkey_of_uid(netuid: NetUid, uid: u16) -> Option; } -pub trait CurrencyReserve { +pub trait TokenReserve { fn reserve(netuid: NetUid) -> C; fn increase_provided(netuid: NetUid, amount: C); fn decrease_provided(netuid: NetUid, amount: C); } pub trait BalanceOps { - fn tao_balance(account_id: &AccountId) -> TaoCurrency; - fn alpha_balance(netuid: NetUid, coldkey: &AccountId, hotkey: &AccountId) -> AlphaCurrency; - fn increase_balance(coldkey: &AccountId, tao: TaoCurrency); - fn decrease_balance( - coldkey: &AccountId, - tao: TaoCurrency, - ) -> Result; + fn tao_balance(account_id: &AccountId) -> TaoBalance; + fn alpha_balance(netuid: NetUid, coldkey: &AccountId, hotkey: &AccountId) -> AlphaBalance; + fn increase_balance(coldkey: &AccountId, tao: TaoBalance); + fn decrease_balance(coldkey: &AccountId, tao: TaoBalance) -> Result; fn increase_stake( coldkey: &AccountId, hotkey: &AccountId, netuid: NetUid, - alpha: AlphaCurrency, + alpha: AlphaBalance, ) -> Result<(), DispatchError>; fn decrease_stake( coldkey: &AccountId, hotkey: &AccountId, netuid: NetUid, - alpha: AlphaCurrency, - ) -> Result; + alpha: AlphaBalance, + ) -> Result; } /// Allows to query the current block author @@ -323,19 +323,19 @@ impl From for MechId { impl From for u16 { fn from(val: MechId) -> Self { - u16::from(val.0) + Into::::into(val.0) } } impl From for u64 { fn from(val: MechId) -> Self { - u64::from(val.0) + Into::::into(val.0) } } impl From for u8 { fn from(val: MechId) -> Self { - u8::from(val.0) + Into::::into(val.0) } } diff --git a/common/src/transaction_error.rs b/common/src/transaction_error.rs new file mode 100644 index 0000000000..de98cdf5f4 --- /dev/null +++ b/common/src/transaction_error.rs @@ -0,0 +1,73 @@ +use sp_runtime::transaction_validity::{InvalidTransaction, TransactionValidityError}; + +#[derive(Debug, PartialEq)] +pub enum CustomTransactionError { + /// Deprecated: coldkey swap now uses announcements and check moved to DispatchGuard + #[deprecated] + ColdkeyInSwapSchedule, + StakeAmountTooLow, + BalanceTooLow, + SubnetNotExists, + HotkeyAccountDoesntExist, + NotEnoughStakeToWithdraw, + RateLimitExceeded, + InsufficientLiquidity, + SlippageTooHigh, + TransferDisallowed, + HotKeyNotRegisteredInNetwork, + InvalidIpAddress, + ServingRateLimitExceeded, + InvalidPort, + BadRequest, + ZeroMaxAmount, + InvalidRevealRound, + CommitNotFound, + CommitBlockNotInRevealRange, + InputLengthsUnequal, + UidNotFound, + EvmKeyAssociateRateLimitExceeded, + ColdkeySwapDisputed, + InvalidRealAccount, + FailedShieldedTxParsing, + InvalidShieldedTxPubKeyHash, +} + +impl From for u8 { + fn from(variant: CustomTransactionError) -> u8 { + match variant { + #[allow(deprecated)] + CustomTransactionError::ColdkeyInSwapSchedule => 0, + CustomTransactionError::StakeAmountTooLow => 1, + CustomTransactionError::BalanceTooLow => 2, + CustomTransactionError::SubnetNotExists => 3, + CustomTransactionError::HotkeyAccountDoesntExist => 4, + CustomTransactionError::NotEnoughStakeToWithdraw => 5, + CustomTransactionError::RateLimitExceeded => 6, + CustomTransactionError::InsufficientLiquidity => 7, + CustomTransactionError::SlippageTooHigh => 8, + CustomTransactionError::TransferDisallowed => 9, + CustomTransactionError::HotKeyNotRegisteredInNetwork => 10, + CustomTransactionError::InvalidIpAddress => 11, + CustomTransactionError::ServingRateLimitExceeded => 12, + CustomTransactionError::InvalidPort => 13, + CustomTransactionError::BadRequest => 255, + CustomTransactionError::ZeroMaxAmount => 14, + CustomTransactionError::InvalidRevealRound => 15, + CustomTransactionError::CommitNotFound => 16, + CustomTransactionError::CommitBlockNotInRevealRange => 17, + CustomTransactionError::InputLengthsUnequal => 18, + CustomTransactionError::UidNotFound => 19, + CustomTransactionError::EvmKeyAssociateRateLimitExceeded => 20, + CustomTransactionError::ColdkeySwapDisputed => 21, + CustomTransactionError::InvalidRealAccount => 22, + CustomTransactionError::FailedShieldedTxParsing => 23, + CustomTransactionError::InvalidShieldedTxPubKeyHash => 24, + } + } +} + +impl From for TransactionValidityError { + fn from(variant: CustomTransactionError) -> Self { + TransactionValidityError::Invalid(InvalidTransaction::Custom(variant.into())) + } +} diff --git a/docs/wasm-contracts.md b/docs/wasm-contracts.md index ed6e9ecdd3..d3a6b5637f 100644 --- a/docs/wasm-contracts.md +++ b/docs/wasm-contracts.md @@ -29,17 +29,17 @@ Subtensor provides a custom chain extension that allows smart contracts to inter | Function ID | Name | Description | Parameters | Returns | |------------|------|-------------|------------|---------| | 0 | `get_stake_info_for_hotkey_coldkey_netuid` | Query stake information | `(AccountId, AccountId, NetUid)` | `Option` | -| 1 | `add_stake` | Delegate stake from coldkey to hotkey | `(AccountId, NetUid, TaoCurrency)` | Error code | -| 2 | `remove_stake` | Withdraw stake from hotkey back to coldkey | `(AccountId, NetUid, AlphaCurrency)` | Error code | +| 1 | `add_stake` | Delegate stake from coldkey to hotkey | `(AccountId, NetUid, TaoBalance)` | Error code | +| 2 | `remove_stake` | Withdraw stake from hotkey back to coldkey | `(AccountId, NetUid, AlphaBalance)` | Error code | | 3 | `unstake_all` | Unstake all TAO from a hotkey | `(AccountId)` | Error code | | 4 | `unstake_all_alpha` | Unstake all Alpha from a hotkey | `(AccountId)` | Error code | -| 5 | `move_stake` | Move stake between hotkeys | `(AccountId, AccountId, NetUid, NetUid, AlphaCurrency)` | Error code | -| 6 | `transfer_stake` | Transfer stake between coldkeys | `(AccountId, AccountId, NetUid, NetUid, AlphaCurrency)` | Error code | -| 7 | `swap_stake` | Swap stake allocations between subnets | `(AccountId, NetUid, NetUid, AlphaCurrency)` | Error code | -| 8 | `add_stake_limit` | Delegate stake with a price limit | `(AccountId, NetUid, TaoCurrency, TaoCurrency, bool)` | Error code | -| 9 | `remove_stake_limit` | Withdraw stake with a price limit | `(AccountId, NetUid, AlphaCurrency, TaoCurrency, bool)` | Error code | -| 10 | `swap_stake_limit` | Swap stake between subnets with price limit | `(AccountId, NetUid, NetUid, AlphaCurrency, TaoCurrency, bool)` | Error code | -| 11 | `remove_stake_full_limit` | Fully withdraw stake with optional price limit | `(AccountId, NetUid, Option)` | Error code | +| 5 | `move_stake` | Move stake between hotkeys | `(AccountId, AccountId, NetUid, NetUid, AlphaBalance)` | Error code | +| 6 | `transfer_stake` | Transfer stake between coldkeys | `(AccountId, AccountId, NetUid, NetUid, AlphaBalance)` | Error code | +| 7 | `swap_stake` | Swap stake allocations between subnets | `(AccountId, NetUid, NetUid, AlphaBalance)` | Error code | +| 8 | `add_stake_limit` | Delegate stake with a price limit | `(AccountId, NetUid, TaoBalance, TaoBalance, bool)` | Error code | +| 9 | `remove_stake_limit` | Withdraw stake with a price limit | `(AccountId, NetUid, AlphaBalance, TaoBalance, bool)` | Error code | +| 10 | `swap_stake_limit` | Swap stake between subnets with price limit | `(AccountId, NetUid, NetUid, AlphaBalance, TaoBalance, bool)` | Error code | +| 11 | `remove_stake_full_limit` | Fully withdraw stake with optional price limit | `(AccountId, NetUid, Option)` | Error code | | 12 | `set_coldkey_auto_stake_hotkey` | Configure automatic stake destination | `(NetUid, AccountId)` | Error code | | 13 | `add_proxy` | Add a staking proxy for the caller | `(AccountId)` | Error code | | 14 | `remove_proxy` | Remove a staking proxy for the caller | `(AccountId)` | Error code | diff --git a/e2e/.gitignore b/e2e/.gitignore new file mode 100644 index 0000000000..8084bdaf01 --- /dev/null +++ b/e2e/.gitignore @@ -0,0 +1,3 @@ +node_modules/ +node-subtensor/ +.papi \ No newline at end of file diff --git a/e2e/.nvmrc b/e2e/.nvmrc new file mode 100644 index 0000000000..cabf43b5dd --- /dev/null +++ b/e2e/.nvmrc @@ -0,0 +1 @@ +24 \ No newline at end of file diff --git a/e2e/.prettierrc b/e2e/.prettierrc new file mode 100644 index 0000000000..90abee2393 --- /dev/null +++ b/e2e/.prettierrc @@ -0,0 +1,6 @@ +{ + "printWidth": 100, + "semi": true, + "singleQuote": false, + "trailingComma": "all" +} diff --git a/e2e/README.md b/e2e/README.md new file mode 100644 index 0000000000..efd79de23f --- /dev/null +++ b/e2e/README.md @@ -0,0 +1,83 @@ +# E2E Tests + +End-to-end tests that run against a local multi-node subtensor network. + +## Quick start + +```bash +cd e2e + +# 1. Set up the development environment (nvm, node, pnpm, jq, yq). +./setup_env.sh + +# 2. Build the node binary and generate polkadot-api type descriptors. +# Installs polkadot-api globally for the CLI and type resolution. +# Re-run this step whenever runtime metadata changes (new pallets, +# modified storage/calls, etc.) to keep descriptors in sync. +./bootstrap_types.sh + +# 3. Install dependencies (requires descriptors from step 2). +pnpm install + +# 4. Run a test suite. +pnpm --filter e2e-shield test # run the shield suite +pnpm --filter e2e- test # run any suite by name +pnpm -r test # run all suites +``` + +## Creating a new test package + +```bash +./bootstrap_package.sh +pnpm install +pnpm --filter e2e- test +``` + +This creates a package with: + +- `package.json` — depends on `e2e-shared` and `polkadot-api` +- `vitest.config.ts` — sequential execution, 120s timeout, alphabetical sequencer +- `setup.ts` — global setup/teardown that spawns a 2-node network +- `tests/00-basic.test.ts` — sample test + +Edit `setup.ts` to configure the number of nodes, extra authorities, and +ports for your suite. Add test-specific dependencies to `package.json`. + +## How it works + +### Network lifecycle + +Each test suite manages its own local network via vitest's `globalSetup`: + +1. **setup()** generates a chain spec, optionally patches it with extra + authorities, spawns validator nodes, waits for peering and finalization, + then writes `NetworkState` to a JSON file under `/tmp/subtensor-e2e/`. +2. **Test files** read the state file in `beforeAll()` to get RPC ports and + connect via polkadot-api. Tests run sequentially (alphabetical by filename), + so later files can build on earlier state changes (e.g. scaling the network). +3. **teardown()** stops all nodes (including extras added mid-suite), cleans + up temp directories and the state file. + +### Shared utilities (`e2e-shared`) + +The `shared/` package provides reusable helpers for all test suites: +spawning and monitoring substrate nodes, generating and patching chain specs, +connecting polkadot-api clients with dev signers, and a custom vitest +sequencer that ensures test files run in alphabetical order. + +### Conventions + +- **File prefixes** — Name test files `00-`, `01-`, `02-` etc. The custom + sequencer sorts alphabetically, so numbering controls execution order. +- **State file** — Each suite writes to `/tmp/subtensor-e2e//`. Tests + can update this file mid-suite (e.g. to register extra nodes). +- **Catalog versions** — To add a new dependency, first pin its version in + `pnpm-workspace.yaml` under `catalog:`, then reference it in your + package's `package.json` with `"catalog:"` as the version. This prevents + version drift across packages. +- **Query at "best"** — Storage queries for values that change every block + (e.g. rotating keys) should use `{ at: "best" }` instead of the default + `"finalized"`, since finalized lags ~2 blocks behind with GRANDPA. +- **Built-in shortcuts** — Substrate dev accounts (`one`, `two`, `alice`, + `bob`, etc.) have their keys auto-injected. Custom authorities need + `insertKeys()` before starting the node. diff --git a/e2e/bootstrap_package.sh b/e2e/bootstrap_package.sh new file mode 100755 index 0000000000..e37dc7f26c --- /dev/null +++ b/e2e/bootstrap_package.sh @@ -0,0 +1,286 @@ +#!/bin/bash +# +# Scaffold a new e2e test package. +# +# Usage: +# ./bootstrap_package.sh +# +# Example: +# ./bootstrap_package.sh staking +# +set -e + +if [ -z "$1" ]; then + echo "Usage: $0 " + exit 1 +fi + +for cmd in jq yq; do + if ! command -v "$cmd" &>/dev/null; then + echo "ERROR: $cmd is required. Run ./setup_env.sh first." + exit 1 + fi +done + +NAME="$1" +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +DIR="$SCRIPT_DIR/$NAME" +WORKSPACE="$SCRIPT_DIR/pnpm-workspace.yaml" + +if [ -d "$DIR" ]; then + echo "ERROR: Directory $DIR already exists" + exit 1 +fi + +echo "==> Creating package e2e-$NAME..." +mkdir -p "$DIR/tests" + +# -- package.json -- +jq -n \ + --arg name "e2e-$NAME" \ + '{ + name: $name, + version: "1.0.0", + type: "module", + scripts: { test: "vitest run" }, + dependencies: { + "e2e-shared": "workspace:*", + "@polkadot-api/descriptors": "file:../.papi/descriptors", + "polkadot-api": "catalog:" + }, + devDependencies: { + "@types/node": "catalog:", + "vitest": "catalog:" + } + }' > "$DIR/package.json" + +# -- tsconfig.json -- +jq -n '{ + compilerOptions: { + target: "ES2022", + module: "ESNext", + moduleResolution: "bundler", + esModuleInterop: true, + strict: true, + skipLibCheck: true, + types: ["node", "vitest/globals"] + } +}' > "$DIR/tsconfig.json" + +# -- vitest.config.ts -- +cat > "$DIR/vitest.config.ts" << 'EOF' +import { defineConfig } from "vitest/config"; +import AlphabeticalSequencer from "e2e-shared/sequencer.js"; + +export default defineConfig({ + test: { + globals: true, + testTimeout: 120_000, + hookTimeout: 300_000, + fileParallelism: false, + globalSetup: "./setup.ts", + include: ["tests/**/*.test.ts"], + sequence: { + sequencer: AlphabeticalSequencer, + }, + }, +}); +EOF + +# -- setup.ts -- +sed "s/__NAME__/$NAME/g" << 'SETUP_EOF' > "$DIR/setup.ts" +import { writeFile, readFile, rm, mkdir } from "node:fs/promises"; +import { + generateChainSpec, + insertKeys, + getGenesisPatch, + addAuthority, +} from "e2e-shared/chainspec.js"; +import { + startNode, + started, + peerCount, + finalizedBlocks, + stop, + log, + type Node, + type NodeOptions, +} from "e2e-shared/node.js"; + +const CHAIN_SPEC_PATH = "/tmp/subtensor-e2e/__NAME__/chain-spec.json"; +const STATE_FILE = "/tmp/subtensor-e2e/__NAME__/nodes.json"; + +export type NetworkState = { + binaryPath: string; + chainSpec: string; + nodes: { + name: string; + rpcPort: number; + port: number; + pid: number; + basePath: string; + }[]; +}; + +const nodes: Node[] = []; + +const BINARY_PATH = process.env.BINARY_PATH || "../../target/release/node-subtensor"; + +// The local chain spec has 2 built-in authorities (One, Two). +// Add extra authorities here if needed. +const EXTRA_AUTHORITY_SEEDS: string[] = []; + +type NodeConfig = Omit & { + keySeed?: string; +}; + +// TODO: Adjust node configs for your test suite. +const NODE_CONFIGS: NodeConfig[] = [ + { name: "one", port: 30333, rpcPort: 9944, basePath: "/tmp/subtensor-e2e/__NAME__/one", validator: true }, + { name: "two", port: 30334, rpcPort: 9945, basePath: "/tmp/subtensor-e2e/__NAME__/two", validator: true }, +]; + +export async function setup() { + log(`Setting up ${NODE_CONFIGS.length}-node network for __NAME__ E2E tests`); + log(`Binary path: ${BINARY_PATH}`); + + await mkdir("/tmp/subtensor-e2e/__NAME__", { recursive: true }); + + await generateChainSpec(BINARY_PATH, CHAIN_SPEC_PATH, (spec) => { + const patch = getGenesisPatch(spec); + for (const seed of EXTRA_AUTHORITY_SEEDS) { + addAuthority(patch, seed); + } + }); + + for (const config of NODE_CONFIGS) { + await rm(config.basePath, { recursive: true, force: true }); + } + + for (const config of NODE_CONFIGS) { + if (config.keySeed) { + insertKeys(BINARY_PATH, config.basePath, CHAIN_SPEC_PATH, config.keySeed); + } + } + + for (const config of NODE_CONFIGS) { + const node = startNode({ + binaryPath: BINARY_PATH, + chainSpec: CHAIN_SPEC_PATH, + ...config, + }); + nodes.push(node); + await started(node); + } + + const all = Promise.all.bind(Promise); + + await all(nodes.map((n) => peerCount(n, nodes.length - 1))); + log("All nodes peered"); + + await all(nodes.map((n) => finalizedBlocks(n, 3))); + log("All nodes finalized block 3"); + + const state: NetworkState = { + binaryPath: BINARY_PATH, + chainSpec: CHAIN_SPEC_PATH, + nodes: NODE_CONFIGS.map((c, i) => ({ + name: c.name, + rpcPort: c.rpcPort, + port: c.port, + pid: nodes[i].process.pid!, + basePath: c.basePath, + })), + }; + + await writeFile(STATE_FILE, JSON.stringify(state, null, 2)); + log("Network state written to " + STATE_FILE); +} + +export async function teardown() { + log("Tearing down __NAME__ E2E test network"); + + let state: NetworkState | undefined; + try { + const data = await readFile(STATE_FILE, "utf-8"); + state = JSON.parse(data); + } catch {} + + for (const node of nodes) { + try { + await stop(node); + } catch (e) { + log(`Warning: failed to stop ${node.name}: ${e}`); + } + } + + if (state) { + const ownPids = new Set(nodes.map((n) => n.process.pid)); + for (const nodeInfo of state.nodes) { + if (!ownPids.has(nodeInfo.pid)) { + try { + process.kill(nodeInfo.pid, "SIGTERM"); + log(`Killed extra node ${nodeInfo.name} (pid ${nodeInfo.pid})`); + } catch {} + } + } + + } + + await rm("/tmp/subtensor-e2e/__NAME__", { recursive: true, force: true }); + + log("Teardown complete"); +} +SETUP_EOF + +# -- tests/00-basic.test.ts -- +sed "s/__NAME__/$NAME/g" << 'TEST_EOF' > "$DIR/tests/00-basic.test.ts" +import { describe, it, expect, beforeAll, afterAll } from "vitest"; +import { readFile } from "node:fs/promises"; +import type { PolkadotClient, TypedApi } from "polkadot-api"; +import { subtensor } from "@polkadot-api/descriptors"; +import type { NetworkState } from "../setup.js"; +import { + connectClient, + createSigner, + waitForFinalizedBlocks, +} from "e2e-shared/client.js"; + +let client: PolkadotClient; +let api: TypedApi; +let state: NetworkState; + +const alice = createSigner("//Alice"); + +beforeAll(async () => { + const data = await readFile("/tmp/subtensor-e2e/__NAME__/nodes.json", "utf-8"); + state = JSON.parse(data); + ({ client, api } = await connectClient(state.nodes[0].rpcPort)); + await waitForFinalizedBlocks(client, 3); +}); + +afterAll(() => { + client?.destroy(); +}); + +describe("__NAME__", () => { + it("should produce finalized blocks", async () => { + const block = await api.query.System.Number.getValue(); + expect(block).toBeGreaterThan(0); + }); +}); +TEST_EOF + +# -- Add to pnpm-workspace.yaml -- +if ! yq '.packages[] | select(. == "'"$NAME"'")' "$WORKSPACE" | grep -q .; then + yq -i '.packages += ["'"$NAME"'"]' "$WORKSPACE" + echo " Added '$NAME' to pnpm-workspace.yaml" +fi + +echo "==> Created e2e/$NAME/" +echo "" +echo "Next steps:" +echo " 1. Edit $NAME/setup.ts to configure your network" +echo " 2. Add test-specific dependencies to $NAME/package.json" +echo " 3. Run: pnpm install" +echo " 4. Run: cd $NAME && pnpm test" diff --git a/e2e/bootstrap_types.sh b/e2e/bootstrap_types.sh new file mode 100755 index 0000000000..74039d37a8 --- /dev/null +++ b/e2e/bootstrap_types.sh @@ -0,0 +1,51 @@ +#!/bin/bash +# +# Build the node binary and (re)generate polkadot-api type descriptors. +# Installs polkadot-api globally for the CLI and type resolution. +# Run this whenever the runtime changes to keep descriptors in sync. +# +# Usage: +# ./bootstrap_types.sh # build + generate types +# ./bootstrap_types.sh --skip-build # generate types only (binary must exist) +# +set -e + +BASE_DIR="/tmp/subtensor-e2e" +mkdir -p $BASE_DIR + +BINARY="${BINARY_PATH:-../target/release/node-subtensor}" +NODE_LOG="${BASE_DIR}/bootstrap-node.log" + +if [ "$1" != "--skip-build" ]; then + echo "==> Building node-subtensor..." + pnpm build-node:debug + BINARY="../target/debug/node-subtensor" +fi + +echo "==> Starting dev node (logs at $NODE_LOG)..." +"$BINARY" --one --dev &>"$NODE_LOG" & +NODE_PID=$! +trap "kill $NODE_PID 2>/dev/null; wait $NODE_PID 2>/dev/null" EXIT + +TIMEOUT=60 +ELAPSED=0 +echo "==> Waiting for node to be ready (timeout: ${TIMEOUT}s)..." +until curl -sf -o /dev/null \ + -H "Content-Type: application/json" \ + -d '{"id":1,"jsonrpc":"2.0","method":"system_health","params":[]}' \ + http://localhost:9944; do + sleep 1 + ELAPSED=$((ELAPSED + 1)) + if [ "$ELAPSED" -ge "$TIMEOUT" ]; then + echo "ERROR: Node failed to start within ${TIMEOUT}s. Check $NODE_LOG" + exit 1 + fi +done + +echo "==> Installing polkadot-api globally..." +npm install -g polkadot-api + +echo "==> Generating papi types..." +pnpm generate-types + +echo "==> Done." diff --git a/e2e/package.json b/e2e/package.json new file mode 100644 index 0000000000..db6090fae4 --- /dev/null +++ b/e2e/package.json @@ -0,0 +1,19 @@ +{ + "name": "e2e", + "private": true, + "scripts": { + "build-node:debug": "cargo build --manifest-path ../Cargo.toml -p node-subtensor", + "build-node:release": "cargo build --manifest-path ../Cargo.toml --profile release -p node-subtensor", + "build-node:fast": "pnpm build-node:release --features fast-runtime", + "generate-types": "polkadot-api add subtensor --wsUrl ws://localhost:9944 --skip-codegen && polkadot-api", + "format": "prettier --write .", + "format:check": "prettier --check ." + }, + "dependencies": { + "@polkadot-api/descriptors": "file:.papi/descriptors", + "polkadot-api": "catalog:" + }, + "devDependencies": { + "prettier": "catalog:" + } +} diff --git a/e2e/pnpm-lock.yaml b/e2e/pnpm-lock.yaml new file mode 100644 index 0000000000..982813a2d4 --- /dev/null +++ b/e2e/pnpm-lock.yaml @@ -0,0 +1,3822 @@ +lockfileVersion: "9.0" + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +catalogs: + default: + "@noble/ciphers": + specifier: ^2.1.1 + version: 2.1.1 + "@polkadot-labs/hdkd": + specifier: ^0.0.25 + version: 0.0.25 + "@polkadot-labs/hdkd-helpers": + specifier: ^0.0.25 + version: 0.0.25 + "@polkadot/keyring": + specifier: ^14.0.1 + version: 14.0.1 + "@polkadot/util": + specifier: ^14.0.1 + version: 14.0.1 + "@polkadot/util-crypto": + specifier: ^14.0.1 + version: 14.0.1 + "@types/node": + specifier: ^24 + version: 24.10.13 + mlkem: + specifier: ^2.5.0 + version: 2.5.0 + polkadot-api: + specifier: ^1.22.0 + version: 1.23.3 + prettier: + specifier: ^3.0.0 + version: 3.8.1 + vitest: + specifier: ^4.0.0 + version: 4.0.18 + +importers: + .: + dependencies: + "@polkadot-api/descriptors": + specifier: file:.papi/descriptors + version: file:.papi/descriptors(polkadot-api@1.23.3(postcss@8.5.6)(rxjs@7.8.2)(tsx@4.21.0)) + polkadot-api: + specifier: "catalog:" + version: 1.23.3(postcss@8.5.6)(rxjs@7.8.2)(tsx@4.21.0) + devDependencies: + prettier: + specifier: "catalog:" + version: 3.8.1 + + shared: + dependencies: + "@polkadot-api/descriptors": + specifier: file:../.papi/descriptors + version: file:.papi/descriptors(polkadot-api@1.23.3(postcss@8.5.6)(rxjs@7.8.2)(tsx@4.21.0)) + "@polkadot-labs/hdkd": + specifier: "catalog:" + version: 0.0.25 + "@polkadot-labs/hdkd-helpers": + specifier: "catalog:" + version: 0.0.25 + "@polkadot/keyring": + specifier: "catalog:" + version: 14.0.1(@polkadot/util-crypto@14.0.1(@polkadot/util@14.0.1))(@polkadot/util@14.0.1) + polkadot-api: + specifier: "catalog:" + version: 1.23.3(postcss@8.5.6)(rxjs@7.8.2)(tsx@4.21.0) + devDependencies: + "@types/node": + specifier: "catalog:" + version: 24.10.13 + vitest: + specifier: "catalog:" + version: 4.0.18(@types/node@24.10.13)(tsx@4.21.0) + + shield: + dependencies: + "@noble/ciphers": + specifier: "catalog:" + version: 2.1.1 + "@polkadot-api/descriptors": + specifier: file:../.papi/descriptors + version: file:.papi/descriptors(polkadot-api@1.23.3(postcss@8.5.6)(rxjs@7.8.2)(tsx@4.21.0)) + "@polkadot/util": + specifier: "catalog:" + version: 14.0.1 + "@polkadot/util-crypto": + specifier: "catalog:" + version: 14.0.1(@polkadot/util@14.0.1) + e2e-shared: + specifier: workspace:* + version: link:../shared + mlkem: + specifier: "catalog:" + version: 2.5.0 + polkadot-api: + specifier: "catalog:" + version: 1.23.3(postcss@8.5.6)(rxjs@7.8.2)(tsx@4.21.0) + devDependencies: + "@types/node": + specifier: "catalog:" + version: 24.10.13 + vitest: + specifier: "catalog:" + version: 4.0.18(@types/node@24.10.13)(tsx@4.21.0) + + staking: + dependencies: + e2e-shared: + specifier: workspace:* + version: link:../shared + devDependencies: + "@types/node": + specifier: "catalog:" + version: 24.10.13 + vitest: + specifier: "catalog:" + version: 4.0.18(@types/node@24.10.13)(tsx@4.21.0) + +packages: + "@babel/code-frame@7.29.0": + resolution: + { + integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==, + } + engines: { node: ">=6.9.0" } + + "@babel/helper-validator-identifier@7.28.5": + resolution: + { + integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==, + } + engines: { node: ">=6.9.0" } + + "@commander-js/extra-typings@14.0.0": + resolution: + { + integrity: sha512-hIn0ncNaJRLkZrxBIp5AsW/eXEHNKYQBh0aPdoUqNgD+Io3NIykQqpKFyKcuasZhicGaEZJX/JBSIkZ4e5x8Dg==, + } + peerDependencies: + commander: ~14.0.0 + + "@esbuild/aix-ppc64@0.25.12": + resolution: + { + integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==, + } + engines: { node: ">=18" } + cpu: [ppc64] + os: [aix] + + "@esbuild/aix-ppc64@0.27.3": + resolution: + { + integrity: sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==, + } + engines: { node: ">=18" } + cpu: [ppc64] + os: [aix] + + "@esbuild/android-arm64@0.25.12": + resolution: + { + integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [android] + + "@esbuild/android-arm64@0.27.3": + resolution: + { + integrity: sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [android] + + "@esbuild/android-arm@0.25.12": + resolution: + { + integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==, + } + engines: { node: ">=18" } + cpu: [arm] + os: [android] + + "@esbuild/android-arm@0.27.3": + resolution: + { + integrity: sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==, + } + engines: { node: ">=18" } + cpu: [arm] + os: [android] + + "@esbuild/android-x64@0.25.12": + resolution: + { + integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [android] + + "@esbuild/android-x64@0.27.3": + resolution: + { + integrity: sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [android] + + "@esbuild/darwin-arm64@0.25.12": + resolution: + { + integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [darwin] + + "@esbuild/darwin-arm64@0.27.3": + resolution: + { + integrity: sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [darwin] + + "@esbuild/darwin-x64@0.25.12": + resolution: + { + integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [darwin] + + "@esbuild/darwin-x64@0.27.3": + resolution: + { + integrity: sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [darwin] + + "@esbuild/freebsd-arm64@0.25.12": + resolution: + { + integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [freebsd] + + "@esbuild/freebsd-arm64@0.27.3": + resolution: + { + integrity: sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [freebsd] + + "@esbuild/freebsd-x64@0.25.12": + resolution: + { + integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [freebsd] + + "@esbuild/freebsd-x64@0.27.3": + resolution: + { + integrity: sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [freebsd] + + "@esbuild/linux-arm64@0.25.12": + resolution: + { + integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [linux] + + "@esbuild/linux-arm64@0.27.3": + resolution: + { + integrity: sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [linux] + + "@esbuild/linux-arm@0.25.12": + resolution: + { + integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==, + } + engines: { node: ">=18" } + cpu: [arm] + os: [linux] + + "@esbuild/linux-arm@0.27.3": + resolution: + { + integrity: sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==, + } + engines: { node: ">=18" } + cpu: [arm] + os: [linux] + + "@esbuild/linux-ia32@0.25.12": + resolution: + { + integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==, + } + engines: { node: ">=18" } + cpu: [ia32] + os: [linux] + + "@esbuild/linux-ia32@0.27.3": + resolution: + { + integrity: sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==, + } + engines: { node: ">=18" } + cpu: [ia32] + os: [linux] + + "@esbuild/linux-loong64@0.25.12": + resolution: + { + integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==, + } + engines: { node: ">=18" } + cpu: [loong64] + os: [linux] + + "@esbuild/linux-loong64@0.27.3": + resolution: + { + integrity: sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==, + } + engines: { node: ">=18" } + cpu: [loong64] + os: [linux] + + "@esbuild/linux-mips64el@0.25.12": + resolution: + { + integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==, + } + engines: { node: ">=18" } + cpu: [mips64el] + os: [linux] + + "@esbuild/linux-mips64el@0.27.3": + resolution: + { + integrity: sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==, + } + engines: { node: ">=18" } + cpu: [mips64el] + os: [linux] + + "@esbuild/linux-ppc64@0.25.12": + resolution: + { + integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==, + } + engines: { node: ">=18" } + cpu: [ppc64] + os: [linux] + + "@esbuild/linux-ppc64@0.27.3": + resolution: + { + integrity: sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==, + } + engines: { node: ">=18" } + cpu: [ppc64] + os: [linux] + + "@esbuild/linux-riscv64@0.25.12": + resolution: + { + integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==, + } + engines: { node: ">=18" } + cpu: [riscv64] + os: [linux] + + "@esbuild/linux-riscv64@0.27.3": + resolution: + { + integrity: sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==, + } + engines: { node: ">=18" } + cpu: [riscv64] + os: [linux] + + "@esbuild/linux-s390x@0.25.12": + resolution: + { + integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==, + } + engines: { node: ">=18" } + cpu: [s390x] + os: [linux] + + "@esbuild/linux-s390x@0.27.3": + resolution: + { + integrity: sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==, + } + engines: { node: ">=18" } + cpu: [s390x] + os: [linux] + + "@esbuild/linux-x64@0.25.12": + resolution: + { + integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [linux] + + "@esbuild/linux-x64@0.27.3": + resolution: + { + integrity: sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [linux] + + "@esbuild/netbsd-arm64@0.25.12": + resolution: + { + integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [netbsd] + + "@esbuild/netbsd-arm64@0.27.3": + resolution: + { + integrity: sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [netbsd] + + "@esbuild/netbsd-x64@0.25.12": + resolution: + { + integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [netbsd] + + "@esbuild/netbsd-x64@0.27.3": + resolution: + { + integrity: sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [netbsd] + + "@esbuild/openbsd-arm64@0.25.12": + resolution: + { + integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [openbsd] + + "@esbuild/openbsd-arm64@0.27.3": + resolution: + { + integrity: sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [openbsd] + + "@esbuild/openbsd-x64@0.25.12": + resolution: + { + integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [openbsd] + + "@esbuild/openbsd-x64@0.27.3": + resolution: + { + integrity: sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [openbsd] + + "@esbuild/openharmony-arm64@0.25.12": + resolution: + { + integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [openharmony] + + "@esbuild/openharmony-arm64@0.27.3": + resolution: + { + integrity: sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [openharmony] + + "@esbuild/sunos-x64@0.25.12": + resolution: + { + integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [sunos] + + "@esbuild/sunos-x64@0.27.3": + resolution: + { + integrity: sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [sunos] + + "@esbuild/win32-arm64@0.25.12": + resolution: + { + integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [win32] + + "@esbuild/win32-arm64@0.27.3": + resolution: + { + integrity: sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [win32] + + "@esbuild/win32-ia32@0.25.12": + resolution: + { + integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==, + } + engines: { node: ">=18" } + cpu: [ia32] + os: [win32] + + "@esbuild/win32-ia32@0.27.3": + resolution: + { + integrity: sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==, + } + engines: { node: ">=18" } + cpu: [ia32] + os: [win32] + + "@esbuild/win32-x64@0.25.12": + resolution: + { + integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [win32] + + "@esbuild/win32-x64@0.27.3": + resolution: + { + integrity: sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [win32] + + "@jridgewell/gen-mapping@0.3.13": + resolution: + { + integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==, + } + + "@jridgewell/resolve-uri@3.1.2": + resolution: + { + integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==, + } + engines: { node: ">=6.0.0" } + + "@jridgewell/sourcemap-codec@1.5.5": + resolution: + { + integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==, + } + + "@jridgewell/trace-mapping@0.3.31": + resolution: + { + integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==, + } + + "@noble/ciphers@2.1.1": + resolution: + { + integrity: sha512-bysYuiVfhxNJuldNXlFEitTVdNnYUc+XNJZd7Qm2a5j1vZHgY+fazadNFWFaMK/2vye0JVlxV3gHmC0WDfAOQw==, + } + engines: { node: ">= 20.19.0" } + + "@noble/curves@1.9.7": + resolution: + { + integrity: sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==, + } + engines: { node: ^14.21.3 || >=16 } + + "@noble/curves@2.0.1": + resolution: + { + integrity: sha512-vs1Az2OOTBiP4q0pwjW5aF0xp9n4MxVrmkFBxc6EKZc6ddYx5gaZiAsZoq0uRRXWbi3AT/sBqn05eRPtn1JCPw==, + } + engines: { node: ">= 20.19.0" } + + "@noble/hashes@1.8.0": + resolution: + { + integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==, + } + engines: { node: ^14.21.3 || >=16 } + + "@noble/hashes@2.0.1": + resolution: + { + integrity: sha512-XlOlEbQcE9fmuXxrVTXCTlG2nlRXa9Rj3rr5Ue/+tX+nmkgbX720YHh0VR3hBF9xDvwnb8D2shVGOwNx+ulArw==, + } + engines: { node: ">= 20.19.0" } + + "@polkadot-api/cli@0.18.1": + resolution: + { + integrity: sha512-jPa8WSNPZWdy372sBAUnm0nU1XX5mLbmgkOOU39+zpYPSE12mYXyM3r7JuT5IHdAccEJr6qK2DplPFTeNSyq9A==, + } + hasBin: true + + "@polkadot-api/codegen@0.21.2": + resolution: + { + integrity: sha512-e1Of2TfB13YndPQ71WrtOIPfRrSlkG6wGprP8/VHC484kkt2JPDOY+io3NdPWkafDblDQ47aG0368sxT+4RSZA==, + } + + "@polkadot-api/descriptors@file:.papi/descriptors": + resolution: { directory: .papi/descriptors, type: directory } + peerDependencies: + polkadot-api: ">=1.21.0" + + "@polkadot-api/ink-contracts@0.4.6": + resolution: + { + integrity: sha512-wpFPa8CnGnmq+cFYMzuTEDmtt3ElBM0UWgTz4RpmI9E7knZ1ctWBhO7amXxOWcILqIG6sqWIE95x0cfF1PRcQg==, + } + + "@polkadot-api/json-rpc-provider-proxy@0.2.8": + resolution: + { + integrity: sha512-AC5KK4p2IamAQuqR0S3YaiiUDRB2r1pWNrdF0Mntm5XGYEmeiAILBmnFa7gyWwemhkTWPYrK5HCurlGfw2EsDA==, + } + + "@polkadot-api/json-rpc-provider@0.0.4": + resolution: + { + integrity: sha512-9cDijLIxzHOBuq6yHqpqjJ9jBmXrctjc1OFqU+tQrS96adQze3mTIH6DTgfb/0LMrqxzxffz1HQGrIlEH00WrA==, + } + + "@polkadot-api/known-chains@0.9.18": + resolution: + { + integrity: sha512-zdU4FA01lXcpNXUiFgSmFKIwDKbTw15KT4U6Zlqo6FPUMZgncVEbbS4dSgVrf+TGw9SDOUjGlEdyTHAiOAG5Tw==, + } + + "@polkadot-api/legacy-provider@0.3.8": + resolution: + { + integrity: sha512-Q747MN/7IUxxXGLWLQfhmSLqFyOLUsUFqQQytlEBjt66ZAv9VwYiHZ8JMBCnMzFuaUpKEWDT62ESKhgXn/hmEQ==, + } + peerDependencies: + rxjs: ">=7.8.0" + + "@polkadot-api/logs-provider@0.0.6": + resolution: + { + integrity: sha512-4WgHlvy+xee1ADaaVf6+MlK/+jGMtsMgAzvbQOJZnP4PfQuagoTqaeayk8HYKxXGphogLlPbD06tANxcb+nvAg==, + } + + "@polkadot-api/merkleize-metadata@1.1.29": + resolution: + { + integrity: sha512-z8ivYDdr4xlh50MQ7hLaSVw4VM6EV7gGgd+v/ej09nue0W08NG77zf7pXWeRKgOXe3+hPOSQQRSZT2OlIYRfqA==, + } + + "@polkadot-api/metadata-builders@0.13.9": + resolution: + { + integrity: sha512-V2GljT6StuK40pfmO5l53CvgFNgy60Trrv20mOZDCsFU9J82F+a1HYAABDYlRgoZ9d0IDwc+u+vI+RHUJoR4xw==, + } + + "@polkadot-api/metadata-compatibility@0.4.4": + resolution: + { + integrity: sha512-V4ye5d2ns32YC45Fdc/IF9Y7CgM8inzJbmHQ2DCPSNd6omTRLJd81gU9zU88QAqPAcH2gKGnS5UF+wLL2VagSQ==, + } + + "@polkadot-api/observable-client@0.17.3": + resolution: + { + integrity: sha512-SJhbMKBIzxNgUUy7ZWflYf/TX9soMqiR2WYyggA7U3DLhgdx4wzFjOSbxCk8RuX9Kf/AmJE4dfleu9HBSCZv6g==, + } + peerDependencies: + rxjs: ">=7.8.0" + + "@polkadot-api/pjs-signer@0.6.19": + resolution: + { + integrity: sha512-jTHKoanZg9ewupthOczWNb2pici+GK+TBQmp9MwhwGs/3uMD2144aA8VNNBEi8rMxOBZlvKYfGkgjiTEGbBwuQ==, + } + + "@polkadot-api/polkadot-sdk-compat@2.4.1": + resolution: + { + integrity: sha512-+sET0N3GpnKkLvsazBZEC5vhqAlamlL1KkJK9STB1tRxHSZcY/yBBa1Udn9DXJfX48kE9cnzfYldl9zsjqpARg==, + } + + "@polkadot-api/polkadot-signer@0.1.6": + resolution: + { + integrity: sha512-X7ghAa4r7doETtjAPTb50IpfGtrBmy3BJM5WCfNKa1saK04VFY9w+vDn+hwEcM4p0PcDHt66Ts74hzvHq54d9A==, + } + + "@polkadot-api/raw-client@0.1.1": + resolution: + { + integrity: sha512-HxalpNEo8JCYXfxKM5p3TrK8sEasTGMkGjBNLzD4TLye9IK2smdb5oTvp2yfkU1iuVBdmjr69uif4NaukOYo2g==, + } + + "@polkadot-api/signer@0.2.13": + resolution: + { + integrity: sha512-XBOtjFsRGETVm/aXeZnsvFcJ1qvtZhRtwUMmpCOBt9s8PWfILaQH/ecOegzda3utNIZGmXXaOoJ5w9Hc/6I3ww==, + } + + "@polkadot-api/signers-common@0.1.20": + resolution: + { + integrity: sha512-v1mrTdRjQOV17riZ8172OsOQ/RJbv1QsEpjwnvxzvdCnjuNpYwtYHZaE+cSdDBb4n1p73XIBMvB/uAK/QFC2JA==, + } + + "@polkadot-api/sm-provider@0.1.16": + resolution: + { + integrity: sha512-3LEDU7nkgtDx1A6ATHLLm3+nFAY6cdkNA9tGltfDzW0efACrhhfDjNqJdI1qLNY0wDyT1aGdoWr5r+4CckRpXA==, + } + peerDependencies: + "@polkadot-api/smoldot": ">=0.3" + + "@polkadot-api/smoldot@0.3.15": + resolution: + { + integrity: sha512-YyV+ytP8FcmKEgLRV7uXepJ5Y6md/7u2F8HKxmkWytmnGXO1z+umg2pHbOxLGifD9V2NhkPY+awpzErtVIzqAA==, + } + + "@polkadot-api/substrate-bindings@0.17.0": + resolution: + { + integrity: sha512-YdbkvG/27N5A94AiKE4soVjDy0Nw74Nn+KD29mUnFmIZvL3fsN/DTYkxvMDVsOuanFXyAIXmzDMoi7iky0fyIw==, + } + + "@polkadot-api/substrate-client@0.5.0": + resolution: + { + integrity: sha512-J+gyZONCak+n6NxADZWtldH+gatYORqEScMAgI9gGu43pHUe7/xNRCqnin0dgDIzmuL3m1ERglF8LR7YhB0nHQ==, + } + + "@polkadot-api/utils@0.2.0": + resolution: + { + integrity: sha512-nY3i5fQJoAxU4n3bD7Fs208/KR2J95SGfVc58kDjbRYN5a84kWaGEqzjBNtP9oqht49POM8Bm9mbIrkvC1Bzuw==, + } + + "@polkadot-api/wasm-executor@0.2.3": + resolution: + { + integrity: sha512-B2h1o+Qlo9idpASaHvMSoViB2I5ko5OAfwfhYF8LQDkTADK0B+SeStzNj1Qn+FG34wqTuv7HzBCdjaUgzYINJQ==, + } + + "@polkadot-api/ws-provider@0.7.5": + resolution: + { + integrity: sha512-2ZLEo0PAFeuOx2DUDkbex85HZMf9lgnmZ8oGB5+NaButIydkoqXy5SHYJNPc45GcZy2tvwzImMZInNMLa5GJhg==, + } + + "@polkadot-labs/hdkd-helpers@0.0.25": + resolution: + { + integrity: sha512-GwHayBuyHKfzvGD0vG47NbjFeiK6rRQHQAn1syut9nt0mhXMg4yb3tJ//IyM317qWuDU3HbD2OIp5jKDEQz2/A==, + } + + "@polkadot-labs/hdkd-helpers@0.0.27": + resolution: + { + integrity: sha512-GTSj/Mw5kwtZbefvq2BhvBnHvs7AY4OnJgppO0kE2S/AuDbD6288C9rmO6qwMNmiNVX8OrYMWaJcs46Mt1UbBw==, + } + + "@polkadot-labs/hdkd@0.0.25": + resolution: + { + integrity: sha512-+yZJC1TE4ZKdfoILw8nGxu3H/klrYXm9GdVB0kcyQDecq320ThUmM1M4l8d1F/3QD0Nez9NwHi9t5B++OgJU5A==, + } + + "@polkadot/keyring@14.0.1": + resolution: + { + integrity: sha512-kHydQPCeTvJrMC9VQO8LPhAhTUxzxfNF1HEknhZDBPPsxP/XpkYsEy/Ln1QzJmQqD5VsgwzLDE6cExbJ2CT9CA==, + } + engines: { node: ">=18" } + peerDependencies: + "@polkadot/util": 14.0.1 + "@polkadot/util-crypto": 14.0.1 + + "@polkadot/networks@14.0.1": + resolution: + { + integrity: sha512-wGlBtXDkusRAj4P7uxfPz80gLO1+j99MLBaQi3bEym2xrFrFhgIWVHOZlBit/1PfaBjhX2Z8XjRxaM2w1p7w2w==, + } + engines: { node: ">=18" } + + "@polkadot/util-crypto@14.0.1": + resolution: + { + integrity: sha512-Cu7AKUzBTsUkbOtyuNzXcTpDjR9QW0fVR56o3gBmzfUCmvO1vlsuGzmmPzqpHymQQ3rrfqV78CPs62EGhw0R+A==, + } + engines: { node: ">=18" } + peerDependencies: + "@polkadot/util": 14.0.1 + + "@polkadot/util@14.0.1": + resolution: + { + integrity: sha512-764HhxkPV3x5rM0/p6QdynC2dw26n+SaE+jisjx556ViCd4E28Ke4xSPef6C0Spy4aoXf2gt0PuLEcBvd6fVZg==, + } + engines: { node: ">=18" } + + "@polkadot/wasm-bridge@7.5.4": + resolution: + { + integrity: sha512-6xaJVvoZbnbgpQYXNw9OHVNWjXmtcoPcWh7hlwx3NpfiLkkjljj99YS+XGZQlq7ks2fVCg7FbfknkNb8PldDaA==, + } + engines: { node: ">=18" } + peerDependencies: + "@polkadot/util": "*" + "@polkadot/x-randomvalues": "*" + + "@polkadot/wasm-crypto-asmjs@7.5.4": + resolution: + { + integrity: sha512-ZYwxQHAJ8pPt6kYk9XFmyuFuSS+yirJLonvP+DYbxOrARRUHfN4nzp4zcZNXUuaFhpbDobDSFn6gYzye6BUotA==, + } + engines: { node: ">=18" } + peerDependencies: + "@polkadot/util": "*" + + "@polkadot/wasm-crypto-init@7.5.4": + resolution: + { + integrity: sha512-U6s4Eo2rHs2n1iR01vTz/sOQ7eOnRPjaCsGWhPV+ZC/20hkVzwPAhiizu/IqMEol4tO2yiSheD4D6bn0KxUJhg==, + } + engines: { node: ">=18" } + peerDependencies: + "@polkadot/util": "*" + "@polkadot/x-randomvalues": "*" + + "@polkadot/wasm-crypto-wasm@7.5.4": + resolution: + { + integrity: sha512-PsHgLsVTu43eprwSvUGnxybtOEuHPES6AbApcs7y5ZbM2PiDMzYbAjNul098xJK/CPtrxZ0ePDFnaQBmIJyTFw==, + } + engines: { node: ">=18" } + peerDependencies: + "@polkadot/util": "*" + + "@polkadot/wasm-crypto@7.5.4": + resolution: + { + integrity: sha512-1seyClxa7Jd7kQjfnCzTTTfYhTa/KUTDUaD3DMHBk5Q4ZUN1D1unJgX+v1aUeXSPxmzocdZETPJJRZjhVOqg9g==, + } + engines: { node: ">=18" } + peerDependencies: + "@polkadot/util": "*" + "@polkadot/x-randomvalues": "*" + + "@polkadot/wasm-util@7.5.4": + resolution: + { + integrity: sha512-hqPpfhCpRAqCIn/CYbBluhh0TXmwkJnDRjxrU9Bnqtw9nMNa97D8JuOjdd2pi0rxm+eeLQ/f1rQMp71RMM9t4w==, + } + engines: { node: ">=18" } + peerDependencies: + "@polkadot/util": "*" + + "@polkadot/x-bigint@14.0.1": + resolution: + { + integrity: sha512-gfozjGnebr2rqURs31KtaWumbW4rRZpbiluhlmai6luCNrf5u8pB+oLA35kPEntrsLk9PnIG9OsC/n4hEtx4OQ==, + } + engines: { node: ">=18" } + + "@polkadot/x-global@14.0.1": + resolution: + { + integrity: sha512-aCI44DJU4fU0XXqrrSGIpi7JrZXK2kpe0jaQ2p6oDVXOOYEnZYXnMhTTmBE1lF/xtxzX50MnZrrU87jziU0qbA==, + } + engines: { node: ">=18" } + + "@polkadot/x-randomvalues@14.0.1": + resolution: + { + integrity: sha512-/XkQcvshzJLHITuPrN3zmQKuFIPdKWoaiHhhVLD6rQWV60lTXA3ajw3ocju8ZN7xRxnweMS9Ce0kMPYa0NhRMg==, + } + engines: { node: ">=18" } + peerDependencies: + "@polkadot/util": 14.0.1 + "@polkadot/wasm-util": "*" + + "@polkadot/x-textdecoder@14.0.1": + resolution: + { + integrity: sha512-CcWiPCuPVJsNk4Vq43lgFHqLRBQHb4r9RD7ZIYgmwoebES8TNm4g2ew9ToCzakFKSpzKu6I07Ne9wv/dt5zLuw==, + } + engines: { node: ">=18" } + + "@polkadot/x-textencoder@14.0.1": + resolution: + { + integrity: sha512-VY51SpQmF1ccmAGLfxhYnAe95Spfz049WZ/+kK4NfsGF9WejxVdU53Im5C80l45r8qHuYQsCWU3+t0FNunh2Kg==, + } + engines: { node: ">=18" } + + "@rollup/rollup-android-arm-eabi@4.57.1": + resolution: + { + integrity: sha512-A6ehUVSiSaaliTxai040ZpZ2zTevHYbvu/lDoeAteHI8QnaosIzm4qwtezfRg1jOYaUmnzLX1AOD6Z+UJjtifg==, + } + cpu: [arm] + os: [android] + + "@rollup/rollup-android-arm64@4.57.1": + resolution: + { + integrity: sha512-dQaAddCY9YgkFHZcFNS/606Exo8vcLHwArFZ7vxXq4rigo2bb494/xKMMwRRQW6ug7Js6yXmBZhSBRuBvCCQ3w==, + } + cpu: [arm64] + os: [android] + + "@rollup/rollup-darwin-arm64@4.57.1": + resolution: + { + integrity: sha512-crNPrwJOrRxagUYeMn/DZwqN88SDmwaJ8Cvi/TN1HnWBU7GwknckyosC2gd0IqYRsHDEnXf328o9/HC6OkPgOg==, + } + cpu: [arm64] + os: [darwin] + + "@rollup/rollup-darwin-x64@4.57.1": + resolution: + { + integrity: sha512-Ji8g8ChVbKrhFtig5QBV7iMaJrGtpHelkB3lsaKzadFBe58gmjfGXAOfI5FV0lYMH8wiqsxKQ1C9B0YTRXVy4w==, + } + cpu: [x64] + os: [darwin] + + "@rollup/rollup-freebsd-arm64@4.57.1": + resolution: + { + integrity: sha512-R+/WwhsjmwodAcz65guCGFRkMb4gKWTcIeLy60JJQbXrJ97BOXHxnkPFrP+YwFlaS0m+uWJTstrUA9o+UchFug==, + } + cpu: [arm64] + os: [freebsd] + + "@rollup/rollup-freebsd-x64@4.57.1": + resolution: + { + integrity: sha512-IEQTCHeiTOnAUC3IDQdzRAGj3jOAYNr9kBguI7MQAAZK3caezRrg0GxAb6Hchg4lxdZEI5Oq3iov/w/hnFWY9Q==, + } + cpu: [x64] + os: [freebsd] + + "@rollup/rollup-linux-arm-gnueabihf@4.57.1": + resolution: + { + integrity: sha512-F8sWbhZ7tyuEfsmOxwc2giKDQzN3+kuBLPwwZGyVkLlKGdV1nvnNwYD0fKQ8+XS6hp9nY7B+ZeK01EBUE7aHaw==, + } + cpu: [arm] + os: [linux] + libc: [glibc] + + "@rollup/rollup-linux-arm-musleabihf@4.57.1": + resolution: + { + integrity: sha512-rGfNUfn0GIeXtBP1wL5MnzSj98+PZe/AXaGBCRmT0ts80lU5CATYGxXukeTX39XBKsxzFpEeK+Mrp9faXOlmrw==, + } + cpu: [arm] + os: [linux] + libc: [musl] + + "@rollup/rollup-linux-arm64-gnu@4.57.1": + resolution: + { + integrity: sha512-MMtej3YHWeg/0klK2Qodf3yrNzz6CGjo2UntLvk2RSPlhzgLvYEB3frRvbEF2wRKh1Z2fDIg9KRPe1fawv7C+g==, + } + cpu: [arm64] + os: [linux] + libc: [glibc] + + "@rollup/rollup-linux-arm64-musl@4.57.1": + resolution: + { + integrity: sha512-1a/qhaaOXhqXGpMFMET9VqwZakkljWHLmZOX48R0I/YLbhdxr1m4gtG1Hq7++VhVUmf+L3sTAf9op4JlhQ5u1Q==, + } + cpu: [arm64] + os: [linux] + libc: [musl] + + "@rollup/rollup-linux-loong64-gnu@4.57.1": + resolution: + { + integrity: sha512-QWO6RQTZ/cqYtJMtxhkRkidoNGXc7ERPbZN7dVW5SdURuLeVU7lwKMpo18XdcmpWYd0qsP1bwKPf7DNSUinhvA==, + } + cpu: [loong64] + os: [linux] + libc: [glibc] + + "@rollup/rollup-linux-loong64-musl@4.57.1": + resolution: + { + integrity: sha512-xpObYIf+8gprgWaPP32xiN5RVTi/s5FCR+XMXSKmhfoJjrpRAjCuuqQXyxUa/eJTdAE6eJ+KDKaoEqjZQxh3Gw==, + } + cpu: [loong64] + os: [linux] + libc: [musl] + + "@rollup/rollup-linux-ppc64-gnu@4.57.1": + resolution: + { + integrity: sha512-4BrCgrpZo4hvzMDKRqEaW1zeecScDCR+2nZ86ATLhAoJ5FQ+lbHVD3ttKe74/c7tNT9c6F2viwB3ufwp01Oh2w==, + } + cpu: [ppc64] + os: [linux] + libc: [glibc] + + "@rollup/rollup-linux-ppc64-musl@4.57.1": + resolution: + { + integrity: sha512-NOlUuzesGauESAyEYFSe3QTUguL+lvrN1HtwEEsU2rOwdUDeTMJdO5dUYl/2hKf9jWydJrO9OL/XSSf65R5+Xw==, + } + cpu: [ppc64] + os: [linux] + libc: [musl] + + "@rollup/rollup-linux-riscv64-gnu@4.57.1": + resolution: + { + integrity: sha512-ptA88htVp0AwUUqhVghwDIKlvJMD/fmL/wrQj99PRHFRAG6Z5nbWoWG4o81Nt9FT+IuqUQi+L31ZKAFeJ5Is+A==, + } + cpu: [riscv64] + os: [linux] + libc: [glibc] + + "@rollup/rollup-linux-riscv64-musl@4.57.1": + resolution: + { + integrity: sha512-S51t7aMMTNdmAMPpBg7OOsTdn4tySRQvklmL3RpDRyknk87+Sp3xaumlatU+ppQ+5raY7sSTcC2beGgvhENfuw==, + } + cpu: [riscv64] + os: [linux] + libc: [musl] + + "@rollup/rollup-linux-s390x-gnu@4.57.1": + resolution: + { + integrity: sha512-Bl00OFnVFkL82FHbEqy3k5CUCKH6OEJL54KCyx2oqsmZnFTR8IoNqBF+mjQVcRCT5sB6yOvK8A37LNm/kPJiZg==, + } + cpu: [s390x] + os: [linux] + libc: [glibc] + + "@rollup/rollup-linux-x64-gnu@4.57.1": + resolution: + { + integrity: sha512-ABca4ceT4N+Tv/GtotnWAeXZUZuM/9AQyCyKYyKnpk4yoA7QIAuBt6Hkgpw8kActYlew2mvckXkvx0FfoInnLg==, + } + cpu: [x64] + os: [linux] + libc: [glibc] + + "@rollup/rollup-linux-x64-musl@4.57.1": + resolution: + { + integrity: sha512-HFps0JeGtuOR2convgRRkHCekD7j+gdAuXM+/i6kGzQtFhlCtQkpwtNzkNj6QhCDp7DRJ7+qC/1Vg2jt5iSOFw==, + } + cpu: [x64] + os: [linux] + libc: [musl] + + "@rollup/rollup-openbsd-x64@4.57.1": + resolution: + { + integrity: sha512-H+hXEv9gdVQuDTgnqD+SQffoWoc0Of59AStSzTEj/feWTBAnSfSD3+Dql1ZruJQxmykT/JVY0dE8Ka7z0DH1hw==, + } + cpu: [x64] + os: [openbsd] + + "@rollup/rollup-openharmony-arm64@4.57.1": + resolution: + { + integrity: sha512-4wYoDpNg6o/oPximyc/NG+mYUejZrCU2q+2w6YZqrAs2UcNUChIZXjtafAiiZSUc7On8v5NyNj34Kzj/Ltk6dQ==, + } + cpu: [arm64] + os: [openharmony] + + "@rollup/rollup-win32-arm64-msvc@4.57.1": + resolution: + { + integrity: sha512-O54mtsV/6LW3P8qdTcamQmuC990HDfR71lo44oZMZlXU4tzLrbvTii87Ni9opq60ds0YzuAlEr/GNwuNluZyMQ==, + } + cpu: [arm64] + os: [win32] + + "@rollup/rollup-win32-ia32-msvc@4.57.1": + resolution: + { + integrity: sha512-P3dLS+IerxCT/7D2q2FYcRdWRl22dNbrbBEtxdWhXrfIMPP9lQhb5h4Du04mdl5Woq05jVCDPCMF7Ub0NAjIew==, + } + cpu: [ia32] + os: [win32] + + "@rollup/rollup-win32-x64-gnu@4.57.1": + resolution: + { + integrity: sha512-VMBH2eOOaKGtIJYleXsi2B8CPVADrh+TyNxJ4mWPnKfLB/DBUmzW+5m1xUrcwWoMfSLagIRpjUFeW5CO5hyciQ==, + } + cpu: [x64] + os: [win32] + + "@rollup/rollup-win32-x64-msvc@4.57.1": + resolution: + { + integrity: sha512-mxRFDdHIWRxg3UfIIAwCm6NzvxG0jDX/wBN6KsQFTvKFqqg9vTrWUE68qEjHt19A5wwx5X5aUi2zuZT7YR0jrA==, + } + cpu: [x64] + os: [win32] + + "@rx-state/core@0.1.4": + resolution: + { + integrity: sha512-Z+3hjU2xh1HisLxt+W5hlYX/eGSDaXXP+ns82gq/PLZpkXLu0uwcNUh9RLY3Clq4zT+hSsA3vcpIGt6+UAb8rQ==, + } + peerDependencies: + rxjs: ">=7" + + "@scure/base@1.2.6": + resolution: + { + integrity: sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==, + } + + "@scure/base@2.0.0": + resolution: + { + integrity: sha512-3E1kpuZginKkek01ovG8krQ0Z44E3DHPjc5S2rjJw9lZn3KSQOs8S7wqikF/AH7iRanHypj85uGyxk0XAyC37w==, + } + + "@scure/sr25519@0.2.0": + resolution: + { + integrity: sha512-uUuLP7Z126XdSizKtrCGqYyR3b3hYtJ6Fg/XFUXmc2//k2aXHDLqZwFeXxL97gg4XydPROPVnuaHGF2+xriSKg==, + } + + "@scure/sr25519@0.3.0": + resolution: + { + integrity: sha512-SKsinX2sImunfcsH3seGrwH/OayBwwaJqVN8J1cJBNRCfbBq5q0jyTKGa9PcW1HWv9vXT6Yuq41JsxFLvF59ew==, + } + engines: { node: ">= 20.19.0" } + + "@scure/sr25519@1.0.0": + resolution: + { + integrity: sha512-b+uhK5akMINXZP95F3gJGcb5CMKYxf+q55fwMl0GoBwZDbWolmGNi1FrBSwuaZX5AhqS2byHiAueZgtDNpot2A==, + } + engines: { node: ">= 20.19.0" } + + "@sec-ant/readable-stream@0.4.1": + resolution: + { + integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==, + } + + "@sindresorhus/merge-streams@4.0.0": + resolution: + { + integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==, + } + engines: { node: ">=18" } + + "@standard-schema/spec@1.1.0": + resolution: + { + integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==, + } + + "@substrate/ss58-registry@1.51.0": + resolution: + { + integrity: sha512-TWDurLiPxndFgKjVavCniytBIw+t4ViOi7TYp9h/D0NMmkEc9klFTo+827eyEJ0lELpqO207Ey7uGxUa+BS1jQ==, + } + + "@types/bn.js@5.2.0": + resolution: + { + integrity: sha512-DLbJ1BPqxvQhIGbeu8VbUC1DiAiahHtAYvA0ZEAa4P31F7IaArc8z3C3BRQdWX4mtLQuABG4yzp76ZrS02Ui1Q==, + } + + "@types/chai@5.2.3": + resolution: + { + integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==, + } + + "@types/deep-eql@4.0.2": + resolution: + { + integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==, + } + + "@types/estree@1.0.8": + resolution: + { + integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==, + } + + "@types/node@24.10.13": + resolution: + { + integrity: sha512-oH72nZRfDv9lADUBSo104Aq7gPHpQZc4BTx38r9xf9pg5LfP6EzSyH2n7qFmmxRQXh7YlUXODcYsg6PuTDSxGg==, + } + + "@types/node@25.3.0": + resolution: + { + integrity: sha512-4K3bqJpXpqfg2XKGK9bpDTc6xO/xoUP/RBWS7AtRMug6zZFaRekiLzjVtAoZMquxoAbzBvy5nxQ7veS5eYzf8A==, + } + + "@types/normalize-package-data@2.4.4": + resolution: + { + integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==, + } + + "@types/ws@8.18.1": + resolution: + { + integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==, + } + + "@vitest/expect@4.0.18": + resolution: + { + integrity: sha512-8sCWUyckXXYvx4opfzVY03EOiYVxyNrHS5QxX3DAIi5dpJAAkyJezHCP77VMX4HKA2LDT/Jpfo8i2r5BE3GnQQ==, + } + + "@vitest/mocker@4.0.18": + resolution: + { + integrity: sha512-HhVd0MDnzzsgevnOWCBj5Otnzobjy5wLBe4EdeeFGv8luMsGcYqDuFRMcttKWZA5vVO8RFjexVovXvAM4JoJDQ==, + } + peerDependencies: + msw: ^2.4.9 + vite: ^6.0.0 || ^7.0.0-0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + "@vitest/pretty-format@4.0.18": + resolution: + { + integrity: sha512-P24GK3GulZWC5tz87ux0m8OADrQIUVDPIjjj65vBXYG17ZeU3qD7r+MNZ1RNv4l8CGU2vtTRqixrOi9fYk/yKw==, + } + + "@vitest/runner@4.0.18": + resolution: + { + integrity: sha512-rpk9y12PGa22Jg6g5M3UVVnTS7+zycIGk9ZNGN+m6tZHKQb7jrP7/77WfZy13Y/EUDd52NDsLRQhYKtv7XfPQw==, + } + + "@vitest/snapshot@4.0.18": + resolution: + { + integrity: sha512-PCiV0rcl7jKQjbgYqjtakly6T1uwv/5BQ9SwBLekVg/EaYeQFPiXcgrC2Y7vDMA8dM1SUEAEV82kgSQIlXNMvA==, + } + + "@vitest/spy@4.0.18": + resolution: + { + integrity: sha512-cbQt3PTSD7P2OARdVW3qWER5EGq7PHlvE+QfzSC0lbwO+xnt7+XH06ZzFjFRgzUX//JmpxrCu92VdwvEPlWSNw==, + } + + "@vitest/utils@4.0.18": + resolution: + { + integrity: sha512-msMRKLMVLWygpK3u2Hybgi4MNjcYJvwTb0Ru09+fOyCXIgT5raYP041DRRdiJiI3k/2U6SEbAETB3YtBrUkCFA==, + } + + acorn@8.16.0: + resolution: + { + integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==, + } + engines: { node: ">=0.4.0" } + hasBin: true + + ansi-regex@6.2.2: + resolution: + { + integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==, + } + engines: { node: ">=12" } + + any-promise@1.3.0: + resolution: + { + integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==, + } + + assertion-error@2.0.1: + resolution: + { + integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==, + } + engines: { node: ">=12" } + + bn.js@5.2.2: + resolution: + { + integrity: sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==, + } + + bundle-require@5.1.0: + resolution: + { + integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==, + } + engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } + peerDependencies: + esbuild: ">=0.18" + + cac@6.7.14: + resolution: + { + integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==, + } + engines: { node: ">=8" } + + chai@6.2.2: + resolution: + { + integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==, + } + engines: { node: ">=18" } + + chalk@5.6.2: + resolution: + { + integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==, + } + engines: { node: ^12.17.0 || ^14.13 || >=16.0.0 } + + chokidar@4.0.3: + resolution: + { + integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==, + } + engines: { node: ">= 14.16.0" } + + cli-cursor@5.0.0: + resolution: + { + integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==, + } + engines: { node: ">=18" } + + cli-spinners@3.4.0: + resolution: + { + integrity: sha512-bXfOC4QcT1tKXGorxL3wbJm6XJPDqEnij2gQ2m7ESQuE+/z9YFIWnl/5RpTiKWbMq3EVKR4fRLJGn6DVfu0mpw==, + } + engines: { node: ">=18.20" } + + commander@14.0.3: + resolution: + { + integrity: sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==, + } + engines: { node: ">=20" } + + commander@4.1.1: + resolution: + { + integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==, + } + engines: { node: ">= 6" } + + confbox@0.1.8: + resolution: + { + integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==, + } + + consola@3.4.2: + resolution: + { + integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==, + } + engines: { node: ^14.18.0 || >=16.10.0 } + + cross-spawn@7.0.6: + resolution: + { + integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==, + } + engines: { node: ">= 8" } + + debug@4.4.3: + resolution: + { + integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==, + } + engines: { node: ">=6.0" } + peerDependencies: + supports-color: "*" + peerDependenciesMeta: + supports-color: + optional: true + + deepmerge-ts@7.1.5: + resolution: + { + integrity: sha512-HOJkrhaYsweh+W+e74Yn7YStZOilkoPb6fycpwNLKzSPtruFs48nYis0zy5yJz1+ktUhHxoRDJ27RQAWLIJVJw==, + } + engines: { node: ">=16.0.0" } + + detect-indent@7.0.2: + resolution: + { + integrity: sha512-y+8xyqdGLL+6sh0tVeHcfP/QDd8gUgbasolJJpY7NgeQGSZ739bDtSiaiDgtoicy+mtYB81dKLxO9xRhCyIB3A==, + } + engines: { node: ">=12.20" } + + es-module-lexer@1.7.0: + resolution: + { + integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==, + } + + esbuild@0.25.12: + resolution: + { + integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==, + } + engines: { node: ">=18" } + hasBin: true + + esbuild@0.27.3: + resolution: + { + integrity: sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==, + } + engines: { node: ">=18" } + hasBin: true + + estree-walker@3.0.3: + resolution: + { + integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==, + } + + execa@9.6.1: + resolution: + { + integrity: sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==, + } + engines: { node: ^18.19.0 || >=20.5.0 } + + expect-type@1.3.0: + resolution: + { + integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==, + } + engines: { node: ">=12.0.0" } + + fdir@6.5.0: + resolution: + { + integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==, + } + engines: { node: ">=12.0.0" } + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + figures@6.1.0: + resolution: + { + integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==, + } + engines: { node: ">=18" } + + fix-dts-default-cjs-exports@1.0.1: + resolution: + { + integrity: sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==, + } + + fs.promises.exists@1.1.4: + resolution: + { + integrity: sha512-lJzUGWbZn8vhGWBedA+RYjB/BeJ+3458ljUfmplqhIeb6ewzTFWNPCR1HCiYCkXV9zxcHz9zXkJzMsEgDLzh3Q==, + } + + fsevents@2.3.3: + resolution: + { + integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==, + } + engines: { node: ^8.16.0 || ^10.6.0 || >=11.0.0 } + os: [darwin] + + get-east-asian-width@1.4.0: + resolution: + { + integrity: sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==, + } + engines: { node: ">=18" } + + get-stream@9.0.1: + resolution: + { + integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==, + } + engines: { node: ">=18" } + + get-tsconfig@4.13.6: + resolution: + { + integrity: sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==, + } + + hosted-git-info@7.0.2: + resolution: + { + integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==, + } + engines: { node: ^16.14.0 || >=18.0.0 } + + hosted-git-info@9.0.2: + resolution: + { + integrity: sha512-M422h7o/BR3rmCQ8UHi7cyyMqKltdP9Uo+J2fXK+RSAY+wTcKOIRyhTuKv4qn+DJf3g+PL890AzId5KZpX+CBg==, + } + engines: { node: ^20.17.0 || >=22.9.0 } + + human-signals@8.0.1: + resolution: + { + integrity: sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==, + } + engines: { node: ">=18.18.0" } + + imurmurhash@0.1.4: + resolution: + { + integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==, + } + engines: { node: ">=0.8.19" } + + index-to-position@1.2.0: + resolution: + { + integrity: sha512-Yg7+ztRkqslMAS2iFaU+Oa4KTSidr63OsFGlOrJoW981kIYO3CGCS3wA95P1mUi/IVSJkn0D479KTJpVpvFNuw==, + } + engines: { node: ">=18" } + + is-interactive@2.0.0: + resolution: + { + integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==, + } + engines: { node: ">=12" } + + is-plain-obj@4.1.0: + resolution: + { + integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==, + } + engines: { node: ">=12" } + + is-stream@4.0.1: + resolution: + { + integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==, + } + engines: { node: ">=18" } + + is-unicode-supported@2.1.0: + resolution: + { + integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==, + } + engines: { node: ">=18" } + + isexe@2.0.0: + resolution: + { + integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==, + } + + joycon@3.1.1: + resolution: + { + integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==, + } + engines: { node: ">=10" } + + js-tokens@4.0.0: + resolution: + { + integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==, + } + + lilconfig@3.1.3: + resolution: + { + integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==, + } + engines: { node: ">=14" } + + lines-and-columns@1.2.4: + resolution: + { + integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==, + } + + load-tsconfig@0.2.5: + resolution: + { + integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==, + } + engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } + + lodash.sortby@4.7.0: + resolution: + { + integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==, + } + + log-symbols@7.0.1: + resolution: + { + integrity: sha512-ja1E3yCr9i/0hmBVaM0bfwDjnGy8I/s6PP4DFp+yP+a+mrHO4Rm7DtmnqROTUkHIkqffC84YY7AeqX6oFk0WFg==, + } + engines: { node: ">=18" } + + lru-cache@10.4.3: + resolution: + { + integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==, + } + + lru-cache@11.2.6: + resolution: + { + integrity: sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==, + } + engines: { node: 20 || >=22 } + + magic-string@0.30.21: + resolution: + { + integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==, + } + + mimic-function@5.0.1: + resolution: + { + integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==, + } + engines: { node: ">=18" } + + mlkem@2.5.0: + resolution: + { + integrity: sha512-TnSvGBs0EVPukQcdPF0882ZoYXYuD2rb+VgO0kUDbFi/XM1rJOwnQoFW3wGGuc3nG3AT/zp3oWJ86W7ewwKYyA==, + } + engines: { node: ">=16.0.0" } + + mlly@1.8.0: + resolution: + { + integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==, + } + + ms@2.1.3: + resolution: + { + integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==, + } + + mz@2.7.0: + resolution: + { + integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==, + } + + nanoid@3.3.11: + resolution: + { + integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==, + } + engines: { node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1 } + hasBin: true + + normalize-package-data@6.0.2: + resolution: + { + integrity: sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==, + } + engines: { node: ^16.14.0 || >=18.0.0 } + + normalize-package-data@8.0.0: + resolution: + { + integrity: sha512-RWk+PI433eESQ7ounYxIp67CYuVsS1uYSonX3kA6ps/3LWfjVQa/ptEg6Y3T6uAMq1mWpX9PQ+qx+QaHpsc7gQ==, + } + engines: { node: ^20.17.0 || >=22.9.0 } + + npm-run-path@6.0.0: + resolution: + { + integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==, + } + engines: { node: ">=18" } + + object-assign@4.1.1: + resolution: + { + integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==, + } + engines: { node: ">=0.10.0" } + + obug@2.1.1: + resolution: + { + integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==, + } + + onetime@7.0.0: + resolution: + { + integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==, + } + engines: { node: ">=18" } + + ora@9.3.0: + resolution: + { + integrity: sha512-lBX72MWFduWEf7v7uWf5DHp9Jn5BI8bNPGuFgtXMmr2uDz2Gz2749y3am3agSDdkhHPHYmmxEGSKH85ZLGzgXw==, + } + engines: { node: ">=20" } + + parse-json@8.3.0: + resolution: + { + integrity: sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==, + } + engines: { node: ">=18" } + + parse-ms@4.0.0: + resolution: + { + integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==, + } + engines: { node: ">=18" } + + path-key@3.1.1: + resolution: + { + integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==, + } + engines: { node: ">=8" } + + path-key@4.0.0: + resolution: + { + integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==, + } + engines: { node: ">=12" } + + pathe@2.0.3: + resolution: + { + integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==, + } + + picocolors@1.1.1: + resolution: + { + integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==, + } + + picomatch@4.0.3: + resolution: + { + integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==, + } + engines: { node: ">=12" } + + pirates@4.0.7: + resolution: + { + integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==, + } + engines: { node: ">= 6" } + + pkg-types@1.3.1: + resolution: + { + integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==, + } + + polkadot-api@1.23.3: + resolution: + { + integrity: sha512-wOWli6Cfk3bO1u/W8qmwriCIKxATkNea8Jyg1jj7GzAqafxy295BYPzYHy2mJZCQ0PAVFPR4/JvCXocTLBsp5A==, + } + hasBin: true + peerDependencies: + rxjs: ">=7.8.0" + + postcss-load-config@6.0.1: + resolution: + { + integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==, + } + 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 + + postcss@8.5.6: + resolution: + { + integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==, + } + engines: { node: ^10 || ^12 || >=14 } + + prettier@3.8.1: + resolution: + { + integrity: sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==, + } + engines: { node: ">=14" } + hasBin: true + + pretty-ms@9.3.0: + resolution: + { + integrity: sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==, + } + engines: { node: ">=18" } + + punycode@2.3.1: + resolution: + { + integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==, + } + engines: { node: ">=6" } + + read-pkg@10.1.0: + resolution: + { + integrity: sha512-I8g2lArQiP78ll51UeMZojewtYgIRCKCWqZEgOO8c/uefTI+XDXvCSXu3+YNUaTNvZzobrL5+SqHjBrByRRTdg==, + } + engines: { node: ">=20" } + + read-pkg@9.0.1: + resolution: + { + integrity: sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==, + } + engines: { node: ">=18" } + + readdirp@4.1.2: + resolution: + { + integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==, + } + engines: { node: ">= 14.18.0" } + + resolve-from@5.0.0: + resolution: + { + integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==, + } + engines: { node: ">=8" } + + resolve-pkg-maps@1.0.0: + resolution: + { + integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==, + } + + restore-cursor@5.1.0: + resolution: + { + integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==, + } + engines: { node: ">=18" } + + rollup@4.57.1: + resolution: + { + integrity: sha512-oQL6lgK3e2QZeQ7gcgIkS2YZPg5slw37hYufJ3edKlfQSGGm8ICoxswK15ntSzF/a8+h7ekRy7k7oWc3BQ7y8A==, + } + engines: { node: ">=18.0.0", npm: ">=8.0.0" } + hasBin: true + + rxjs@7.8.2: + resolution: + { + integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==, + } + + scale-ts@1.6.1: + resolution: + { + integrity: sha512-PBMc2AWc6wSEqJYBDPcyCLUj9/tMKnLX70jLOSndMtcUoLQucP/DM0vnQo1wJAYjTrQiq8iG9rD0q6wFzgjH7g==, + } + + semver@7.7.4: + resolution: + { + integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==, + } + engines: { node: ">=10" } + hasBin: true + + shebang-command@2.0.0: + resolution: + { + integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==, + } + engines: { node: ">=8" } + + shebang-regex@3.0.0: + resolution: + { + integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==, + } + engines: { node: ">=8" } + + siginfo@2.0.0: + resolution: + { + integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==, + } + + signal-exit@4.1.0: + resolution: + { + integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==, + } + engines: { node: ">=14" } + + smoldot@2.0.40: + resolution: + { + integrity: sha512-h6XC/kKDLdZBBTI0X8y4ZxmaZ2KYVVB0+5isCQm6j26ljeNjHZUDOV+hf8VyoE23+jg00wrxNJ2IVcIAURxwtg==, + } + + sort-keys@5.1.0: + resolution: + { + integrity: sha512-aSbHV0DaBcr7u0PVHXzM6NbZNAtrr9sF6+Qfs9UUVG7Ll3jQ6hHi8F/xqIIcn2rvIVbr0v/2zyjSdwSV47AgLQ==, + } + engines: { node: ">=12" } + + source-map-js@1.2.1: + resolution: + { + integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==, + } + engines: { node: ">=0.10.0" } + + source-map@0.8.0-beta.0: + resolution: + { + integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==, + } + engines: { node: ">= 8" } + deprecated: The work that was done in this beta branch won't be included in future versions + + spdx-correct@3.2.0: + resolution: + { + integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==, + } + + spdx-exceptions@2.5.0: + resolution: + { + integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==, + } + + spdx-expression-parse@3.0.1: + resolution: + { + integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==, + } + + spdx-license-ids@3.0.23: + resolution: + { + integrity: sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==, + } + + stackback@0.0.2: + resolution: + { + integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==, + } + + std-env@3.10.0: + resolution: + { + integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==, + } + + stdin-discarder@0.3.1: + resolution: + { + integrity: sha512-reExS1kSGoElkextOcPkel4NE99S0BWxjUHQeDFnR8S993JxpPX7KU4MNmO19NXhlJp+8dmdCbKQVNgLJh2teA==, + } + engines: { node: ">=18" } + + string-width@8.1.1: + resolution: + { + integrity: sha512-KpqHIdDL9KwYk22wEOg/VIqYbrnLeSApsKT/bSj6Ez7pn3CftUiLAv2Lccpq1ALcpLV9UX1Ppn92npZWu2w/aw==, + } + engines: { node: ">=20" } + + strip-ansi@7.1.2: + resolution: + { + integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==, + } + engines: { node: ">=12" } + + strip-final-newline@4.0.0: + resolution: + { + integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==, + } + engines: { node: ">=18" } + + sucrase@3.35.1: + resolution: + { + integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==, + } + engines: { node: ">=16 || 14 >=14.17" } + hasBin: true + + tagged-tag@1.0.0: + resolution: + { + integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==, + } + engines: { node: ">=20" } + + thenify-all@1.6.0: + resolution: + { + integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==, + } + engines: { node: ">=0.8" } + + thenify@3.3.1: + resolution: + { + integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==, + } + + tinybench@2.9.0: + resolution: + { + integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==, + } + + tinyexec@0.3.2: + resolution: + { + integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==, + } + + tinyexec@1.0.2: + resolution: + { + integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==, + } + engines: { node: ">=18" } + + tinyglobby@0.2.15: + resolution: + { + integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==, + } + engines: { node: ">=12.0.0" } + + tinyrainbow@3.0.3: + resolution: + { + integrity: sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==, + } + engines: { node: ">=14.0.0" } + + tr46@1.0.1: + resolution: + { + integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==, + } + + tree-kill@1.2.2: + resolution: + { + integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==, + } + hasBin: true + + ts-interface-checker@0.1.13: + resolution: + { + integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==, + } + + tsc-prog@2.3.0: + resolution: + { + integrity: sha512-ycET2d75EgcX7y8EmG4KiZkLAwUzbY4xRhA6NU0uVbHkY4ZjrAAuzTMxXI85kOwATqPnBI5C/7y7rlpY0xdqHA==, + } + engines: { node: ">=12" } + peerDependencies: + typescript: ">=4" + + tslib@2.8.1: + resolution: + { + integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==, + } + + tsup@8.5.0: + resolution: + { + integrity: sha512-VmBp77lWNQq6PfuMqCHD3xWl22vEoWsKajkF8t+yMBawlUS8JzEI+vOVMeuNZIuMML8qXRizFKi9oD5glKQVcQ==, + } + engines: { node: ">=18" } + hasBin: true + 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 + + tsx@4.21.0: + resolution: + { + integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==, + } + engines: { node: ">=18.0.0" } + hasBin: true + + type-fest@4.41.0: + resolution: + { + integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==, + } + engines: { node: ">=16" } + + type-fest@5.4.4: + resolution: + { + integrity: sha512-JnTrzGu+zPV3aXIUhnyWJj4z/wigMsdYajGLIYakqyOW1nPllzXEJee0QQbHj+CTIQtXGlAjuK0UY+2xTyjVAw==, + } + engines: { node: ">=20" } + + typescript@5.9.3: + resolution: + { + integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==, + } + engines: { node: ">=14.17" } + hasBin: true + + ufo@1.6.3: + resolution: + { + integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==, + } + + undici-types@7.16.0: + resolution: + { + integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==, + } + + undici-types@7.18.2: + resolution: + { + integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==, + } + + unicorn-magic@0.1.0: + resolution: + { + integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==, + } + engines: { node: ">=18" } + + unicorn-magic@0.3.0: + resolution: + { + integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==, + } + engines: { node: ">=18" } + + unicorn-magic@0.4.0: + resolution: + { + integrity: sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw==, + } + engines: { node: ">=20" } + + validate-npm-package-license@3.0.4: + resolution: + { + integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==, + } + + vite@7.3.1: + resolution: + { + integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==, + } + engines: { node: ^20.19.0 || >=22.12.0 } + hasBin: true + peerDependencies: + "@types/node": ^20.19.0 || >=22.12.0 + jiti: ">=1.21.0" + less: ^4.0.0 + lightningcss: ^1.21.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: ">=0.54.8" + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + "@types/node": + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vitest@4.0.18: + resolution: + { + integrity: sha512-hOQuK7h0FGKgBAas7v0mSAsnvrIgAvWmRFjmzpJ7SwFHH3g1k2u37JtYwOwmEKhK6ZO3v9ggDBBm0La1LCK4uQ==, + } + engines: { node: ^20.0.0 || ^22.0.0 || >=24.0.0 } + hasBin: true + peerDependencies: + "@edge-runtime/vm": "*" + "@opentelemetry/api": ^1.9.0 + "@types/node": ^20.0.0 || ^22.0.0 || >=24.0.0 + "@vitest/browser-playwright": 4.0.18 + "@vitest/browser-preview": 4.0.18 + "@vitest/browser-webdriverio": 4.0.18 + "@vitest/ui": 4.0.18 + happy-dom: "*" + jsdom: "*" + peerDependenciesMeta: + "@edge-runtime/vm": + optional: true + "@opentelemetry/api": + optional: true + "@types/node": + optional: true + "@vitest/browser-playwright": + optional: true + "@vitest/browser-preview": + optional: true + "@vitest/browser-webdriverio": + optional: true + "@vitest/ui": + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + webidl-conversions@4.0.2: + resolution: + { + integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==, + } + + whatwg-url@7.1.0: + resolution: + { + integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==, + } + + which@2.0.2: + resolution: + { + integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==, + } + engines: { node: ">= 8" } + hasBin: true + + why-is-node-running@2.3.0: + resolution: + { + integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==, + } + engines: { node: ">=8" } + hasBin: true + + write-file-atomic@5.0.1: + resolution: + { + integrity: sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==, + } + engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } + + write-json-file@6.0.0: + resolution: + { + integrity: sha512-MNHcU3f9WxnNyR6MxsYSj64Jz0+dwIpisWKWq9gqLj/GwmA9INg3BZ3vt70/HB3GEwrnDQWr4RPrywnhNzmUFA==, + } + engines: { node: ">=18" } + + write-package@7.2.0: + resolution: + { + integrity: sha512-uMQTubF/vcu+Wd0b5BGtDmiXePd/+44hUWQz2nZPbs92/BnxRo74tqs+hqDo12RLiEd+CXFKUwxvvIZvtt34Jw==, + } + engines: { node: ">=18" } + + ws@8.19.0: + resolution: + { + integrity: sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==, + } + 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 + + yoctocolors@2.1.2: + resolution: + { + integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==, + } + engines: { node: ">=18" } + +snapshots: + "@babel/code-frame@7.29.0": + dependencies: + "@babel/helper-validator-identifier": 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + "@babel/helper-validator-identifier@7.28.5": {} + + "@commander-js/extra-typings@14.0.0(commander@14.0.3)": + dependencies: + commander: 14.0.3 + + "@esbuild/aix-ppc64@0.25.12": + optional: true + + "@esbuild/aix-ppc64@0.27.3": + optional: true + + "@esbuild/android-arm64@0.25.12": + optional: true + + "@esbuild/android-arm64@0.27.3": + optional: true + + "@esbuild/android-arm@0.25.12": + optional: true + + "@esbuild/android-arm@0.27.3": + optional: true + + "@esbuild/android-x64@0.25.12": + optional: true + + "@esbuild/android-x64@0.27.3": + optional: true + + "@esbuild/darwin-arm64@0.25.12": + optional: true + + "@esbuild/darwin-arm64@0.27.3": + optional: true + + "@esbuild/darwin-x64@0.25.12": + optional: true + + "@esbuild/darwin-x64@0.27.3": + optional: true + + "@esbuild/freebsd-arm64@0.25.12": + optional: true + + "@esbuild/freebsd-arm64@0.27.3": + optional: true + + "@esbuild/freebsd-x64@0.25.12": + optional: true + + "@esbuild/freebsd-x64@0.27.3": + optional: true + + "@esbuild/linux-arm64@0.25.12": + optional: true + + "@esbuild/linux-arm64@0.27.3": + optional: true + + "@esbuild/linux-arm@0.25.12": + optional: true + + "@esbuild/linux-arm@0.27.3": + optional: true + + "@esbuild/linux-ia32@0.25.12": + optional: true + + "@esbuild/linux-ia32@0.27.3": + optional: true + + "@esbuild/linux-loong64@0.25.12": + optional: true + + "@esbuild/linux-loong64@0.27.3": + optional: true + + "@esbuild/linux-mips64el@0.25.12": + optional: true + + "@esbuild/linux-mips64el@0.27.3": + optional: true + + "@esbuild/linux-ppc64@0.25.12": + optional: true + + "@esbuild/linux-ppc64@0.27.3": + optional: true + + "@esbuild/linux-riscv64@0.25.12": + optional: true + + "@esbuild/linux-riscv64@0.27.3": + optional: true + + "@esbuild/linux-s390x@0.25.12": + optional: true + + "@esbuild/linux-s390x@0.27.3": + optional: true + + "@esbuild/linux-x64@0.25.12": + optional: true + + "@esbuild/linux-x64@0.27.3": + optional: true + + "@esbuild/netbsd-arm64@0.25.12": + optional: true + + "@esbuild/netbsd-arm64@0.27.3": + optional: true + + "@esbuild/netbsd-x64@0.25.12": + optional: true + + "@esbuild/netbsd-x64@0.27.3": + optional: true + + "@esbuild/openbsd-arm64@0.25.12": + optional: true + + "@esbuild/openbsd-arm64@0.27.3": + optional: true + + "@esbuild/openbsd-x64@0.25.12": + optional: true + + "@esbuild/openbsd-x64@0.27.3": + optional: true + + "@esbuild/openharmony-arm64@0.25.12": + optional: true + + "@esbuild/openharmony-arm64@0.27.3": + optional: true + + "@esbuild/sunos-x64@0.25.12": + optional: true + + "@esbuild/sunos-x64@0.27.3": + optional: true + + "@esbuild/win32-arm64@0.25.12": + optional: true + + "@esbuild/win32-arm64@0.27.3": + optional: true + + "@esbuild/win32-ia32@0.25.12": + optional: true + + "@esbuild/win32-ia32@0.27.3": + optional: true + + "@esbuild/win32-x64@0.25.12": + optional: true + + "@esbuild/win32-x64@0.27.3": + optional: true + + "@jridgewell/gen-mapping@0.3.13": + dependencies: + "@jridgewell/sourcemap-codec": 1.5.5 + "@jridgewell/trace-mapping": 0.3.31 + + "@jridgewell/resolve-uri@3.1.2": {} + + "@jridgewell/sourcemap-codec@1.5.5": {} + + "@jridgewell/trace-mapping@0.3.31": + dependencies: + "@jridgewell/resolve-uri": 3.1.2 + "@jridgewell/sourcemap-codec": 1.5.5 + + "@noble/ciphers@2.1.1": {} + + "@noble/curves@1.9.7": + dependencies: + "@noble/hashes": 1.8.0 + + "@noble/curves@2.0.1": + dependencies: + "@noble/hashes": 2.0.1 + + "@noble/hashes@1.8.0": {} + + "@noble/hashes@2.0.1": {} + + "@polkadot-api/cli@0.18.1(postcss@8.5.6)(tsx@4.21.0)": + dependencies: + "@commander-js/extra-typings": 14.0.0(commander@14.0.3) + "@polkadot-api/codegen": 0.21.2 + "@polkadot-api/ink-contracts": 0.4.6 + "@polkadot-api/json-rpc-provider": 0.0.4 + "@polkadot-api/known-chains": 0.9.18 + "@polkadot-api/legacy-provider": 0.3.8(rxjs@7.8.2) + "@polkadot-api/metadata-compatibility": 0.4.4 + "@polkadot-api/observable-client": 0.17.3(rxjs@7.8.2) + "@polkadot-api/polkadot-sdk-compat": 2.4.1 + "@polkadot-api/sm-provider": 0.1.16(@polkadot-api/smoldot@0.3.15) + "@polkadot-api/smoldot": 0.3.15 + "@polkadot-api/substrate-bindings": 0.17.0 + "@polkadot-api/substrate-client": 0.5.0 + "@polkadot-api/utils": 0.2.0 + "@polkadot-api/wasm-executor": 0.2.3 + "@polkadot-api/ws-provider": 0.7.5 + "@types/node": 25.3.0 + commander: 14.0.3 + execa: 9.6.1 + fs.promises.exists: 1.1.4 + ora: 9.3.0 + read-pkg: 10.1.0 + rxjs: 7.8.2 + tsc-prog: 2.3.0(typescript@5.9.3) + tsup: 8.5.0(postcss@8.5.6)(tsx@4.21.0)(typescript@5.9.3) + typescript: 5.9.3 + write-package: 7.2.0 + transitivePeerDependencies: + - "@microsoft/api-extractor" + - "@swc/core" + - bufferutil + - jiti + - postcss + - supports-color + - tsx + - utf-8-validate + - yaml + + "@polkadot-api/codegen@0.21.2": + dependencies: + "@polkadot-api/ink-contracts": 0.4.6 + "@polkadot-api/metadata-builders": 0.13.9 + "@polkadot-api/metadata-compatibility": 0.4.4 + "@polkadot-api/substrate-bindings": 0.17.0 + "@polkadot-api/utils": 0.2.0 + + "@polkadot-api/descriptors@file:.papi/descriptors(polkadot-api@1.23.3(postcss@8.5.6)(rxjs@7.8.2)(tsx@4.21.0))": + dependencies: + polkadot-api: 1.23.3(postcss@8.5.6)(rxjs@7.8.2)(tsx@4.21.0) + + "@polkadot-api/ink-contracts@0.4.6": + dependencies: + "@polkadot-api/metadata-builders": 0.13.9 + "@polkadot-api/substrate-bindings": 0.17.0 + "@polkadot-api/utils": 0.2.0 + + "@polkadot-api/json-rpc-provider-proxy@0.2.8": {} + + "@polkadot-api/json-rpc-provider@0.0.4": {} + + "@polkadot-api/known-chains@0.9.18": {} + + "@polkadot-api/legacy-provider@0.3.8(rxjs@7.8.2)": + dependencies: + "@polkadot-api/json-rpc-provider": 0.0.4 + "@polkadot-api/raw-client": 0.1.1 + "@polkadot-api/substrate-bindings": 0.17.0 + "@polkadot-api/utils": 0.2.0 + rxjs: 7.8.2 + + "@polkadot-api/logs-provider@0.0.6": + dependencies: + "@polkadot-api/json-rpc-provider": 0.0.4 + + "@polkadot-api/merkleize-metadata@1.1.29": + dependencies: + "@polkadot-api/metadata-builders": 0.13.9 + "@polkadot-api/substrate-bindings": 0.17.0 + "@polkadot-api/utils": 0.2.0 + + "@polkadot-api/metadata-builders@0.13.9": + dependencies: + "@polkadot-api/substrate-bindings": 0.17.0 + "@polkadot-api/utils": 0.2.0 + + "@polkadot-api/metadata-compatibility@0.4.4": + dependencies: + "@polkadot-api/metadata-builders": 0.13.9 + "@polkadot-api/substrate-bindings": 0.17.0 + + "@polkadot-api/observable-client@0.17.3(rxjs@7.8.2)": + dependencies: + "@polkadot-api/metadata-builders": 0.13.9 + "@polkadot-api/substrate-bindings": 0.17.0 + "@polkadot-api/substrate-client": 0.5.0 + "@polkadot-api/utils": 0.2.0 + rxjs: 7.8.2 + + "@polkadot-api/pjs-signer@0.6.19": + dependencies: + "@polkadot-api/metadata-builders": 0.13.9 + "@polkadot-api/polkadot-signer": 0.1.6 + "@polkadot-api/signers-common": 0.1.20 + "@polkadot-api/substrate-bindings": 0.17.0 + "@polkadot-api/utils": 0.2.0 + + "@polkadot-api/polkadot-sdk-compat@2.4.1": + dependencies: + "@polkadot-api/json-rpc-provider": 0.0.4 + + "@polkadot-api/polkadot-signer@0.1.6": {} + + "@polkadot-api/raw-client@0.1.1": + dependencies: + "@polkadot-api/json-rpc-provider": 0.0.4 + + "@polkadot-api/signer@0.2.13": + dependencies: + "@noble/hashes": 2.0.1 + "@polkadot-api/merkleize-metadata": 1.1.29 + "@polkadot-api/polkadot-signer": 0.1.6 + "@polkadot-api/signers-common": 0.1.20 + "@polkadot-api/substrate-bindings": 0.17.0 + "@polkadot-api/utils": 0.2.0 + + "@polkadot-api/signers-common@0.1.20": + dependencies: + "@polkadot-api/metadata-builders": 0.13.9 + "@polkadot-api/polkadot-signer": 0.1.6 + "@polkadot-api/substrate-bindings": 0.17.0 + "@polkadot-api/utils": 0.2.0 + + "@polkadot-api/sm-provider@0.1.16(@polkadot-api/smoldot@0.3.15)": + dependencies: + "@polkadot-api/json-rpc-provider": 0.0.4 + "@polkadot-api/json-rpc-provider-proxy": 0.2.8 + "@polkadot-api/smoldot": 0.3.15 + + "@polkadot-api/smoldot@0.3.15": + dependencies: + "@types/node": 24.10.13 + smoldot: 2.0.40 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + "@polkadot-api/substrate-bindings@0.17.0": + dependencies: + "@noble/hashes": 2.0.1 + "@polkadot-api/utils": 0.2.0 + "@scure/base": 2.0.0 + scale-ts: 1.6.1 + + "@polkadot-api/substrate-client@0.5.0": + dependencies: + "@polkadot-api/json-rpc-provider": 0.0.4 + "@polkadot-api/raw-client": 0.1.1 + "@polkadot-api/utils": 0.2.0 + + "@polkadot-api/utils@0.2.0": {} + + "@polkadot-api/wasm-executor@0.2.3": {} + + "@polkadot-api/ws-provider@0.7.5": + dependencies: + "@polkadot-api/json-rpc-provider": 0.0.4 + "@polkadot-api/json-rpc-provider-proxy": 0.2.8 + "@types/ws": 8.18.1 + ws: 8.19.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + "@polkadot-labs/hdkd-helpers@0.0.25": + 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 + + "@polkadot-labs/hdkd-helpers@0.0.27": + dependencies: + "@noble/curves": 2.0.1 + "@noble/hashes": 2.0.1 + "@scure/base": 2.0.0 + "@scure/sr25519": 1.0.0 + scale-ts: 1.6.1 + + "@polkadot-labs/hdkd@0.0.25": + dependencies: + "@polkadot-labs/hdkd-helpers": 0.0.27 + + "@polkadot/keyring@14.0.1(@polkadot/util-crypto@14.0.1(@polkadot/util@14.0.1))(@polkadot/util@14.0.1)": + dependencies: + "@polkadot/util": 14.0.1 + "@polkadot/util-crypto": 14.0.1(@polkadot/util@14.0.1) + tslib: 2.8.1 + + "@polkadot/networks@14.0.1": + dependencies: + "@polkadot/util": 14.0.1 + "@substrate/ss58-registry": 1.51.0 + tslib: 2.8.1 + + "@polkadot/util-crypto@14.0.1(@polkadot/util@14.0.1)": + dependencies: + "@noble/curves": 1.9.7 + "@noble/hashes": 1.8.0 + "@polkadot/networks": 14.0.1 + "@polkadot/util": 14.0.1 + "@polkadot/wasm-crypto": 7.5.4(@polkadot/util@14.0.1)(@polkadot/x-randomvalues@14.0.1(@polkadot/util@14.0.1)(@polkadot/wasm-util@7.5.4(@polkadot/util@14.0.1))) + "@polkadot/wasm-util": 7.5.4(@polkadot/util@14.0.1) + "@polkadot/x-bigint": 14.0.1 + "@polkadot/x-randomvalues": 14.0.1(@polkadot/util@14.0.1)(@polkadot/wasm-util@7.5.4(@polkadot/util@14.0.1)) + "@scure/base": 1.2.6 + "@scure/sr25519": 0.2.0 + tslib: 2.8.1 + + "@polkadot/util@14.0.1": + 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.2.0 + bn.js: 5.2.2 + tslib: 2.8.1 + + "@polkadot/wasm-bridge@7.5.4(@polkadot/util@14.0.1)(@polkadot/x-randomvalues@14.0.1(@polkadot/util@14.0.1)(@polkadot/wasm-util@7.5.4(@polkadot/util@14.0.1)))": + dependencies: + "@polkadot/util": 14.0.1 + "@polkadot/wasm-util": 7.5.4(@polkadot/util@14.0.1) + "@polkadot/x-randomvalues": 14.0.1(@polkadot/util@14.0.1)(@polkadot/wasm-util@7.5.4(@polkadot/util@14.0.1)) + tslib: 2.8.1 + + "@polkadot/wasm-crypto-asmjs@7.5.4(@polkadot/util@14.0.1)": + dependencies: + "@polkadot/util": 14.0.1 + tslib: 2.8.1 + + "@polkadot/wasm-crypto-init@7.5.4(@polkadot/util@14.0.1)(@polkadot/x-randomvalues@14.0.1(@polkadot/util@14.0.1)(@polkadot/wasm-util@7.5.4(@polkadot/util@14.0.1)))": + dependencies: + "@polkadot/util": 14.0.1 + "@polkadot/wasm-bridge": 7.5.4(@polkadot/util@14.0.1)(@polkadot/x-randomvalues@14.0.1(@polkadot/util@14.0.1)(@polkadot/wasm-util@7.5.4(@polkadot/util@14.0.1))) + "@polkadot/wasm-crypto-asmjs": 7.5.4(@polkadot/util@14.0.1) + "@polkadot/wasm-crypto-wasm": 7.5.4(@polkadot/util@14.0.1) + "@polkadot/wasm-util": 7.5.4(@polkadot/util@14.0.1) + "@polkadot/x-randomvalues": 14.0.1(@polkadot/util@14.0.1)(@polkadot/wasm-util@7.5.4(@polkadot/util@14.0.1)) + tslib: 2.8.1 + + "@polkadot/wasm-crypto-wasm@7.5.4(@polkadot/util@14.0.1)": + dependencies: + "@polkadot/util": 14.0.1 + "@polkadot/wasm-util": 7.5.4(@polkadot/util@14.0.1) + tslib: 2.8.1 + + "@polkadot/wasm-crypto@7.5.4(@polkadot/util@14.0.1)(@polkadot/x-randomvalues@14.0.1(@polkadot/util@14.0.1)(@polkadot/wasm-util@7.5.4(@polkadot/util@14.0.1)))": + dependencies: + "@polkadot/util": 14.0.1 + "@polkadot/wasm-bridge": 7.5.4(@polkadot/util@14.0.1)(@polkadot/x-randomvalues@14.0.1(@polkadot/util@14.0.1)(@polkadot/wasm-util@7.5.4(@polkadot/util@14.0.1))) + "@polkadot/wasm-crypto-asmjs": 7.5.4(@polkadot/util@14.0.1) + "@polkadot/wasm-crypto-init": 7.5.4(@polkadot/util@14.0.1)(@polkadot/x-randomvalues@14.0.1(@polkadot/util@14.0.1)(@polkadot/wasm-util@7.5.4(@polkadot/util@14.0.1))) + "@polkadot/wasm-crypto-wasm": 7.5.4(@polkadot/util@14.0.1) + "@polkadot/wasm-util": 7.5.4(@polkadot/util@14.0.1) + "@polkadot/x-randomvalues": 14.0.1(@polkadot/util@14.0.1)(@polkadot/wasm-util@7.5.4(@polkadot/util@14.0.1)) + tslib: 2.8.1 + + "@polkadot/wasm-util@7.5.4(@polkadot/util@14.0.1)": + dependencies: + "@polkadot/util": 14.0.1 + tslib: 2.8.1 + + "@polkadot/x-bigint@14.0.1": + dependencies: + "@polkadot/x-global": 14.0.1 + tslib: 2.8.1 + + "@polkadot/x-global@14.0.1": + dependencies: + tslib: 2.8.1 + + "@polkadot/x-randomvalues@14.0.1(@polkadot/util@14.0.1)(@polkadot/wasm-util@7.5.4(@polkadot/util@14.0.1))": + dependencies: + "@polkadot/util": 14.0.1 + "@polkadot/wasm-util": 7.5.4(@polkadot/util@14.0.1) + "@polkadot/x-global": 14.0.1 + tslib: 2.8.1 + + "@polkadot/x-textdecoder@14.0.1": + dependencies: + "@polkadot/x-global": 14.0.1 + tslib: 2.8.1 + + "@polkadot/x-textencoder@14.0.1": + dependencies: + "@polkadot/x-global": 14.0.1 + tslib: 2.8.1 + + "@rollup/rollup-android-arm-eabi@4.57.1": + optional: true + + "@rollup/rollup-android-arm64@4.57.1": + optional: true + + "@rollup/rollup-darwin-arm64@4.57.1": + optional: true + + "@rollup/rollup-darwin-x64@4.57.1": + optional: true + + "@rollup/rollup-freebsd-arm64@4.57.1": + optional: true + + "@rollup/rollup-freebsd-x64@4.57.1": + optional: true + + "@rollup/rollup-linux-arm-gnueabihf@4.57.1": + optional: true + + "@rollup/rollup-linux-arm-musleabihf@4.57.1": + optional: true + + "@rollup/rollup-linux-arm64-gnu@4.57.1": + optional: true + + "@rollup/rollup-linux-arm64-musl@4.57.1": + optional: true + + "@rollup/rollup-linux-loong64-gnu@4.57.1": + optional: true + + "@rollup/rollup-linux-loong64-musl@4.57.1": + optional: true + + "@rollup/rollup-linux-ppc64-gnu@4.57.1": + optional: true + + "@rollup/rollup-linux-ppc64-musl@4.57.1": + optional: true + + "@rollup/rollup-linux-riscv64-gnu@4.57.1": + optional: true + + "@rollup/rollup-linux-riscv64-musl@4.57.1": + optional: true + + "@rollup/rollup-linux-s390x-gnu@4.57.1": + optional: true + + "@rollup/rollup-linux-x64-gnu@4.57.1": + optional: true + + "@rollup/rollup-linux-x64-musl@4.57.1": + optional: true + + "@rollup/rollup-openbsd-x64@4.57.1": + optional: true + + "@rollup/rollup-openharmony-arm64@4.57.1": + optional: true + + "@rollup/rollup-win32-arm64-msvc@4.57.1": + optional: true + + "@rollup/rollup-win32-ia32-msvc@4.57.1": + optional: true + + "@rollup/rollup-win32-x64-gnu@4.57.1": + optional: true + + "@rollup/rollup-win32-x64-msvc@4.57.1": + optional: true + + "@rx-state/core@0.1.4(rxjs@7.8.2)": + dependencies: + rxjs: 7.8.2 + + "@scure/base@1.2.6": {} + + "@scure/base@2.0.0": {} + + "@scure/sr25519@0.2.0": + dependencies: + "@noble/curves": 1.9.7 + "@noble/hashes": 1.8.0 + + "@scure/sr25519@0.3.0": + dependencies: + "@noble/curves": 2.0.1 + "@noble/hashes": 2.0.1 + + "@scure/sr25519@1.0.0": + dependencies: + "@noble/curves": 2.0.1 + "@noble/hashes": 2.0.1 + + "@sec-ant/readable-stream@0.4.1": {} + + "@sindresorhus/merge-streams@4.0.0": {} + + "@standard-schema/spec@1.1.0": {} + + "@substrate/ss58-registry@1.51.0": {} + + "@types/bn.js@5.2.0": + dependencies: + "@types/node": 25.3.0 + + "@types/chai@5.2.3": + dependencies: + "@types/deep-eql": 4.0.2 + assertion-error: 2.0.1 + + "@types/deep-eql@4.0.2": {} + + "@types/estree@1.0.8": {} + + "@types/node@24.10.13": + dependencies: + undici-types: 7.16.0 + + "@types/node@25.3.0": + dependencies: + undici-types: 7.18.2 + + "@types/normalize-package-data@2.4.4": {} + + "@types/ws@8.18.1": + dependencies: + "@types/node": 25.3.0 + + "@vitest/expect@4.0.18": + dependencies: + "@standard-schema/spec": 1.1.0 + "@types/chai": 5.2.3 + "@vitest/spy": 4.0.18 + "@vitest/utils": 4.0.18 + chai: 6.2.2 + tinyrainbow: 3.0.3 + + "@vitest/mocker@4.0.18(vite@7.3.1(@types/node@24.10.13)(tsx@4.21.0))": + dependencies: + "@vitest/spy": 4.0.18 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 7.3.1(@types/node@24.10.13)(tsx@4.21.0) + + "@vitest/pretty-format@4.0.18": + dependencies: + tinyrainbow: 3.0.3 + + "@vitest/runner@4.0.18": + dependencies: + "@vitest/utils": 4.0.18 + pathe: 2.0.3 + + "@vitest/snapshot@4.0.18": + dependencies: + "@vitest/pretty-format": 4.0.18 + magic-string: 0.30.21 + pathe: 2.0.3 + + "@vitest/spy@4.0.18": {} + + "@vitest/utils@4.0.18": + dependencies: + "@vitest/pretty-format": 4.0.18 + tinyrainbow: 3.0.3 + + acorn@8.16.0: {} + + ansi-regex@6.2.2: {} + + any-promise@1.3.0: {} + + assertion-error@2.0.1: {} + + bn.js@5.2.2: {} + + bundle-require@5.1.0(esbuild@0.25.12): + dependencies: + esbuild: 0.25.12 + load-tsconfig: 0.2.5 + + cac@6.7.14: {} + + chai@6.2.2: {} + + chalk@5.6.2: {} + + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + + cli-cursor@5.0.0: + dependencies: + restore-cursor: 5.1.0 + + cli-spinners@3.4.0: {} + + commander@14.0.3: {} + + commander@4.1.1: {} + + confbox@0.1.8: {} + + consola@3.4.2: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + deepmerge-ts@7.1.5: {} + + detect-indent@7.0.2: {} + + es-module-lexer@1.7.0: {} + + esbuild@0.25.12: + 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 + + esbuild@0.27.3: + optionalDependencies: + "@esbuild/aix-ppc64": 0.27.3 + "@esbuild/android-arm": 0.27.3 + "@esbuild/android-arm64": 0.27.3 + "@esbuild/android-x64": 0.27.3 + "@esbuild/darwin-arm64": 0.27.3 + "@esbuild/darwin-x64": 0.27.3 + "@esbuild/freebsd-arm64": 0.27.3 + "@esbuild/freebsd-x64": 0.27.3 + "@esbuild/linux-arm": 0.27.3 + "@esbuild/linux-arm64": 0.27.3 + "@esbuild/linux-ia32": 0.27.3 + "@esbuild/linux-loong64": 0.27.3 + "@esbuild/linux-mips64el": 0.27.3 + "@esbuild/linux-ppc64": 0.27.3 + "@esbuild/linux-riscv64": 0.27.3 + "@esbuild/linux-s390x": 0.27.3 + "@esbuild/linux-x64": 0.27.3 + "@esbuild/netbsd-arm64": 0.27.3 + "@esbuild/netbsd-x64": 0.27.3 + "@esbuild/openbsd-arm64": 0.27.3 + "@esbuild/openbsd-x64": 0.27.3 + "@esbuild/openharmony-arm64": 0.27.3 + "@esbuild/sunos-x64": 0.27.3 + "@esbuild/win32-arm64": 0.27.3 + "@esbuild/win32-ia32": 0.27.3 + "@esbuild/win32-x64": 0.27.3 + + estree-walker@3.0.3: + dependencies: + "@types/estree": 1.0.8 + + execa@9.6.1: + dependencies: + "@sindresorhus/merge-streams": 4.0.0 + cross-spawn: 7.0.6 + figures: 6.1.0 + get-stream: 9.0.1 + 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.3.0 + signal-exit: 4.1.0 + strip-final-newline: 4.0.0 + yoctocolors: 2.1.2 + + expect-type@1.3.0: {} + + fdir@6.5.0(picomatch@4.0.3): + optionalDependencies: + picomatch: 4.0.3 + + figures@6.1.0: + dependencies: + is-unicode-supported: 2.1.0 + + fix-dts-default-cjs-exports@1.0.1: + dependencies: + magic-string: 0.30.21 + mlly: 1.8.0 + rollup: 4.57.1 + + fs.promises.exists@1.1.4: {} + + fsevents@2.3.3: + optional: true + + get-east-asian-width@1.4.0: {} + + get-stream@9.0.1: + dependencies: + "@sec-ant/readable-stream": 0.4.1 + is-stream: 4.0.1 + + get-tsconfig@4.13.6: + dependencies: + resolve-pkg-maps: 1.0.0 + optional: true + + hosted-git-info@7.0.2: + dependencies: + lru-cache: 10.4.3 + + hosted-git-info@9.0.2: + dependencies: + lru-cache: 11.2.6 + + human-signals@8.0.1: {} + + imurmurhash@0.1.4: {} + + index-to-position@1.2.0: {} + + is-interactive@2.0.0: {} + + is-plain-obj@4.1.0: {} + + is-stream@4.0.1: {} + + is-unicode-supported@2.1.0: {} + + isexe@2.0.0: {} + + joycon@3.1.1: {} + + js-tokens@4.0.0: {} + + lilconfig@3.1.3: {} + + lines-and-columns@1.2.4: {} + + load-tsconfig@0.2.5: {} + + lodash.sortby@4.7.0: {} + + log-symbols@7.0.1: + dependencies: + is-unicode-supported: 2.1.0 + yoctocolors: 2.1.2 + + lru-cache@10.4.3: {} + + lru-cache@11.2.6: {} + + magic-string@0.30.21: + dependencies: + "@jridgewell/sourcemap-codec": 1.5.5 + + mimic-function@5.0.1: {} + + mlkem@2.5.0: {} + + mlly@1.8.0: + dependencies: + acorn: 8.16.0 + pathe: 2.0.3 + pkg-types: 1.3.1 + ufo: 1.6.3 + + ms@2.1.3: {} + + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + + nanoid@3.3.11: {} + + normalize-package-data@6.0.2: + dependencies: + hosted-git-info: 7.0.2 + semver: 7.7.4 + validate-npm-package-license: 3.0.4 + + normalize-package-data@8.0.0: + dependencies: + hosted-git-info: 9.0.2 + semver: 7.7.4 + validate-npm-package-license: 3.0.4 + + npm-run-path@6.0.0: + dependencies: + path-key: 4.0.0 + unicorn-magic: 0.3.0 + + object-assign@4.1.1: {} + + obug@2.1.1: {} + + onetime@7.0.0: + dependencies: + mimic-function: 5.0.1 + + ora@9.3.0: + dependencies: + chalk: 5.6.2 + cli-cursor: 5.0.0 + cli-spinners: 3.4.0 + is-interactive: 2.0.0 + is-unicode-supported: 2.1.0 + log-symbols: 7.0.1 + stdin-discarder: 0.3.1 + string-width: 8.1.1 + + parse-json@8.3.0: + dependencies: + "@babel/code-frame": 7.29.0 + index-to-position: 1.2.0 + type-fest: 4.41.0 + + parse-ms@4.0.0: {} + + path-key@3.1.1: {} + + path-key@4.0.0: {} + + pathe@2.0.3: {} + + picocolors@1.1.1: {} + + picomatch@4.0.3: {} + + pirates@4.0.7: {} + + pkg-types@1.3.1: + dependencies: + confbox: 0.1.8 + mlly: 1.8.0 + pathe: 2.0.3 + + polkadot-api@1.23.3(postcss@8.5.6)(rxjs@7.8.2)(tsx@4.21.0): + dependencies: + "@polkadot-api/cli": 0.18.1(postcss@8.5.6)(tsx@4.21.0) + "@polkadot-api/ink-contracts": 0.4.6 + "@polkadot-api/json-rpc-provider": 0.0.4 + "@polkadot-api/known-chains": 0.9.18 + "@polkadot-api/logs-provider": 0.0.6 + "@polkadot-api/metadata-builders": 0.13.9 + "@polkadot-api/metadata-compatibility": 0.4.4 + "@polkadot-api/observable-client": 0.17.3(rxjs@7.8.2) + "@polkadot-api/pjs-signer": 0.6.19 + "@polkadot-api/polkadot-sdk-compat": 2.4.1 + "@polkadot-api/polkadot-signer": 0.1.6 + "@polkadot-api/signer": 0.2.13 + "@polkadot-api/sm-provider": 0.1.16(@polkadot-api/smoldot@0.3.15) + "@polkadot-api/smoldot": 0.3.15 + "@polkadot-api/substrate-bindings": 0.17.0 + "@polkadot-api/substrate-client": 0.5.0 + "@polkadot-api/utils": 0.2.0 + "@polkadot-api/ws-provider": 0.7.5 + "@rx-state/core": 0.1.4(rxjs@7.8.2) + rxjs: 7.8.2 + transitivePeerDependencies: + - "@microsoft/api-extractor" + - "@swc/core" + - bufferutil + - jiti + - postcss + - supports-color + - tsx + - utf-8-validate + - yaml + + postcss-load-config@6.0.1(postcss@8.5.6)(tsx@4.21.0): + dependencies: + lilconfig: 3.1.3 + optionalDependencies: + postcss: 8.5.6 + tsx: 4.21.0 + + postcss@8.5.6: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prettier@3.8.1: {} + + pretty-ms@9.3.0: + dependencies: + parse-ms: 4.0.0 + + punycode@2.3.1: {} + + read-pkg@10.1.0: + dependencies: + "@types/normalize-package-data": 2.4.4 + normalize-package-data: 8.0.0 + parse-json: 8.3.0 + type-fest: 5.4.4 + unicorn-magic: 0.4.0 + + read-pkg@9.0.1: + dependencies: + "@types/normalize-package-data": 2.4.4 + normalize-package-data: 6.0.2 + parse-json: 8.3.0 + type-fest: 4.41.0 + unicorn-magic: 0.1.0 + + readdirp@4.1.2: {} + + resolve-from@5.0.0: {} + + resolve-pkg-maps@1.0.0: + optional: true + + restore-cursor@5.1.0: + dependencies: + onetime: 7.0.0 + signal-exit: 4.1.0 + + rollup@4.57.1: + dependencies: + "@types/estree": 1.0.8 + optionalDependencies: + "@rollup/rollup-android-arm-eabi": 4.57.1 + "@rollup/rollup-android-arm64": 4.57.1 + "@rollup/rollup-darwin-arm64": 4.57.1 + "@rollup/rollup-darwin-x64": 4.57.1 + "@rollup/rollup-freebsd-arm64": 4.57.1 + "@rollup/rollup-freebsd-x64": 4.57.1 + "@rollup/rollup-linux-arm-gnueabihf": 4.57.1 + "@rollup/rollup-linux-arm-musleabihf": 4.57.1 + "@rollup/rollup-linux-arm64-gnu": 4.57.1 + "@rollup/rollup-linux-arm64-musl": 4.57.1 + "@rollup/rollup-linux-loong64-gnu": 4.57.1 + "@rollup/rollup-linux-loong64-musl": 4.57.1 + "@rollup/rollup-linux-ppc64-gnu": 4.57.1 + "@rollup/rollup-linux-ppc64-musl": 4.57.1 + "@rollup/rollup-linux-riscv64-gnu": 4.57.1 + "@rollup/rollup-linux-riscv64-musl": 4.57.1 + "@rollup/rollup-linux-s390x-gnu": 4.57.1 + "@rollup/rollup-linux-x64-gnu": 4.57.1 + "@rollup/rollup-linux-x64-musl": 4.57.1 + "@rollup/rollup-openbsd-x64": 4.57.1 + "@rollup/rollup-openharmony-arm64": 4.57.1 + "@rollup/rollup-win32-arm64-msvc": 4.57.1 + "@rollup/rollup-win32-ia32-msvc": 4.57.1 + "@rollup/rollup-win32-x64-gnu": 4.57.1 + "@rollup/rollup-win32-x64-msvc": 4.57.1 + fsevents: 2.3.3 + + rxjs@7.8.2: + dependencies: + tslib: 2.8.1 + + scale-ts@1.6.1: {} + + semver@7.7.4: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + siginfo@2.0.0: {} + + signal-exit@4.1.0: {} + + smoldot@2.0.40: + dependencies: + ws: 8.19.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + sort-keys@5.1.0: + dependencies: + is-plain-obj: 4.1.0 + + source-map-js@1.2.1: {} + + source-map@0.8.0-beta.0: + dependencies: + whatwg-url: 7.1.0 + + spdx-correct@3.2.0: + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.23 + + spdx-exceptions@2.5.0: {} + + spdx-expression-parse@3.0.1: + dependencies: + spdx-exceptions: 2.5.0 + spdx-license-ids: 3.0.23 + + spdx-license-ids@3.0.23: {} + + stackback@0.0.2: {} + + std-env@3.10.0: {} + + stdin-discarder@0.3.1: {} + + string-width@8.1.1: + dependencies: + get-east-asian-width: 1.4.0 + strip-ansi: 7.1.2 + + strip-ansi@7.1.2: + dependencies: + ansi-regex: 6.2.2 + + strip-final-newline@4.0.0: {} + + sucrase@3.35.1: + dependencies: + "@jridgewell/gen-mapping": 0.3.13 + commander: 4.1.1 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.7 + tinyglobby: 0.2.15 + ts-interface-checker: 0.1.13 + + tagged-tag@1.0.0: {} + + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + + tinybench@2.9.0: {} + + tinyexec@0.3.2: {} + + tinyexec@1.0.2: {} + + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + + tinyrainbow@3.0.3: {} + + tr46@1.0.1: + dependencies: + punycode: 2.3.1 + + tree-kill@1.2.2: {} + + ts-interface-checker@0.1.13: {} + + tsc-prog@2.3.0(typescript@5.9.3): + dependencies: + typescript: 5.9.3 + + tslib@2.8.1: {} + + tsup@8.5.0(postcss@8.5.6)(tsx@4.21.0)(typescript@5.9.3): + dependencies: + bundle-require: 5.1.0(esbuild@0.25.12) + cac: 6.7.14 + chokidar: 4.0.3 + consola: 3.4.2 + debug: 4.4.3 + esbuild: 0.25.12 + fix-dts-default-cjs-exports: 1.0.1 + joycon: 3.1.1 + picocolors: 1.1.1 + postcss-load-config: 6.0.1(postcss@8.5.6)(tsx@4.21.0) + resolve-from: 5.0.0 + rollup: 4.57.1 + source-map: 0.8.0-beta.0 + sucrase: 3.35.1 + tinyexec: 0.3.2 + tinyglobby: 0.2.15 + tree-kill: 1.2.2 + optionalDependencies: + postcss: 8.5.6 + typescript: 5.9.3 + transitivePeerDependencies: + - jiti + - supports-color + - tsx + - yaml + + tsx@4.21.0: + dependencies: + esbuild: 0.27.3 + get-tsconfig: 4.13.6 + optionalDependencies: + fsevents: 2.3.3 + optional: true + + type-fest@4.41.0: {} + + type-fest@5.4.4: + dependencies: + tagged-tag: 1.0.0 + + typescript@5.9.3: {} + + ufo@1.6.3: {} + + undici-types@7.16.0: {} + + undici-types@7.18.2: {} + + unicorn-magic@0.1.0: {} + + unicorn-magic@0.3.0: {} + + unicorn-magic@0.4.0: {} + + validate-npm-package-license@3.0.4: + dependencies: + spdx-correct: 3.2.0 + spdx-expression-parse: 3.0.1 + + vite@7.3.1(@types/node@24.10.13)(tsx@4.21.0): + dependencies: + esbuild: 0.27.3 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.57.1 + tinyglobby: 0.2.15 + optionalDependencies: + "@types/node": 24.10.13 + fsevents: 2.3.3 + tsx: 4.21.0 + + vitest@4.0.18(@types/node@24.10.13)(tsx@4.21.0): + dependencies: + "@vitest/expect": 4.0.18 + "@vitest/mocker": 4.0.18(vite@7.3.1(@types/node@24.10.13)(tsx@4.21.0)) + "@vitest/pretty-format": 4.0.18 + "@vitest/runner": 4.0.18 + "@vitest/snapshot": 4.0.18 + "@vitest/spy": 4.0.18 + "@vitest/utils": 4.0.18 + es-module-lexer: 1.7.0 + expect-type: 1.3.0 + magic-string: 0.30.21 + obug: 2.1.1 + pathe: 2.0.3 + picomatch: 4.0.3 + std-env: 3.10.0 + tinybench: 2.9.0 + tinyexec: 1.0.2 + tinyglobby: 0.2.15 + tinyrainbow: 3.0.3 + vite: 7.3.1(@types/node@24.10.13)(tsx@4.21.0) + why-is-node-running: 2.3.0 + optionalDependencies: + "@types/node": 24.10.13 + transitivePeerDependencies: + - jiti + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - terser + - tsx + - yaml + + webidl-conversions@4.0.2: {} + + whatwg-url@7.1.0: + dependencies: + lodash.sortby: 4.7.0 + tr46: 1.0.1 + webidl-conversions: 4.0.2 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + + write-file-atomic@5.0.1: + dependencies: + imurmurhash: 0.1.4 + signal-exit: 4.1.0 + + write-json-file@6.0.0: + dependencies: + detect-indent: 7.0.2 + is-plain-obj: 4.1.0 + sort-keys: 5.1.0 + write-file-atomic: 5.0.1 + + write-package@7.2.0: + dependencies: + deepmerge-ts: 7.1.5 + read-pkg: 9.0.1 + sort-keys: 5.1.0 + type-fest: 4.41.0 + write-json-file: 6.0.0 + + ws@8.19.0: {} + + yoctocolors@2.1.2: {} diff --git a/e2e/pnpm-workspace.yaml b/e2e/pnpm-workspace.yaml new file mode 100644 index 0000000000..5c59deeac3 --- /dev/null +++ b/e2e/pnpm-workspace.yaml @@ -0,0 +1,17 @@ +packages: + - shared + - shield + - staking + +catalog: + "@noble/ciphers": "^2.1.1" + "@polkadot/keyring": "^14.0.1" + "@polkadot/util": "^14.0.1" + "@polkadot/util-crypto": "^14.0.1" + "@polkadot-labs/hdkd": "^0.0.25" + "@polkadot-labs/hdkd-helpers": "^0.0.25" + "@types/node": "^24" + "mlkem": "^2.5.0" + "polkadot-api": "^1.22.0" + "prettier": "^3.0.0" + "vitest": "^4.0.0" diff --git a/e2e/setup_env.sh b/e2e/setup_env.sh new file mode 100755 index 0000000000..96b531e22b --- /dev/null +++ b/e2e/setup_env.sh @@ -0,0 +1,66 @@ +#!/bin/bash +# +# Verify and set up the development environment for e2e tests. +# Checks for nvm, the correct Node.js version (.nvmrc), pnpm, jq, and yq. +# Installs what it can, exits with an error for what it cannot. +# +set -e + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +NVMRC="$SCRIPT_DIR/.nvmrc" + +check() { + local name="$1" + if command -v "$name" &>/dev/null; then + echo " $name: $(command -v "$name")" + return 0 + fi + return 1 +} + +echo "==> Checking prerequisites..." + +# -- nvm -- +NVM_DIR="${NVM_DIR:-$HOME/.nvm}" +if [ -s "$NVM_DIR/nvm.sh" ]; then + echo " nvm: $NVM_DIR" + # shellcheck source=/dev/null + source "$NVM_DIR/nvm.sh" +else + echo "ERROR: nvm not found. Install it from https://github.com/nvm-sh/nvm" + exit 1 +fi + +# -- Node.js (version from .nvmrc) -- +REQUIRED_NODE="$(cat "$NVMRC")" +if ! nvm ls "$REQUIRED_NODE" &>/dev/null; then + echo " Node $REQUIRED_NODE not installed, installing..." + nvm install "$REQUIRED_NODE" +fi +nvm use "$REQUIRED_NODE" +echo " node: $(node --version)" + +# -- pnpm -- +if ! check pnpm; then + echo " pnpm not found, installing..." + npm install -g pnpm + check pnpm || { echo "ERROR: Failed to install pnpm"; exit 1; } +fi + +# -- jq -- +if ! check jq; then + echo "ERROR: jq not found. Install it:" + echo " macOS: brew install jq" + echo " Ubuntu: sudo apt install jq" + exit 1 +fi + +# -- yq -- +if ! check yq; then + echo "ERROR: yq not found. Install it:" + echo " macOS: brew install yq" + echo " Ubuntu: sudo snap install yq" + exit 1 +fi + +echo "==> All prerequisites satisfied." diff --git a/e2e/shared/address.ts b/e2e/shared/address.ts new file mode 100644 index 0000000000..75eff6342a --- /dev/null +++ b/e2e/shared/address.ts @@ -0,0 +1,49 @@ +import { sr25519CreateDerive } from "@polkadot-labs/hdkd"; +import { + DEV_PHRASE, + entropyToMiniSecret, + mnemonicToEntropy, + KeyPair, +} from "@polkadot-labs/hdkd-helpers"; +import { getPolkadotSigner } from "polkadot-api/signer"; +import { PolkadotSigner } from "polkadot-api"; +import { randomBytes } from "crypto"; +import { ss58Address } from "@polkadot-labs/hdkd-helpers"; + +export const SS58_PREFIX = 42; + +// ─── KEYPAIR UTILITIES ─────────────────────────────────────────────────────── + +export function getKeypairFromPath(path: string): KeyPair { + const entropy = mnemonicToEntropy(DEV_PHRASE); + const miniSecret = entropyToMiniSecret(entropy); + const derive = sr25519CreateDerive(miniSecret); + return derive(path); +} + +export const getAlice = () => getKeypairFromPath("//Alice"); + +export function getRandomSubstrateKeypair(): KeyPair { + const seed = randomBytes(32); + const miniSecret = entropyToMiniSecret(seed); + const derive = sr25519CreateDerive(miniSecret); + return derive(""); +} + +// ─── SIGNER UTILITIES ──────────────────────────────────────────────────────── + +export function getSignerFromKeypair(keypair: KeyPair): PolkadotSigner { + return getPolkadotSigner(keypair.publicKey, "Sr25519", keypair.sign); +} + +export function getSignerFromPath(path: string): PolkadotSigner { + return getSignerFromKeypair(getKeypairFromPath(path)); +} + +export const getAliceSigner = () => getSignerFromPath("//Alice"); + +// ─── ADDRESS UTILITIES ─────────────────────────────────────────────────────── + +export function convertPublicKeyToSs58(publicKey: Uint8Array): string { + return ss58Address(publicKey, SS58_PREFIX); +} diff --git a/e2e/shared/balance.ts b/e2e/shared/balance.ts new file mode 100644 index 0000000000..c54d2c7e18 --- /dev/null +++ b/e2e/shared/balance.ts @@ -0,0 +1,32 @@ +import { subtensor, MultiAddress } from "@polkadot-api/descriptors"; +import { TypedApi } from "polkadot-api"; +import { getAliceSigner } from "./address.js"; +import { waitForTransactionWithRetry } from "./transactions.js"; + +export const TAO = BigInt(1000000000); // 10^9 RAO per TAO + +export function tao(value: number): bigint { + return TAO * BigInt(value); +} + +export async function getBalance( + api: TypedApi, + ss58Address: string, +): Promise { + const account = await api.query.System.Account.getValue(ss58Address); + return account.data.free; +} + +export async function forceSetBalance( + api: TypedApi, + ss58Address: string, + amount: bigint = tao(1e10), +): Promise { + const alice = getAliceSigner(); + const internalCall = api.tx.Balances.force_set_balance({ + who: MultiAddress.Id(ss58Address), + new_free: amount, + }); + const tx = api.tx.Sudo.sudo({ call: internalCall.decodedCall }); + await waitForTransactionWithRetry(api, tx, alice, "force_set_balance"); +} diff --git a/e2e/shared/chainspec.ts b/e2e/shared/chainspec.ts new file mode 100644 index 0000000000..514b6c0028 --- /dev/null +++ b/e2e/shared/chainspec.ts @@ -0,0 +1,191 @@ +import { spawn, execFileSync } from "node:child_process"; +import { writeFile, readFile } from "node:fs/promises"; +import { Keyring } from "@polkadot/keyring"; +import { log } from "./node.js"; + +// --------------------------------------------------------------------------- +// Chain spec generation +// --------------------------------------------------------------------------- + +/** + * Generate a raw chain spec. If `patchSpec` is provided, first generates a + * non-raw spec, applies the patch, then converts to raw. This allows adding + * extra authorities, balances, etc. without modifying the Rust chain spec. + */ +export const generateChainSpec = async ( + binaryPath: string, + outputPath: string, + patchSpec?: (spec: any) => void, +) => { + if (!patchSpec) { + return generateRawChainSpec(binaryPath, outputPath, "local"); + } + + // 2-step: generate non-raw → patch → generate raw. + const nonRawPath = outputPath + ".nonraw.json"; + + await new Promise((resolve, reject) => { + const proc = spawn(binaryPath, [ + "build-spec", + "--disable-default-bootnode", + "--chain", + "local", + ]); + const chunks: Buffer[] = []; + proc.stdout.on("data", (chunk: Buffer) => chunks.push(chunk)); + let stderr = ""; + proc.stderr?.on("data", (chunk: Buffer) => { + stderr += chunk.toString(); + }); + proc.on("close", async (code) => { + if (code !== 0) { + reject(new Error(`Failed to generate non-raw chain spec (exit ${code}): ${stderr}`)); + return; + } + await writeFile(nonRawPath, Buffer.concat(chunks)); + resolve(); + }); + proc.on("error", reject); + }); + + const specJson = JSON.parse(await readFile(nonRawPath, "utf-8")); + patchSpec(specJson); + await writeFile(nonRawPath, JSON.stringify(specJson, null, 2)); + + await generateRawChainSpec(binaryPath, outputPath, nonRawPath); +}; + +async function generateRawChainSpec(binaryPath: string, outputPath: string, chain: string) { + return new Promise((resolve, reject) => { + const proc = spawn(binaryPath, [ + "build-spec", + "--disable-default-bootnode", + "--raw", + "--chain", + chain, + ]); + + const chunks: Buffer[] = []; + proc.stdout.on("data", (chunk: Buffer) => chunks.push(chunk)); + + let stderr = ""; + proc.stderr?.on("data", (chunk: Buffer) => { + stderr += chunk.toString(); + }); + + proc.on("close", async (code) => { + if (code !== 0) { + reject(new Error(`Failed to generate chain spec (exit ${code}): ${stderr}`)); + return; + } + const data = Buffer.concat(chunks); + await writeFile(outputPath, data); + log(`Chain spec written to ${outputPath} (${data.length} bytes)`); + resolve(); + }); + + proc.on("error", reject); + }); +} + +// --------------------------------------------------------------------------- +// Chain spec patching helpers (composable) +// --------------------------------------------------------------------------- + +/** + * Extract the genesis runtime patch object from a non-raw chain spec. + * Works with both the `runtimeGenesis.patch` and legacy `runtime` formats. + */ +export function getGenesisPatch(spec: any): any { + const patch = spec.genesis?.runtimeGenesis?.patch ?? spec.genesis?.runtime; + if (!patch) throw new Error("Cannot find genesis patch in chain spec"); + return patch; +} + +/** Add an Aura authority (sr25519 address) to the chain spec. */ +export function addAuraAuthority(patch: any, address: string) { + if (patch.aura?.authorities) { + patch.aura.authorities.push(address); + } +} + +/** Add a GRANDPA authority (ed25519 address, weight) to the chain spec. */ +export function addGrandpaAuthority(patch: any, address: string, weight = 1) { + if (patch.grandpa?.authorities) { + patch.grandpa.authorities.push([address, weight]); + } +} + +/** Add a balance entry to the chain spec. */ +export function addBalance(patch: any, address: string, amount: number | bigint) { + if (patch.balances?.balances) { + patch.balances.balances.push([address, Number(amount)]); + } +} + +// --------------------------------------------------------------------------- +// Authority key helpers +// --------------------------------------------------------------------------- + +export type AuthorityKeys = { + aura: string; + grandpa: string; + account: string; +}; + +/** Derive authority keys (aura sr25519, grandpa ed25519, account) from a seed. */ +export function generateAuthorityKeys(seed: string): AuthorityKeys { + const sr = new Keyring({ type: "sr25519" }); + const ed = new Keyring({ type: "ed25519" }); + return { + aura: sr.addFromUri(`//${seed}`).address, + grandpa: ed.addFromUri(`//${seed}`).address, + account: sr.addFromUri(`//${seed}`).address, + }; +} + +/** + * Convenience: add a full authority (aura + grandpa + funded account) to a + * chain spec genesis patch. Derives keys from the given seed. + */ +export function addAuthority(patch: any, seed: string, balance = 2_000_000_000_000) { + const keys = generateAuthorityKeys(seed); + addAuraAuthority(patch, keys.aura); + addGrandpaAuthority(patch, keys.grandpa); + addBalance(patch, keys.account, balance); +} + +// --------------------------------------------------------------------------- +// Key insertion +// --------------------------------------------------------------------------- + +/** + * Insert Aura (sr25519) and GRANDPA (ed25519) keys into a node's keystore. + * Required for authority nodes that don't have a built-in substrate CLI shortcut. + */ +export const insertKeys = ( + binaryPath: string, + basePath: string, + chainSpec: string, + seed: string, +) => { + const run = (scheme: string, keyType: string) => { + execFileSync(binaryPath, [ + "key", + "insert", + "--base-path", + basePath, + "--chain", + chainSpec, + "--suri", + seed, + "--scheme", + scheme, + "--key-type", + keyType, + ]); + }; + run("sr25519", "aura"); + run("ed25519", "gran"); + log(`Inserted aura+grandpa keys for ${seed} into ${basePath}`); +}; diff --git a/e2e/shared/client.ts b/e2e/shared/client.ts new file mode 100644 index 0000000000..1dd76dd48e --- /dev/null +++ b/e2e/shared/client.ts @@ -0,0 +1,82 @@ +import { createClient, type PolkadotClient, type TypedApi } from "polkadot-api"; +import { getWsProvider } from "polkadot-api/ws-provider"; +import { getPolkadotSigner, type PolkadotSigner } from "polkadot-api/signer"; +import { sr25519CreateDerive } from "@polkadot-labs/hdkd"; +import { + DEV_PHRASE, + entropyToMiniSecret, + mnemonicToEntropy, + ss58Address, +} from "@polkadot-labs/hdkd-helpers"; +import { subtensor } from "@polkadot-api/descriptors"; + +const SECOND = 1000; + +export type ClientConnection = { + client: PolkadotClient; + api: TypedApi; +}; + +export const connectClient = async (rpcPort: number): Promise => { + const provider = getWsProvider(`ws://localhost:${rpcPort}`); + const client = createClient(provider); + const api = client.getTypedApi(subtensor); + return { client, api }; +}; + +export type Signer = { + signer: PolkadotSigner; + address: string; +}; + +export const createSigner = (uri: string): Signer => { + const entropy = mnemonicToEntropy(DEV_PHRASE); + const miniSecret = entropyToMiniSecret(entropy); + const derive = sr25519CreateDerive(miniSecret); + const keypair = derive(uri); + return { + signer: getPolkadotSigner(keypair.publicKey, "Sr25519", keypair.sign), + address: ss58Address(keypair.publicKey), + }; +}; + +export const getAccountNonce = async ( + api: TypedApi, + address: string, +): Promise => { + const account = await api.query.System.Account.getValue(address, { at: "best" }); + return account.nonce; +}; + +export const getBalance = async ( + api: TypedApi, + address: string, +): Promise => { + const account = await api.query.System.Account.getValue(address); + return account.data.free; +}; + +export const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); + +/** Polls the chain until `count` new finalized blocks have been produced. */ +export async function waitForFinalizedBlocks( + client: PolkadotClient, + count: number, + pollInterval = 1 * SECOND, + timeout = 120 * SECOND, +): Promise { + const startBlock = await client.getFinalizedBlock(); + const start = startBlock.number; + const target = start + count; + const deadline = Date.now() + timeout; + + while (Date.now() < deadline) { + await sleep(pollInterval); + const block = await client.getFinalizedBlock(); + if (block.number >= target) return; + } + + throw new Error( + `Timed out waiting for ${count} finalized blocks (from #${start}, target #${target})`, + ); +} diff --git a/e2e/shared/devnet-client.ts b/e2e/shared/devnet-client.ts new file mode 100644 index 0000000000..776472fb5e --- /dev/null +++ b/e2e/shared/devnet-client.ts @@ -0,0 +1,30 @@ +import { subtensor } from "@polkadot-api/descriptors"; +import { TypedApi, PolkadotClient, createClient } from "polkadot-api"; +import { getWsProvider } from "polkadot-api/ws-provider/web"; + +export const SUB_LOCAL_URL = "ws://localhost:9944"; + +let client: PolkadotClient | undefined = undefined; +let api: TypedApi | undefined = undefined; + +export async function getClient(): Promise { + if (client === undefined) { + const provider = getWsProvider(SUB_LOCAL_URL); + client = createClient(provider); + } + return client; +} + +export async function getDevnetApi(): Promise> { + if (api === undefined) { + const c = await getClient(); + api = c.getTypedApi(subtensor); + } + return api; +} + +export function destroyClient(): void { + client?.destroy(); + client = undefined; + api = undefined; +} diff --git a/e2e/shared/index.ts b/e2e/shared/index.ts new file mode 100644 index 0000000000..1e686b816d --- /dev/null +++ b/e2e/shared/index.ts @@ -0,0 +1,35 @@ +// Node management +export { + startNode, + stop, + started, + peerCount, + finalizedBlocks, + innerEnsure, + log as nodeLog, + type NodeOptions, + type Node, +} from "./node.js"; +export * from "./chainspec.js"; +export * from "./sequencer.js"; + +// Client utilities (shield-style) +export { + connectClient, + createSigner, + getAccountNonce, + getBalance as getBalanceByAddress, + sleep, + waitForFinalizedBlocks, + type ClientConnection, + type Signer, +} from "./client.js"; + +// Blockchain API utilities (staking-tests style) +export * from "./logger.js"; +export * from "./devnet-client.js"; +export * from "./address.js"; +export * from "./transactions.js"; +export * from "./balance.js"; +export * from "./subnet.js"; +export * from "./staking.js"; diff --git a/e2e/shared/logger.ts b/e2e/shared/logger.ts new file mode 100644 index 0000000000..041443353a --- /dev/null +++ b/e2e/shared/logger.ts @@ -0,0 +1,7 @@ +const LOG_INDENT = " "; + +export const log = { + tx: (label: string, msg: string) => console.log(`${LOG_INDENT}[${label}] ${msg}`), + info: (msg: string) => console.log(`${LOG_INDENT}${msg}`), + error: (label: string, msg: string) => console.error(`${LOG_INDENT}[${label}] ${msg}`), +}; diff --git a/e2e/shared/node.ts b/e2e/shared/node.ts new file mode 100644 index 0000000000..5e93e5007a --- /dev/null +++ b/e2e/shared/node.ts @@ -0,0 +1,148 @@ +import { spawn, ChildProcess } from "node:child_process"; + +const SECOND = 1000; +const MINUTE = 60 * SECOND; + +// Substrate CLI shortcuts that inject keystore keys automatically. +const SUBSTRATE_SHORTCUTS = new Set([ + "alice", + "bob", + "charlie", + "dave", + "eve", + "ferdie", + "one", + "two", +]); + +export type NodeOptions = { + binaryPath: string; + basePath: string; + name: string; + port: number; + rpcPort: number; + validator: boolean; + chainSpec: string; +}; + +export type Node = { + name: string; + binaryPath: string; + rpcPort: number; + port: number; + process: ChildProcess; +}; + +export const log = (message: string) => console.log(`[${new Date().toISOString()}] ${message}`); + +export const startNode = (opts: NodeOptions): Node => { + const nameArgs = SUBSTRATE_SHORTCUTS.has(opts.name) ? [`--${opts.name}`] : ["--name", opts.name]; + + const child = spawn(opts.binaryPath, [ + ...nameArgs, + ...["--chain", opts.chainSpec], + ...["--base-path", opts.basePath], + ...["--port", opts.port.toString()], + ...["--rpc-port", opts.rpcPort.toString()], + ...(opts.validator ? ["--validator"] : []), + "--rpc-cors=all", + "--allow-private-ipv4", + "--discover-local", + "--unsafe-force-node-key-generation", + ]); + + let lastStderr = ""; + child.stderr?.on("data", (chunk: Buffer) => { + lastStderr = chunk.toString(); + }); + child.on("error", (error) => console.error(`${opts.name} (error): ${error}`)); + child.on("close", (code) => { + if (code !== 0 && code !== null) { + log(`${opts.name}: process crashed with code ${code}. Last stderr: ${lastStderr}`); + } else { + log(`${opts.name}: process closed with code ${code}`); + } + }); + + return { + name: opts.name, + binaryPath: opts.binaryPath, + rpcPort: opts.rpcPort, + port: opts.port, + process: child, + }; +}; + +export const stop = (node: Node): Promise => { + return new Promise((resolve, reject) => { + node.process.on("close", () => resolve()); + node.process.on("error", reject); + + if (!node.process.kill()) { + reject(new Error(`Failed to stop ${node.name}`)); + } + }); +}; + +export const started = (node: Node, timeout = 60 * SECOND) => { + const errorMessage = `${node.name} failed to start in time`; + + return innerEnsure(node, errorMessage, timeout, (data, ok) => { + if (data.includes("💤 Idle")) { + log(`${node.name}: started using ${node.binaryPath}`); + ok(); + } + }); +}; + +export const peerCount = (node: Node, expectedPeers: number, timeout = 60 * SECOND) => { + const errorMessage = `${node.name} failed to reach ${expectedPeers} peers in time`; + + return innerEnsure(node, errorMessage, timeout, (data, ok) => { + const maybePeers = /Idle \((?\d+) peers\)/.exec(data)?.groups?.peers; + if (!maybePeers) return; + + const peers = parseInt(maybePeers); + if (peers >= expectedPeers) { + log(`${node.name}: reached ${expectedPeers} peers`); + ok(); + } + }); +}; + +export const finalizedBlocks = (node: Node, expectedFinalized: number, timeout = 10 * MINUTE) => { + const errorMessage = `${node.name} failed to reach ${expectedFinalized} finalized blocks in time`; + + return innerEnsure(node, errorMessage, timeout, (data, ok) => { + const maybeFinalized = /finalized #(?\d+)/.exec(data)?.groups?.blocks; + if (!maybeFinalized) return; + + const finalized = parseInt(maybeFinalized); + if (finalized >= expectedFinalized) { + log(`${node.name}: reached ${expectedFinalized} finalized blocks`); + ok(); + } + }); +}; + +export function innerEnsure( + node: Node, + errorMessage: string, + timeout: number, + f: (data: string, ok: () => void) => void, +) { + return new Promise((resolve, reject) => { + const id = setTimeout(() => reject(new Error(errorMessage)), timeout); + + const fn = (chunk: Buffer) => { + const data = chunk.toString(); + f(data, () => { + clearTimeout(id); + node.process.stderr?.off("data", fn); + resolve(); + }); + }; + + node.process.stderr?.on("data", fn); + }); +} diff --git a/e2e/shared/package.json b/e2e/shared/package.json new file mode 100644 index 0000000000..6efbfae4e6 --- /dev/null +++ b/e2e/shared/package.json @@ -0,0 +1,30 @@ +{ + "name": "e2e-shared", + "version": "1.0.0", + "type": "module", + "exports": { + ".": "./index.ts", + "./node.js": "./node.ts", + "./chainspec.js": "./chainspec.ts", + "./sequencer.js": "./sequencer.ts", + "./client.js": "./client.ts", + "./logger.js": "./logger.ts", + "./devnet-client.js": "./devnet-client.ts", + "./address.js": "./address.ts", + "./transactions.js": "./transactions.ts", + "./balance.js": "./balance.ts", + "./subnet.js": "./subnet.ts", + "./staking.js": "./staking.ts" + }, + "dependencies": { + "@polkadot/keyring": "catalog:", + "@polkadot-api/descriptors": "file:../.papi/descriptors", + "@polkadot-labs/hdkd": "catalog:", + "@polkadot-labs/hdkd-helpers": "catalog:", + "polkadot-api": "catalog:" + }, + "devDependencies": { + "@types/node": "catalog:", + "vitest": "catalog:" + } +} diff --git a/e2e/shared/pnpm-lock.yaml b/e2e/shared/pnpm-lock.yaml new file mode 100644 index 0000000000..767156e260 --- /dev/null +++ b/e2e/shared/pnpm-lock.yaml @@ -0,0 +1,1628 @@ +lockfileVersion: "9.0" + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + .: + dependencies: + "@polkadot/keyring": + specifier: ^14.0.1 + version: 14.0.1(@polkadot/util-crypto@14.0.1(@polkadot/util@14.0.1))(@polkadot/util@14.0.1) + devDependencies: + "@types/node": + specifier: ^24 + version: 24.10.13 + vitest: + specifier: ^3.0.0 + version: 3.2.4(@types/node@24.10.13) + +packages: + "@esbuild/aix-ppc64@0.27.3": + resolution: + { + integrity: sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==, + } + engines: { node: ">=18" } + cpu: [ppc64] + os: [aix] + + "@esbuild/android-arm64@0.27.3": + resolution: + { + integrity: sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [android] + + "@esbuild/android-arm@0.27.3": + resolution: + { + integrity: sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==, + } + engines: { node: ">=18" } + cpu: [arm] + os: [android] + + "@esbuild/android-x64@0.27.3": + resolution: + { + integrity: sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [android] + + "@esbuild/darwin-arm64@0.27.3": + resolution: + { + integrity: sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [darwin] + + "@esbuild/darwin-x64@0.27.3": + resolution: + { + integrity: sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [darwin] + + "@esbuild/freebsd-arm64@0.27.3": + resolution: + { + integrity: sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [freebsd] + + "@esbuild/freebsd-x64@0.27.3": + resolution: + { + integrity: sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [freebsd] + + "@esbuild/linux-arm64@0.27.3": + resolution: + { + integrity: sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [linux] + + "@esbuild/linux-arm@0.27.3": + resolution: + { + integrity: sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==, + } + engines: { node: ">=18" } + cpu: [arm] + os: [linux] + + "@esbuild/linux-ia32@0.27.3": + resolution: + { + integrity: sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==, + } + engines: { node: ">=18" } + cpu: [ia32] + os: [linux] + + "@esbuild/linux-loong64@0.27.3": + resolution: + { + integrity: sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==, + } + engines: { node: ">=18" } + cpu: [loong64] + os: [linux] + + "@esbuild/linux-mips64el@0.27.3": + resolution: + { + integrity: sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==, + } + engines: { node: ">=18" } + cpu: [mips64el] + os: [linux] + + "@esbuild/linux-ppc64@0.27.3": + resolution: + { + integrity: sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==, + } + engines: { node: ">=18" } + cpu: [ppc64] + os: [linux] + + "@esbuild/linux-riscv64@0.27.3": + resolution: + { + integrity: sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==, + } + engines: { node: ">=18" } + cpu: [riscv64] + os: [linux] + + "@esbuild/linux-s390x@0.27.3": + resolution: + { + integrity: sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==, + } + engines: { node: ">=18" } + cpu: [s390x] + os: [linux] + + "@esbuild/linux-x64@0.27.3": + resolution: + { + integrity: sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [linux] + + "@esbuild/netbsd-arm64@0.27.3": + resolution: + { + integrity: sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [netbsd] + + "@esbuild/netbsd-x64@0.27.3": + resolution: + { + integrity: sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [netbsd] + + "@esbuild/openbsd-arm64@0.27.3": + resolution: + { + integrity: sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [openbsd] + + "@esbuild/openbsd-x64@0.27.3": + resolution: + { + integrity: sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [openbsd] + + "@esbuild/openharmony-arm64@0.27.3": + resolution: + { + integrity: sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [openharmony] + + "@esbuild/sunos-x64@0.27.3": + resolution: + { + integrity: sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [sunos] + + "@esbuild/win32-arm64@0.27.3": + resolution: + { + integrity: sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [win32] + + "@esbuild/win32-ia32@0.27.3": + resolution: + { + integrity: sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==, + } + engines: { node: ">=18" } + cpu: [ia32] + os: [win32] + + "@esbuild/win32-x64@0.27.3": + resolution: + { + integrity: sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [win32] + + "@jridgewell/sourcemap-codec@1.5.5": + resolution: + { + integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==, + } + + "@noble/curves@1.9.7": + resolution: + { + integrity: sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==, + } + engines: { node: ^14.21.3 || >=16 } + + "@noble/hashes@1.8.0": + resolution: + { + integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==, + } + engines: { node: ^14.21.3 || >=16 } + + "@polkadot/keyring@14.0.1": + resolution: + { + integrity: sha512-kHydQPCeTvJrMC9VQO8LPhAhTUxzxfNF1HEknhZDBPPsxP/XpkYsEy/Ln1QzJmQqD5VsgwzLDE6cExbJ2CT9CA==, + } + engines: { node: ">=18" } + peerDependencies: + "@polkadot/util": 14.0.1 + "@polkadot/util-crypto": 14.0.1 + + "@polkadot/networks@14.0.1": + resolution: + { + integrity: sha512-wGlBtXDkusRAj4P7uxfPz80gLO1+j99MLBaQi3bEym2xrFrFhgIWVHOZlBit/1PfaBjhX2Z8XjRxaM2w1p7w2w==, + } + engines: { node: ">=18" } + + "@polkadot/util-crypto@14.0.1": + resolution: + { + integrity: sha512-Cu7AKUzBTsUkbOtyuNzXcTpDjR9QW0fVR56o3gBmzfUCmvO1vlsuGzmmPzqpHymQQ3rrfqV78CPs62EGhw0R+A==, + } + engines: { node: ">=18" } + peerDependencies: + "@polkadot/util": 14.0.1 + + "@polkadot/util@14.0.1": + resolution: + { + integrity: sha512-764HhxkPV3x5rM0/p6QdynC2dw26n+SaE+jisjx556ViCd4E28Ke4xSPef6C0Spy4aoXf2gt0PuLEcBvd6fVZg==, + } + engines: { node: ">=18" } + + "@polkadot/wasm-bridge@7.5.4": + resolution: + { + integrity: sha512-6xaJVvoZbnbgpQYXNw9OHVNWjXmtcoPcWh7hlwx3NpfiLkkjljj99YS+XGZQlq7ks2fVCg7FbfknkNb8PldDaA==, + } + engines: { node: ">=18" } + peerDependencies: + "@polkadot/util": "*" + "@polkadot/x-randomvalues": "*" + + "@polkadot/wasm-crypto-asmjs@7.5.4": + resolution: + { + integrity: sha512-ZYwxQHAJ8pPt6kYk9XFmyuFuSS+yirJLonvP+DYbxOrARRUHfN4nzp4zcZNXUuaFhpbDobDSFn6gYzye6BUotA==, + } + engines: { node: ">=18" } + peerDependencies: + "@polkadot/util": "*" + + "@polkadot/wasm-crypto-init@7.5.4": + resolution: + { + integrity: sha512-U6s4Eo2rHs2n1iR01vTz/sOQ7eOnRPjaCsGWhPV+ZC/20hkVzwPAhiizu/IqMEol4tO2yiSheD4D6bn0KxUJhg==, + } + engines: { node: ">=18" } + peerDependencies: + "@polkadot/util": "*" + "@polkadot/x-randomvalues": "*" + + "@polkadot/wasm-crypto-wasm@7.5.4": + resolution: + { + integrity: sha512-PsHgLsVTu43eprwSvUGnxybtOEuHPES6AbApcs7y5ZbM2PiDMzYbAjNul098xJK/CPtrxZ0ePDFnaQBmIJyTFw==, + } + engines: { node: ">=18" } + peerDependencies: + "@polkadot/util": "*" + + "@polkadot/wasm-crypto@7.5.4": + resolution: + { + integrity: sha512-1seyClxa7Jd7kQjfnCzTTTfYhTa/KUTDUaD3DMHBk5Q4ZUN1D1unJgX+v1aUeXSPxmzocdZETPJJRZjhVOqg9g==, + } + engines: { node: ">=18" } + peerDependencies: + "@polkadot/util": "*" + "@polkadot/x-randomvalues": "*" + + "@polkadot/wasm-util@7.5.4": + resolution: + { + integrity: sha512-hqPpfhCpRAqCIn/CYbBluhh0TXmwkJnDRjxrU9Bnqtw9nMNa97D8JuOjdd2pi0rxm+eeLQ/f1rQMp71RMM9t4w==, + } + engines: { node: ">=18" } + peerDependencies: + "@polkadot/util": "*" + + "@polkadot/x-bigint@14.0.1": + resolution: + { + integrity: sha512-gfozjGnebr2rqURs31KtaWumbW4rRZpbiluhlmai6luCNrf5u8pB+oLA35kPEntrsLk9PnIG9OsC/n4hEtx4OQ==, + } + engines: { node: ">=18" } + + "@polkadot/x-global@14.0.1": + resolution: + { + integrity: sha512-aCI44DJU4fU0XXqrrSGIpi7JrZXK2kpe0jaQ2p6oDVXOOYEnZYXnMhTTmBE1lF/xtxzX50MnZrrU87jziU0qbA==, + } + engines: { node: ">=18" } + + "@polkadot/x-randomvalues@14.0.1": + resolution: + { + integrity: sha512-/XkQcvshzJLHITuPrN3zmQKuFIPdKWoaiHhhVLD6rQWV60lTXA3ajw3ocju8ZN7xRxnweMS9Ce0kMPYa0NhRMg==, + } + engines: { node: ">=18" } + peerDependencies: + "@polkadot/util": 14.0.1 + "@polkadot/wasm-util": "*" + + "@polkadot/x-textdecoder@14.0.1": + resolution: + { + integrity: sha512-CcWiPCuPVJsNk4Vq43lgFHqLRBQHb4r9RD7ZIYgmwoebES8TNm4g2ew9ToCzakFKSpzKu6I07Ne9wv/dt5zLuw==, + } + engines: { node: ">=18" } + + "@polkadot/x-textencoder@14.0.1": + resolution: + { + integrity: sha512-VY51SpQmF1ccmAGLfxhYnAe95Spfz049WZ/+kK4NfsGF9WejxVdU53Im5C80l45r8qHuYQsCWU3+t0FNunh2Kg==, + } + engines: { node: ">=18" } + + "@rollup/rollup-android-arm-eabi@4.57.1": + resolution: + { + integrity: sha512-A6ehUVSiSaaliTxai040ZpZ2zTevHYbvu/lDoeAteHI8QnaosIzm4qwtezfRg1jOYaUmnzLX1AOD6Z+UJjtifg==, + } + cpu: [arm] + os: [android] + + "@rollup/rollup-android-arm64@4.57.1": + resolution: + { + integrity: sha512-dQaAddCY9YgkFHZcFNS/606Exo8vcLHwArFZ7vxXq4rigo2bb494/xKMMwRRQW6ug7Js6yXmBZhSBRuBvCCQ3w==, + } + cpu: [arm64] + os: [android] + + "@rollup/rollup-darwin-arm64@4.57.1": + resolution: + { + integrity: sha512-crNPrwJOrRxagUYeMn/DZwqN88SDmwaJ8Cvi/TN1HnWBU7GwknckyosC2gd0IqYRsHDEnXf328o9/HC6OkPgOg==, + } + cpu: [arm64] + os: [darwin] + + "@rollup/rollup-darwin-x64@4.57.1": + resolution: + { + integrity: sha512-Ji8g8ChVbKrhFtig5QBV7iMaJrGtpHelkB3lsaKzadFBe58gmjfGXAOfI5FV0lYMH8wiqsxKQ1C9B0YTRXVy4w==, + } + cpu: [x64] + os: [darwin] + + "@rollup/rollup-freebsd-arm64@4.57.1": + resolution: + { + integrity: sha512-R+/WwhsjmwodAcz65guCGFRkMb4gKWTcIeLy60JJQbXrJ97BOXHxnkPFrP+YwFlaS0m+uWJTstrUA9o+UchFug==, + } + cpu: [arm64] + os: [freebsd] + + "@rollup/rollup-freebsd-x64@4.57.1": + resolution: + { + integrity: sha512-IEQTCHeiTOnAUC3IDQdzRAGj3jOAYNr9kBguI7MQAAZK3caezRrg0GxAb6Hchg4lxdZEI5Oq3iov/w/hnFWY9Q==, + } + cpu: [x64] + os: [freebsd] + + "@rollup/rollup-linux-arm-gnueabihf@4.57.1": + resolution: + { + integrity: sha512-F8sWbhZ7tyuEfsmOxwc2giKDQzN3+kuBLPwwZGyVkLlKGdV1nvnNwYD0fKQ8+XS6hp9nY7B+ZeK01EBUE7aHaw==, + } + cpu: [arm] + os: [linux] + libc: [glibc] + + "@rollup/rollup-linux-arm-musleabihf@4.57.1": + resolution: + { + integrity: sha512-rGfNUfn0GIeXtBP1wL5MnzSj98+PZe/AXaGBCRmT0ts80lU5CATYGxXukeTX39XBKsxzFpEeK+Mrp9faXOlmrw==, + } + cpu: [arm] + os: [linux] + libc: [musl] + + "@rollup/rollup-linux-arm64-gnu@4.57.1": + resolution: + { + integrity: sha512-MMtej3YHWeg/0klK2Qodf3yrNzz6CGjo2UntLvk2RSPlhzgLvYEB3frRvbEF2wRKh1Z2fDIg9KRPe1fawv7C+g==, + } + cpu: [arm64] + os: [linux] + libc: [glibc] + + "@rollup/rollup-linux-arm64-musl@4.57.1": + resolution: + { + integrity: sha512-1a/qhaaOXhqXGpMFMET9VqwZakkljWHLmZOX48R0I/YLbhdxr1m4gtG1Hq7++VhVUmf+L3sTAf9op4JlhQ5u1Q==, + } + cpu: [arm64] + os: [linux] + libc: [musl] + + "@rollup/rollup-linux-loong64-gnu@4.57.1": + resolution: + { + integrity: sha512-QWO6RQTZ/cqYtJMtxhkRkidoNGXc7ERPbZN7dVW5SdURuLeVU7lwKMpo18XdcmpWYd0qsP1bwKPf7DNSUinhvA==, + } + cpu: [loong64] + os: [linux] + libc: [glibc] + + "@rollup/rollup-linux-loong64-musl@4.57.1": + resolution: + { + integrity: sha512-xpObYIf+8gprgWaPP32xiN5RVTi/s5FCR+XMXSKmhfoJjrpRAjCuuqQXyxUa/eJTdAE6eJ+KDKaoEqjZQxh3Gw==, + } + cpu: [loong64] + os: [linux] + libc: [musl] + + "@rollup/rollup-linux-ppc64-gnu@4.57.1": + resolution: + { + integrity: sha512-4BrCgrpZo4hvzMDKRqEaW1zeecScDCR+2nZ86ATLhAoJ5FQ+lbHVD3ttKe74/c7tNT9c6F2viwB3ufwp01Oh2w==, + } + cpu: [ppc64] + os: [linux] + libc: [glibc] + + "@rollup/rollup-linux-ppc64-musl@4.57.1": + resolution: + { + integrity: sha512-NOlUuzesGauESAyEYFSe3QTUguL+lvrN1HtwEEsU2rOwdUDeTMJdO5dUYl/2hKf9jWydJrO9OL/XSSf65R5+Xw==, + } + cpu: [ppc64] + os: [linux] + libc: [musl] + + "@rollup/rollup-linux-riscv64-gnu@4.57.1": + resolution: + { + integrity: sha512-ptA88htVp0AwUUqhVghwDIKlvJMD/fmL/wrQj99PRHFRAG6Z5nbWoWG4o81Nt9FT+IuqUQi+L31ZKAFeJ5Is+A==, + } + cpu: [riscv64] + os: [linux] + libc: [glibc] + + "@rollup/rollup-linux-riscv64-musl@4.57.1": + resolution: + { + integrity: sha512-S51t7aMMTNdmAMPpBg7OOsTdn4tySRQvklmL3RpDRyknk87+Sp3xaumlatU+ppQ+5raY7sSTcC2beGgvhENfuw==, + } + cpu: [riscv64] + os: [linux] + libc: [musl] + + "@rollup/rollup-linux-s390x-gnu@4.57.1": + resolution: + { + integrity: sha512-Bl00OFnVFkL82FHbEqy3k5CUCKH6OEJL54KCyx2oqsmZnFTR8IoNqBF+mjQVcRCT5sB6yOvK8A37LNm/kPJiZg==, + } + cpu: [s390x] + os: [linux] + libc: [glibc] + + "@rollup/rollup-linux-x64-gnu@4.57.1": + resolution: + { + integrity: sha512-ABca4ceT4N+Tv/GtotnWAeXZUZuM/9AQyCyKYyKnpk4yoA7QIAuBt6Hkgpw8kActYlew2mvckXkvx0FfoInnLg==, + } + cpu: [x64] + os: [linux] + libc: [glibc] + + "@rollup/rollup-linux-x64-musl@4.57.1": + resolution: + { + integrity: sha512-HFps0JeGtuOR2convgRRkHCekD7j+gdAuXM+/i6kGzQtFhlCtQkpwtNzkNj6QhCDp7DRJ7+qC/1Vg2jt5iSOFw==, + } + cpu: [x64] + os: [linux] + libc: [musl] + + "@rollup/rollup-openbsd-x64@4.57.1": + resolution: + { + integrity: sha512-H+hXEv9gdVQuDTgnqD+SQffoWoc0Of59AStSzTEj/feWTBAnSfSD3+Dql1ZruJQxmykT/JVY0dE8Ka7z0DH1hw==, + } + cpu: [x64] + os: [openbsd] + + "@rollup/rollup-openharmony-arm64@4.57.1": + resolution: + { + integrity: sha512-4wYoDpNg6o/oPximyc/NG+mYUejZrCU2q+2w6YZqrAs2UcNUChIZXjtafAiiZSUc7On8v5NyNj34Kzj/Ltk6dQ==, + } + cpu: [arm64] + os: [openharmony] + + "@rollup/rollup-win32-arm64-msvc@4.57.1": + resolution: + { + integrity: sha512-O54mtsV/6LW3P8qdTcamQmuC990HDfR71lo44oZMZlXU4tzLrbvTii87Ni9opq60ds0YzuAlEr/GNwuNluZyMQ==, + } + cpu: [arm64] + os: [win32] + + "@rollup/rollup-win32-ia32-msvc@4.57.1": + resolution: + { + integrity: sha512-P3dLS+IerxCT/7D2q2FYcRdWRl22dNbrbBEtxdWhXrfIMPP9lQhb5h4Du04mdl5Woq05jVCDPCMF7Ub0NAjIew==, + } + cpu: [ia32] + os: [win32] + + "@rollup/rollup-win32-x64-gnu@4.57.1": + resolution: + { + integrity: sha512-VMBH2eOOaKGtIJYleXsi2B8CPVADrh+TyNxJ4mWPnKfLB/DBUmzW+5m1xUrcwWoMfSLagIRpjUFeW5CO5hyciQ==, + } + cpu: [x64] + os: [win32] + + "@rollup/rollup-win32-x64-msvc@4.57.1": + resolution: + { + integrity: sha512-mxRFDdHIWRxg3UfIIAwCm6NzvxG0jDX/wBN6KsQFTvKFqqg9vTrWUE68qEjHt19A5wwx5X5aUi2zuZT7YR0jrA==, + } + cpu: [x64] + os: [win32] + + "@scure/base@1.2.6": + resolution: + { + integrity: sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==, + } + + "@scure/sr25519@0.2.0": + resolution: + { + integrity: sha512-uUuLP7Z126XdSizKtrCGqYyR3b3hYtJ6Fg/XFUXmc2//k2aXHDLqZwFeXxL97gg4XydPROPVnuaHGF2+xriSKg==, + } + + "@substrate/ss58-registry@1.51.0": + resolution: + { + integrity: sha512-TWDurLiPxndFgKjVavCniytBIw+t4ViOi7TYp9h/D0NMmkEc9klFTo+827eyEJ0lELpqO207Ey7uGxUa+BS1jQ==, + } + + "@types/bn.js@5.2.0": + resolution: + { + integrity: sha512-DLbJ1BPqxvQhIGbeu8VbUC1DiAiahHtAYvA0ZEAa4P31F7IaArc8z3C3BRQdWX4mtLQuABG4yzp76ZrS02Ui1Q==, + } + + "@types/chai@5.2.3": + resolution: + { + integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==, + } + + "@types/deep-eql@4.0.2": + resolution: + { + integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==, + } + + "@types/estree@1.0.8": + resolution: + { + integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==, + } + + "@types/node@24.10.13": + resolution: + { + integrity: sha512-oH72nZRfDv9lADUBSo104Aq7gPHpQZc4BTx38r9xf9pg5LfP6EzSyH2n7qFmmxRQXh7YlUXODcYsg6PuTDSxGg==, + } + + "@vitest/expect@3.2.4": + resolution: + { + integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==, + } + + "@vitest/mocker@3.2.4": + resolution: + { + integrity: sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==, + } + peerDependencies: + msw: ^2.4.9 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + "@vitest/pretty-format@3.2.4": + resolution: + { + integrity: sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==, + } + + "@vitest/runner@3.2.4": + resolution: + { + integrity: sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==, + } + + "@vitest/snapshot@3.2.4": + resolution: + { + integrity: sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==, + } + + "@vitest/spy@3.2.4": + resolution: + { + integrity: sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==, + } + + "@vitest/utils@3.2.4": + resolution: + { + integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==, + } + + assertion-error@2.0.1: + resolution: + { + integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==, + } + engines: { node: ">=12" } + + bn.js@5.2.2: + resolution: + { + integrity: sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==, + } + + cac@6.7.14: + resolution: + { + integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==, + } + engines: { node: ">=8" } + + chai@5.3.3: + resolution: + { + integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==, + } + engines: { node: ">=18" } + + check-error@2.1.3: + resolution: + { + integrity: sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==, + } + engines: { node: ">= 16" } + + debug@4.4.3: + resolution: + { + integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==, + } + engines: { node: ">=6.0" } + peerDependencies: + supports-color: "*" + peerDependenciesMeta: + supports-color: + optional: true + + deep-eql@5.0.2: + resolution: + { + integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==, + } + engines: { node: ">=6" } + + es-module-lexer@1.7.0: + resolution: + { + integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==, + } + + esbuild@0.27.3: + resolution: + { + integrity: sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==, + } + engines: { node: ">=18" } + hasBin: true + + estree-walker@3.0.3: + resolution: + { + integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==, + } + + expect-type@1.3.0: + resolution: + { + integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==, + } + engines: { node: ">=12.0.0" } + + fdir@6.5.0: + resolution: + { + integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==, + } + engines: { node: ">=12.0.0" } + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + fsevents@2.3.3: + resolution: + { + integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==, + } + engines: { node: ^8.16.0 || ^10.6.0 || >=11.0.0 } + os: [darwin] + + js-tokens@9.0.1: + resolution: + { + integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==, + } + + loupe@3.2.1: + resolution: + { + integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==, + } + + magic-string@0.30.21: + resolution: + { + integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==, + } + + ms@2.1.3: + resolution: + { + integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==, + } + + nanoid@3.3.11: + resolution: + { + integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==, + } + engines: { node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1 } + hasBin: true + + pathe@2.0.3: + resolution: + { + integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==, + } + + pathval@2.0.1: + resolution: + { + integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==, + } + engines: { node: ">= 14.16" } + + picocolors@1.1.1: + resolution: + { + integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==, + } + + picomatch@4.0.3: + resolution: + { + integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==, + } + engines: { node: ">=12" } + + postcss@8.5.6: + resolution: + { + integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==, + } + engines: { node: ^10 || ^12 || >=14 } + + rollup@4.57.1: + resolution: + { + integrity: sha512-oQL6lgK3e2QZeQ7gcgIkS2YZPg5slw37hYufJ3edKlfQSGGm8ICoxswK15ntSzF/a8+h7ekRy7k7oWc3BQ7y8A==, + } + engines: { node: ">=18.0.0", npm: ">=8.0.0" } + hasBin: true + + siginfo@2.0.0: + resolution: + { + integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==, + } + + source-map-js@1.2.1: + resolution: + { + integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==, + } + engines: { node: ">=0.10.0" } + + stackback@0.0.2: + resolution: + { + integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==, + } + + std-env@3.10.0: + resolution: + { + integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==, + } + + strip-literal@3.1.0: + resolution: + { + integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==, + } + + tinybench@2.9.0: + resolution: + { + integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==, + } + + tinyexec@0.3.2: + resolution: + { + integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==, + } + + tinyglobby@0.2.15: + resolution: + { + integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==, + } + engines: { node: ">=12.0.0" } + + tinypool@1.1.1: + resolution: + { + integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==, + } + engines: { node: ^18.0.0 || >=20.0.0 } + + tinyrainbow@2.0.0: + resolution: + { + integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==, + } + engines: { node: ">=14.0.0" } + + tinyspy@4.0.4: + resolution: + { + integrity: sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==, + } + engines: { node: ">=14.0.0" } + + tslib@2.8.1: + resolution: + { + integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==, + } + + undici-types@7.16.0: + resolution: + { + integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==, + } + + vite-node@3.2.4: + resolution: + { + integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==, + } + engines: { node: ^18.0.0 || ^20.0.0 || >=22.0.0 } + hasBin: true + + vite@7.3.1: + resolution: + { + integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==, + } + engines: { node: ^20.19.0 || >=22.12.0 } + hasBin: true + peerDependencies: + "@types/node": ^20.19.0 || >=22.12.0 + jiti: ">=1.21.0" + less: ^4.0.0 + lightningcss: ^1.21.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: ">=0.54.8" + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + "@types/node": + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vitest@3.2.4: + resolution: + { + integrity: sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==, + } + engines: { node: ^18.0.0 || ^20.0.0 || >=22.0.0 } + hasBin: true + peerDependencies: + "@edge-runtime/vm": "*" + "@types/debug": ^4.1.12 + "@types/node": ^18.0.0 || ^20.0.0 || >=22.0.0 + "@vitest/browser": 3.2.4 + "@vitest/ui": 3.2.4 + happy-dom: "*" + jsdom: "*" + peerDependenciesMeta: + "@edge-runtime/vm": + optional: true + "@types/debug": + optional: true + "@types/node": + optional: true + "@vitest/browser": + optional: true + "@vitest/ui": + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + why-is-node-running@2.3.0: + resolution: + { + integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==, + } + engines: { node: ">=8" } + hasBin: true + +snapshots: + "@esbuild/aix-ppc64@0.27.3": + optional: true + + "@esbuild/android-arm64@0.27.3": + optional: true + + "@esbuild/android-arm@0.27.3": + optional: true + + "@esbuild/android-x64@0.27.3": + optional: true + + "@esbuild/darwin-arm64@0.27.3": + optional: true + + "@esbuild/darwin-x64@0.27.3": + optional: true + + "@esbuild/freebsd-arm64@0.27.3": + optional: true + + "@esbuild/freebsd-x64@0.27.3": + optional: true + + "@esbuild/linux-arm64@0.27.3": + optional: true + + "@esbuild/linux-arm@0.27.3": + optional: true + + "@esbuild/linux-ia32@0.27.3": + optional: true + + "@esbuild/linux-loong64@0.27.3": + optional: true + + "@esbuild/linux-mips64el@0.27.3": + optional: true + + "@esbuild/linux-ppc64@0.27.3": + optional: true + + "@esbuild/linux-riscv64@0.27.3": + optional: true + + "@esbuild/linux-s390x@0.27.3": + optional: true + + "@esbuild/linux-x64@0.27.3": + optional: true + + "@esbuild/netbsd-arm64@0.27.3": + optional: true + + "@esbuild/netbsd-x64@0.27.3": + optional: true + + "@esbuild/openbsd-arm64@0.27.3": + optional: true + + "@esbuild/openbsd-x64@0.27.3": + optional: true + + "@esbuild/openharmony-arm64@0.27.3": + optional: true + + "@esbuild/sunos-x64@0.27.3": + optional: true + + "@esbuild/win32-arm64@0.27.3": + optional: true + + "@esbuild/win32-ia32@0.27.3": + optional: true + + "@esbuild/win32-x64@0.27.3": + optional: true + + "@jridgewell/sourcemap-codec@1.5.5": {} + + "@noble/curves@1.9.7": + dependencies: + "@noble/hashes": 1.8.0 + + "@noble/hashes@1.8.0": {} + + "@polkadot/keyring@14.0.1(@polkadot/util-crypto@14.0.1(@polkadot/util@14.0.1))(@polkadot/util@14.0.1)": + dependencies: + "@polkadot/util": 14.0.1 + "@polkadot/util-crypto": 14.0.1(@polkadot/util@14.0.1) + tslib: 2.8.1 + + "@polkadot/networks@14.0.1": + dependencies: + "@polkadot/util": 14.0.1 + "@substrate/ss58-registry": 1.51.0 + tslib: 2.8.1 + + "@polkadot/util-crypto@14.0.1(@polkadot/util@14.0.1)": + dependencies: + "@noble/curves": 1.9.7 + "@noble/hashes": 1.8.0 + "@polkadot/networks": 14.0.1 + "@polkadot/util": 14.0.1 + "@polkadot/wasm-crypto": 7.5.4(@polkadot/util@14.0.1)(@polkadot/x-randomvalues@14.0.1(@polkadot/util@14.0.1)(@polkadot/wasm-util@7.5.4(@polkadot/util@14.0.1))) + "@polkadot/wasm-util": 7.5.4(@polkadot/util@14.0.1) + "@polkadot/x-bigint": 14.0.1 + "@polkadot/x-randomvalues": 14.0.1(@polkadot/util@14.0.1)(@polkadot/wasm-util@7.5.4(@polkadot/util@14.0.1)) + "@scure/base": 1.2.6 + "@scure/sr25519": 0.2.0 + tslib: 2.8.1 + + "@polkadot/util@14.0.1": + 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.2.0 + bn.js: 5.2.2 + tslib: 2.8.1 + + "@polkadot/wasm-bridge@7.5.4(@polkadot/util@14.0.1)(@polkadot/x-randomvalues@14.0.1(@polkadot/util@14.0.1)(@polkadot/wasm-util@7.5.4(@polkadot/util@14.0.1)))": + dependencies: + "@polkadot/util": 14.0.1 + "@polkadot/wasm-util": 7.5.4(@polkadot/util@14.0.1) + "@polkadot/x-randomvalues": 14.0.1(@polkadot/util@14.0.1)(@polkadot/wasm-util@7.5.4(@polkadot/util@14.0.1)) + tslib: 2.8.1 + + "@polkadot/wasm-crypto-asmjs@7.5.4(@polkadot/util@14.0.1)": + dependencies: + "@polkadot/util": 14.0.1 + tslib: 2.8.1 + + "@polkadot/wasm-crypto-init@7.5.4(@polkadot/util@14.0.1)(@polkadot/x-randomvalues@14.0.1(@polkadot/util@14.0.1)(@polkadot/wasm-util@7.5.4(@polkadot/util@14.0.1)))": + dependencies: + "@polkadot/util": 14.0.1 + "@polkadot/wasm-bridge": 7.5.4(@polkadot/util@14.0.1)(@polkadot/x-randomvalues@14.0.1(@polkadot/util@14.0.1)(@polkadot/wasm-util@7.5.4(@polkadot/util@14.0.1))) + "@polkadot/wasm-crypto-asmjs": 7.5.4(@polkadot/util@14.0.1) + "@polkadot/wasm-crypto-wasm": 7.5.4(@polkadot/util@14.0.1) + "@polkadot/wasm-util": 7.5.4(@polkadot/util@14.0.1) + "@polkadot/x-randomvalues": 14.0.1(@polkadot/util@14.0.1)(@polkadot/wasm-util@7.5.4(@polkadot/util@14.0.1)) + tslib: 2.8.1 + + "@polkadot/wasm-crypto-wasm@7.5.4(@polkadot/util@14.0.1)": + dependencies: + "@polkadot/util": 14.0.1 + "@polkadot/wasm-util": 7.5.4(@polkadot/util@14.0.1) + tslib: 2.8.1 + + "@polkadot/wasm-crypto@7.5.4(@polkadot/util@14.0.1)(@polkadot/x-randomvalues@14.0.1(@polkadot/util@14.0.1)(@polkadot/wasm-util@7.5.4(@polkadot/util@14.0.1)))": + dependencies: + "@polkadot/util": 14.0.1 + "@polkadot/wasm-bridge": 7.5.4(@polkadot/util@14.0.1)(@polkadot/x-randomvalues@14.0.1(@polkadot/util@14.0.1)(@polkadot/wasm-util@7.5.4(@polkadot/util@14.0.1))) + "@polkadot/wasm-crypto-asmjs": 7.5.4(@polkadot/util@14.0.1) + "@polkadot/wasm-crypto-init": 7.5.4(@polkadot/util@14.0.1)(@polkadot/x-randomvalues@14.0.1(@polkadot/util@14.0.1)(@polkadot/wasm-util@7.5.4(@polkadot/util@14.0.1))) + "@polkadot/wasm-crypto-wasm": 7.5.4(@polkadot/util@14.0.1) + "@polkadot/wasm-util": 7.5.4(@polkadot/util@14.0.1) + "@polkadot/x-randomvalues": 14.0.1(@polkadot/util@14.0.1)(@polkadot/wasm-util@7.5.4(@polkadot/util@14.0.1)) + tslib: 2.8.1 + + "@polkadot/wasm-util@7.5.4(@polkadot/util@14.0.1)": + dependencies: + "@polkadot/util": 14.0.1 + tslib: 2.8.1 + + "@polkadot/x-bigint@14.0.1": + dependencies: + "@polkadot/x-global": 14.0.1 + tslib: 2.8.1 + + "@polkadot/x-global@14.0.1": + dependencies: + tslib: 2.8.1 + + "@polkadot/x-randomvalues@14.0.1(@polkadot/util@14.0.1)(@polkadot/wasm-util@7.5.4(@polkadot/util@14.0.1))": + dependencies: + "@polkadot/util": 14.0.1 + "@polkadot/wasm-util": 7.5.4(@polkadot/util@14.0.1) + "@polkadot/x-global": 14.0.1 + tslib: 2.8.1 + + "@polkadot/x-textdecoder@14.0.1": + dependencies: + "@polkadot/x-global": 14.0.1 + tslib: 2.8.1 + + "@polkadot/x-textencoder@14.0.1": + dependencies: + "@polkadot/x-global": 14.0.1 + tslib: 2.8.1 + + "@rollup/rollup-android-arm-eabi@4.57.1": + optional: true + + "@rollup/rollup-android-arm64@4.57.1": + optional: true + + "@rollup/rollup-darwin-arm64@4.57.1": + optional: true + + "@rollup/rollup-darwin-x64@4.57.1": + optional: true + + "@rollup/rollup-freebsd-arm64@4.57.1": + optional: true + + "@rollup/rollup-freebsd-x64@4.57.1": + optional: true + + "@rollup/rollup-linux-arm-gnueabihf@4.57.1": + optional: true + + "@rollup/rollup-linux-arm-musleabihf@4.57.1": + optional: true + + "@rollup/rollup-linux-arm64-gnu@4.57.1": + optional: true + + "@rollup/rollup-linux-arm64-musl@4.57.1": + optional: true + + "@rollup/rollup-linux-loong64-gnu@4.57.1": + optional: true + + "@rollup/rollup-linux-loong64-musl@4.57.1": + optional: true + + "@rollup/rollup-linux-ppc64-gnu@4.57.1": + optional: true + + "@rollup/rollup-linux-ppc64-musl@4.57.1": + optional: true + + "@rollup/rollup-linux-riscv64-gnu@4.57.1": + optional: true + + "@rollup/rollup-linux-riscv64-musl@4.57.1": + optional: true + + "@rollup/rollup-linux-s390x-gnu@4.57.1": + optional: true + + "@rollup/rollup-linux-x64-gnu@4.57.1": + optional: true + + "@rollup/rollup-linux-x64-musl@4.57.1": + optional: true + + "@rollup/rollup-openbsd-x64@4.57.1": + optional: true + + "@rollup/rollup-openharmony-arm64@4.57.1": + optional: true + + "@rollup/rollup-win32-arm64-msvc@4.57.1": + optional: true + + "@rollup/rollup-win32-ia32-msvc@4.57.1": + optional: true + + "@rollup/rollup-win32-x64-gnu@4.57.1": + optional: true + + "@rollup/rollup-win32-x64-msvc@4.57.1": + optional: true + + "@scure/base@1.2.6": {} + + "@scure/sr25519@0.2.0": + dependencies: + "@noble/curves": 1.9.7 + "@noble/hashes": 1.8.0 + + "@substrate/ss58-registry@1.51.0": {} + + "@types/bn.js@5.2.0": + dependencies: + "@types/node": 24.10.13 + + "@types/chai@5.2.3": + dependencies: + "@types/deep-eql": 4.0.2 + assertion-error: 2.0.1 + + "@types/deep-eql@4.0.2": {} + + "@types/estree@1.0.8": {} + + "@types/node@24.10.13": + dependencies: + undici-types: 7.16.0 + + "@vitest/expect@3.2.4": + dependencies: + "@types/chai": 5.2.3 + "@vitest/spy": 3.2.4 + "@vitest/utils": 3.2.4 + chai: 5.3.3 + tinyrainbow: 2.0.0 + + "@vitest/mocker@3.2.4(vite@7.3.1(@types/node@24.10.13))": + dependencies: + "@vitest/spy": 3.2.4 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 7.3.1(@types/node@24.10.13) + + "@vitest/pretty-format@3.2.4": + dependencies: + tinyrainbow: 2.0.0 + + "@vitest/runner@3.2.4": + dependencies: + "@vitest/utils": 3.2.4 + pathe: 2.0.3 + strip-literal: 3.1.0 + + "@vitest/snapshot@3.2.4": + dependencies: + "@vitest/pretty-format": 3.2.4 + magic-string: 0.30.21 + pathe: 2.0.3 + + "@vitest/spy@3.2.4": + dependencies: + tinyspy: 4.0.4 + + "@vitest/utils@3.2.4": + dependencies: + "@vitest/pretty-format": 3.2.4 + loupe: 3.2.1 + tinyrainbow: 2.0.0 + + assertion-error@2.0.1: {} + + bn.js@5.2.2: {} + + cac@6.7.14: {} + + chai@5.3.3: + dependencies: + assertion-error: 2.0.1 + check-error: 2.1.3 + deep-eql: 5.0.2 + loupe: 3.2.1 + pathval: 2.0.1 + + check-error@2.1.3: {} + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + deep-eql@5.0.2: {} + + es-module-lexer@1.7.0: {} + + esbuild@0.27.3: + optionalDependencies: + "@esbuild/aix-ppc64": 0.27.3 + "@esbuild/android-arm": 0.27.3 + "@esbuild/android-arm64": 0.27.3 + "@esbuild/android-x64": 0.27.3 + "@esbuild/darwin-arm64": 0.27.3 + "@esbuild/darwin-x64": 0.27.3 + "@esbuild/freebsd-arm64": 0.27.3 + "@esbuild/freebsd-x64": 0.27.3 + "@esbuild/linux-arm": 0.27.3 + "@esbuild/linux-arm64": 0.27.3 + "@esbuild/linux-ia32": 0.27.3 + "@esbuild/linux-loong64": 0.27.3 + "@esbuild/linux-mips64el": 0.27.3 + "@esbuild/linux-ppc64": 0.27.3 + "@esbuild/linux-riscv64": 0.27.3 + "@esbuild/linux-s390x": 0.27.3 + "@esbuild/linux-x64": 0.27.3 + "@esbuild/netbsd-arm64": 0.27.3 + "@esbuild/netbsd-x64": 0.27.3 + "@esbuild/openbsd-arm64": 0.27.3 + "@esbuild/openbsd-x64": 0.27.3 + "@esbuild/openharmony-arm64": 0.27.3 + "@esbuild/sunos-x64": 0.27.3 + "@esbuild/win32-arm64": 0.27.3 + "@esbuild/win32-ia32": 0.27.3 + "@esbuild/win32-x64": 0.27.3 + + estree-walker@3.0.3: + dependencies: + "@types/estree": 1.0.8 + + expect-type@1.3.0: {} + + fdir@6.5.0(picomatch@4.0.3): + optionalDependencies: + picomatch: 4.0.3 + + fsevents@2.3.3: + optional: true + + js-tokens@9.0.1: {} + + loupe@3.2.1: {} + + magic-string@0.30.21: + dependencies: + "@jridgewell/sourcemap-codec": 1.5.5 + + ms@2.1.3: {} + + nanoid@3.3.11: {} + + pathe@2.0.3: {} + + pathval@2.0.1: {} + + picocolors@1.1.1: {} + + picomatch@4.0.3: {} + + postcss@8.5.6: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + rollup@4.57.1: + dependencies: + "@types/estree": 1.0.8 + optionalDependencies: + "@rollup/rollup-android-arm-eabi": 4.57.1 + "@rollup/rollup-android-arm64": 4.57.1 + "@rollup/rollup-darwin-arm64": 4.57.1 + "@rollup/rollup-darwin-x64": 4.57.1 + "@rollup/rollup-freebsd-arm64": 4.57.1 + "@rollup/rollup-freebsd-x64": 4.57.1 + "@rollup/rollup-linux-arm-gnueabihf": 4.57.1 + "@rollup/rollup-linux-arm-musleabihf": 4.57.1 + "@rollup/rollup-linux-arm64-gnu": 4.57.1 + "@rollup/rollup-linux-arm64-musl": 4.57.1 + "@rollup/rollup-linux-loong64-gnu": 4.57.1 + "@rollup/rollup-linux-loong64-musl": 4.57.1 + "@rollup/rollup-linux-ppc64-gnu": 4.57.1 + "@rollup/rollup-linux-ppc64-musl": 4.57.1 + "@rollup/rollup-linux-riscv64-gnu": 4.57.1 + "@rollup/rollup-linux-riscv64-musl": 4.57.1 + "@rollup/rollup-linux-s390x-gnu": 4.57.1 + "@rollup/rollup-linux-x64-gnu": 4.57.1 + "@rollup/rollup-linux-x64-musl": 4.57.1 + "@rollup/rollup-openbsd-x64": 4.57.1 + "@rollup/rollup-openharmony-arm64": 4.57.1 + "@rollup/rollup-win32-arm64-msvc": 4.57.1 + "@rollup/rollup-win32-ia32-msvc": 4.57.1 + "@rollup/rollup-win32-x64-gnu": 4.57.1 + "@rollup/rollup-win32-x64-msvc": 4.57.1 + fsevents: 2.3.3 + + siginfo@2.0.0: {} + + source-map-js@1.2.1: {} + + stackback@0.0.2: {} + + std-env@3.10.0: {} + + strip-literal@3.1.0: + dependencies: + js-tokens: 9.0.1 + + tinybench@2.9.0: {} + + tinyexec@0.3.2: {} + + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + + tinypool@1.1.1: {} + + tinyrainbow@2.0.0: {} + + tinyspy@4.0.4: {} + + tslib@2.8.1: {} + + undici-types@7.16.0: {} + + vite-node@3.2.4(@types/node@24.10.13): + dependencies: + cac: 6.7.14 + debug: 4.4.3 + es-module-lexer: 1.7.0 + pathe: 2.0.3 + vite: 7.3.1(@types/node@24.10.13) + transitivePeerDependencies: + - "@types/node" + - jiti + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + + vite@7.3.1(@types/node@24.10.13): + dependencies: + esbuild: 0.27.3 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.57.1 + tinyglobby: 0.2.15 + optionalDependencies: + "@types/node": 24.10.13 + fsevents: 2.3.3 + + vitest@3.2.4(@types/node@24.10.13): + dependencies: + "@types/chai": 5.2.3 + "@vitest/expect": 3.2.4 + "@vitest/mocker": 3.2.4(vite@7.3.1(@types/node@24.10.13)) + "@vitest/pretty-format": 3.2.4 + "@vitest/runner": 3.2.4 + "@vitest/snapshot": 3.2.4 + "@vitest/spy": 3.2.4 + "@vitest/utils": 3.2.4 + chai: 5.3.3 + debug: 4.4.3 + expect-type: 1.3.0 + magic-string: 0.30.21 + pathe: 2.0.3 + picomatch: 4.0.3 + std-env: 3.10.0 + tinybench: 2.9.0 + tinyexec: 0.3.2 + tinyglobby: 0.2.15 + tinypool: 1.1.1 + tinyrainbow: 2.0.0 + vite: 7.3.1(@types/node@24.10.13) + vite-node: 3.2.4(@types/node@24.10.13) + why-is-node-running: 2.3.0 + optionalDependencies: + "@types/node": 24.10.13 + transitivePeerDependencies: + - jiti + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 diff --git a/e2e/shared/sequencer.ts b/e2e/shared/sequencer.ts new file mode 100644 index 0000000000..a87490d89b --- /dev/null +++ b/e2e/shared/sequencer.ts @@ -0,0 +1,21 @@ +import { BaseSequencer } from "vitest/node"; +import type { TestSpecification } from "vitest/node"; + +/** + * Sorts test files alphabetically by their module path. + * + * Vitest's default sequencer orders files by cached duration/failure history, + * which does not respect numeric prefixes (00-, 01-, 02-, ...). This sequencer + * ensures files always run in the order they are named, which matters for + * multi-file suites where later files depend on state set up by earlier ones + * (e.g. a scaling test that adds nodes for subsequent edge-case tests). + */ +export default class AlphabeticalSequencer extends BaseSequencer { + async shard(files: TestSpecification[]): Promise { + return super.shard(files); + } + + async sort(files: TestSpecification[]): Promise { + return files.sort((a, b) => a.moduleId.localeCompare(b.moduleId)); + } +} diff --git a/e2e/shared/staking.ts b/e2e/shared/staking.ts new file mode 100644 index 0000000000..96241f64e9 --- /dev/null +++ b/e2e/shared/staking.ts @@ -0,0 +1,508 @@ +import { subtensor } from "@polkadot-api/descriptors"; +import { TypedApi } from "polkadot-api"; +import { KeyPair } from "@polkadot-labs/hdkd-helpers"; +import { getSignerFromKeypair, getAliceSigner } from "./address.js"; +import { waitForTransactionWithRetry } from "./transactions.js"; + +// U64F64 is a 128-bit fixed-point type with 64 fractional bits. +// Raw storage values must be divided by 2^64 to get the actual value. +const U64F64_FRACTIONAL_BITS = 64n; +const U64F64_MULTIPLIER = 1n << U64F64_FRACTIONAL_BITS; // 2^64 + +/** + * Convert a raw U64F64 storage value to its integer part (truncated). + */ +export function u64f64ToInt(raw: bigint): bigint { + return raw >> U64F64_FRACTIONAL_BITS; +} + +/** + * Convert an integer to U64F64 raw format for use in extrinsics. + */ +export function intToU64f64(value: bigint): bigint { + return value << U64F64_FRACTIONAL_BITS; +} + +/** + * Convert a raw U64F64 storage value to a decimal number for display. + */ +export function u64f64ToNumber(raw: bigint): number { + return Number(raw) / Number(U64F64_MULTIPLIER); +} + +export async function addStake( + api: TypedApi, + coldkey: KeyPair, + hotkey: string, + netuid: number, + amount: bigint, +): Promise { + const signer = getSignerFromKeypair(coldkey); + const tx = api.tx.SubtensorModule.add_stake({ + hotkey: hotkey, + netuid: netuid, + amount_staked: amount, + }); + await waitForTransactionWithRetry(api, tx, signer, "add_stake"); +} + +export async function addStakeLimit( + api: TypedApi, + coldkey: KeyPair, + hotkey: string, + netuid: number, + amount: bigint, + limitPrice: bigint, + allowPartial: boolean, +): Promise { + const signer = getSignerFromKeypair(coldkey); + const tx = api.tx.SubtensorModule.add_stake_limit({ + hotkey: hotkey, + netuid: netuid, + amount_staked: amount, + limit_price: limitPrice, + allow_partial: allowPartial, + }); + await waitForTransactionWithRetry(api, tx, signer, "add_stake_limit"); +} + +export async function removeStake( + api: TypedApi, + coldkey: KeyPair, + hotkey: string, + netuid: number, + amount: bigint, +): Promise { + const signer = getSignerFromKeypair(coldkey); + const tx = api.tx.SubtensorModule.remove_stake({ + hotkey: hotkey, + netuid: netuid, + amount_unstaked: amount, + }); + await waitForTransactionWithRetry(api, tx, signer, "remove_stake"); +} + +export async function removeStakeLimit( + api: TypedApi, + coldkey: KeyPair, + hotkey: string, + netuid: number, + amount: bigint, + limitPrice: bigint, + allowPartial: boolean, +): Promise { + const signer = getSignerFromKeypair(coldkey); + const tx = api.tx.SubtensorModule.remove_stake_limit({ + hotkey: hotkey, + netuid: netuid, + amount_unstaked: amount, + limit_price: limitPrice, + allow_partial: allowPartial, + }); + await waitForTransactionWithRetry(api, tx, signer, "remove_stake_limit"); +} + +export async function removeStakeFullLimit( + api: TypedApi, + coldkey: KeyPair, + hotkey: string, + netuid: number, + limitPrice: bigint | undefined, +): Promise { + const signer = getSignerFromKeypair(coldkey); + const tx = api.tx.SubtensorModule.remove_stake_full_limit({ + hotkey: hotkey, + netuid: netuid, + limit_price: limitPrice, + }); + await waitForTransactionWithRetry(api, tx, signer, "remove_stake_full_limit"); +} + +export async function unstakeAll( + api: TypedApi, + coldkey: KeyPair, + hotkey: string, +): Promise { + const signer = getSignerFromKeypair(coldkey); + const tx = api.tx.SubtensorModule.unstake_all({ + hotkey: hotkey, + }); + await waitForTransactionWithRetry(api, tx, signer, "unstake_all"); +} + +export async function unstakeAllAlpha( + api: TypedApi, + coldkey: KeyPair, + hotkey: string, +): Promise { + const signer = getSignerFromKeypair(coldkey); + const tx = api.tx.SubtensorModule.unstake_all_alpha({ + hotkey: hotkey, + }); + await waitForTransactionWithRetry(api, tx, signer, "unstake_all_alpha"); +} + +/** + * Get stake shares (Alpha) for a hotkey/coldkey/netuid triplet. + * Returns the integer part of the U64F64 value. + */ +export async function getStake( + api: TypedApi, + hotkey: string, + coldkey: string, + netuid: number, +): Promise { + const raw = await api.query.SubtensorModule.Alpha.getValue(hotkey, coldkey, netuid); + return u64f64ToInt(raw); +} + +/** + * Get raw stake shares (Alpha) in U64F64 format. + * Use this when you need the raw value for extrinsics like transfer_stake. + */ +export async function getStakeRaw( + api: TypedApi, + hotkey: string, + coldkey: string, + netuid: number, +): Promise { + return await api.query.SubtensorModule.Alpha.getValue(hotkey, coldkey, netuid); +} + +export async function transferStake( + api: TypedApi, + originColdkey: KeyPair, + destinationColdkey: string, + hotkey: string, + originNetuid: number, + destinationNetuid: number, + amount: bigint, +): Promise { + const signer = getSignerFromKeypair(originColdkey); + const tx = api.tx.SubtensorModule.transfer_stake({ + destination_coldkey: destinationColdkey, + hotkey: hotkey, + origin_netuid: originNetuid, + destination_netuid: destinationNetuid, + alpha_amount: amount, + }); + await waitForTransactionWithRetry(api, tx, signer, "transfer_stake"); +} + +export async function moveStake( + api: TypedApi, + coldkey: KeyPair, + originHotkey: string, + destinationHotkey: string, + originNetuid: number, + destinationNetuid: number, + amount: bigint, +): Promise { + const signer = getSignerFromKeypair(coldkey); + const tx = api.tx.SubtensorModule.move_stake({ + origin_hotkey: originHotkey, + destination_hotkey: destinationHotkey, + origin_netuid: originNetuid, + destination_netuid: destinationNetuid, + alpha_amount: amount, + }); + await waitForTransactionWithRetry(api, tx, signer, "move_stake"); +} + +export async function swapStake( + api: TypedApi, + coldkey: KeyPair, + hotkey: string, + originNetuid: number, + destinationNetuid: number, + amount: bigint, +): Promise { + const signer = getSignerFromKeypair(coldkey); + const tx = api.tx.SubtensorModule.swap_stake({ + hotkey: hotkey, + origin_netuid: originNetuid, + destination_netuid: destinationNetuid, + alpha_amount: amount, + }); + await waitForTransactionWithRetry(api, tx, signer, "swap_stake"); +} + +export async function swapStakeLimit( + api: TypedApi, + coldkey: KeyPair, + hotkey: string, + originNetuid: number, + destinationNetuid: number, + amount: bigint, + limitPrice: bigint, + allowPartial: boolean, +): Promise { + const signer = getSignerFromKeypair(coldkey); + const tx = api.tx.SubtensorModule.swap_stake_limit({ + hotkey: hotkey, + origin_netuid: originNetuid, + destination_netuid: destinationNetuid, + alpha_amount: amount, + limit_price: limitPrice, + allow_partial: allowPartial, + }); + await waitForTransactionWithRetry(api, tx, signer, "swap_stake_limit"); +} + +export type RootClaimType = "Swap" | "Keep" | { type: "KeepSubnets"; subnets: number[] }; + +export async function getRootClaimType( + api: TypedApi, + coldkey: string, +): Promise { + const result = await api.query.SubtensorModule.RootClaimType.getValue(coldkey); + if (result.type === "KeepSubnets") { + return { type: "KeepSubnets", subnets: result.value.subnets as number[] }; + } + return result.type as "Swap" | "Keep"; +} + +export async function setRootClaimType( + api: TypedApi, + coldkey: KeyPair, + claimType: RootClaimType, +): Promise { + const signer = getSignerFromKeypair(coldkey); + let newRootClaimType; + if (typeof claimType === "string") { + newRootClaimType = { type: claimType, value: undefined }; + } else { + newRootClaimType = { type: "KeepSubnets", value: { subnets: claimType.subnets } }; + } + const tx = api.tx.SubtensorModule.set_root_claim_type({ + new_root_claim_type: newRootClaimType, + }); + await waitForTransactionWithRetry(api, tx, signer, "set_root_claim_type"); +} + +export async function claimRoot( + api: TypedApi, + coldkey: KeyPair, + subnets: number[], +): Promise { + const signer = getSignerFromKeypair(coldkey); + const tx = api.tx.SubtensorModule.claim_root({ + subnets: subnets, + }); + await waitForTransactionWithRetry(api, tx, signer, "claim_root"); +} + +export async function getNumRootClaims(api: TypedApi): Promise { + return await api.query.SubtensorModule.NumRootClaim.getValue(); +} + +export async function sudoSetNumRootClaims( + api: TypedApi, + newValue: bigint, +): Promise { + const alice = getAliceSigner(); + const internalCall = api.tx.SubtensorModule.sudo_set_num_root_claims({ + new_value: newValue, + }); + const tx = api.tx.Sudo.sudo({ call: internalCall.decodedCall }); + await waitForTransactionWithRetry(api, tx, alice, "sudo_set_num_root_claims"); +} + +export async function getRootClaimThreshold( + api: TypedApi, + netuid: number, +): Promise { + return await api.query.SubtensorModule.RootClaimableThreshold.getValue(netuid); +} + +export async function sudoSetRootClaimThreshold( + api: TypedApi, + netuid: number, + newValue: bigint, +): Promise { + const alice = getAliceSigner(); + const internalCall = api.tx.SubtensorModule.sudo_set_root_claim_threshold({ + netuid: netuid, + new_value: newValue, + }); + const tx = api.tx.Sudo.sudo({ call: internalCall.decodedCall }); + await waitForTransactionWithRetry(api, tx, alice, "sudo_set_root_claim_threshold"); +} + +export async function getTempo(api: TypedApi, netuid: number): Promise { + return await api.query.SubtensorModule.Tempo.getValue(netuid); +} + +export async function sudoSetTempo( + api: TypedApi, + netuid: number, + tempo: number, +): Promise { + const alice = getAliceSigner(); + const internalCall = api.tx.AdminUtils.sudo_set_tempo({ + netuid: netuid, + tempo: tempo, + }); + const tx = api.tx.Sudo.sudo({ call: internalCall.decodedCall }); + await waitForTransactionWithRetry(api, tx, alice, "sudo_set_tempo"); +} + +export async function waitForBlocks( + api: TypedApi, + numBlocks: number, +): Promise { + const startBlock = await api.query.System.Number.getValue(); + const targetBlock = startBlock + numBlocks; + + while (true) { + const currentBlock = await api.query.System.Number.getValue(); + if (currentBlock >= targetBlock) { + break; + } + await new Promise((resolve) => setTimeout(resolve, 1000)); + } +} + +export async function getRootClaimable( + api: TypedApi, + hotkey: string, +): Promise> { + const result = await api.query.SubtensorModule.RootClaimable.getValue(hotkey); + const claimableMap = new Map(); + for (const [netuid, amount] of result) { + claimableMap.set(netuid, amount); + } + return claimableMap; +} + +export async function getRootClaimed( + api: TypedApi, + netuid: number, + hotkey: string, + coldkey: string, +): Promise { + return await api.query.SubtensorModule.RootClaimed.getValue(netuid, hotkey, coldkey); +} + +export async function isSubtokenEnabled( + api: TypedApi, + netuid: number, +): Promise { + return await api.query.SubtensorModule.SubtokenEnabled.getValue(netuid); +} + +export async function sudoSetSubtokenEnabled( + api: TypedApi, + netuid: number, + enabled: boolean, +): Promise { + const alice = getAliceSigner(); + const internalCall = api.tx.AdminUtils.sudo_set_subtoken_enabled({ + netuid: netuid, + subtoken_enabled: enabled, + }); + const tx = api.tx.Sudo.sudo({ call: internalCall.decodedCall }); + await waitForTransactionWithRetry(api, tx, alice, "sudo_set_subtoken_enabled"); +} + +export async function isNetworkAdded( + api: TypedApi, + netuid: number, +): Promise { + return await api.query.SubtensorModule.NetworksAdded.getValue(netuid); +} + +export async function getAdminFreezeWindow(api: TypedApi): Promise { + return await api.query.SubtensorModule.AdminFreezeWindow.getValue(); +} + +export async function sudoSetAdminFreezeWindow( + api: TypedApi, + window: number, +): Promise { + const alice = getAliceSigner(); + const internalCall = api.tx.AdminUtils.sudo_set_admin_freeze_window({ + window: window, + }); + const tx = api.tx.Sudo.sudo({ call: internalCall.decodedCall }); + await waitForTransactionWithRetry(api, tx, alice, "sudo_set_admin_freeze_window"); +} + +export async function sudoSetEmaPriceHalvingPeriod( + api: TypedApi, + netuid: number, + emaPriceHalvingPeriod: number, +): Promise { + const alice = getAliceSigner(); + const internalCall = api.tx.AdminUtils.sudo_set_ema_price_halving_period({ + netuid: netuid, + ema_halving: BigInt(emaPriceHalvingPeriod), + }); + const tx = api.tx.Sudo.sudo({ call: internalCall.decodedCall }); + await waitForTransactionWithRetry(api, tx, alice, "sudo_set_ema_price_halving_period"); +} + +export async function sudoSetLockReductionInterval( + api: TypedApi, + interval: number, +): Promise { + const alice = getAliceSigner(); + const internalCall = api.tx.AdminUtils.sudo_set_lock_reduction_interval({ + interval: BigInt(interval), + }); + const tx = api.tx.Sudo.sudo({ call: internalCall.decodedCall }); + await waitForTransactionWithRetry(api, tx, alice, "sudo_set_lock_reduction_interval"); +} + +export async function sudoSetSubnetMovingAlpha( + api: TypedApi, + alpha: bigint, +): Promise { + const alice = getAliceSigner(); + const internalCall = api.tx.AdminUtils.sudo_set_subnet_moving_alpha({ + alpha: alpha, + }); + const tx = api.tx.Sudo.sudo({ call: internalCall.decodedCall }); + await waitForTransactionWithRetry(api, tx, alice, "sudo_set_subnet_moving_alpha"); +} + +// Debug helpers for claim_root investigation +export async function getSubnetTAO( + api: TypedApi, + netuid: number, +): Promise { + return await api.query.SubtensorModule.SubnetTAO.getValue(netuid); +} + +export async function getSubnetMovingPrice( + api: TypedApi, + netuid: number, +): Promise { + return await api.query.SubtensorModule.SubnetMovingPrice.getValue(netuid); +} + +export async function getPendingRootAlphaDivs( + api: TypedApi, + netuid: number, +): Promise { + return await api.query.SubtensorModule.PendingRootAlphaDivs.getValue(netuid); +} + +export async function getTaoWeight(api: TypedApi): Promise { + return await api.query.SubtensorModule.TaoWeight.getValue(); +} + +export async function getSubnetAlphaIn( + api: TypedApi, + netuid: number, +): Promise { + return await api.query.SubtensorModule.SubnetAlphaIn.getValue(netuid); +} + +export async function getTotalHotkeyAlpha( + api: TypedApi, + hotkey: string, + netuid: number, +): Promise { + return await api.query.SubtensorModule.TotalHotkeyAlpha.getValue(hotkey, netuid); +} diff --git a/e2e/shared/subnet.ts b/e2e/shared/subnet.ts new file mode 100644 index 0000000000..e15bd7cbe9 --- /dev/null +++ b/e2e/shared/subnet.ts @@ -0,0 +1,74 @@ +import { subtensor } from "@polkadot-api/descriptors"; +import { TypedApi } from "polkadot-api"; +import { KeyPair } from "@polkadot-labs/hdkd-helpers"; +import { getAliceSigner, getSignerFromKeypair, convertPublicKeyToSs58 } from "./address.js"; +import { waitForTransactionWithRetry } from "./transactions.js"; +import { log } from "./logger.js"; + +export async function addNewSubnetwork( + api: TypedApi, + hotkey: KeyPair, + coldkey: KeyPair, +): Promise { + const alice = getAliceSigner(); + const totalNetworks = await api.query.SubtensorModule.TotalNetworks.getValue(); + + // Disable network rate limit for testing + const rateLimit = await api.query.SubtensorModule.NetworkRateLimit.getValue(); + if (rateLimit !== BigInt(0)) { + const internalCall = api.tx.AdminUtils.sudo_set_network_rate_limit({ rate_limit: BigInt(0) }); + const tx = api.tx.Sudo.sudo({ call: internalCall.decodedCall }); + await waitForTransactionWithRetry(api, tx, alice, "set_network_rate_limit"); + } + + const signer = getSignerFromKeypair(coldkey); + const registerNetworkTx = api.tx.SubtensorModule.register_network({ + hotkey: convertPublicKeyToSs58(hotkey.publicKey), + }); + await waitForTransactionWithRetry(api, registerNetworkTx, signer, "register_network"); + + return totalNetworks; +} + +export async function burnedRegister( + api: TypedApi, + netuid: number, + hotkeyAddress: string, + coldkey: KeyPair, +): Promise { + const registered = await api.query.SubtensorModule.Uids.getValue(netuid, hotkeyAddress); + if (registered !== undefined) { + log.tx("burned_register", `skipped: hotkey already registered on netuid ${netuid}`); + return; + } + + await new Promise((resolve) => setTimeout(resolve, 1000)); + const signer = getSignerFromKeypair(coldkey); + const tx = api.tx.SubtensorModule.burned_register({ hotkey: hotkeyAddress, netuid: netuid }); + await waitForTransactionWithRetry(api, tx, signer, "burned_register"); +} + +export async function startCall( + api: TypedApi, + netuid: number, + coldkey: KeyPair, +): Promise { + const registerBlock = Number( + await api.query.SubtensorModule.NetworkRegisteredAt.getValue(netuid), + ); + let currentBlock = await api.query.System.Number.getValue(); + const duration = Number(await api.constants.SubtensorModule.InitialStartCallDelay); + + while (currentBlock - registerBlock <= duration) { + await new Promise((resolve) => setTimeout(resolve, 2000)); + currentBlock = await api.query.System.Number.getValue(); + } + + await new Promise((resolve) => setTimeout(resolve, 2000)); + + const signer = getSignerFromKeypair(coldkey); + const tx = api.tx.SubtensorModule.start_call({ netuid: netuid }); + await waitForTransactionWithRetry(api, tx, signer, "start_call"); + + await new Promise((resolve) => setTimeout(resolve, 1000)); +} diff --git a/e2e/shared/transactions.ts b/e2e/shared/transactions.ts new file mode 100644 index 0000000000..f6bb700335 --- /dev/null +++ b/e2e/shared/transactions.ts @@ -0,0 +1,71 @@ +import { subtensor } from "@polkadot-api/descriptors"; +import { TypedApi, Transaction, PolkadotSigner } from "polkadot-api"; +import { log } from "./logger.js"; + +export const TX_TIMEOUT = 5000; + +export async function waitForTransactionWithRetry( + api: TypedApi, + tx: Transaction<{}, string, string, void>, + signer: PolkadotSigner, + label: string, + maxRetries = 1, +): Promise { + let success = false; + let retries = 0; + + while (!success && retries < maxRetries) { + await waitForTransactionCompletion(tx, signer, label) + .then(() => { + success = true; + }) + .catch((error) => { + log.tx(label, `error: ${error}`); + }); + await new Promise((resolve) => setTimeout(resolve, 1000)); + retries += 1; + } + + if (!success) { + throw new Error(`[${label}] failed after ${maxRetries} retries`); + } +} + +async function waitForTransactionCompletion( + tx: Transaction<{}, string, string, void>, + signer: PolkadotSigner, + label: string, +): Promise { + return new Promise((resolve, reject) => { + let txHash = ""; + const subscription = tx.signSubmitAndWatch(signer).subscribe({ + next(value) { + txHash = value.txHash; + if (value.type === "finalized") { + log.tx(label, `finalized: ${value.txHash}`); + subscription.unsubscribe(); + clearTimeout(timeoutId); + if (!value.ok) { + const errorStr = JSON.stringify(value.dispatchError, null, 2); + log.tx(label, `dispatch error: ${errorStr}`); + reject(new Error(`[${label}] dispatch error: ${errorStr}`)); + } else { + resolve(); + } + } + }, + error(err) { + log.error(label, `failed: ${err}`); + subscription.unsubscribe(); + clearTimeout(timeoutId); + reject(err); + }, + }); + + const timeoutId = setTimeout(() => { + subscription.unsubscribe(); + log.tx(label, `timeout for tx: ${txHash}`); + reject(new Error(`[${label}] timeout`)); + }, TX_TIMEOUT); + }); +} diff --git a/e2e/shared/tsconfig.json b/e2e/shared/tsconfig.json new file mode 100644 index 0000000000..b4cbbb843b --- /dev/null +++ b/e2e/shared/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ESNext", + "moduleResolution": "bundler", + "esModuleInterop": true, + "strict": true, + "skipLibCheck": true, + "types": ["node"] + } +} diff --git a/e2e/shield/.gitignore b/e2e/shield/.gitignore new file mode 100644 index 0000000000..3e6b0f99ff --- /dev/null +++ b/e2e/shield/.gitignore @@ -0,0 +1,2 @@ +node_modules/ +node-subtensor/ diff --git a/e2e/shield/helpers.ts b/e2e/shield/helpers.ts new file mode 100644 index 0000000000..1b8af56450 --- /dev/null +++ b/e2e/shield/helpers.ts @@ -0,0 +1,75 @@ +import type { TypedApi, PolkadotSigner } from "polkadot-api"; +import { Binary } from "polkadot-api"; +import { hexToU8a } from "@polkadot/util"; +import { xchacha20poly1305 } from "@noble/ciphers/chacha.js"; +import { randomBytes } from "@noble/ciphers/utils.js"; +import { MlKem768 } from "mlkem"; +import { xxhashAsU8a } from "@polkadot/util-crypto"; +import type { subtensor } from "@polkadot-api/descriptors"; + +export const getNextKey = async ( + api: TypedApi, +): Promise => { + // Query at "best" (not default "finalized") because keys rotate every block + // and finalized lags ~2 blocks behind best with GRANDPA. Using finalized + // would return a stale key whose hash won't match CurrentKey/NextKey at + // block-building time, causing InvalidShieldedTxPubKeyHash rejection. + const key = await api.query.MevShield.NextKey.getValue({ at: "best" }); + if (!key) return undefined; + if (key instanceof Binary) return key.asBytes(); + return hexToU8a(key as string); +}; + +export const getCurrentKey = async ( + api: TypedApi, +): Promise => { + const key = await api.query.MevShield.CurrentKey.getValue({ at: "best" }); + if (!key) return undefined; + if (key instanceof Binary) return key.asBytes(); + return hexToU8a(key as string); +}; + +export const encryptTransaction = async ( + plaintext: Uint8Array, + publicKey: Uint8Array, +): Promise => { + const keyHash = xxhashAsU8a(publicKey, 128); + + const mlKem = new MlKem768(); + const [kemCt, sharedSecret] = await mlKem.encap(publicKey); + + const nonce = randomBytes(24); + const chacha = xchacha20poly1305(sharedSecret, nonce); + const aeadCt = chacha.encrypt(plaintext); + + const kemLenBytes = new Uint8Array(2); + new DataView(kemLenBytes.buffer).setUint16(0, kemCt.length, true); + + return new Uint8Array([...keyHash, ...kemLenBytes, ...kemCt, ...nonce, ...aeadCt]); +}; + +export const submitEncrypted = async ( + api: TypedApi, + signer: PolkadotSigner, + innerTxBytes: Uint8Array, + publicKey: Uint8Array, + nonce?: number, +) => { + const ciphertext = await encryptTransaction(innerTxBytes, publicKey); + return submitEncryptedRaw(api, signer, ciphertext, nonce); +}; + +export const submitEncryptedRaw = async ( + api: TypedApi, + signer: PolkadotSigner, + ciphertext: Uint8Array, + nonce?: number, +) => { + const tx = api.tx.MevShield.submit_encrypted({ + ciphertext: Binary.fromBytes(ciphertext), + }); + return tx.signAndSubmit(signer, { + ...(nonce !== undefined ? { nonce } : {}), + mortality: { mortal: true, period: 8 }, + }); +}; diff --git a/e2e/shield/package.json b/e2e/shield/package.json new file mode 100644 index 0000000000..d04f2acf6a --- /dev/null +++ b/e2e/shield/package.json @@ -0,0 +1,21 @@ +{ + "name": "e2e-shield", + "version": "1.0.0", + "type": "module", + "scripts": { + "test": "vitest run" + }, + "dependencies": { + "e2e-shared": "workspace:*", + "@noble/ciphers": "catalog:", + "@polkadot/util": "catalog:", + "@polkadot/util-crypto": "catalog:", + "@polkadot-api/descriptors": "file:../.papi/descriptors", + "mlkem": "catalog:", + "polkadot-api": "catalog:" + }, + "devDependencies": { + "@types/node": "catalog:", + "vitest": "catalog:" + } +} diff --git a/e2e/shield/setup.ts b/e2e/shield/setup.ts new file mode 100644 index 0000000000..3ba1294026 --- /dev/null +++ b/e2e/shield/setup.ts @@ -0,0 +1,147 @@ +import { writeFile, readFile, rm, mkdir } from "node:fs/promises"; +import { generateChainSpec, insertKeys } from "e2e-shared/chainspec.js"; +import { + startNode, + started, + peerCount, + finalizedBlocks, + stop, + log, + type Node, + type NodeOptions, +} from "e2e-shared/node.js"; + +const BASE_DIR = "/tmp/subtensor-e2e/shield-tests"; +const CHAIN_SPEC_PATH = `${BASE_DIR}/chain-spec.json`; +const STATE_FILE = `${BASE_DIR}/nodes.json`; + +export type NetworkState = { + binaryPath: string; + chainSpec: string; + nodes: { + name: string; + rpcPort: number; + port: number; + pid: number; + basePath: string; + }[]; +}; + +const nodes: Node[] = []; + +const BINARY_PATH = process.env.BINARY_PATH || "../../target/release/node-subtensor"; + +type NodeConfig = Omit & { + keySeed?: string; +}; + +const NODE_CONFIGS: NodeConfig[] = [ + { name: "one", port: 30333, rpcPort: 9944, basePath: `${BASE_DIR}/one`, validator: true }, + { name: "two", port: 30334, rpcPort: 9945, basePath: `${BASE_DIR}/two`, validator: true }, + { + name: "three", + port: 30335, + rpcPort: 9946, + basePath: `${BASE_DIR}/three`, + validator: true, + keySeed: "//Three", + }, +]; + +export async function setup() { + log(`Setting up ${NODE_CONFIGS.length}-node network for shield E2E tests`); + log(`Binary path: ${BINARY_PATH}`); + + await mkdir(BASE_DIR, { recursive: true }); + + await generateChainSpec(BINARY_PATH, CHAIN_SPEC_PATH); + + for (const config of NODE_CONFIGS) { + await rm(config.basePath, { recursive: true, force: true }); + } + + // Insert keys for authority nodes that don't have built-in substrate shortcuts. + for (const config of NODE_CONFIGS) { + if (config.keySeed) { + insertKeys(BINARY_PATH, config.basePath, CHAIN_SPEC_PATH, config.keySeed); + } + } + + for (const config of NODE_CONFIGS) { + const node = startNode({ + binaryPath: BINARY_PATH, + chainSpec: CHAIN_SPEC_PATH, + ...config, + }); + nodes.push(node); + await started(node); + } + + const all = Promise.all.bind(Promise); + + await all(nodes.map((n) => peerCount(n, nodes.length - 1))); + log("All nodes peered"); + + await all(nodes.map((n) => finalizedBlocks(n, 3))); + log("All nodes finalized block 3"); + + const state: NetworkState = { + binaryPath: BINARY_PATH, + chainSpec: CHAIN_SPEC_PATH, + nodes: NODE_CONFIGS.map((c, i) => ({ + name: c.name, + rpcPort: c.rpcPort, + port: c.port, + pid: nodes[i].process.pid!, + basePath: c.basePath, + })), + }; + + await writeFile(STATE_FILE, JSON.stringify(state, null, 2)); + log("Network state written to " + STATE_FILE); +} + +export async function teardown() { + log("Tearing down shield E2E test network"); + + // Read the state file to find ALL nodes (including extras added by scaling tests). + let state: NetworkState | undefined; + try { + const data = await readFile(STATE_FILE, "utf-8"); + state = JSON.parse(data); + } catch {} + + // Stop nodes we have handles to (from globalSetup). + for (const node of nodes) { + try { + await stop(node); + } catch (e) { + log(`Warning: failed to stop ${node.name}: ${e}`); + } + } + + // Kill any extra nodes (added by scaling tests) by PID. + if (state) { + const ownPids = new Set(nodes.map((n) => n.process.pid)); + for (const nodeInfo of state.nodes) { + if (!ownPids.has(nodeInfo.pid)) { + try { + process.kill(nodeInfo.pid, "SIGTERM"); + log(`Killed extra node ${nodeInfo.name} (pid ${nodeInfo.pid})`); + } catch { + // Already dead, ignore. + } + } + } + } + + // Clean up the entire suite directory in one shot. + await rm(BASE_DIR, { recursive: true, force: true }); + + log("Teardown complete"); +} + +export async function readNetworkState(): Promise { + const data = await readFile(STATE_FILE, "utf-8"); + return JSON.parse(data); +} diff --git a/e2e/shield/tests/00-basic.test.ts b/e2e/shield/tests/00-basic.test.ts new file mode 100644 index 0000000000..8eca09daf6 --- /dev/null +++ b/e2e/shield/tests/00-basic.test.ts @@ -0,0 +1,232 @@ +import { describe, it, expect, beforeAll, afterAll } from "vitest"; +import { readFile } from "node:fs/promises"; +import type { PolkadotClient, TypedApi } from "polkadot-api"; +import { Binary } from "polkadot-api"; +import { hexToU8a } from "@polkadot/util"; +import { subtensor, MultiAddress } from "@polkadot-api/descriptors"; +import type { NetworkState } from "../setup.js"; +import { + connectClient, + createSigner, + getAccountNonce, + getBalance, + waitForFinalizedBlocks, +} from "e2e-shared/client.js"; +import { getNextKey, getCurrentKey, encryptTransaction, submitEncrypted } from "../helpers.js"; + +let client: PolkadotClient; +let api: TypedApi; +let state: NetworkState; + +const alice = createSigner("//Alice"); +const bob = createSigner("//Bob"); +const charlie = createSigner("//Charlie"); + +beforeAll(async () => { + const data = await readFile("/tmp/subtensor-e2e/shield-tests/nodes.json", "utf-8"); + state = JSON.parse(data); + ({ client, api } = await connectClient(state.nodes[0].rpcPort)); + + // Wait for enough finalized blocks so the inherent has had time to run + // and keys have rotated at least once. + await waitForFinalizedBlocks(client, 3); +}); + +afterAll(() => { + client?.destroy(); +}); + +describe("MEV Shield — key rotation", () => { + it("NextKey and CurrentKey are populated and rotate across blocks", async () => { + const nextKey1 = await getNextKey(api); + expect(nextKey1).toBeDefined(); + expect(nextKey1!.length).toBe(1184); // ML-KEM-768 public key + + const currentKey1 = await getCurrentKey(api); + expect(currentKey1).toBeDefined(); + expect(currentKey1!.length).toBe(1184); + + await waitForFinalizedBlocks(client, 2); + + const nextKey2 = await getNextKey(api); + expect(nextKey2).toBeDefined(); + // Keys should have rotated — nextKey changes each block. + expect(nextKey2).not.toEqual(nextKey1); + + const currentKey2 = await getCurrentKey(api); + expect(currentKey2).toBeDefined(); + expect(currentKey2).not.toEqual(currentKey1); + }); + + it("AuthorKeys stores per-author keys", async () => { + const authorities = await api.query.Aura.Authorities.getValue(); + expect(authorities.length).toBeGreaterThan(0); + + let foundKeys = 0; + for (const authority of authorities) { + const key = await api.query.MevShield.AuthorKeys.getValue(authority); + if (key) foundKeys++; + } + + expect(foundKeys).toBeGreaterThan(0); + }); +}); + +describe("MEV Shield — encrypted transactions", () => { + it("Happy path: wrapper and inner tx are included in the same block", async () => { + const nextKey = await getNextKey(api); + expect(nextKey).toBeDefined(); + + const balanceBefore = await getBalance(api, bob.address); + + const nonce = await getAccountNonce(api, alice.address); + const innerTxHex = await api.tx.Balances.transfer_keep_alive({ + dest: MultiAddress.Id(bob.address), + value: 10_000_000_000n, + }).sign(alice.signer, { nonce: nonce + 1 }); + + await submitEncrypted(api, alice.signer, hexToU8a(innerTxHex), nextKey!, nonce); + + const balanceAfter = await getBalance(api, bob.address); + expect(balanceAfter).toBeGreaterThan(balanceBefore); + }); + + it("Failed inner tx: wrapper succeeds but inner transfer has no effect", async () => { + const nextKey = await getNextKey(api); + expect(nextKey).toBeDefined(); + + const balanceBefore = await getBalance(api, bob.address); + + // Encrypt a transfer of more than Alice has. + // The wrapper is valid (correct key_hash, valid encryption), but the + // inner transfer should fail at dispatch with InsufficientBalance. + const nonce = await getAccountNonce(api, alice.address); + const innerTxHex = await api.tx.Balances.transfer_keep_alive({ + dest: MultiAddress.Id(bob.address), + value: 9_000_000_000_000_000_000n, + }).sign(alice.signer, { nonce: nonce + 1 }); + + await submitEncrypted(api, alice.signer, hexToU8a(innerTxHex), nextKey!, nonce); + + // The inner transfer failed, so bob's balance should not increase. + const balanceAfter = await getBalance(api, bob.address); + expect(balanceAfter).toBe(balanceBefore); + }); + + it("Malformed ciphertext is rejected at pool level", async () => { + const nonce = await getAccountNonce(api, alice.address); + + // 5 bytes of garbage — not valid ciphertext at all. + const garbage = new Uint8Array([0x01, 0x02, 0x03, 0x04, 0x05]); + + const tx = api.tx.MevShield.submit_encrypted({ + ciphertext: Binary.fromBytes(garbage), + }); + + // Pool validation rejects with FailedShieldedTxParsing (Custom code 23). + await expect( + tx.signAndSubmit(alice.signer, { nonce, mortality: { mortal: true, period: 8 } }), + ).rejects.toThrow(); + }); + + it("Multiple encrypted txs in same block", async () => { + // Use different signers to avoid nonce ordering issues between + // the outer wrappers and decrypted inner transactions. + const nextKey = await getNextKey(api); + expect(nextKey).toBeDefined(); + + const balanceBefore = await getBalance(api, charlie.address); + + const senders = [alice, bob]; + const amount = 1_000_000_000n; + const txPromises = []; + + for (const sender of senders) { + const nonce = await getAccountNonce(api, sender.address); + + const innerTxHex = await api.tx.Balances.transfer_keep_alive({ + dest: MultiAddress.Id(charlie.address), + value: amount, + }).sign(sender.signer, { nonce: nonce + 1 }); + + txPromises.push(submitEncrypted(api, sender.signer, hexToU8a(innerTxHex), nextKey!, nonce)); + } + + await Promise.all(txPromises); + + const balanceAfter = await getBalance(api, charlie.address); + expect(balanceAfter).toBeGreaterThan(balanceBefore); + }); + + it("Wrong key hash is not included by the block proposer", async () => { + const nextKey = await getNextKey(api); + expect(nextKey).toBeDefined(); + + const balanceBefore = await getBalance(api, bob.address); + + const nonce = await getAccountNonce(api, alice.address); + const innerTxHex = await api.tx.Balances.transfer_keep_alive({ + dest: MultiAddress.Id(bob.address), + value: 1_000_000_000n, + }).sign(alice.signer, { nonce: nonce + 1 }); + + const ciphertext = await encryptTransaction(hexToU8a(innerTxHex), nextKey!); + + // Tamper the first 16 bytes (key_hash). + const tampered = new Uint8Array(ciphertext); + for (let i = 0; i < 16; i++) tampered[i] = 0xff; + + const tx = api.tx.MevShield.submit_encrypted({ + ciphertext: Binary.fromBytes(tampered), + }); + const signedHex = await tx.sign(alice.signer, { + nonce, + mortality: { mortal: true, period: 8 }, + }); + // Send without waiting — the tx enters the pool but the block + // proposer will skip it because the key_hash doesn't match. + client.submit(signedHex).catch(() => {}); + + await waitForFinalizedBlocks(client, 3); + + // The inner transfer should NOT have executed. + const balanceAfter = await getBalance(api, bob.address); + expect(balanceAfter).toBe(balanceBefore); + }); + + it("Stale key is not included after rotation", async () => { + const staleKey = await getNextKey(api); + expect(staleKey).toBeDefined(); + + // Wait for enough blocks that the key has rotated past both + // currentKey and nextKey positions. + await waitForFinalizedBlocks(client, 3); + + const balanceBefore = await getBalance(api, bob.address); + + const nonce = await getAccountNonce(api, alice.address); + const innerTxHex = await api.tx.Balances.transfer_keep_alive({ + dest: MultiAddress.Id(bob.address), + value: 1_000_000_000n, + }).sign(alice.signer, { nonce: nonce + 1 }); + + const ciphertext = await encryptTransaction(hexToU8a(innerTxHex), staleKey!); + + const tx = api.tx.MevShield.submit_encrypted({ + ciphertext: Binary.fromBytes(ciphertext), + }); + const signedHex = await tx.sign(alice.signer, { + nonce, + mortality: { mortal: true, period: 8 }, + }); + // Send without waiting — the block proposer will reject because + // key_hash no longer matches currentKey or nextKey. + client.submit(signedHex).catch(() => {}); + + await waitForFinalizedBlocks(client, 3); + + // The inner transfer should NOT have executed. + const balanceAfter = await getBalance(api, bob.address); + expect(balanceAfter).toBe(balanceBefore); + }); +}); diff --git a/e2e/shield/tests/01-scaling.test.ts b/e2e/shield/tests/01-scaling.test.ts new file mode 100644 index 0000000000..386124a655 --- /dev/null +++ b/e2e/shield/tests/01-scaling.test.ts @@ -0,0 +1,131 @@ +import { describe, it, expect, beforeAll, afterAll } from "vitest"; +import { readFile, writeFile, rm } from "node:fs/promises"; +import type { PolkadotClient, TypedApi } from "polkadot-api"; +import { hexToU8a } from "@polkadot/util"; +import { subtensor, MultiAddress } from "@polkadot-api/descriptors"; +import type { NetworkState } from "../setup.js"; +import { + connectClient, + createSigner, + getAccountNonce, + getBalance, + waitForFinalizedBlocks, +} from "e2e-shared/client.js"; +import { startNode, started, log } from "e2e-shared/node.js"; +import { getNextKey, submitEncrypted } from "../helpers.js"; + +let client: PolkadotClient; +let api: TypedApi; +let state: NetworkState; + +const alice = createSigner("//Alice"); +const bob = createSigner("//Bob"); +const charlie = createSigner("//Charlie"); + +// Extra nodes join as non-authority full nodes. +const EXTRA_NODE_CONFIGS = [ + { name: "four", port: 30336, rpcPort: 9947, basePath: "/tmp/subtensor-e2e/shield-tests/four" }, + { name: "five", port: 30337, rpcPort: 9948, basePath: "/tmp/subtensor-e2e/shield-tests/five" }, + { name: "six", port: 30338, rpcPort: 9949, basePath: "/tmp/subtensor-e2e/shield-tests/six" }, +]; + +beforeAll(async () => { + const data = await readFile("/tmp/subtensor-e2e/shield-tests/nodes.json", "utf-8"); + state = JSON.parse(data); + ({ client, api } = await connectClient(state.nodes[0].rpcPort)); + + // Start 3 additional full nodes to scale from 3 → 6. + for (const config of EXTRA_NODE_CONFIGS) { + await rm(config.basePath, { recursive: true, force: true }); + + const node = startNode({ + ...config, + binaryPath: state.binaryPath, + validator: false, + chainSpec: state.chainSpec, + }); + await started(node); + log(`Extra node ${config.name} started`); + + // Track in state file so global teardown can clean up. + state.nodes.push({ + name: config.name, + rpcPort: config.rpcPort, + port: config.port, + pid: node.process.pid!, + basePath: config.basePath, + }); + } + + // Persist updated state for subsequent test files (edge-cases). + await writeFile("/tmp/subtensor-e2e/shield-tests/nodes.json", JSON.stringify(state, null, 2)); +}); + +afterAll(() => { + client?.destroy(); +}); + +describe("MEV Shield — 6 node scaling", () => { + it("Network scales to 6 nodes with full peering", async () => { + expect(state.nodes.length).toBe(6); + + // Verify the network is healthy by checking finalization continues. + await waitForFinalizedBlocks(client, 2); + }); + + it("Key rotation continues with more peers", async () => { + const key1 = await getNextKey(api); + expect(key1).toBeDefined(); + + await waitForFinalizedBlocks(client, 2); + + const key2 = await getNextKey(api); + expect(key2).toBeDefined(); + expect(key2!.length).toBe(1184); + }); + + it("Encrypted tx works with 6 nodes", async () => { + const nextKey = await getNextKey(api); + expect(nextKey).toBeDefined(); + + const balanceBefore = await getBalance(api, bob.address); + + const nonce = await getAccountNonce(api, alice.address); + const innerTxHex = await api.tx.Balances.transfer_keep_alive({ + dest: MultiAddress.Id(bob.address), + value: 5_000_000_000n, + }).sign(alice.signer, { nonce: nonce + 1 }); + + await submitEncrypted(api, alice.signer, hexToU8a(innerTxHex), nextKey!, nonce); + + const balanceAfter = await getBalance(api, bob.address); + expect(balanceAfter).toBeGreaterThan(balanceBefore); + }); + + it("Multiple encrypted txs in same block with 6 nodes", async () => { + const nextKey = await getNextKey(api); + expect(nextKey).toBeDefined(); + + const balanceBefore = await getBalance(api, charlie.address); + + const senders = [alice, bob]; + const amount = 1_000_000_000n; + const txPromises = []; + + for (const sender of senders) { + const nonce = await getAccountNonce(api, sender.address); + + const innerTxHex = await api.tx.Balances.transfer_keep_alive({ + dest: MultiAddress.Id(charlie.address), + value: amount, + }).sign(sender.signer, { nonce: nonce + 1 }); + + txPromises.push(submitEncrypted(api, sender.signer, hexToU8a(innerTxHex), nextKey!, nonce)); + } + + await Promise.all(txPromises); + + const balanceAfter = await getBalance(api, charlie.address); + expect(balanceAfter).toBeGreaterThan(balanceBefore); + }); +}); diff --git a/e2e/shield/tests/02-edge-cases.test.ts b/e2e/shield/tests/02-edge-cases.test.ts new file mode 100644 index 0000000000..55dc53f134 --- /dev/null +++ b/e2e/shield/tests/02-edge-cases.test.ts @@ -0,0 +1,75 @@ +import { describe, it, expect, beforeAll, afterAll } from "vitest"; +import { readFile } from "node:fs/promises"; +import type { PolkadotClient, TypedApi } from "polkadot-api"; +import { hexToU8a } from "@polkadot/util"; +import { subtensor, MultiAddress } from "@polkadot-api/descriptors"; +import type { NetworkState } from "../setup.js"; +import { connectClient, createSigner, getAccountNonce, getBalance } from "e2e-shared/client.js"; +import { getNextKey, submitEncrypted } from "../helpers.js"; + +let client: PolkadotClient; +let api: TypedApi; +let state: NetworkState; + +const alice = createSigner("//Alice"); +const bob = createSigner("//Bob"); + +beforeAll(async () => { + const data = await readFile("/tmp/subtensor-e2e/shield-tests/nodes.json", "utf-8"); + state = JSON.parse(data); + ({ client, api } = await connectClient(state.nodes[0].rpcPort)); +}); + +afterAll(() => { + client?.destroy(); +}); + +describe("MEV Shield — edge cases", () => { + it("Encrypted tx persists across blocks (CurrentKey fallback)", async () => { + // The idea: submit an encrypted tx right at a block boundary. + // Even if the key rotates (NextKey changes), the old key becomes + // CurrentKey, so the extension still accepts it. + const nextKey = await getNextKey(api); + expect(nextKey).toBeDefined(); + + const balanceBefore = await getBalance(api, bob.address); + + const nonce = await getAccountNonce(api, alice.address); + const innerTxHex = await api.tx.Balances.transfer_keep_alive({ + dest: MultiAddress.Id(bob.address), + value: 2_000_000_000n, + }).sign(alice.signer, { nonce: nonce + 1 }); + + // Submit and wait for finalization — the tx may land in the next block + // or the one after, where CurrentKey = the old NextKey. + await submitEncrypted(api, alice.signer, hexToU8a(innerTxHex), nextKey!, nonce); + + const balanceAfter = await getBalance(api, bob.address); + expect(balanceAfter).toBeGreaterThan(balanceBefore); + }); + + it("Valid ciphertext with invalid inner call", async () => { + // Encrypt garbage bytes (not a valid extrinsic) using a valid NextKey. + // The wrapper tx should be included in a block because: + // - The ciphertext is well-formed (key_hash, kem_ct, nonce, aead_ct) + // - The key_hash matches a known key + // But the inner decrypted bytes won't decode as a valid extrinsic, + // so no inner transaction should execute. + const nextKey = await getNextKey(api); + expect(nextKey).toBeDefined(); + + const balanceBefore = await getBalance(api, bob.address); + + // Garbage "inner transaction" bytes — not a valid extrinsic at all. + const garbageInner = new Uint8Array(64); + for (let i = 0; i < 64; i++) garbageInner[i] = (i * 7 + 13) & 0xff; + + const nonce = await getAccountNonce(api, alice.address); + + await submitEncrypted(api, alice.signer, garbageInner, nextKey!, nonce); + + // No balance change — the garbage inner call could not have been a valid transfer. + const balanceAfter = await getBalance(api, bob.address); + expect(balanceAfter).toBe(balanceBefore); + }); +}); diff --git a/e2e/shield/tests/03-timing.test.ts b/e2e/shield/tests/03-timing.test.ts new file mode 100644 index 0000000000..c7309708d2 --- /dev/null +++ b/e2e/shield/tests/03-timing.test.ts @@ -0,0 +1,127 @@ +import { describe, it, expect, beforeAll, afterAll } from "vitest"; +import { readFile } from "node:fs/promises"; +import type { PolkadotClient, TypedApi } from "polkadot-api"; +import { hexToU8a } from "@polkadot/util"; +import { subtensor, MultiAddress } from "@polkadot-api/descriptors"; +import type { NetworkState } from "../setup.js"; +import { + connectClient, + createSigner, + getAccountNonce, + getBalance, + waitForFinalizedBlocks, + sleep, +} from "e2e-shared/client.js"; +import { getNextKey, submitEncrypted } from "../helpers.js"; + +let client: PolkadotClient; +let api: TypedApi; +let state: NetworkState; + +const alice = createSigner("//Alice"); +const bob = createSigner("//Bob"); + +beforeAll(async () => { + const data = await readFile("/tmp/subtensor-e2e/shield-tests/nodes.json", "utf-8"); + state = JSON.parse(data); + ({ client, api } = await connectClient(state.nodes[0].rpcPort)); +}); + +afterAll(() => { + client?.destroy(); +}); + +describe("MEV Shield — timing boundaries", () => { + it("Submit immediately after a new block", async () => { + // Wait for a fresh finalized block, then immediately read NextKey and submit. + // This tests the "just after block" boundary where keys just rotated. + await waitForFinalizedBlocks(client, 1); + + const nextKey = await getNextKey(api); + expect(nextKey).toBeDefined(); + + const balanceBefore = await getBalance(api, bob.address); + + const nonce = await getAccountNonce(api, alice.address); + const innerTxHex = await api.tx.Balances.transfer_keep_alive({ + dest: MultiAddress.Id(bob.address), + value: 1_000_000_000n, + }).sign(alice.signer, { nonce: nonce + 1 }); + + await submitEncrypted(api, alice.signer, hexToU8a(innerTxHex), nextKey!, nonce); + + const balanceAfter = await getBalance(api, bob.address); + expect(balanceAfter).toBeGreaterThan(balanceBefore); + }); + + it("Submit mid-block (~6s after block)", async () => { + // Wait for a block, then sleep 6s (half of 12s slot) before submitting. + // The key should still be valid — the same NextKey applies until the next block. + await waitForFinalizedBlocks(client, 1); + await sleep(6_000); + + const nextKey = await getNextKey(api); + expect(nextKey).toBeDefined(); + + const balanceBefore = await getBalance(api, bob.address); + + const nonce = await getAccountNonce(api, alice.address); + const innerTxHex = await api.tx.Balances.transfer_keep_alive({ + dest: MultiAddress.Id(bob.address), + value: 1_000_000_000n, + }).sign(alice.signer, { nonce: nonce + 1 }); + + await submitEncrypted(api, alice.signer, hexToU8a(innerTxHex), nextKey!, nonce); + + const balanceAfter = await getBalance(api, bob.address); + expect(balanceAfter).toBeGreaterThan(balanceBefore); + }); + + it("Submit just before next block (~11s after block)", async () => { + // Wait for a block, then sleep ~11s to submit right before the next slot. + // The tx enters the pool just as the next block is about to be produced. + // It should still be included because the N+2 author hasn't changed yet, + // and PendingKey will match on the next block's proposer check. + await waitForFinalizedBlocks(client, 1); + await sleep(11_000); + + const nextKey = await getNextKey(api); + expect(nextKey).toBeDefined(); + + const balanceBefore = await getBalance(api, bob.address); + + const nonce = await getAccountNonce(api, alice.address); + const innerTxHex = await api.tx.Balances.transfer_keep_alive({ + dest: MultiAddress.Id(bob.address), + value: 1_000_000_000n, + }).sign(alice.signer, { nonce: nonce + 1 }); + + await submitEncrypted(api, alice.signer, hexToU8a(innerTxHex), nextKey!, nonce); + + const balanceAfter = await getBalance(api, bob.address); + expect(balanceAfter).toBeGreaterThan(balanceBefore); + }); + + it("Read key, wait full slot (12s), then submit", async () => { + // Read NextKey, wait a full slot duration, then submit. + // After one full slot, the key rotates: old NextKey becomes PendingKey. + // The tx should still be included by the target N+2 author. + const nextKey = await getNextKey(api); + expect(nextKey).toBeDefined(); + + await sleep(12_000); + + const balanceBefore = await getBalance(api, bob.address); + + const nonce = await getAccountNonce(api, alice.address); + const innerTxHex = await api.tx.Balances.transfer_keep_alive({ + dest: MultiAddress.Id(bob.address), + value: 1_000_000_000n, + }).sign(alice.signer, { nonce: nonce + 1 }); + + await submitEncrypted(api, alice.signer, hexToU8a(innerTxHex), nextKey!, nonce); + + const balanceAfter = await getBalance(api, bob.address); + expect(balanceAfter).toBeGreaterThan(balanceBefore); + }); +}); diff --git a/e2e/shield/tests/04-mortality.test.ts b/e2e/shield/tests/04-mortality.test.ts new file mode 100644 index 0000000000..76e704f82b --- /dev/null +++ b/e2e/shield/tests/04-mortality.test.ts @@ -0,0 +1,160 @@ +import { describe, it, expect, beforeAll, afterAll } from "vitest"; +import { readFile, writeFile, rm } from "node:fs/promises"; +import type { PolkadotClient, TypedApi } from "polkadot-api"; +import { Binary } from "polkadot-api"; +import { hexToU8a } from "@polkadot/util"; +import { subtensor, MultiAddress } from "@polkadot-api/descriptors"; +import type { NetworkState } from "../setup.js"; +import { + connectClient, + createSigner, + getAccountNonce, + getBalance, + sleep, +} from "e2e-shared/client.js"; +import { startNode, started, peerCount, stop, log, type Node } from "e2e-shared/node.js"; +import { getNextKey, encryptTransaction } from "../helpers.js"; + +let authorityClient: PolkadotClient; +let authorityApi: TypedApi; +let extraClient: PolkadotClient; +let extraApi: TypedApi; +let state: NetworkState; +let extraNode: Node; + +const alice = createSigner("//Alice"); +const bob = createSigner("//Bob"); + +const EXTRA_NODE = { + name: "mortality-test", + port: 30339, + rpcPort: 9950, + basePath: "/tmp/subtensor-e2e/shield-tests/mortality-test", +}; + +// MAX_SHIELD_ERA_PERIOD is 8 blocks. With 12s slots, that's ~96s. +const MAX_ERA_BLOCKS = 8; +const SLOT_DURATION_MS = 12_000; +const POLL_INTERVAL_MS = 3_000; + +beforeAll(async () => { + const data = await readFile("/tmp/subtensor-e2e/shield-tests/nodes.json", "utf-8"); + state = JSON.parse(data); + + // Connect to an authority node for key queries. + ({ client: authorityClient, api: authorityApi } = await connectClient(state.nodes[0].rpcPort)); + + // Start a non-authority node to submit txs to. + await rm(EXTRA_NODE.basePath, { recursive: true, force: true }); + extraNode = startNode({ + ...EXTRA_NODE, + binaryPath: state.binaryPath, + validator: false, + chainSpec: state.chainSpec, + }); + await started(extraNode); + await peerCount(extraNode, state.nodes.length); + log(`Extra non-authority node started for mortality tests`); + + // Track for teardown. + state.nodes.push({ + ...EXTRA_NODE, + pid: extraNode.process.pid!, + }); + await writeFile("/tmp/subtensor-e2e/shield-tests/nodes.json", JSON.stringify(state, null, 2)); + + ({ client: extraClient, api: extraApi } = await connectClient(EXTRA_NODE.rpcPort)); +}); + +afterAll(async () => { + extraClient?.destroy(); + authorityClient?.destroy(); + if (extraNode) { + try { + await stop(extraNode); + } catch {} + } +}); + +describe("MEV Shield — mortality eviction", () => { + it( + "Tx with tampered key_hash submitted to non-authority is evicted within mortality window", + async () => { + // Read a valid NextKey from an authority node, encrypt a real inner tx. + const nextKey = await getNextKey(authorityApi); + expect(nextKey).toBeDefined(); + + const balanceBefore = await getBalance(extraApi, bob.address); + + const nonce = await getAccountNonce(extraApi, alice.address); + const innerTxHex = await extraApi.tx.Balances.transfer_keep_alive({ + dest: MultiAddress.Id(bob.address), + value: 1_000_000_000n, + }).sign(alice.signer, { nonce: nonce + 1 }); + + // Encrypt with valid key, then tamper the key_hash so no proposer will include it. + const ciphertext = await encryptTransaction(hexToU8a(innerTxHex), nextKey!); + const tampered = new Uint8Array(ciphertext); + for (let i = 0; i < 16; i++) tampered[i] = 0xff; + + const tx = extraApi.tx.MevShield.submit_encrypted({ + ciphertext: Binary.fromBytes(tampered), + }); + + // Sign with short mortality (must be ≤ MAX_SHIELD_ERA_PERIOD=8 to pass + // CheckMortality validation). The tx enters the pool but no proposer + // will include it (tampered key_hash doesn't match PendingKey). + const signedHex = await tx.sign(alice.signer, { + nonce, + mortality: { mortal: true, period: 8 }, + }); + + // Submit via raw RPC to get immediate feedback on pool acceptance. + let txHash: string; + try { + txHash = await extraClient._request("author_submitExtrinsic", [signedHex]); + log(`Tx submitted successfully, hash: ${txHash}`); + } catch (err: unknown) { + throw new Error(`Tx rejected at pool entry: ${err}`); + } + + // Verify it's in the pool. + await sleep(1_000); + const pending: string[] = await extraClient._request("author_pendingExtrinsics", []); + log(`Pool has ${pending.length} pending tx(s)`); + + // Now poll until the tx disappears (mortality eviction). + const start = Date.now(); + const maxPollMs = (MAX_ERA_BLOCKS + 4) * SLOT_DURATION_MS; + let evicted = false; + + log(`Waiting for mortality eviction (up to ${maxPollMs / 1000}s)...`); + + while (Date.now() - start < maxPollMs) { + await sleep(POLL_INTERVAL_MS); + + const pending: string[] = await extraClient._request("author_pendingExtrinsics", []); + + if (pending.length === 0) { + evicted = true; + break; + } + } + + const elapsed = Date.now() - start; + log(`Tx ${evicted ? "evicted" : "still in pool"} after ${(elapsed / 1000).toFixed(1)}s`); + + expect(evicted).toBe(true); + + // Eviction should happen within the mortality window plus margin. + const maxExpectedMs = (MAX_ERA_BLOCKS + 2) * SLOT_DURATION_MS; + expect(elapsed).toBeLessThan(maxExpectedMs); + + // The inner transfer should NOT have executed. + const balanceAfter = await getBalance(extraApi, bob.address); + expect(balanceAfter).toBe(balanceBefore); + }, + // Longer timeout: wait for mortality window + setup overhead. + (MAX_ERA_BLOCKS + 8) * SLOT_DURATION_MS, + ); +}); diff --git a/e2e/shield/tsconfig.json b/e2e/shield/tsconfig.json new file mode 100644 index 0000000000..c2f86d9e2c --- /dev/null +++ b/e2e/shield/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ESNext", + "moduleResolution": "bundler", + "esModuleInterop": true, + "strict": true, + "skipLibCheck": true, + "types": ["node", "vitest/globals"] + } +} diff --git a/e2e/shield/vitest.config.ts b/e2e/shield/vitest.config.ts new file mode 100644 index 0000000000..d9c2978930 --- /dev/null +++ b/e2e/shield/vitest.config.ts @@ -0,0 +1,16 @@ +import { defineConfig } from "vitest/config"; +import AlphabeticalSequencer from "e2e-shared/sequencer.js"; + +export default defineConfig({ + test: { + globals: true, + testTimeout: 120_000, + hookTimeout: 300_000, + fileParallelism: false, + globalSetup: "./setup.ts", + include: ["tests/**/*.test.ts"], + sequence: { + sequencer: AlphabeticalSequencer, + }, + }, +}); diff --git a/e2e/staking/package.json b/e2e/staking/package.json new file mode 100644 index 0000000000..80648d3d0f --- /dev/null +++ b/e2e/staking/package.json @@ -0,0 +1,21 @@ +{ + "name": "e2e-staking", + "version": "1.0.0", + "type": "module", + "license": "ISC", + "scripts": { + "test": "vitest run" + }, + "dependencies": { + "e2e-shared": "workspace:*" + }, + "devDependencies": { + "@types/node": "catalog:", + "vitest": "catalog:" + }, + "prettier": { + "singleQuote": false, + "trailingComma": "all", + "printWidth": 120 + } +} diff --git a/e2e/staking/setup.ts b/e2e/staking/setup.ts new file mode 100644 index 0000000000..d1887be5a6 --- /dev/null +++ b/e2e/staking/setup.ts @@ -0,0 +1,123 @@ +import { rm, mkdir } from "node:fs/promises"; +import { + generateChainSpec, + insertKeys, + startNode, + started, + peerCount, + finalizedBlocks, + stop, + nodeLog, + destroyClient, + getDevnetApi, + sudoSetLockReductionInterval, + log, + type Node, + type NodeOptions, +} from "e2e-shared"; + +const CHAIN_SPEC_PATH = "/tmp/subtensor-e2e/staking-tests/chain-spec.json"; +const BASE_DIR = "/tmp/subtensor-e2e/staking-tests"; + +const BINARY_PATH = process.env.BINARY_PATH || "../../target/release/node-subtensor"; + +const nodes: Node[] = []; + +type NodeConfig = Omit & { + keySeed?: string; +}; + +const NODE_CONFIGS: NodeConfig[] = [ + { name: "one", port: 30433, rpcPort: 9944, basePath: `${BASE_DIR}/one`, validator: true }, + { name: "two", port: 30434, rpcPort: 9945, basePath: `${BASE_DIR}/two`, validator: true }, + { + name: "three", + port: 30435, + rpcPort: 9946, + basePath: `${BASE_DIR}/three`, + validator: true, + keySeed: "//Three", + }, +]; + +async function startNetwork() { + nodeLog(`Setting up ${NODE_CONFIGS.length}-node network for staking E2E tests`); + nodeLog(`Binary path: ${BINARY_PATH}`); + + await mkdir(BASE_DIR, { recursive: true }); + + // Generate local chain spec (built-in has One, Two and Three as authorities) + await generateChainSpec(BINARY_PATH, CHAIN_SPEC_PATH); + + // Clean up old base paths + for (const config of NODE_CONFIGS) { + await rm(config.basePath, { recursive: true, force: true }); + } + + // Insert keys for authority nodes that don't have built-in substrate shortcuts. + for (const config of NODE_CONFIGS) { + if (config.keySeed) { + insertKeys(BINARY_PATH, config.basePath, CHAIN_SPEC_PATH, config.keySeed); + } + } + + // Start all validator nodes + for (const config of NODE_CONFIGS) { + const node = startNode({ + binaryPath: BINARY_PATH, + chainSpec: CHAIN_SPEC_PATH, + ...config, + }); + nodes.push(node); + await started(node); + } + + const all = Promise.all.bind(Promise); + + // Wait for nodes to peer with each other + await all(nodes.map((n) => peerCount(n, nodes.length - 1))); + nodeLog("All nodes peered"); + + // Wait for block finalization + await all(nodes.map((n) => finalizedBlocks(n, 3))); + nodeLog("All nodes finalized block 3"); +} + +async function stopNetwork() { + nodeLog("Stopping staking-tests network"); + + for (const node of nodes) { + try { + await stop(node); + } catch (e) { + nodeLog(`Warning: failed to stop ${node.name}: ${e}`); + } + } + + // Clean up the suite directory + await rm(BASE_DIR, { recursive: true, force: true }); + + nodeLog("Network stopped"); +} + +export async function setup() { + // Start the network + await startNetwork(); + + // Connect to the network and configure for tests + const api = await getDevnetApi(); + log.info("Setup: set lock reduction interval to 1 for instant lock cost decay"); + + // Set lock reduction interval to 1 block to make network registration lock cost decay instantly. + // By default, the lock cost doubles with each subnet registration and decays over 14 days (100,800 blocks). + // Without this, tests creating multiple subnets would fail with CannotAffordLockCost. + await sudoSetLockReductionInterval(api, 1); +} + +export async function teardown() { + // Destroy the API client first + destroyClient(); + + // Stop the network + await stopNetwork(); +} diff --git a/e2e/staking/test/add-stake-limit.test.ts b/e2e/staking/test/add-stake-limit.test.ts new file mode 100644 index 0000000000..63e1bb6ba0 --- /dev/null +++ b/e2e/staking/test/add-stake-limit.test.ts @@ -0,0 +1,65 @@ +import { describe, it, expect, beforeAll } from "vitest"; +import { + getDevnetApi, + getRandomSubstrateKeypair, + convertPublicKeyToSs58, + forceSetBalance, + addNewSubnetwork, + startCall, + addStakeLimit, + getStake, + tao, + log, +} from "e2e-shared"; + +describe("▶ add_stake_limit extrinsic", () => { + const hotkey = getRandomSubstrateKeypair(); + const coldkey = getRandomSubstrateKeypair(); + const hotkeyAddress = convertPublicKeyToSs58(hotkey.publicKey); + const coldkeyAddress = convertPublicKeyToSs58(coldkey.publicKey); + let netuid: number; + + beforeAll(async () => { + const api = await getDevnetApi(); + await forceSetBalance(api, hotkeyAddress); + await forceSetBalance(api, coldkeyAddress); + netuid = await addNewSubnetwork(api, hotkey, coldkey); + await startCall(api, netuid, coldkey); + }); + + it("should add stake with price limit (allow partial)", async () => { + const api = await getDevnetApi(); + + // Get initial stake + const stakeBefore = await getStake(api, hotkeyAddress, coldkeyAddress, netuid); + + // Add stake with limit price and allow partial fills, limit_price is MAX TAO per Alpha willing to pay. + const stakeAmount = tao(44); + const limitPrice = tao(6); + await addStakeLimit(api, coldkey, hotkeyAddress, netuid, stakeAmount, limitPrice, true); + + // Verify stake increased + const stakeAfter = await getStake(api, hotkeyAddress, coldkeyAddress, netuid); + expect(stakeAfter, "Stake should increase").toBeGreaterThan(stakeBefore); + + log.info("✅ Successfully added stake with limit (allow partial)."); + }); + + it("should add stake with price limit (fill or kill)", async () => { + const api = await getDevnetApi(); + + // Get initial stake + const stakeBefore = await getStake(api, hotkeyAddress, coldkeyAddress, netuid); + + // Add stake with limit price (fill or kill mode), limit_price is MAX TAO per Alpha willing to pay + const stakeAmount = tao(44); + const limitPrice = tao(6); + await addStakeLimit(api, coldkey, hotkeyAddress, netuid, stakeAmount, limitPrice, false); + + // Verify stake increased + const stakeAfter = await getStake(api, hotkeyAddress, coldkeyAddress, netuid); + expect(stakeAfter, "Stake should increase").toBeGreaterThan(stakeBefore); + + log.info("✅ Successfully added stake with limit (fill or kill)."); + }); +}); diff --git a/e2e/staking/test/add-stake.test.ts b/e2e/staking/test/add-stake.test.ts new file mode 100644 index 0000000000..fd3eecf052 --- /dev/null +++ b/e2e/staking/test/add-stake.test.ts @@ -0,0 +1,46 @@ +import { describe, it, expect, beforeAll } from "vitest"; +import { + getDevnetApi, + getRandomSubstrateKeypair, + convertPublicKeyToSs58, + forceSetBalance, + addNewSubnetwork, + startCall, + addStake, + getStake, + tao, + log, +} from "e2e-shared"; + +describe("▶ add_stake extrinsic", () => { + const hotkey = getRandomSubstrateKeypair(); + const coldkey = getRandomSubstrateKeypair(); + const hotkeyAddress = convertPublicKeyToSs58(hotkey.publicKey); + const coldkeyAddress = convertPublicKeyToSs58(coldkey.publicKey); + let netuid: number; + + beforeAll(async () => { + const api = await getDevnetApi(); + await forceSetBalance(api, hotkeyAddress); + await forceSetBalance(api, coldkeyAddress); + netuid = await addNewSubnetwork(api, hotkey, coldkey); + await startCall(api, netuid, coldkey); + }); + + it("should add stake to a hotkey", async () => { + const api = await getDevnetApi(); + + // Get initial stake + const stakeBefore = await getStake(api, hotkeyAddress, coldkeyAddress, netuid); + + // Add stake + const stakeAmount = tao(100); + await addStake(api, coldkey, hotkeyAddress, netuid, stakeAmount); + + // Verify stake increased + const stakeAfter = await getStake(api, hotkeyAddress, coldkeyAddress, netuid); + expect(stakeAfter, "Stake should increase after adding stake").toBeGreaterThan(stakeBefore); + + log.info("✅ Successfully added stake."); + }); +}); diff --git a/e2e/staking/test/claim-root.test.ts b/e2e/staking/test/claim-root.test.ts new file mode 100644 index 0000000000..e6ca55876c --- /dev/null +++ b/e2e/staking/test/claim-root.test.ts @@ -0,0 +1,471 @@ +import { describe, it, expect } from "vitest"; +import { + getDevnetApi, + getRandomSubstrateKeypair, + convertPublicKeyToSs58, + forceSetBalance, + addNewSubnetwork, + startCall, + getRootClaimType, + setRootClaimType, + getNumRootClaims, + sudoSetNumRootClaims, + getRootClaimThreshold, + sudoSetRootClaimThreshold, + addStake, + getStake, + claimRoot, + sudoSetTempo, + waitForBlocks, + getRootClaimable, + getRootClaimed, + isSubtokenEnabled, + sudoSetSubtokenEnabled, + sudoSetAdminFreezeWindow, + sudoSetEmaPriceHalvingPeriod, + getSubnetTAO, + getSubnetMovingPrice, + getPendingRootAlphaDivs, + getTaoWeight, + getSubnetAlphaIn, + getTotalHotkeyAlpha, + sudoSetSubnetMovingAlpha, + tao, + log, +} from "e2e-shared"; + +describe("▶ set_root_claim_type extrinsic", () => { + it("should set root claim type to Keep", async () => { + const api = await getDevnetApi(); + + const coldkey = getRandomSubstrateKeypair(); + const coldkeyAddress = convertPublicKeyToSs58(coldkey.publicKey); + + await forceSetBalance(api, coldkeyAddress); + + // Check initial claim type (default is "Swap") + const claimTypeBefore = await getRootClaimType(api, coldkeyAddress); + log.info(`Root claim type before: ${claimTypeBefore}`); + + // Set root claim type to Keep + await setRootClaimType(api, coldkey, "Keep"); + + // Verify claim type changed + const claimTypeAfter = await getRootClaimType(api, coldkeyAddress); + log.info(`Root claim type after: ${claimTypeAfter}`); + + expect(claimTypeAfter).toBe("Keep"); + + log.info("✅ Successfully set root claim type to Keep."); + }); + + it("should set root claim type to Swap", async () => { + const api = await getDevnetApi(); + + const coldkey = getRandomSubstrateKeypair(); + const coldkeyAddress = convertPublicKeyToSs58(coldkey.publicKey); + + await forceSetBalance(api, coldkeyAddress); + + // First set to Keep so we can verify the change to Swap + await setRootClaimType(api, coldkey, "Keep"); + const claimTypeBefore = await getRootClaimType(api, coldkeyAddress); + log.info(`Root claim type before: ${claimTypeBefore}`); + expect(claimTypeBefore).toBe("Keep"); + + // Set root claim type to Swap + await setRootClaimType(api, coldkey, "Swap"); + + // Verify claim type changed + const claimTypeAfter = await getRootClaimType(api, coldkeyAddress); + log.info(`Root claim type after: ${claimTypeAfter}`); + + expect(claimTypeAfter).toBe("Swap"); + + log.info("✅ Successfully set root claim type to Swap."); + }); + + it("should set root claim type to KeepSubnets", async () => { + const api = await getDevnetApi(); + + const coldkey = getRandomSubstrateKeypair(); + const coldkeyAddress = convertPublicKeyToSs58(coldkey.publicKey); + + await forceSetBalance(api, coldkeyAddress); + + // Check initial claim type (default is "Swap") + const claimTypeBefore = await getRootClaimType(api, coldkeyAddress); + log.info(`Root claim type before: ${JSON.stringify(claimTypeBefore)}`); + + // Set root claim type to KeepSubnets with specific subnets + const subnetsToKeep = [1, 2]; + await setRootClaimType(api, coldkey, { type: "KeepSubnets", subnets: subnetsToKeep }); + + // Verify claim type changed + const claimTypeAfter = await getRootClaimType(api, coldkeyAddress); + log.info(`Root claim type after: ${JSON.stringify(claimTypeAfter)}`); + + expect(typeof claimTypeAfter).toBe("object"); + expect((claimTypeAfter as { type: string }).type).toBe("KeepSubnets"); + expect((claimTypeAfter as { subnets: number[] }).subnets).toEqual(subnetsToKeep); + + log.info("✅ Successfully set root claim type to KeepSubnets."); + }); +}); + +describe("▶ sudo_set_num_root_claims extrinsic", () => { + it("should set num root claims", async () => { + const api = await getDevnetApi(); + + // Get initial value + const numClaimsBefore = await getNumRootClaims(api); + log.info(`Num root claims before: ${numClaimsBefore}`); + + // Set new value (different from current) + const newValue = numClaimsBefore + 5n; + await sudoSetNumRootClaims(api, newValue); + + // Verify value changed + const numClaimsAfter = await getNumRootClaims(api); + log.info(`Num root claims after: ${numClaimsAfter}`); + + expect(numClaimsAfter).toBe(newValue); + + log.info("✅ Successfully set num root claims."); + }); +}); + +describe("▶ sudo_set_root_claim_threshold extrinsic", () => { + it("should set root claim threshold for subnet", async () => { + const api = await getDevnetApi(); + + // Create a subnet to test with + const hotkey = getRandomSubstrateKeypair(); + const coldkey = getRandomSubstrateKeypair(); + const hotkeyAddress = convertPublicKeyToSs58(hotkey.publicKey); + const coldkeyAddress = convertPublicKeyToSs58(coldkey.publicKey); + + await forceSetBalance(api, hotkeyAddress); + await forceSetBalance(api, coldkeyAddress); + + const netuid = await addNewSubnetwork(api, hotkey, coldkey); + await startCall(api, netuid, coldkey); + + // Get initial threshold + const thresholdBefore = await getRootClaimThreshold(api, netuid); + log.info(`Root claim threshold before: ${thresholdBefore}`); + + // Set new threshold value (MAX_ROOT_CLAIM_THRESHOLD is 10_000_000) + // The value is stored as I96F32 fixed-point with 32 fractional bits + const newThreshold = 1_000_000n; + await sudoSetRootClaimThreshold(api, netuid, newThreshold); + + // Verify threshold changed + // I96F32 encoding: newThreshold * 2^32 = 1_000_000 * 4294967296 = 4294967296000000 + const thresholdAfter = await getRootClaimThreshold(api, netuid); + log.info(`Root claim threshold after: ${thresholdAfter}`); + + const expectedStoredValue = newThreshold * (1n << 32n); // I96F32 encoding + expect(thresholdAfter).toBe(expectedStoredValue); + + log.info("✅ Successfully set root claim threshold."); + }); +}); + +// Root subnet netuid is 0 +const ROOT_NETUID = 0; + +describe("▶ claim_root extrinsic", () => { + it("should claim root dividends with Keep type (stake to dynamic subnet)", async () => { + const api = await getDevnetApi(); + + // Setup accounts + // - owner1Hotkey/owner1Coldkey: subnet 1 owner + // - owner2Hotkey/owner2Coldkey: subnet 2 owner (needed for root_sell_flag) + // - stakerColdkey: the coldkey that will stake on root and claim dividends + const owner1Hotkey = getRandomSubstrateKeypair(); + const owner1Coldkey = getRandomSubstrateKeypair(); + const owner2Hotkey = getRandomSubstrateKeypair(); + const owner2Coldkey = getRandomSubstrateKeypair(); + const stakerColdkey = getRandomSubstrateKeypair(); + const owner1HotkeyAddress = convertPublicKeyToSs58(owner1Hotkey.publicKey); + const owner1ColdkeyAddress = convertPublicKeyToSs58(owner1Coldkey.publicKey); + const owner2HotkeyAddress = convertPublicKeyToSs58(owner2Hotkey.publicKey); + const owner2ColdkeyAddress = convertPublicKeyToSs58(owner2Coldkey.publicKey); + const stakerColdkeyAddress = convertPublicKeyToSs58(stakerColdkey.publicKey); + + // Fund all accounts + await forceSetBalance(api, owner1HotkeyAddress); + await forceSetBalance(api, owner1ColdkeyAddress); + await forceSetBalance(api, owner2HotkeyAddress); + await forceSetBalance(api, owner2ColdkeyAddress); + await forceSetBalance(api, stakerColdkeyAddress); + + // Disable admin freeze window to allow enabling subtoken for ROOT + await sudoSetAdminFreezeWindow(api, 0); + log.info("Admin freeze window set to 0"); + + // Enable subtoken for ROOT subnet (required for staking on root) + const subtokenEnabledBefore = await isSubtokenEnabled(api, ROOT_NETUID); + if (!subtokenEnabledBefore) { + await sudoSetSubtokenEnabled(api, ROOT_NETUID, true); + const subtokenEnabledAfter = await isSubtokenEnabled(api, ROOT_NETUID); + log.info(`ROOT subtoken enabled: ${subtokenEnabledAfter}`); + expect(subtokenEnabledAfter).toBe(true); + } + + // Create TWO dynamic subnets - needed for root_sell_flag to become true + // root_sell_flag = sum(moving_prices) > 1.0 + // Each subnet's moving price approaches 1.0 via EMA, so 2 subnets can exceed threshold + const netuid1 = await addNewSubnetwork(api, owner1Hotkey, owner1Coldkey); + await startCall(api, netuid1, owner1Coldkey); + log.info(`Created subnet 1 with netuid: ${netuid1}`); + + const netuid2 = await addNewSubnetwork(api, owner2Hotkey, owner2Coldkey); + await startCall(api, netuid2, owner2Coldkey); + log.info(`Created subnet 2 with netuid: ${netuid2}`); + + // Set short tempo for faster emission distribution + await sudoSetTempo(api, netuid1, 1); + await sudoSetTempo(api, netuid2, 1); + log.info("Set tempo to 1 for both subnets"); + + // Set EMA price halving period to 1 for fast moving price convergence + // Formula: alpha = SubnetMovingAlpha * blocks/(blocks + halving_time) + // With halving_time=1: after 10 blocks, alpha ≈ 0.91, moving price ≈ 0.91 + // With 2 subnets at ~0.9 each, total > 1.0 enabling root_sell_flag + await sudoSetEmaPriceHalvingPeriod(api, netuid1, 1); + await sudoSetEmaPriceHalvingPeriod(api, netuid2, 1); + log.info("Set EMA halving period to 1 for fast price convergence"); + + // Set SubnetMovingAlpha to 1.0 (default is 0.000003 which is way too slow) + // I96F32 encoding: 1.0 * 2^32 = 4294967296 + const movingAlpha = BigInt(4294967296); // 1.0 in I96F32 + await sudoSetSubnetMovingAlpha(api, movingAlpha); + log.info("Set SubnetMovingAlpha to 1.0 for fast EMA convergence"); + + // Set threshold to 0 to allow claiming any amount + await sudoSetRootClaimThreshold(api, netuid1, 0n); + await sudoSetRootClaimThreshold(api, netuid2, 0n); + + // Add stake to ROOT subnet for the staker (makes them eligible for root dividends) + const rootStakeAmount = tao(100); + await addStake(api, stakerColdkey, owner1HotkeyAddress, ROOT_NETUID, rootStakeAmount); + log.info(`Added ${rootStakeAmount} stake to root subnet for staker`); + + // Verify root stake was added + const rootStake = await getStake(api, owner1HotkeyAddress, stakerColdkeyAddress, ROOT_NETUID); + log.info(`Root stake: ${rootStake}`); + expect(rootStake, "Should have stake on root subnet").toBeGreaterThan(0n); + + // Add stake to both dynamic subnets (owner stake to enable emissions flow) + const subnetStakeAmount = tao(50); + await addStake(api, owner1Coldkey, owner1HotkeyAddress, netuid1, subnetStakeAmount); + await addStake(api, owner2Coldkey, owner2HotkeyAddress, netuid2, subnetStakeAmount); + log.info(`Added ${subnetStakeAmount} owner stake to subnets ${netuid1} and ${netuid2}`); + + // Get initial stake on subnet 1 for the staker (should be 0) + const stakerSubnetStakeBefore = await getStake(api, owner1HotkeyAddress, stakerColdkeyAddress, netuid1); + log.info(`Staker subnet stake before claim: ${stakerSubnetStakeBefore}`); + + // Set root claim type to Keep (keep alpha on subnet instead of swapping to TAO) + await setRootClaimType(api, stakerColdkey, "Keep"); + const claimType = await getRootClaimType(api, stakerColdkeyAddress); + log.info(`Root claim type: ${claimType}`); + expect(claimType).toBe("Keep"); + + // Wait for blocks to: + // 1. Allow moving prices to converge (need sum > 1.0 for root_sell_flag) + // 2. Accumulate PendingRootAlphaDivs + // 3. Distribute emissions at tempo boundary + const blocksToWait = 25; + log.info(`Waiting for ${blocksToWait} blocks for moving prices to converge and emissions to accumulate...`); + await waitForBlocks(api, blocksToWait); + + // Debug: Check key storage values + const subnetTaoRoot = await getSubnetTAO(api, ROOT_NETUID); + const subnetTao1 = await getSubnetTAO(api, netuid1); + const subnetTao2 = await getSubnetTAO(api, netuid2); + log.info(`SubnetTAO - ROOT: ${subnetTaoRoot}, netuid1: ${subnetTao1}, netuid2: ${subnetTao2}`); + + const movingPrice1 = await getSubnetMovingPrice(api, netuid1); + const movingPrice2 = await getSubnetMovingPrice(api, netuid2); + log.info(`SubnetMovingPrice - netuid1: ${movingPrice1}, netuid2: ${movingPrice2}`); + // Note: Moving price is I96F32, so divide by 2^32 to get actual value + const mp1Float = Number(movingPrice1) / 2 ** 32; + const mp2Float = Number(movingPrice2) / 2 ** 32; + log.info(`SubnetMovingPrice (float) - netuid1: ${mp1Float}, netuid2: ${mp2Float}, sum: ${mp1Float + mp2Float}`); + + const pendingDivs1 = await getPendingRootAlphaDivs(api, netuid1); + const pendingDivs2 = await getPendingRootAlphaDivs(api, netuid2); + log.info(`PendingRootAlphaDivs - netuid1: ${pendingDivs1}, netuid2: ${pendingDivs2}`); + + const taoWeight = await getTaoWeight(api); + log.info(`TaoWeight: ${taoWeight}`); + + const alphaIn1 = await getSubnetAlphaIn(api, netuid1); + const alphaIn2 = await getSubnetAlphaIn(api, netuid2); + log.info(`SubnetAlphaIn - netuid1: ${alphaIn1}, netuid2: ${alphaIn2}`); + + const totalHotkeyAlpha1 = await getTotalHotkeyAlpha(api, owner1HotkeyAddress, netuid1); + log.info(`TotalHotkeyAlpha for hotkey1 on netuid1: ${totalHotkeyAlpha1}`); + + // Check if there are any claimable dividends + const claimable = await getRootClaimable(api, owner1HotkeyAddress); + const claimableStr = [...claimable.entries()].map(([k, v]) => `[${k}: ${v.toString()}]`).join(", "); + log.info(`RootClaimable entries for hotkey1: ${claimableStr || "(none)"}`); + + // Call claim_root to claim dividends for subnet 1 + await claimRoot(api, stakerColdkey, [netuid1]); + log.info("Called claim_root"); + + // Get stake on subnet 1 after claim + const stakerSubnetStakeAfter = await getStake(api, owner1HotkeyAddress, stakerColdkeyAddress, netuid1); + log.info(`Staker subnet stake after claim: ${stakerSubnetStakeAfter}`); + + // Check RootClaimed value + const rootClaimed = await getRootClaimed(api, netuid1, owner1HotkeyAddress, stakerColdkeyAddress); + log.info(`RootClaimed value: ${rootClaimed}`); + + // Verify dividends were claimed + expect(stakerSubnetStakeAfter, "Stake should increase after claiming root dividends").toBeGreaterThan( + stakerSubnetStakeBefore, + ); + log.info(`✅ Root claim successful: stake increased from ${stakerSubnetStakeBefore} to ${stakerSubnetStakeAfter}`); + }); + + it("should claim root dividends with Swap type (swap to TAO on ROOT)", async () => { + const api = await getDevnetApi(); + + // Setup accounts + // - owner1Hotkey/owner1Coldkey: subnet 1 owner + // - owner2Hotkey/owner2Coldkey: subnet 2 owner (needed for root_sell_flag) + // - stakerColdkey: the coldkey that will stake on root and claim dividends + const owner1Hotkey = getRandomSubstrateKeypair(); + const owner1Coldkey = getRandomSubstrateKeypair(); + const owner2Hotkey = getRandomSubstrateKeypair(); + const owner2Coldkey = getRandomSubstrateKeypair(); + const stakerColdkey = getRandomSubstrateKeypair(); + const owner1HotkeyAddress = convertPublicKeyToSs58(owner1Hotkey.publicKey); + const owner1ColdkeyAddress = convertPublicKeyToSs58(owner1Coldkey.publicKey); + const owner2HotkeyAddress = convertPublicKeyToSs58(owner2Hotkey.publicKey); + const owner2ColdkeyAddress = convertPublicKeyToSs58(owner2Coldkey.publicKey); + const stakerColdkeyAddress = convertPublicKeyToSs58(stakerColdkey.publicKey); + + // Fund all accounts + await forceSetBalance(api, owner1HotkeyAddress); + await forceSetBalance(api, owner1ColdkeyAddress); + await forceSetBalance(api, owner2HotkeyAddress); + await forceSetBalance(api, owner2ColdkeyAddress); + await forceSetBalance(api, stakerColdkeyAddress); + + // Disable admin freeze window to allow enabling subtoken for ROOT + await sudoSetAdminFreezeWindow(api, 0); + log.info("Admin freeze window set to 0"); + + // Create TWO dynamic subnets + const netuid1 = await addNewSubnetwork(api, owner1Hotkey, owner1Coldkey); + await startCall(api, netuid1, owner1Coldkey); + log.info(`Created subnet 1 with netuid: ${netuid1}`); + + const netuid2 = await addNewSubnetwork(api, owner2Hotkey, owner2Coldkey); + await startCall(api, netuid2, owner2Coldkey); + log.info(`Created subnet 2 with netuid: ${netuid2}`); + + // Set short tempo for faster emission distribution + await sudoSetTempo(api, netuid1, 1); + await sudoSetTempo(api, netuid2, 1); + log.info("Set tempo to 1 for both subnets"); + + // Set EMA price halving period to 1 for fast moving price convergence + await sudoSetEmaPriceHalvingPeriod(api, netuid1, 1); + await sudoSetEmaPriceHalvingPeriod(api, netuid2, 1); + log.info("Set EMA halving period to 1 for fast price convergence"); + + // Set SubnetMovingAlpha to 1.0 (default is 0.000003 which is way too slow) + // I96F32 encoding: 1.0 * 2^32 = 4294967296 + const movingAlpha = BigInt(4294967296); // 1.0 in I96F32 + await sudoSetSubnetMovingAlpha(api, movingAlpha); + log.info("Set SubnetMovingAlpha to 1.0 for fast EMA convergence"); + + // Set threshold to 0 to allow claiming any amount + await sudoSetRootClaimThreshold(api, netuid1, 0n); + await sudoSetRootClaimThreshold(api, netuid2, 0n); + + // Add stake to ROOT subnet for the staker + const rootStakeAmount = tao(100); + await addStake(api, stakerColdkey, owner1HotkeyAddress, ROOT_NETUID, rootStakeAmount); + log.info(`Added ${rootStakeAmount} stake to root subnet for staker`); + + // Get initial ROOT stake + const rootStakeBefore = await getStake(api, owner1HotkeyAddress, stakerColdkeyAddress, ROOT_NETUID); + log.info(`Root stake before: ${rootStakeBefore}`); + + // Add stake to both dynamic subnets (owner stake to enable emissions flow) + const subnetStakeAmount = tao(50); + await addStake(api, owner1Coldkey, owner1HotkeyAddress, netuid1, subnetStakeAmount); + await addStake(api, owner2Coldkey, owner2HotkeyAddress, netuid2, subnetStakeAmount); + log.info(`Added ${subnetStakeAmount} owner stake to subnets ${netuid1} and ${netuid2}`); + + // Set root claim type to Swap (swap alpha to TAO and add to ROOT stake) + await setRootClaimType(api, stakerColdkey, "Swap"); + const claimType = await getRootClaimType(api, stakerColdkeyAddress); + log.info(`Root claim type: ${claimType}`); + expect(claimType).toBe("Swap"); + + // Wait for blocks + const blocksToWait = 25; + log.info(`Waiting for ${blocksToWait} blocks for emissions to accumulate...`); + await waitForBlocks(api, blocksToWait); + + // Debug: Check moving prices + const movingPrice1 = await getSubnetMovingPrice(api, netuid1); + const movingPrice2 = await getSubnetMovingPrice(api, netuid2); + const mp1Float = Number(movingPrice1) / 2 ** 32; + const mp2Float = Number(movingPrice2) / 2 ** 32; + log.info(`SubnetMovingPrice (float) - netuid1: ${mp1Float}, netuid2: ${mp2Float}, sum: ${mp1Float + mp2Float}`); + + const pendingDivs1 = await getPendingRootAlphaDivs(api, netuid1); + log.info(`PendingRootAlphaDivs netuid1: ${pendingDivs1}`); + + // Check claimable + const claimable = await getRootClaimable(api, owner1HotkeyAddress); + const claimableStr = [...claimable.entries()].map(([k, v]) => `[${k}: ${v.toString()}]`).join(", "); + log.info(`RootClaimable entries for hotkey1: ${claimableStr || "(none)"}`); + + // Call claim_root - with Swap type, dividends are swapped to TAO and added to ROOT stake + await claimRoot(api, stakerColdkey, [netuid1]); + log.info("Called claim_root with Swap type"); + + // Get ROOT stake after claim + const rootStakeAfter = await getStake(api, owner1HotkeyAddress, stakerColdkeyAddress, ROOT_NETUID); + log.info(`Root stake after claim: ${rootStakeAfter}`); + + // Check RootClaimed value + const rootClaimed = await getRootClaimed(api, netuid1, owner1HotkeyAddress, stakerColdkeyAddress); + log.info(`RootClaimed value: ${rootClaimed}`); + + // With Swap type, ROOT stake should increase (not dynamic subnet stake) + expect(rootStakeAfter, "ROOT stake should increase after claiming with Swap type").toBeGreaterThan(rootStakeBefore); + log.info(`✅ Root claim with Swap successful: ROOT stake increased from ${rootStakeBefore} to ${rootStakeAfter}`); + }); + + it("should handle claim_root when no dividends are available", async () => { + const api = await getDevnetApi(); + + // Setup accounts + const coldkey = getRandomSubstrateKeypair(); + const coldkeyAddress = convertPublicKeyToSs58(coldkey.publicKey); + + await forceSetBalance(api, coldkeyAddress); + + // Set root claim type to Keep + await setRootClaimType(api, coldkey, "Keep"); + + // Try to claim on a non-existent subnet (should succeed but be a no-op) + // According to Rust tests, claiming on unrelated subnets returns Ok but does nothing + await claimRoot(api, coldkey, [1]); + + log.info("✅ claim_root with no dividends executed successfully (no-op)."); + }); +}); diff --git a/e2e/staking/test/move-stake.test.ts b/e2e/staking/test/move-stake.test.ts new file mode 100644 index 0000000000..292d8d8ded --- /dev/null +++ b/e2e/staking/test/move-stake.test.ts @@ -0,0 +1,121 @@ +import { describe, it, expect } from "vitest"; +import { + getDevnetApi, + getRandomSubstrateKeypair, + convertPublicKeyToSs58, + forceSetBalance, + addNewSubnetwork, + burnedRegister, + startCall, + addStake, + moveStake, + getStake, + getStakeRaw, + tao, + log, +} from "e2e-shared"; + +describe("▶ move_stake extrinsic", () => { + it("should move stake to another hotkey across subnets", async () => { + const api = await getDevnetApi(); + + // Setup accounts + const originHotkey = getRandomSubstrateKeypair(); + const destinationHotkey = getRandomSubstrateKeypair(); + const coldkey = getRandomSubstrateKeypair(); + const originHotkeyAddress = convertPublicKeyToSs58(originHotkey.publicKey); + const destinationHotkeyAddress = convertPublicKeyToSs58(destinationHotkey.publicKey); + const coldkeyAddress = convertPublicKeyToSs58(coldkey.publicKey); + + await forceSetBalance(api, originHotkeyAddress); + await forceSetBalance(api, destinationHotkeyAddress); + await forceSetBalance(api, coldkeyAddress); + + // Create first subnet with origin hotkey + const netuid1 = await addNewSubnetwork(api, originHotkey, coldkey); + await startCall(api, netuid1, coldkey); + + // Create second subnet with destination hotkey + const netuid2 = await addNewSubnetwork(api, destinationHotkey, coldkey); + await startCall(api, netuid2, coldkey); + + // Add stake to origin hotkey on first subnet + await addStake(api, coldkey, originHotkeyAddress, netuid1, tao(200)); + + // Get initial stakes (converted from U64F64 for display) + const originStakeBefore = await getStake(api, originHotkeyAddress, coldkeyAddress, netuid1); + const destStakeBefore = await getStake(api, destinationHotkeyAddress, coldkeyAddress, netuid2); + expect(originStakeBefore, "Origin hotkey should have stake before move").toBeGreaterThan(0n); + + log.info( + `Origin stake (netuid1) before: ${originStakeBefore}, Destination stake (netuid2) before: ${destStakeBefore}`, + ); + + // Move stake to destination hotkey on different subnet + // Use raw U64F64 value for the extrinsic + const originStakeRaw = await getStakeRaw(api, originHotkeyAddress, coldkeyAddress, netuid1); + const moveAmount = originStakeRaw / 2n; + await moveStake(api, coldkey, originHotkeyAddress, destinationHotkeyAddress, netuid1, netuid2, moveAmount); + + // Verify stakes changed + const originStakeAfter = await getStake(api, originHotkeyAddress, coldkeyAddress, netuid1); + const destStakeAfter = await getStake(api, destinationHotkeyAddress, coldkeyAddress, netuid2); + + log.info(`Origin stake (netuid1) after: ${originStakeAfter}, Destination stake (netuid2) after: ${destStakeAfter}`); + + expect(originStakeAfter, "Origin stake should decrease").toBeLessThan(originStakeBefore); + expect(destStakeAfter, "Destination stake should increase").toBeGreaterThan(destStakeBefore); + + log.info("✅ Successfully moved stake to another hotkey across subnets."); + }); + + it("should move stake to another hotkey on the same subnet", async () => { + const api = await getDevnetApi(); + + // Setup accounts + const originHotkey = getRandomSubstrateKeypair(); + const destinationHotkey = getRandomSubstrateKeypair(); + const coldkey = getRandomSubstrateKeypair(); + const originHotkeyAddress = convertPublicKeyToSs58(originHotkey.publicKey); + const destinationHotkeyAddress = convertPublicKeyToSs58(destinationHotkey.publicKey); + const coldkeyAddress = convertPublicKeyToSs58(coldkey.publicKey); + + await forceSetBalance(api, originHotkeyAddress); + await forceSetBalance(api, destinationHotkeyAddress); + await forceSetBalance(api, coldkeyAddress); + + // Create subnet with origin hotkey + const netuid = await addNewSubnetwork(api, originHotkey, coldkey); + await startCall(api, netuid, coldkey); + + // Register destination hotkey on the same subnet + await burnedRegister(api, netuid, destinationHotkeyAddress, coldkey); + + // Add stake to origin hotkey + await addStake(api, coldkey, originHotkeyAddress, netuid, tao(200)); + + // Get initial stakes (converted from U64F64 for display) + const originStakeBefore = await getStake(api, originHotkeyAddress, coldkeyAddress, netuid); + const destStakeBefore = await getStake(api, destinationHotkeyAddress, coldkeyAddress, netuid); + expect(originStakeBefore, "Origin hotkey should have stake before move").toBeGreaterThan(0n); + + log.info(`Origin stake before: ${originStakeBefore}, Destination stake before: ${destStakeBefore}`); + + // Move stake to destination hotkey on the same subnet + // Use raw U64F64 value for the extrinsic + const originStakeRaw = await getStakeRaw(api, originHotkeyAddress, coldkeyAddress, netuid); + const moveAmount = originStakeRaw / 2n; + await moveStake(api, coldkey, originHotkeyAddress, destinationHotkeyAddress, netuid, netuid, moveAmount); + + // Verify stakes changed + const originStakeAfter = await getStake(api, originHotkeyAddress, coldkeyAddress, netuid); + const destStakeAfter = await getStake(api, destinationHotkeyAddress, coldkeyAddress, netuid); + + log.info(`Origin stake after: ${originStakeAfter}, Destination stake after: ${destStakeAfter}`); + + expect(originStakeAfter, "Origin stake should decrease").toBeLessThan(originStakeBefore); + expect(destStakeAfter, "Destination stake should increase").toBeGreaterThan(destStakeBefore); + + log.info("✅ Successfully moved stake to another hotkey on the same subnet."); + }); +}); diff --git a/e2e/staking/test/remove-stake-full-limit.test.ts b/e2e/staking/test/remove-stake-full-limit.test.ts new file mode 100644 index 0000000000..47af798512 --- /dev/null +++ b/e2e/staking/test/remove-stake-full-limit.test.ts @@ -0,0 +1,95 @@ +import { describe, it, expect, beforeAll } from "vitest"; +import { + getDevnetApi, + getRandomSubstrateKeypair, + convertPublicKeyToSs58, + forceSetBalance, + getBalance, + addNewSubnetwork, + burnedRegister, + startCall, + addStake, + removeStakeFullLimit, + getStake, + sudoSetTempo, + tao, + log, +} from "e2e-shared"; + +describe("▶ remove_stake_full_limit extrinsic", () => { + // Separate owner and staker hotkeys to avoid minimum owner stake retention + const ownerHotkey = getRandomSubstrateKeypair(); + const stakerHotkey = getRandomSubstrateKeypair(); + const coldkey = getRandomSubstrateKeypair(); + const ownerAddress = convertPublicKeyToSs58(ownerHotkey.publicKey); + const stakerAddress = convertPublicKeyToSs58(stakerHotkey.publicKey); + const coldkeyAddress = convertPublicKeyToSs58(coldkey.publicKey); + let netuid: number; + + beforeAll(async () => { + const api = await getDevnetApi(); + await forceSetBalance(api, ownerAddress); + await forceSetBalance(api, stakerAddress); + await forceSetBalance(api, coldkeyAddress); + netuid = await addNewSubnetwork(api, ownerHotkey, coldkey); + await startCall(api, netuid, coldkey); + // Set high tempo to prevent emissions during test + await sudoSetTempo(api, netuid, 10000); + // Register staker hotkey (not the owner) + await burnedRegister(api, netuid, stakerAddress, coldkey); + }); + + it("should remove all stake with price limit", async () => { + const api = await getDevnetApi(); + + // Add stake first + await addStake(api, coldkey, stakerAddress, netuid, tao(100)); + + // Get initial stake and balance + const stakeBefore = await getStake(api, stakerAddress, coldkeyAddress, netuid); + const balanceBefore = await getBalance(api, coldkeyAddress); + log.info(`Stake before: ${stakeBefore}, Balance before: ${balanceBefore}`); + expect(stakeBefore, "Should have stake before removal").toBeGreaterThan(0n); + + // Remove all stake with a reasonable limit price (low limit to avoid slippage rejection) + // Using a low limit price (0.09 TAO per alpha) allows the transaction to succeed + const limitPrice = tao(1) / 10n; // 0.1 TAO + await removeStakeFullLimit(api, coldkey, stakerAddress, netuid, limitPrice); + + // Verify stake is zero (staker is not owner, so all stake can be removed) + const stakeAfter = await getStake(api, stakerAddress, coldkeyAddress, netuid); + const balanceAfter = await getBalance(api, coldkeyAddress); + log.info(`Stake after: ${stakeAfter}, Balance after: ${balanceAfter}`); + + expect(stakeAfter, "Stake should be zero after full removal").toBe(0n); + expect(balanceAfter, "Balance should increase after unstaking").toBeGreaterThan(balanceBefore); + + log.info("✅ Successfully removed all stake with price limit."); + }); + + it("should remove all stake without price limit", async () => { + const api = await getDevnetApi(); + + // Add stake first + await addStake(api, coldkey, stakerAddress, netuid, tao(100)); + + // Get initial stake and balance + const stakeBefore = await getStake(api, stakerAddress, coldkeyAddress, netuid); + const balanceBefore = await getBalance(api, coldkeyAddress); + log.info(`Stake before: ${stakeBefore}, Balance before: ${balanceBefore}`); + expect(stakeBefore, "Should have stake before removal").toBeGreaterThan(0n); + + // Remove all stake without limit price (undefined = no slippage protection) + await removeStakeFullLimit(api, coldkey, stakerAddress, netuid, undefined); + + // Verify stake is zero (staker is not owner, so all stake can be removed) + const stakeAfter = await getStake(api, stakerAddress, coldkeyAddress, netuid); + const balanceAfter = await getBalance(api, coldkeyAddress); + log.info(`Stake after: ${stakeAfter}, Balance after: ${balanceAfter}`); + + expect(stakeAfter, "Stake should be zero after full removal").toBe(0n); + expect(balanceAfter, "Balance should increase after unstaking").toBeGreaterThan(balanceBefore); + + log.info("✅ Successfully removed all stake without price limit."); + }); +}); diff --git a/e2e/staking/test/remove-stake-limit.test.ts b/e2e/staking/test/remove-stake-limit.test.ts new file mode 100644 index 0000000000..9578fb8e3f --- /dev/null +++ b/e2e/staking/test/remove-stake-limit.test.ts @@ -0,0 +1,79 @@ +import { describe, it, expect, beforeAll } from "vitest"; +import { + getDevnetApi, + getRandomSubstrateKeypair, + convertPublicKeyToSs58, + forceSetBalance, + getBalance, + addNewSubnetwork, + startCall, + addStake, + removeStakeLimit, + getStake, + tao, + log, +} from "e2e-shared"; + +describe("▶ remove_stake_limit extrinsic", () => { + const hotkey = getRandomSubstrateKeypair(); + const coldkey = getRandomSubstrateKeypair(); + const hotkeyAddress = convertPublicKeyToSs58(hotkey.publicKey); + const coldkeyAddress = convertPublicKeyToSs58(coldkey.publicKey); + let netuid: number; + + beforeAll(async () => { + const api = await getDevnetApi(); + await forceSetBalance(api, hotkeyAddress); + await forceSetBalance(api, coldkeyAddress); + netuid = await addNewSubnetwork(api, hotkey, coldkey); + await startCall(api, netuid, coldkey); + }); + + it("should remove stake with price limit (allow partial)", async () => { + const api = await getDevnetApi(); + + // Add stake first (100 TAO like benchmark) + await addStake(api, coldkey, hotkeyAddress, netuid, tao(100)); + + // Get initial stake and balance + const stakeBefore = await getStake(api, hotkeyAddress, coldkeyAddress, netuid); + const balanceBefore = await getBalance(api, coldkeyAddress); + log.info(`Stake before: ${stakeBefore}, Balance before: ${balanceBefore}`); + expect(stakeBefore, "Should have stake before removal").toBeGreaterThan(0n); + + // Remove stake with limit price and allow partial fills + const unstakeAmount = tao(30); + const limitPrice = tao(1); + await removeStakeLimit(api, coldkey, hotkeyAddress, netuid, unstakeAmount, limitPrice, true); + + // Verify balance increased (received TAO from unstaking) + const balanceAfter = await getBalance(api, coldkeyAddress); + expect(balanceAfter, "Balance should increase after unstaking").toBeGreaterThan(balanceBefore); + + log.info("✅ Successfully removed stake with limit (allow partial)."); + }); + + it("should remove stake with price limit (fill or kill)", async () => { + const api = await getDevnetApi(); + + // Add stake first (100 TAO like benchmark) + await addStake(api, coldkey, hotkeyAddress, netuid, tao(100)); + + // Get initial stake and balance + const stakeBefore = await getStake(api, hotkeyAddress, coldkeyAddress, netuid); + const balanceBefore = await getBalance(api, coldkeyAddress); + log.info(`Stake before: ${stakeBefore}, Balance before: ${balanceBefore}`); + expect(stakeBefore, "Should have stake before removal").toBeGreaterThan(0n); + + // Remove stake with limit price (fill or kill mode) + const unstakeAmount = tao(30); + const limitPrice = tao(1); + await removeStakeLimit(api, coldkey, hotkeyAddress, netuid, unstakeAmount, limitPrice, false); + + // Verify balance increased (received TAO from unstaking) + const balanceAfter = await getBalance(api, coldkeyAddress); + expect(balanceAfter, "Balance should increase after unstaking").toBeGreaterThan(balanceBefore); + + log.info("✅ Successfully removed stake with limit (fill or kill)."); + }); +}); diff --git a/e2e/staking/test/remove-stake.test.ts b/e2e/staking/test/remove-stake.test.ts new file mode 100644 index 0000000000..db9f5aa150 --- /dev/null +++ b/e2e/staking/test/remove-stake.test.ts @@ -0,0 +1,55 @@ +import { describe, it, expect, beforeAll } from "vitest"; +import { + getDevnetApi, + getRandomSubstrateKeypair, + convertPublicKeyToSs58, + forceSetBalance, + getBalance, + addNewSubnetwork, + startCall, + addStake, + removeStake, + getStake, + getStakeRaw, + tao, + log, +} from "e2e-shared"; + +describe("▶ remove_stake extrinsic", () => { + const hotkey = getRandomSubstrateKeypair(); + const coldkey = getRandomSubstrateKeypair(); + const hotkeyAddress = convertPublicKeyToSs58(hotkey.publicKey); + const coldkeyAddress = convertPublicKeyToSs58(coldkey.publicKey); + let netuid: number; + + beforeAll(async () => { + const api = await getDevnetApi(); + await forceSetBalance(api, hotkeyAddress); + await forceSetBalance(api, coldkeyAddress); + netuid = await addNewSubnetwork(api, hotkey, coldkey); + await startCall(api, netuid, coldkey); + }); + + it("should remove stake from a hotkey", async () => { + const api = await getDevnetApi(); + + // Add stake first + await addStake(api, coldkey, hotkeyAddress, netuid, tao(200)); + + // Get initial stake and balance (converted from U64F64 for display) + const stakeBefore = await getStake(api, hotkeyAddress, coldkeyAddress, netuid); + const balanceBefore = await getBalance(api, coldkeyAddress); + expect(stakeBefore, "Should have stake before removal").toBeGreaterThan(0n); + + // Remove stake (amount is in alpha units - use raw U64F64 value) + const stakeRaw = await getStakeRaw(api, hotkeyAddress, coldkeyAddress, netuid); + const unstakeAmount = stakeRaw / 2n; + await removeStake(api, coldkey, hotkeyAddress, netuid, unstakeAmount); + + // Verify balance increased (received TAO from unstaking) + const balanceAfter = await getBalance(api, coldkeyAddress); + expect(balanceAfter, "Balance should increase after unstaking").toBeGreaterThan(balanceBefore); + + log.info("✅ Successfully removed stake."); + }); +}); diff --git a/e2e/staking/test/swap-stake-limit.test.ts b/e2e/staking/test/swap-stake-limit.test.ts new file mode 100644 index 0000000000..316ddff051 --- /dev/null +++ b/e2e/staking/test/swap-stake-limit.test.ts @@ -0,0 +1,128 @@ +import { describe, it, expect } from "vitest"; +import { + getDevnetApi, + getRandomSubstrateKeypair, + convertPublicKeyToSs58, + forceSetBalance, + addNewSubnetwork, + burnedRegister, + startCall, + addStake, + swapStakeLimit, + getStake, + getStakeRaw, + tao, + log, +} from "e2e-shared"; + +describe("▶ swap_stake_limit extrinsic", () => { + it("should swap stake with price limit (allow partial)", async () => { + const api = await getDevnetApi(); + + // Setup accounts + const hotkey1 = getRandomSubstrateKeypair(); + const hotkey2 = getRandomSubstrateKeypair(); + const coldkey = getRandomSubstrateKeypair(); + const hotkey1Address = convertPublicKeyToSs58(hotkey1.publicKey); + const hotkey2Address = convertPublicKeyToSs58(hotkey2.publicKey); + const coldkeyAddress = convertPublicKeyToSs58(coldkey.publicKey); + + await forceSetBalance(api, hotkey1Address); + await forceSetBalance(api, hotkey2Address); + await forceSetBalance(api, coldkeyAddress); + + // Create first subnet + const netuid1 = await addNewSubnetwork(api, hotkey1, coldkey); + await startCall(api, netuid1, coldkey); + + // Create second subnet + const netuid2 = await addNewSubnetwork(api, hotkey2, coldkey); + await startCall(api, netuid2, coldkey); + + // Register hotkey1 on subnet2 so we can swap stake there + await burnedRegister(api, netuid2, hotkey1Address, coldkey); + + // Add stake to hotkey1 on subnet1 + await addStake(api, coldkey, hotkey1Address, netuid1, tao(100)); + + // Get initial stakes (converted from U64F64 for display) + const stake1Before = await getStake(api, hotkey1Address, coldkeyAddress, netuid1); + const stake2Before = await getStake(api, hotkey1Address, coldkeyAddress, netuid2); + expect(stake1Before, "Should have stake on subnet1 before swap").toBeGreaterThan(0n); + + log.info(`Stake on netuid1 before: ${stake1Before}, Stake on netuid2 before: ${stake2Before}`); + + // Swap stake with limit price (0.99 TAO relative price limit, allow partial fills) + // Use raw U64F64 value for the extrinsic + const stake1Raw = await getStakeRaw(api, hotkey1Address, coldkeyAddress, netuid1); + const swapAmount = stake1Raw / 2n; + const limitPrice = (tao(1) * 99n) / 100n; // 0.99 TAO + await swapStakeLimit(api, coldkey, hotkey1Address, netuid1, netuid2, swapAmount, limitPrice, true); + + // Verify stakes changed + const stake1After = await getStake(api, hotkey1Address, coldkeyAddress, netuid1); + const stake2After = await getStake(api, hotkey1Address, coldkeyAddress, netuid2); + + log.info(`Stake on netuid1 after: ${stake1After}, Stake on netuid2 after: ${stake2After}`); + + expect(stake1After, "Stake on subnet1 should decrease").toBeLessThan(stake1Before); + expect(stake2After, "Stake on subnet2 should increase").toBeGreaterThan(stake2Before); + + log.info("✅ Successfully swapped stake with price limit (allow partial)."); + }); + + it("should swap stake with price limit (fill or kill)", async () => { + const api = await getDevnetApi(); + + // Setup accounts + const hotkey1 = getRandomSubstrateKeypair(); + const hotkey2 = getRandomSubstrateKeypair(); + const coldkey = getRandomSubstrateKeypair(); + const hotkey1Address = convertPublicKeyToSs58(hotkey1.publicKey); + const hotkey2Address = convertPublicKeyToSs58(hotkey2.publicKey); + const coldkeyAddress = convertPublicKeyToSs58(coldkey.publicKey); + + await forceSetBalance(api, hotkey1Address); + await forceSetBalance(api, hotkey2Address); + await forceSetBalance(api, coldkeyAddress); + + // Create first subnet + const netuid1 = await addNewSubnetwork(api, hotkey1, coldkey); + await startCall(api, netuid1, coldkey); + + // Create second subnet + const netuid2 = await addNewSubnetwork(api, hotkey2, coldkey); + await startCall(api, netuid2, coldkey); + + // Register hotkey1 on subnet2 so we can swap stake there + await burnedRegister(api, netuid2, hotkey1Address, coldkey); + + // Add stake to hotkey1 on subnet1 + await addStake(api, coldkey, hotkey1Address, netuid1, tao(100)); + + // Get initial stakes (converted from U64F64 for display) + const stake1Before = await getStake(api, hotkey1Address, coldkeyAddress, netuid1); + const stake2Before = await getStake(api, hotkey1Address, coldkeyAddress, netuid2); + expect(stake1Before, "Should have stake on subnet1 before swap").toBeGreaterThan(0n); + + log.info(`Stake on netuid1 before: ${stake1Before}, Stake on netuid2 before: ${stake2Before}`); + + // Swap stake with limit price (fill or kill mode - allow_partial = false) + // Use raw U64F64 value for the extrinsic + const stake1Raw = await getStakeRaw(api, hotkey1Address, coldkeyAddress, netuid1); + const swapAmount = stake1Raw / 2n; + const limitPrice = tao(1) / 10n; // 0.1 TAO - permissive limit to allow slippage + await swapStakeLimit(api, coldkey, hotkey1Address, netuid1, netuid2, swapAmount, limitPrice, false); + + // Verify stakes changed + const stake1After = await getStake(api, hotkey1Address, coldkeyAddress, netuid1); + const stake2After = await getStake(api, hotkey1Address, coldkeyAddress, netuid2); + + log.info(`Stake on netuid1 after: ${stake1After}, Stake on netuid2 after: ${stake2After}`); + + expect(stake1After, "Stake on subnet1 should decrease").toBeLessThan(stake1Before); + expect(stake2After, "Stake on subnet2 should increase").toBeGreaterThan(stake2Before); + + log.info("✅ Successfully swapped stake with price limit (fill or kill)."); + }); +}); diff --git a/e2e/staking/test/swap-stake.test.ts b/e2e/staking/test/swap-stake.test.ts new file mode 100644 index 0000000000..44a818dd81 --- /dev/null +++ b/e2e/staking/test/swap-stake.test.ts @@ -0,0 +1,73 @@ +import { describe, it, expect } from "vitest"; +import { + getDevnetApi, + getRandomSubstrateKeypair, + convertPublicKeyToSs58, + forceSetBalance, + addNewSubnetwork, + burnedRegister, + startCall, + addStake, + swapStake, + getStake, + getStakeRaw, + tao, + log, +} from "e2e-shared"; + +describe("▶ swap_stake extrinsic", () => { + it("should swap stake from one subnet to another", async () => { + const api = await getDevnetApi(); + + // Setup accounts + const hotkey1 = getRandomSubstrateKeypair(); + const hotkey2 = getRandomSubstrateKeypair(); + const coldkey = getRandomSubstrateKeypair(); + const hotkey1Address = convertPublicKeyToSs58(hotkey1.publicKey); + const hotkey2Address = convertPublicKeyToSs58(hotkey2.publicKey); + const coldkeyAddress = convertPublicKeyToSs58(coldkey.publicKey); + + await forceSetBalance(api, hotkey1Address); + await forceSetBalance(api, hotkey2Address); + await forceSetBalance(api, coldkeyAddress); + + // Create first subnet + const netuid1 = await addNewSubnetwork(api, hotkey1, coldkey); + await startCall(api, netuid1, coldkey); + + // Create second subnet + const netuid2 = await addNewSubnetwork(api, hotkey2, coldkey); + await startCall(api, netuid2, coldkey); + + // Register hotkey1 on subnet2 so we can swap stake there + await burnedRegister(api, netuid2, hotkey1Address, coldkey); + + // Add stake to hotkey1 on subnet1 + await addStake(api, coldkey, hotkey1Address, netuid1, tao(100)); + + // Get initial stakes + const stake1Before = await getStake(api, hotkey1Address, coldkeyAddress, netuid1); + const stake2Before = await getStake(api, hotkey1Address, coldkeyAddress, netuid2); + expect(stake1Before, "Should have stake on subnet1 before swap").toBeGreaterThan(0n); + + log.info(`Stake on netuid1 before: ${stake1Before}, Stake on netuid2 before: ${stake2Before}`); + + // Swap half the stake from subnet1 to subnet2 + // Use raw U64F64 value for the extrinsic + const stake1Raw = await getStakeRaw(api, hotkey1Address, coldkeyAddress, netuid1); + const swapAmount = stake1Raw / 2n; + await swapStake(api, coldkey, hotkey1Address, netuid1, netuid2, swapAmount); + + // Verify stakes changed + const stake1After = await getStake(api, hotkey1Address, coldkeyAddress, netuid1); + const stake2After = await getStake(api, hotkey1Address, coldkeyAddress, netuid2); + + log.info(`Stake on netuid1 after: ${stake1After}, Stake on netuid2 after: ${stake2After}`); + + // Note: hotkey1 is the owner of netuid1, so minimum owner stake may be retained + expect(stake1After, "Stake on subnet1 should decrease after swap").toBeLessThan(stake1Before); + expect(stake2After, "Stake on subnet2 should increase after swap").toBeGreaterThan(stake2Before); + + log.info("✅ Successfully swapped stake from one subnet to another."); + }); +}); diff --git a/e2e/staking/test/transfer-stake.test.ts b/e2e/staking/test/transfer-stake.test.ts new file mode 100644 index 0000000000..330ca0b8d9 --- /dev/null +++ b/e2e/staking/test/transfer-stake.test.ts @@ -0,0 +1,128 @@ +import { describe, it, expect } from "vitest"; +import { + getDevnetApi, + getRandomSubstrateKeypair, + convertPublicKeyToSs58, + forceSetBalance, + addNewSubnetwork, + startCall, + addStake, + transferStake, + getStake, + getStakeRaw, + tao, + log, +} from "e2e-shared"; + +describe("▶ transfer_stake extrinsic", () => { + it("should transfer stake to another coldkey across subnets", async () => { + const api = await getDevnetApi(); + + // Setup accounts + const hotkey1 = getRandomSubstrateKeypair(); + const hotkey2 = getRandomSubstrateKeypair(); + const originColdkey = getRandomSubstrateKeypair(); + const destinationColdkey = getRandomSubstrateKeypair(); + const hotkey1Address = convertPublicKeyToSs58(hotkey1.publicKey); + const hotkey2Address = convertPublicKeyToSs58(hotkey2.publicKey); + const originColdkeyAddress = convertPublicKeyToSs58(originColdkey.publicKey); + const destinationColdkeyAddress = convertPublicKeyToSs58(destinationColdkey.publicKey); + + await forceSetBalance(api, hotkey1Address); + await forceSetBalance(api, hotkey2Address); + await forceSetBalance(api, originColdkeyAddress); + await forceSetBalance(api, destinationColdkeyAddress); + + // Create first subnet + const netuid1 = await addNewSubnetwork(api, hotkey1, originColdkey); + await startCall(api, netuid1, originColdkey); + + // Create second subnet + const netuid2 = await addNewSubnetwork(api, hotkey2, originColdkey); + await startCall(api, netuid2, originColdkey); + + // Add stake from origin coldkey on first subnet + await addStake(api, originColdkey, hotkey1Address, netuid1, tao(200)); + + // Get initial stakes (converted from U64F64 for display) + const originStakeBefore = await getStake(api, hotkey1Address, originColdkeyAddress, netuid1); + const destStakeBefore = await getStake(api, hotkey1Address, destinationColdkeyAddress, netuid2); + expect(originStakeBefore, "Origin should have stake before transfer").toBeGreaterThan(0n); + + log.info( + `Origin stake (netuid1) before: ${originStakeBefore}, Destination stake (netuid2) before: ${destStakeBefore}`, + ); + + // Transfer stake to destination coldkey on a different subnet + // Use raw U64F64 value for the extrinsic + const originStakeRaw = await getStakeRaw(api, hotkey1Address, originColdkeyAddress, netuid1); + const transferAmount = originStakeRaw / 2n; + await transferStake( + api, + originColdkey, + destinationColdkeyAddress, + hotkey1Address, + netuid1, + netuid2, + transferAmount, + ); + + // Verify stakes changed + const originStakeAfter = await getStake(api, hotkey1Address, originColdkeyAddress, netuid1); + const destStakeAfter = await getStake(api, hotkey1Address, destinationColdkeyAddress, netuid2); + + log.info(`Origin stake (netuid1) after: ${originStakeAfter}, Destination stake (netuid2) after: ${destStakeAfter}`); + + expect(originStakeAfter, "Origin stake should decrease").toBeLessThan(originStakeBefore); + expect(destStakeAfter, "Destination stake should increase").toBeGreaterThan(destStakeBefore); + + log.info("✅ Successfully transferred stake to another coldkey across subnets."); + }); + + it("should transfer stake to another coldkey", async () => { + const api = await getDevnetApi(); + + // Setup accounts + const hotkey = getRandomSubstrateKeypair(); + const originColdkey = getRandomSubstrateKeypair(); + const destinationColdkey = getRandomSubstrateKeypair(); + const hotkeyAddress = convertPublicKeyToSs58(hotkey.publicKey); + const originColdkeyAddress = convertPublicKeyToSs58(originColdkey.publicKey); + const destinationColdkeyAddress = convertPublicKeyToSs58(destinationColdkey.publicKey); + + await forceSetBalance(api, hotkeyAddress); + await forceSetBalance(api, originColdkeyAddress); + await forceSetBalance(api, destinationColdkeyAddress); + + // Create subnet + const netuid = await addNewSubnetwork(api, hotkey, originColdkey); + await startCall(api, netuid, originColdkey); + + // Add stake from origin coldkey + const stakeAmount = tao(100); + await addStake(api, originColdkey, hotkeyAddress, netuid, stakeAmount); + + // Get initial stake (converted from U64F64 for display) + const originStakeBefore = await getStake(api, hotkeyAddress, originColdkeyAddress, netuid); + expect(originStakeBefore, "Origin should have stake before transfer").toBeGreaterThan(0n); + + log.info(`Origin stake before: ${originStakeBefore}`); + + // Transfer stake to destination coldkey + // Use raw U64F64 value for the extrinsic, transfer half to avoid AmountTooLow error + const originStakeRaw = await getStakeRaw(api, hotkeyAddress, originColdkeyAddress, netuid); + const transferAmount = originStakeRaw / 2n; + await transferStake(api, originColdkey, destinationColdkeyAddress, hotkeyAddress, netuid, netuid, transferAmount); + + // Verify destination received stake + const originStakeAfter = await getStake(api, hotkeyAddress, originColdkeyAddress, netuid); + const destStakeAfter = await getStake(api, hotkeyAddress, destinationColdkeyAddress, netuid); + + log.info(`Origin stake after: ${originStakeAfter}, Destination stake after: ${destStakeAfter}`); + + expect(originStakeAfter, "Origin stake should decrease after transfer").toBeLessThan(originStakeBefore); + expect(destStakeAfter, "Destination stake should be non-zero after transfer").toBeGreaterThan(0n); + + log.info("✅ Successfully transferred stake to another coldkey."); + }); +}); diff --git a/e2e/staking/test/unstake-all-alpha.test.ts b/e2e/staking/test/unstake-all-alpha.test.ts new file mode 100644 index 0000000000..dd71a27192 --- /dev/null +++ b/e2e/staking/test/unstake-all-alpha.test.ts @@ -0,0 +1,84 @@ +import { describe, it, expect } from "vitest"; +import { + getDevnetApi, + getRandomSubstrateKeypair, + convertPublicKeyToSs58, + forceSetBalance, + addNewSubnetwork, + burnedRegister, + startCall, + addStake, + unstakeAllAlpha, + getStake, + sudoSetTempo, + tao, + log, +} from "e2e-shared"; + +describe("▶ unstake_all_alpha extrinsic", () => { + it("should unstake all alpha from multiple subnets and restake to root", async () => { + const api = await getDevnetApi(); + + // Setup accounts + // - owner1/coldkey: owns subnet 1 + // - owner2/coldkey: owns subnet 2 + // - stakerHotkey: staker (not owner) on both subnets - used for testing unstake_all_alpha + const owner1Hotkey = getRandomSubstrateKeypair(); + const owner2Hotkey = getRandomSubstrateKeypair(); + const stakerHotkey = getRandomSubstrateKeypair(); + const coldkey = getRandomSubstrateKeypair(); + const owner1Address = convertPublicKeyToSs58(owner1Hotkey.publicKey); + const owner2Address = convertPublicKeyToSs58(owner2Hotkey.publicKey); + const stakerAddress = convertPublicKeyToSs58(stakerHotkey.publicKey); + const coldkeyAddress = convertPublicKeyToSs58(coldkey.publicKey); + + await forceSetBalance(api, owner1Address); + await forceSetBalance(api, owner2Address); + await forceSetBalance(api, stakerAddress); + await forceSetBalance(api, coldkeyAddress); + + // Create first subnet with owner1 + const netuid1 = await addNewSubnetwork(api, owner1Hotkey, coldkey); + await startCall(api, netuid1, coldkey); + + // Create second subnet with owner2 + const netuid2 = await addNewSubnetwork(api, owner2Hotkey, coldkey); + await startCall(api, netuid2, coldkey); + + // Set very high tempo to prevent emissions during test + await sudoSetTempo(api, netuid1, 10000); + await sudoSetTempo(api, netuid2, 10000); + + // Register stakerHotkey on both subnets (it's not the owner) + await burnedRegister(api, netuid1, stakerAddress, coldkey); + await burnedRegister(api, netuid2, stakerAddress, coldkey); + + // Add stake to both subnets using stakerHotkey (not the owner) + await addStake(api, coldkey, stakerAddress, netuid1, tao(100)); + await addStake(api, coldkey, stakerAddress, netuid2, tao(50)); + + // Verify stake was added to both subnets + const stake1Before = await getStake(api, stakerAddress, coldkeyAddress, netuid1); + const stake2Before = await getStake(api, stakerAddress, coldkeyAddress, netuid2); + + expect(stake1Before, "Should have stake in subnet 1 before unstake_all_alpha").toBeGreaterThan(0n); + expect(stake2Before, "Should have stake in subnet 2 before unstake_all_alpha").toBeGreaterThan(0n); + log.info(`Stake1 before: ${stake1Before}, Stake2 before: ${stake2Before}`); + + // Unstake all alpha - this removes stake from dynamic subnets and restakes to root + await unstakeAllAlpha(api, coldkey, stakerAddress); + + // Verify stakes are removed from both dynamic subnets + const stake1After = await getStake(api, stakerAddress, coldkeyAddress, netuid1); + const stake2After = await getStake(api, stakerAddress, coldkeyAddress, netuid2); + + log.info(`Stake1 after: ${stake1After}, Stake2 after: ${stake2After}`); + + // Since stakerHotkey is not the owner of either subnet, all stake should be removed + // High tempo prevents emissions during test, so expect exact zero + expect(stake1After, "Stake1 should be zero after unstake_all_alpha").toBe(0n); + expect(stake2After, "Stake2 should be zero after unstake_all_alpha").toBe(0n); + + log.info("✅ Successfully unstaked all alpha from multiple subnets to root."); + }); +}); diff --git a/e2e/staking/test/unstake-all.test.ts b/e2e/staking/test/unstake-all.test.ts new file mode 100644 index 0000000000..146a2c3225 --- /dev/null +++ b/e2e/staking/test/unstake-all.test.ts @@ -0,0 +1,87 @@ +import { describe, it, expect } from "vitest"; +import { + getDevnetApi, + getRandomSubstrateKeypair, + convertPublicKeyToSs58, + forceSetBalance, + getBalance, + addNewSubnetwork, + burnedRegister, + startCall, + addStake, + unstakeAll, + getStake, + sudoSetTempo, + tao, + log, +} from "e2e-shared"; + +describe("▶ unstake_all extrinsic", () => { + it("should unstake all from a hotkey across all subnets", async () => { + const api = await getDevnetApi(); + + // Setup accounts + // - owner1Hotkey/coldkey: owns subnet 1 + // - owner2Hotkey/coldkey: owns subnet 2 + // - stakerHotkey: staker (not owner) on both subnets - used for testing unstake_all + const owner1Hotkey = getRandomSubstrateKeypair(); + const owner2Hotkey = getRandomSubstrateKeypair(); + const stakerHotkey = getRandomSubstrateKeypair(); + const coldkey = getRandomSubstrateKeypair(); + const owner1Address = convertPublicKeyToSs58(owner1Hotkey.publicKey); + const owner2Address = convertPublicKeyToSs58(owner2Hotkey.publicKey); + const stakerAddress = convertPublicKeyToSs58(stakerHotkey.publicKey); + const coldkeyAddress = convertPublicKeyToSs58(coldkey.publicKey); + + await forceSetBalance(api, owner1Address); + await forceSetBalance(api, owner2Address); + await forceSetBalance(api, stakerAddress); + await forceSetBalance(api, coldkeyAddress); + + // Create first subnet with owner1 + const netuid1 = await addNewSubnetwork(api, owner1Hotkey, coldkey); + await startCall(api, netuid1, coldkey); + + // Create second subnet with owner2 + const netuid2 = await addNewSubnetwork(api, owner2Hotkey, coldkey); + await startCall(api, netuid2, coldkey); + + // Set high tempo to prevent emissions during test + await sudoSetTempo(api, netuid1, 10000); + await sudoSetTempo(api, netuid2, 10000); + + // Register stakerHotkey on both subnets (it's not the owner) + await burnedRegister(api, netuid1, stakerAddress, coldkey); + await burnedRegister(api, netuid2, stakerAddress, coldkey); + + // Add stake to both subnets using stakerHotkey (not the owner) + await addStake(api, coldkey, stakerAddress, netuid1, tao(100)); + await addStake(api, coldkey, stakerAddress, netuid2, tao(50)); + + // Verify stake was added to both subnets + const stake1Before = await getStake(api, stakerAddress, coldkeyAddress, netuid1); + const stake2Before = await getStake(api, stakerAddress, coldkeyAddress, netuid2); + const balanceBefore = await getBalance(api, coldkeyAddress); + + expect(stake1Before, "Should have stake in subnet 1 before unstake_all").toBeGreaterThan(0n); + expect(stake2Before, "Should have stake in subnet 2 before unstake_all").toBeGreaterThan(0n); + log.info(`Stake1 before: ${stake1Before}, Stake2 before: ${stake2Before}, Balance before: ${balanceBefore}`); + + // Unstake all + await unstakeAll(api, coldkey, stakerAddress); + + // Verify stakes are removed from both subnets and balance increased + const stake1After = await getStake(api, stakerAddress, coldkeyAddress, netuid1); + const stake2After = await getStake(api, stakerAddress, coldkeyAddress, netuid2); + const balanceAfter = await getBalance(api, coldkeyAddress); + + log.info(`Stake1 after: ${stake1After}, Stake2 after: ${stake2After}, Balance after: ${balanceAfter}`); + + // Since stakerHotkey is not the owner of either subnet, all stake should be removed + expect(stake1After, "Stake1 should be zero after unstake_all").toBe(0n); + expect(stake2After, "Stake2 should be zero after unstake_all").toBe(0n); + expect(balanceAfter, "Balance should increase after unstaking").toBeGreaterThan(balanceBefore); + + log.info("✅ Successfully unstaked all from multiple subnets."); + }); +}); diff --git a/e2e/staking/tsconfig.json b/e2e/staking/tsconfig.json new file mode 100644 index 0000000000..c2f86d9e2c --- /dev/null +++ b/e2e/staking/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ESNext", + "moduleResolution": "bundler", + "esModuleInterop": true, + "strict": true, + "skipLibCheck": true, + "types": ["node", "vitest/globals"] + } +} diff --git a/e2e/staking/vitest.config.ts b/e2e/staking/vitest.config.ts new file mode 100644 index 0000000000..c33905bdbe --- /dev/null +++ b/e2e/staking/vitest.config.ts @@ -0,0 +1,22 @@ +import { defineConfig } from "vitest/config"; +import { BaseSequencer, type TestSpecification } from "vitest/node"; + +class AlphabeticalSequencer extends BaseSequencer { + async sort(files: TestSpecification[]): Promise { + return files.sort((a, b) => a.moduleId.localeCompare(b.moduleId)); + } +} + +export default defineConfig({ + test: { + globals: true, + testTimeout: 120_000, + hookTimeout: 300_000, + fileParallelism: false, + globalSetup: "./setup.ts", + include: ["test/**/*.test.ts"], + sequence: { + sequencer: AlphabeticalSequencer, + }, + }, +}); diff --git a/node/Cargo.toml b/node/Cargo.toml index 1d2351c265..2766893452 100644 --- a/node/Cargo.toml +++ b/node/Cargo.toml @@ -26,6 +26,7 @@ clap = { workspace = true, features = ["derive"] } futures = { workspace = true, features = ["thread-pool"] } serde = { workspace = true, features = ["derive"] } hex.workspace = true +tokio = { workspace = true, features = ["time"] } # Storage import memmap2.workspace = true @@ -94,6 +95,7 @@ pallet-transaction-payment-rpc-runtime-api.workspace = true # These dependencies are used for runtime benchmarking frame-benchmarking.workspace = true frame-benchmarking-cli.workspace = true +pallet-subtensor.workspace = true # Needed for Frontier fc-mapping-sync.workspace = true @@ -116,18 +118,8 @@ num-traits = { workspace = true, features = ["std"] } # Mev Shield pallet-shield.workspace = true -tokio = { version = "1.38", features = ["time"] } -x25519-dalek = "2" -hkdf = "0.12" -chacha20poly1305 = { version = "0.10", features = ["std"] } -codec.workspace = true -rand.workspace = true -sha2.workspace = true -anyhow.workspace = true -pallet-subtensor.workspace = true -ml-kem.workspace = true -rand_core = "0.9.3" -blake2 = "0.10.6" +stp-shield.workspace = true +stc-shield.workspace = true # Local Dependencies node-subtensor-runtime = { workspace = true, features = ["std"] } @@ -173,6 +165,7 @@ runtime-benchmarks = [ "polkadot-sdk/runtime-benchmarks", "pallet-subtensor/runtime-benchmarks", "pallet-shield/runtime-benchmarks", + "subtensor-runtime-common/runtime-benchmarks", ] pow-faucet = [] @@ -187,8 +180,8 @@ try-runtime = [ "pallet-commitments/try-runtime", "pallet-drand/try-runtime", "polkadot-sdk/try-runtime", - "pallet-shield/try-runtime", "pallet-subtensor/try-runtime", + "pallet-shield/try-runtime", ] metadata-hash = ["node-subtensor-runtime/metadata-hash"] diff --git a/node/src/benchmarking.rs b/node/src/benchmarking.rs index 02e31e750e..d0c0ac9a40 100644 --- a/node/src/benchmarking.rs +++ b/node/src/benchmarking.rs @@ -5,7 +5,7 @@ use crate::client::FullClient; use node_subtensor_runtime as runtime; -use node_subtensor_runtime::{check_nonce, transaction_payment_wrapper}; +use node_subtensor_runtime::{check_mortality, check_nonce, transaction_payment_wrapper}; use node_subtensor_runtime::{pallet_subtensor, sudo_wrapper}; use runtime::{BalancesCall, SystemCall}; use sc_cli::Result; @@ -14,7 +14,7 @@ use sp_core::{Encode, Pair}; use sp_inherents::{InherentData, InherentDataProvider}; use sp_keyring::Sr25519Keyring; use sp_runtime::{OpaqueExtrinsic, SaturatedConversion}; -use subtensor_runtime_common::{AccountId, Balance, Signature}; +use subtensor_runtime_common::{AccountId, Balance, Signature, TaoBalance}; use std::{sync::Arc, time::Duration}; @@ -124,23 +124,24 @@ 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), + let era = sp_runtime::generic::Era::mortal(period, best_block.saturated_into()); + let extra: runtime::TxExtension = ( + ( + frame_system::CheckNonZeroSender::::new(), + frame_system::CheckSpecVersion::::new(), + frame_system::CheckTxVersion::::new(), + frame_system::CheckGenesis::::new(), + check_mortality::CheckMortality::::from(era), + check_nonce::CheckNonce::::from(nonce), + frame_system::CheckWeight::::new(), + ), + ( + transaction_payment_wrapper::ChargeTransactionPaymentWrapper::new(TaoBalance::new(0)), + sudo_wrapper::SudoTransactionExtension::::new(), + pallet_shield::CheckShieldedTxValidity::::new(), + pallet_subtensor::SubtensorTransactionExtension::::new(), + pallet_drand::drand_priority::DrandPriority::::new(), ), - sudo_wrapper::SudoTransactionExtension::::new(), - pallet_subtensor::SubtensorTransactionExtension::::new(), - pallet_drand::drand_priority::DrandPriority::::new(), frame_metadata_hash_extension::CheckMetadataHash::::new(true), ); @@ -148,17 +149,16 @@ pub fn create_benchmark_extrinsic( call.clone(), extra.clone(), ( - (), - runtime::VERSION.spec_version, - runtime::VERSION.transaction_version, - genesis_hash, - best_hash, - (), - (), - (), - (), - (), - (), + ( + (), + runtime::VERSION.spec_version, + runtime::VERSION.transaction_version, + genesis_hash, + best_hash, + (), + (), + ), + ((), (), (), (), ()), None, ), ); diff --git a/node/src/chain_spec/localnet.rs b/node/src/chain_spec/localnet.rs index 02ea8896b5..57a60bbd1b 100644 --- a/node/src/chain_spec/localnet.rs +++ b/node/src/chain_spec/localnet.rs @@ -39,6 +39,7 @@ pub fn localnet_config(single_authority: bool) -> Result { vec![ authority_keys_from_seed("One"), authority_keys_from_seed("Two"), + authority_keys_from_seed("Three"), ] }, // Pre-funded accounts @@ -85,6 +86,10 @@ fn localnet_genesis( get_account_id_from_seed::("Two"), 2000000000000u128, ), + ( + get_account_id_from_seed::("Three"), + 2000000000000u128, + ), // ETH ( // Alith - 0xf24FF3a9CF04c71Dbc94D0b566f7A27B94566cac @@ -101,7 +106,11 @@ fn localnet_genesis( // Check if the environment variable is set if let Ok(bt_wallet) = env::var("BT_DEFAULT_TOKEN_WALLET") { if let Ok(decoded_wallet) = Ss58Codec::from_ss58check(&bt_wallet) { - balances.push((decoded_wallet, 1_000_000_000_000_000u128)); + if let Some(existing) = balances.iter_mut().find(|(acc, _)| acc == &decoded_wallet) { + existing.1 = 1_000_000_000_000_000u128; + } else { + balances.push((decoded_wallet, 1_000_000_000_000_000u128)); + } } else { eprintln!("Invalid format for BT_DEFAULT_TOKEN_WALLET."); } diff --git a/node/src/command.rs b/node/src/command.rs index 3350c1443e..670ae6f4e4 100644 --- a/node/src/command.rs +++ b/node/src/command.rs @@ -217,7 +217,7 @@ pub fn run() -> sc_cli::Result<()> { Box::new(TransferKeepAliveBuilder::new( client.clone(), Sr25519Keyring::Alice.to_account_id(), - EXISTENTIAL_DEPOSIT, + EXISTENTIAL_DEPOSIT.into(), )), ]); diff --git a/node/src/consensus/aura_consensus.rs b/node/src/consensus/aura_consensus.rs index 16bdae6c01..ce34e8125a 100644 --- a/node/src/consensus/aura_consensus.rs +++ b/node/src/consensus/aura_consensus.rs @@ -28,7 +28,9 @@ use sp_inherents::CreateInherentDataProviders; use sp_keystore::KeystorePtr; use sp_runtime::traits::Block as BlockT; use sp_runtime::traits::NumberFor; +use stc_shield::InherentDataProvider as ShieldInherentDataProvider; use std::{error::Error, sync::Arc}; +use stp_shield::ShieldKeystorePtr; pub struct AuraConsensus; @@ -36,6 +38,7 @@ impl ConsensusMechanism for AuraConsensus { type InherentDataProviders = ( sp_consensus_aura::inherents::InherentDataProvider, sp_timestamp::InherentDataProvider, + stc_shield::InherentDataProvider, ); fn start_authoring( @@ -101,6 +104,7 @@ impl ConsensusMechanism for AuraConsensus { fn create_inherent_data_providers( slot_duration: SlotDuration, + shield_keystore: ShieldKeystorePtr, ) -> Result> { let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); let slot = @@ -108,11 +112,13 @@ impl ConsensusMechanism for AuraConsensus { *timestamp, slot_duration, ); - Ok((slot, timestamp)) + let shield = ShieldInherentDataProvider::new(shield_keystore); + Ok((slot, timestamp, shield)) } fn pending_create_inherent_data_providers( slot_duration: SlotDuration, + shield_keystore: ShieldKeystorePtr, ) -> Result> { let current = sp_timestamp::InherentDataProvider::from_system_time(); let next_slot = current @@ -125,7 +131,8 @@ impl ConsensusMechanism for AuraConsensus { *timestamp, slot_duration, ); - Ok((slot, timestamp)) + let shield = stc_shield::InherentDataProvider::new(shield_keystore); + Ok((slot, timestamp, shield)) } fn new() -> Self { diff --git a/node/src/consensus/babe_consensus.rs b/node/src/consensus/babe_consensus.rs index 490a505f4d..4f84cbb87b 100644 --- a/node/src/consensus/babe_consensus.rs +++ b/node/src/consensus/babe_consensus.rs @@ -31,7 +31,9 @@ use sp_consensus_slots::SlotDuration; use sp_inherents::CreateInherentDataProviders; use sp_keystore::KeystorePtr; use sp_runtime::traits::NumberFor; +use stc_shield::InherentDataProvider as ShieldInherentDataProvider; use std::{error::Error, sync::Arc}; +use stp_shield::ShieldKeystorePtr; pub struct BabeConsensus { babe_link: Option>, @@ -42,6 +44,7 @@ impl ConsensusMechanism for BabeConsensus { type InherentDataProviders = ( sp_consensus_babe::inherents::InherentDataProvider, sp_timestamp::InherentDataProvider, + stc_shield::InherentDataProvider, ); #[allow(clippy::expect_used)] @@ -111,6 +114,7 @@ impl ConsensusMechanism for BabeConsensus { fn create_inherent_data_providers( slot_duration: SlotDuration, + shield_keystore: ShieldKeystorePtr, ) -> Result> { let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); let slot = @@ -118,11 +122,13 @@ impl ConsensusMechanism for BabeConsensus { *timestamp, slot_duration, ); - Ok((slot, timestamp)) + let shield = stc_shield::InherentDataProvider::new(shield_keystore); + Ok((slot, timestamp, shield)) } fn pending_create_inherent_data_providers( slot_duration: SlotDuration, + shield_keystore: ShieldKeystorePtr, ) -> Result> { let current = sp_timestamp::InherentDataProvider::from_system_time(); let next_slot = current @@ -135,7 +141,8 @@ impl ConsensusMechanism for BabeConsensus { *timestamp, slot_duration, ); - Ok((slot, timestamp)) + let shield = ShieldInherentDataProvider::new(shield_keystore); + Ok((slot, timestamp, shield)) } fn new() -> Self { diff --git a/node/src/consensus/consensus_mechanism.rs b/node/src/consensus/consensus_mechanism.rs index b88e2d0462..9fd8cad63b 100644 --- a/node/src/consensus/consensus_mechanism.rs +++ b/node/src/consensus/consensus_mechanism.rs @@ -24,6 +24,7 @@ use sp_keystore::KeystorePtr; use sp_runtime::traits::NumberFor; use std::sync::Arc; use std::sync::atomic::AtomicBool; +use stp_shield::ShieldKeystorePtr; use crate::client::FullClient; use crate::service::BIQ; @@ -85,11 +86,13 @@ pub trait ConsensusMechanism { /// Creates IDPs for the consensus mechanism. fn create_inherent_data_providers( slot_duration: SlotDuration, + shield_keystore: ShieldKeystorePtr, ) -> Result>; /// Creates IDPs for the consensus mechanism for pending blocks. fn pending_create_inherent_data_providers( slot_duration: SlotDuration, + shield_keystore: ShieldKeystorePtr, ) -> Result>; /// Creates the frontier consensus data provider with this mechanism. diff --git a/node/src/lib.rs b/node/src/lib.rs index ab4a409e1b..c447a07309 100644 --- a/node/src/lib.rs +++ b/node/src/lib.rs @@ -4,6 +4,5 @@ pub mod client; pub mod conditional_evm_block_import; pub mod consensus; pub mod ethereum; -pub mod mev_shield; pub mod rpc; pub mod service; diff --git a/node/src/main.rs b/node/src/main.rs index 7adffa0ae9..64f25acc67 100644 --- a/node/src/main.rs +++ b/node/src/main.rs @@ -10,7 +10,6 @@ mod command; mod conditional_evm_block_import; mod consensus; mod ethereum; -mod mev_shield; mod rpc; mod service; diff --git a/node/src/mev_shield/author.rs b/node/src/mev_shield/author.rs deleted file mode 100644 index 35f362df3d..0000000000 --- a/node/src/mev_shield/author.rs +++ /dev/null @@ -1,469 +0,0 @@ -use chacha20poly1305::{ - KeyInit, XChaCha20Poly1305, XNonce, - aead::{Aead, Payload}, -}; -use frame_system_rpc_runtime_api::AccountNonceApi; -use ml_kem::{EncodedSizeUser, KemCore, MlKem768}; -use node_subtensor_runtime as runtime; -use rand::rngs::OsRng; -use sp_api::ProvideRuntimeApi; -use sp_core::blake2_256; -use sp_runtime::{AccountId32, KeyTypeId}; -use std::sync::{Arc, Mutex}; -use subtensor_macros::freeze_struct; -use tokio::time::sleep; - -/// Parameters controlling time windows inside the slot. -#[freeze_struct("5c7ce101b36950de")] -#[derive(Clone)] -pub struct TimeParams { - pub slot_ms: u64, - pub announce_at_ms: u64, - pub decrypt_window_ms: u64, -} - -/// Holds the current/next ML‑KEM keypairs and their 32‑byte fingerprints. -#[freeze_struct("5e3c8209248282c3")] -#[derive(Clone)] -pub struct ShieldKeys { - pub current_sk: Vec, // ML‑KEM secret key bytes (encoded form) - pub current_pk: Vec, // ML‑KEM public key bytes (encoded form) - pub current_fp: [u8; 32], // blake2_256(pk) - pub next_sk: Vec, - pub next_pk: Vec, - pub next_fp: [u8; 32], -} - -impl ShieldKeys { - pub fn new() -> Self { - let (sk, pk) = MlKem768::generate(&mut OsRng); - - let sk_bytes = sk.as_bytes(); - let pk_bytes = pk.as_bytes(); - let sk_slice: &[u8] = sk_bytes.as_ref(); - let pk_slice: &[u8] = pk_bytes.as_ref(); - - let current_sk = sk_slice.to_vec(); - let current_pk = pk_slice.to_vec(); - let current_fp = blake2_256(pk_slice); - - let (nsk, npk) = MlKem768::generate(&mut OsRng); - let nsk_bytes = nsk.as_bytes(); - let npk_bytes = npk.as_bytes(); - let nsk_slice: &[u8] = nsk_bytes.as_ref(); - let npk_slice: &[u8] = npk_bytes.as_ref(); - let next_sk = nsk_slice.to_vec(); - let next_pk = npk_slice.to_vec(); - let next_fp = blake2_256(npk_slice); - - Self { - current_sk, - current_pk, - current_fp, - next_sk, - next_pk, - next_fp, - } - } - - pub fn roll_for_next_slot(&mut self) { - // Move next -> current - self.current_sk = core::mem::take(&mut self.next_sk); - self.current_pk = core::mem::take(&mut self.next_pk); - self.current_fp = self.next_fp; - - // Generate fresh next - let (nsk, npk) = MlKem768::generate(&mut OsRng); - let nsk_bytes = nsk.as_bytes(); - let npk_bytes = npk.as_bytes(); - let nsk_slice: &[u8] = nsk_bytes.as_ref(); - let npk_slice: &[u8] = npk_bytes.as_ref(); - self.next_sk = nsk_slice.to_vec(); - self.next_pk = npk_slice.to_vec(); - self.next_fp = blake2_256(npk_slice); - } -} - -impl Default for ShieldKeys { - fn default() -> Self { - Self::new() - } -} - -/// Shared context state. -#[freeze_struct("245b565abca7d403")] -#[derive(Clone)] -pub struct ShieldContext { - pub keys: Arc>, -} - -/// Derive AEAD key directly from the 32‑byte ML‑KEM shared secret. -pub fn derive_aead_key(ss: &[u8]) -> [u8; 32] { - let mut key = [0u8; 32]; - let n = ss.len().min(32); - - if let (Some(dst), Some(src)) = (key.get_mut(..n), ss.get(..n)) { - dst.copy_from_slice(src); - } - key -} - -/// Plain XChaCha20-Poly1305 decrypt helper -pub fn aead_decrypt( - key: [u8; 32], - nonce24: [u8; 24], - ciphertext: &[u8], - aad: &[u8], -) -> Option> { - let aead = XChaCha20Poly1305::new((&key).into()); - aead.decrypt( - XNonce::from_slice(&nonce24), - Payload { - msg: ciphertext, - aad, - }, - ) - .ok() -} - -const AURA_KEY_TYPE: KeyTypeId = KeyTypeId(*b"aura"); - -/// Start background tasks: -/// - per-slot ML‑KEM key rotation -/// - at ~announce_at_ms announce the next key bytes on chain, -pub fn spawn_author_tasks( - task_spawner: &sc_service::SpawnTaskHandle, - client: Arc, - pool: Arc, - keystore: sp_keystore::KeystorePtr, - timing: TimeParams, -) -> ShieldContext -where - B: sp_runtime::traits::Block, - C: sc_client_api::HeaderBackend - + sc_client_api::BlockchainEvents - + ProvideRuntimeApi - + Send - + Sync - + 'static, - C::Api: AccountNonceApi, - Pool: sc_transaction_pool_api::TransactionPool + Send + Sync + 'static, - B::Extrinsic: From, -{ - let ctx = ShieldContext { - keys: Arc::new(Mutex::new(ShieldKeys::new())), - }; - - let aura_keys: Vec = keystore.sr25519_public_keys(AURA_KEY_TYPE); - - let local_aura_pub = match aura_keys.first().copied() { - Some(k) => k, - None => { - log::warn!( - target: "mev-shield", - "spawn_author_tasks: no local Aura sr25519 key in keystore; \ - this node will NOT announce MEV-Shield keys" - ); - return ctx; - } - }; - - let aura_account: AccountId32 = local_aura_pub.into(); - let ctx_clone = ctx.clone(); - let client_clone = client.clone(); - let pool_clone = pool.clone(); - let keystore_clone = keystore.clone(); - - // Slot tick / key-announce loop. - task_spawner.spawn( - "mev-shield-keys-and-announce", - None, - async move { - use futures::StreamExt; - use sp_consensus::BlockOrigin; - - let slot_ms = timing.slot_ms; - - // Clamp announce_at_ms so it never exceeds slot_ms. - let mut announce_at_ms = timing.announce_at_ms; - if announce_at_ms > slot_ms { - log::warn!( - target: "mev-shield", - "spawn_author_tasks: announce_at_ms ({announce_at_ms}) > slot_ms ({slot_ms}); clamping to slot_ms", - ); - announce_at_ms = slot_ms; - } - let tail_ms = slot_ms.saturating_sub(announce_at_ms); - - log::debug!( - target: "mev-shield", - "author timing: slot_ms={slot_ms} announce_at_ms={announce_at_ms} (effective) tail_ms={tail_ms}", - ); - - let mut import_stream = client_clone.import_notification_stream(); - - while let Some(notif) = import_stream.next().await { - // Only act on blocks that this node authored. - if notif.origin != BlockOrigin::Own { - continue; - } - - let (curr_pk_len, next_pk_len) = match ctx_clone.keys.lock() { - Ok(k) => (k.current_pk.len(), k.next_pk.len()), - Err(e) => { - log::debug!( - target: "mev-shield", - "spawn_author_tasks: failed to lock ShieldKeys (poisoned?): {e:?}", - ); - continue; - } - }; - - log::debug!( - target: "mev-shield", - "Slot start (local author): (pk sizes: curr={curr_pk_len}B, next={next_pk_len}B)", - ); - - // Wait until the announce window in this slot. - if announce_at_ms > 0 { - sleep(std::time::Duration::from_millis(announce_at_ms)).await; - } - - // Read the next key we intend to use for the following block. - let next_pk = match ctx_clone.keys.lock() { - Ok(k) => k.next_pk.clone(), - Err(e) => { - log::debug!( - target: "mev-shield", - "spawn_author_tasks: failed to lock ShieldKeys for next_pk: {e:?}", - ); - continue; - } - }; - - // 🔑 Fetch the current on-chain nonce for the Aura account using the best block hash. - let best_hash = client_clone.info().best_hash; - - let nonce: u32 = match client_clone - .runtime_api() - .account_nonce(best_hash, aura_account.clone()) - { - Ok(n) => n, - Err(e) => { - log::debug!( - target: "mev-shield", - "spawn_author_tasks: failed to fetch account nonce for MEV-Shield author: {e:?}", - ); - continue; - } - }; - - // Submit announce_next_key signed with the Aura key using the correct nonce. - if let Err(e) = submit_announce_extrinsic::( - client_clone.clone(), - pool_clone.clone(), - keystore_clone.clone(), - local_aura_pub, - next_pk.clone(), - nonce, - ) - .await - { - log::debug!( - target: "mev-shield", - "announce_next_key submit error (nonce={nonce:?}): {e:?}" - ); - } - - // Sleep the remainder of the slot (if any). - if tail_ms > 0 { - sleep(std::time::Duration::from_millis(tail_ms)).await; - } - - // Roll keys for the next block. - match ctx_clone.keys.lock() { - Ok(mut k) => { - k.roll_for_next_slot(); - log::debug!( - target: "mev-shield", - "Rolled ML-KEM key at slot boundary", - ); - } - Err(e) => { - log::debug!( - target: "mev-shield", - "spawn_author_tasks: failed to lock ShieldKeys for roll_for_next_slot: {e:?}", - ); - } - } - } - }, - ); - - ctx -} - -/// Build & submit the signed `announce_next_key` extrinsic OFF-CHAIN -pub async fn submit_announce_extrinsic( - client: Arc, - pool: Arc, - keystore: sp_keystore::KeystorePtr, - aura_pub: sp_core::sr25519::Public, - next_public_key: Vec, - nonce: u32, -) -> anyhow::Result<()> -where - B: sp_runtime::traits::Block, - C: sc_client_api::HeaderBackend + sp_api::ProvideRuntimeApi + Send + Sync + 'static, - C::Api: sp_api::Core, - Pool: sc_transaction_pool_api::TransactionPool + Send + Sync + 'static, - B::Extrinsic: From, - B::Hash: AsRef<[u8]>, -{ - use node_subtensor_runtime as runtime; - use runtime::{RuntimeCall, SignedPayload, UncheckedExtrinsic}; - - use sc_transaction_pool_api::TransactionSource; - use sp_api::Core as _; - use sp_core::H256; - use sp_runtime::codec::Encode; - use sp_runtime::{ - BoundedVec, MultiSignature, - generic::Era, - traits::{ConstU32, SaturatedConversion, TransactionExtension}, - }; - - fn to_h256>(h: H) -> H256 { - let bytes = h.as_ref(); - let mut out = [0u8; 32]; - - if bytes.is_empty() { - return H256(out); - } - - let n = bytes.len().min(32); - let src_start = bytes.len().saturating_sub(n); - let dst_start = 32usize.saturating_sub(n); - - let src_slice = bytes.get(src_start..).and_then(|s| s.get(..n)); - - if let (Some(dst), Some(src)) = (out.get_mut(dst_start..32), src_slice) { - dst.copy_from_slice(src); - H256(out) - } else { - // Extremely defensive fallback. - H256([0u8; 32]) - } - } - - type MaxPk = ConstU32<2048>; - let public_key: BoundedVec = BoundedVec::try_from(next_public_key) - .map_err(|_| anyhow::anyhow!("public key too long (>2048 bytes)"))?; - - // 1) Runtime call carrying the public key bytes. - let call = RuntimeCall::MevShield(pallet_shield::Call::announce_next_key { public_key }); - - // 2) Build the transaction extensions exactly like the runtime. - type Extra = runtime::TransactionExtensions; - - let info = client.info(); - let at_hash = info.best_hash; - let at_hash_h256: H256 = to_h256(at_hash); - let genesis_h256: H256 = to_h256(info.genesis_hash); - - const ERA_PERIOD: u64 = 12; - 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::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; - - // Try to get the *current* runtime version from on-chain WASM; if that fails, - // fall back to the compiled runtime::VERSION. - let (spec_version, tx_version) = match client.runtime_api().version(at_hash) { - Ok(v) => (v.spec_version, v.transaction_version), - Err(e) => { - log::debug!( - target: "mev-shield", - "runtime_api::version failed at_hash={at_hash:?}: {e:?}; \ - falling back to compiled runtime::VERSION", - ); - ( - runtime::VERSION.spec_version, - runtime::VERSION.transaction_version, - ) - } - }; - - let implicit: Implicit = ( - (), // CheckNonZeroSender - spec_version, // dynamic or fallback spec_version - tx_version, // dynamic or fallback transaction_version - genesis_h256, // CheckGenesis::Implicit = Hash - at_hash_h256, // CheckEra::Implicit = hash of the block the tx is created at - (), // CheckNonce::Implicit = () - (), // CheckWeight::Implicit = () - (), // ChargeTransactionPaymentWrapper::Implicit = () - (), // SudoTransactionExtension::Implicit = () - (), // SubtensorTransactionExtension::Implicit = () - (), // DrandPriority::Implicit = () - None, // CheckMetadataHash::Implicit = Option<[u8; 32]> - ); - - // 4) Build the exact signable payload from call + extra + implicit. - let payload: SignedPayload = SignedPayload::from_raw(call.clone(), extra.clone(), implicit); - - // 5) Sign with the local Aura key using the same SCALE bytes the runtime expects. - let sig_opt = payload - .using_encoded(|bytes| keystore.sr25519_sign(AURA_KEY_TYPE, &aura_pub, bytes)) - .map_err(|e| anyhow::anyhow!("keystore sr25519_sign error: {e:?}"))?; - - let sig = sig_opt - .ok_or_else(|| anyhow::anyhow!("keystore sr25519_sign returned None for Aura key"))?; - - let signature: MultiSignature = sig.into(); - - // 6) Sender address = AccountId32 derived from the Aura sr25519 public key. - let who: AccountId32 = aura_pub.into(); - let address = sp_runtime::MultiAddress::Id(who); - - // 7) Assemble the signed extrinsic and submit it to the pool. - let uxt: UncheckedExtrinsic = UncheckedExtrinsic::new_signed(call, address, signature, extra); - - let xt_bytes = uxt.encode(); - let xt_hash = sp_core::hashing::blake2_256(&xt_bytes); - let xt_hash_hex = hex::encode(xt_hash); - - let opaque: sp_runtime::OpaqueExtrinsic = uxt.into(); - let xt: ::Extrinsic = opaque.into(); - - pool.submit_one(at_hash, TransactionSource::Local, xt) - .await?; - - log::debug!( - target: "mev-shield", - "announce_next_key submitted: xt=0x{xt_hash_hex}, nonce={nonce:?}, \ - spec_version={spec_version}, tx_version={tx_version}, era={era:?}", - ); - - Ok(()) -} diff --git a/node/src/mev_shield/mod.rs b/node/src/mev_shield/mod.rs deleted file mode 100644 index 91817097bf..0000000000 --- a/node/src/mev_shield/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod author; -pub mod proposer; diff --git a/node/src/mev_shield/proposer.rs b/node/src/mev_shield/proposer.rs deleted file mode 100644 index a9a854e362..0000000000 --- a/node/src/mev_shield/proposer.rs +++ /dev/null @@ -1,847 +0,0 @@ -use super::author::ShieldContext; -use futures::StreamExt; -use ml_kem::kem::{Decapsulate, DecapsulationKey}; -use ml_kem::{Ciphertext, Encoded, EncodedSizeUser, MlKem768, MlKem768Params}; -use sc_service::SpawnTaskHandle; -use sc_transaction_pool_api::{TransactionPool, TransactionSource}; -use sp_core::H256; -use sp_runtime::traits::{Header, SaturatedConversion}; -use sp_runtime::{AccountId32, OpaqueExtrinsic}; -use std::{ - collections::HashMap, - sync::{Arc, Mutex}, -}; - -/// Truncate a UTF-8 string to at most `max_bytes` bytes without splitting codepoints. -fn truncate_utf8_to_bytes(s: &str, max_bytes: usize) -> String { - if s.len() <= max_bytes { - return s.to_string(); - } - - let mut end = max_bytes.min(s.len()); - - // Decrement until we find a valid UTF-8 boundary. - while end > 0 { - if let Some(prefix) = s.get(..end) { - return prefix.to_string(); - } - end = end.saturating_sub(1); - } - - // If max_bytes was 0 or we couldn't find a boundary (extremely defensive), return empty. - String::new() -} - -/// Helper to build a `mark_decryption_failed` runtime call with a bounded reason string. -fn create_failed_call(id: H256, reason: &str) -> node_subtensor_runtime::RuntimeCall { - use sp_runtime::BoundedVec; - - let reason_bytes = reason.as_bytes(); - let reason_bounded = BoundedVec::try_from(reason_bytes.to_vec()).unwrap_or_else(|_| { - // Fallback if the reason is too long for the bounded vector. - BoundedVec::try_from(b"Decryption failed".to_vec()).unwrap_or_default() - }); - - node_subtensor_runtime::RuntimeCall::MevShield(pallet_shield::Call::mark_decryption_failed { - id, - reason: reason_bounded, - }) -} - -/// Buffer of wrappers keyed by the block number in which they were included. -#[derive(Default, Clone)] -struct WrapperBuffer { - by_id: HashMap< - H256, - ( - Vec, // ciphertext blob - u64, // originating block number - AccountId32, // wrapper author - ), - >, -} - -impl WrapperBuffer { - fn upsert(&mut self, id: H256, block_number: u64, author: AccountId32, ciphertext: Vec) { - self.by_id.insert(id, (ciphertext, block_number, author)); - } - - /// Drain only wrappers whose `block_number` matches the given `block`. - /// - Wrappers with `block_number > block` are kept for future decrypt passes. - /// - Wrappers with `block_number < block` are considered stale and dropped, and - /// we emit `mark_decryption_failed` calls for them so they are visible on-chain. - fn drain_for_block( - &mut self, - block: u64, - failed_calls: &mut Vec<(H256, node_subtensor_runtime::RuntimeCall)>, - ) -> Vec<(H256, u64, sp_runtime::AccountId32, Vec)> { - let mut ready = Vec::new(); - let mut kept_future: usize = 0; - let mut dropped_past: usize = 0; - - self.by_id.retain(|id, (ct, block_number, who)| { - if *block_number == block { - // Ready to process now; remove from buffer. - ready.push((*id, *block_number, who.clone(), ct.clone())); - false - } else if *block_number > block { - // Not yet reveal time; keep for future blocks. - kept_future = kept_future.saturating_add(1); - true - } else { - // block_number < block => stale / missed decrypt opportunity; drop and mark failed. - dropped_past = dropped_past.saturating_add(1); - log::debug!( - target: "mev-shield", - "revealer: dropping stale wrapper id=0x{} block_number={} < block={}", - hex::encode(id.as_bytes()), - *block_number, - block - ); - - // Mark decryption failed on-chain so clients can observe the missed wrapper. - failed_calls.push(( - *id, - create_failed_call( - *id, - "missed decrypt window (wrapper submitted in an earlier block)", - ), - )); - - false - } - }); - - log::debug!( - target: "mev-shield", - "revealer: drain_for_block(block={}): ready={}, kept_future={}, dropped_past={}", - block, - ready.len(), - kept_future, - dropped_past - ); - - ready - } -} - -/// Start a background worker that: -/// • watches imported blocks and captures `MevShield::submit_encrypted` -/// • buffers those wrappers per originating block, -/// • on each **locally authored** block: decrypt & submit wrappers for that block. -/// -pub fn spawn_revealer( - task_spawner: &SpawnTaskHandle, - client: Arc, - pool: Arc, - ctx: ShieldContext, -) where - B: sp_runtime::traits::Block, - C: sc_client_api::HeaderBackend - + sc_client_api::BlockchainEvents - + sc_client_api::BlockBackend - + Send - + Sync - + 'static, - Pool: TransactionPool + Send + Sync + 'static, -{ - use codec::{Decode, Encode}; - - type Address = sp_runtime::MultiAddress; - type RUnchecked = node_subtensor_runtime::UncheckedExtrinsic; - - let buffer: Arc> = Arc::new(Mutex::new(WrapperBuffer::default())); - - { - let client = Arc::clone(&client); - let pool = Arc::clone(&pool); - let buffer = Arc::clone(&buffer); - let ctx = ctx.clone(); - - task_spawner.spawn( - "mev-shield-block-revealer", - None, - async move { - log::debug!(target: "mev-shield", "Revealer task started"); - let mut import_stream = client.import_notification_stream(); - - while let Some(notif) = import_stream.next().await { - - let at_hash = notif.hash; - let block_number_u64: u64 = (*notif.header.number()).saturated_into(); - - log::debug!( - target: "mev-shield", - "imported block hash={:?} number={} origin={:?}", - at_hash, - block_number_u64, - notif.origin - ); - - // ── 1) buffer wrappers from this (locally authored) block ─────────── - match client.block_body(at_hash) { - Ok(Some(body)) => { - log::debug!( - target: "mev-shield", - " block has {} extrinsics", - body.len() - ); - - for (idx, opaque_xt) in body.into_iter().enumerate() { - let encoded = opaque_xt.encode(); - log::debug!( - target: "mev-shield", - " [xt #{idx}] opaque len={} bytes", - encoded.len() - ); - - let uxt: RUnchecked = match RUnchecked::decode(&mut &encoded[..]) { - Ok(u) => u, - Err(e) => { - log::debug!( - target: "mev-shield", - " [xt #{idx}] failed to decode UncheckedExtrinsic: {e:?}", - ); - continue; - } - }; - - log::debug!( - target: "mev-shield", - " [xt #{idx}] decoded call: {:?}", - &uxt.0.function - ); - - let author_opt: Option = - match &uxt.0.preamble { - sp_runtime::generic::Preamble::Signed( - addr, - _sig, - _ext, - ) => match addr.clone() { - Address::Id(acc) => Some(acc), - Address::Address32(bytes) => { - Some(sp_runtime::AccountId32::new(bytes)) - } - _ => None, - }, - _ => None, - }; - - let Some(author) = author_opt else { - log::debug!( - target: "mev-shield", - " [xt #{idx}] not a Signed(AccountId32) extrinsic; skipping" - ); - continue; - }; - - if let node_subtensor_runtime::RuntimeCall::MevShield( - pallet_shield::Call::submit_encrypted { - commitment, - ciphertext, - }, - ) = &uxt.0.function - { - let payload = - (author.clone(), *commitment, ciphertext).encode(); - let id = H256(sp_core::hashing::blake2_256(&payload)); - - log::debug!( - target: "mev-shield", - " [xt #{idx}] buffered submit_encrypted: id=0x{}, block_number={}, author={}, ct_len={}, commitment={:?}", - hex::encode(id.as_bytes()), - block_number_u64, - author, - ciphertext.len(), - commitment - ); - - if let Ok(mut buf) = buffer.lock() { - buf.upsert( - id, - block_number_u64, - author, - ciphertext.to_vec(), - ); - } else { - log::debug!( - target: "mev-shield", - " [xt #{idx}] failed to lock WrapperBuffer; dropping wrapper" - ); - } - } - } - } - Ok(None) => log::debug!( - target: "mev-shield", - " block_body returned None for hash={at_hash:?}", - ), - Err(e) => log::debug!( - target: "mev-shield", - " block_body error for hash={at_hash:?}: {e:?}", - ), - } - - // ── 2) snapshot current ML‑KEM secret for this block ──────────────── - let snapshot_opt = match ctx.keys.lock() { - Ok(k) => { - let sk_hash = sp_core::hashing::blake2_256(&k.current_sk); - Some(( - k.current_sk.clone(), - k.current_pk.len(), - k.next_pk.len(), - sk_hash, - )) - } - Err(e) => { - log::debug!( - target: "mev-shield", - "revealer: failed to lock ShieldKeys (poisoned?): {e:?}", - ); - None - } - }; - - let (curr_sk_bytes, curr_pk_len, next_pk_len, sk_hash) = match snapshot_opt { - Some(v) => v, - None => { - log::debug!( - target: "mev-shield", - "revealer: Cannot snapshot key for this block", - ); - continue; - } - }; - - // Use this block as the reveal block. - let curr_block: u64 = block_number_u64; - - log::debug!( - target: "mev-shield", - "revealer: decrypt for block {}. sk_len={} sk_hash=0x{} curr_pk_len={} next_pk_len={}", - curr_block, - curr_sk_bytes.len(), - hex::encode(sk_hash), - curr_pk_len, - next_pk_len - ); - - // ── 3) drain & decrypt wrappers for this block ───────────────────── - let mut to_submit: Vec<(H256, node_subtensor_runtime::UncheckedExtrinsic)> = - Vec::new(); - let mut failed_calls: Vec<(H256, node_subtensor_runtime::RuntimeCall)> = - Vec::new(); - - // Only process wrappers whose originating block matches this block. - let drained: Vec<(H256, u64, sp_runtime::AccountId32, Vec)> = - match buffer.lock() { - Ok(mut buf) => buf.drain_for_block(curr_block, &mut failed_calls), - Err(e) => { - log::debug!( - target: "mev-shield", - "revealer: failed to lock WrapperBuffer for drain_for_block: {e:?}", - ); - Vec::new() - } - }; - - log::debug!( - target: "mev-shield", - "revealer: drained {} buffered wrappers for block={}", - drained.len(), - curr_block - ); - - for (id, block_number, author, blob) in drained.into_iter() { - log::debug!( - target: "mev-shield", - "revealer: candidate id=0x{} submitted_in={} (block={}) author={} blob_len={}", - hex::encode(id.as_bytes()), - block_number, - curr_block, - author, - blob.len() - ); - - // Safely parse blob: [u16 kem_len][kem_ct][nonce24][aead_ct] - if blob.len() < 2 { - let error_message = "blob too short to contain kem_len"; - log::debug!( - target: "mev-shield", - " id=0x{}: {}", - hex::encode(id.as_bytes()), - error_message - ); - failed_calls.push((id, create_failed_call(id, error_message))); - continue; - } - - let mut cursor: usize = 0; - - // 1) kem_len (u16 LE) - let kem_len_end = match cursor.checked_add(2usize) { - Some(e) => e, - None => { - let error_message = "kem_len range overflow"; - log::debug!( - target: "mev-shield", - " id=0x{}: {}", - hex::encode(id.as_bytes()), - error_message - ); - failed_calls.push((id, create_failed_call(id, error_message))); - continue; - } - }; - - let kem_len_slice = match blob.get(cursor..kem_len_end) { - Some(s) => s, - None => { - let error_message = "blob too short for kem_len bytes"; - log::debug!( - target: "mev-shield", - " id=0x{}: {} (cursor={} end={})", - hex::encode(id.as_bytes()), - error_message, - cursor, - kem_len_end - ); - failed_calls.push((id, create_failed_call(id, error_message))); - continue; - } - }; - - let kem_len_bytes: [u8; 2] = match kem_len_slice.try_into() { - Ok(arr) => arr, - Err(_) => { - let error_message = "kem_len slice not 2 bytes"; - log::debug!( - target: "mev-shield", - " id=0x{}: {}", - hex::encode(id.as_bytes()), - error_message - ); - failed_calls.push((id, create_failed_call(id, error_message))); - continue; - } - }; - - let kem_len = u16::from_le_bytes(kem_len_bytes) as usize; - cursor = kem_len_end; - - // 2) KEM ciphertext - let kem_ct_end = match cursor.checked_add(kem_len) { - Some(e) => e, - None => { - let error_message = "kem_ct range overflow"; - log::debug!( - target: "mev-shield", - " id=0x{}: {} (cursor={} kem_len={})", - hex::encode(id.as_bytes()), - error_message, - cursor, - kem_len - ); - failed_calls.push((id, create_failed_call(id, error_message))); - continue; - } - }; - - let kem_ct_bytes = match blob.get(cursor..kem_ct_end) { - Some(s) => s, - None => { - let error_message = "blob too short for kem_ct"; - log::debug!( - target: "mev-shield", - " id=0x{}: {} (cursor={} end={})", - hex::encode(id.as_bytes()), - error_message, - cursor, - kem_ct_end - ); - failed_calls.push((id, create_failed_call(id, error_message))); - continue; - } - }; - cursor = kem_ct_end; - - // 3) Nonce (24 bytes) - const NONCE_LEN: usize = 24; - let nonce_end = match cursor.checked_add(NONCE_LEN) { - Some(e) => e, - None => { - let error_message = "nonce range overflow"; - log::debug!( - target: "mev-shield", - " id=0x{}: {} (cursor={})", - hex::encode(id.as_bytes()), - error_message, - cursor - ); - failed_calls.push((id, create_failed_call(id, error_message))); - continue; - } - }; - - let nonce_bytes = match blob.get(cursor..nonce_end) { - Some(s) => s, - None => { - let error_message = "blob too short for nonce24"; - log::debug!( - target: "mev-shield", - " id=0x{}: {} (cursor={} end={})", - hex::encode(id.as_bytes()), - error_message, - cursor, - nonce_end - ); - failed_calls.push((id, create_failed_call(id, error_message))); - continue; - } - }; - cursor = nonce_end; - - // 4) AEAD body (rest) - let aead_body = match blob.get(cursor..) { - Some(s) => s, - None => { - let error_message = "blob too short for aead_body"; - log::debug!( - target: "mev-shield", - " id=0x{}: {} (cursor={})", - hex::encode(id.as_bytes()), - error_message, - cursor - ); - failed_calls.push((id, create_failed_call(id, error_message))); - continue; - } - }; - - let kem_ct_hash = sp_core::hashing::blake2_256(kem_ct_bytes); - let aead_body_hash = sp_core::hashing::blake2_256(aead_body); - - log::debug!( - target: "mev-shield", - " id=0x{}: kem_len={} kem_ct_hash=0x{} nonce=0x{} aead_body_len={} aead_body_hash=0x{}", - hex::encode(id.as_bytes()), - kem_len, - hex::encode(kem_ct_hash), - hex::encode(nonce_bytes), - aead_body.len(), - hex::encode(aead_body_hash), - ); - - // Rebuild DecapsulationKey and decapsulate. - let enc_sk = - match Encoded::>::try_from( - &curr_sk_bytes[..], - ) { - Ok(e) => e, - Err(e) => { - let error_message = "DecapsulationKey::try_from failed"; - log::debug!( - target: "mev-shield", - " id=0x{}: {} (len={}, err={:?})", - hex::encode(id.as_bytes()), - error_message, - curr_sk_bytes.len(), - e - ); - failed_calls.push((id, create_failed_call(id, error_message))); - continue; - } - }; - let sk = DecapsulationKey::::from_bytes(&enc_sk); - - let ct = match Ciphertext::::try_from(kem_ct_bytes) { - Ok(c) => c, - Err(e) => { - let error_message = "Ciphertext::try_from failed"; - log::debug!( - target: "mev-shield", - " id=0x{}: {}: {:?}", - hex::encode(id.as_bytes()), - error_message, - e - ); - failed_calls.push((id, create_failed_call(id, error_message))); - continue; - } - }; - - let ss = match sk.decapsulate(&ct) { - Ok(s) => s, - Err(_) => { - let error_message = "ML-KEM decapsulate failed"; - log::debug!( - target: "mev-shield", - " id=0x{}: {}", - hex::encode(id.as_bytes()), - error_message - ); - failed_calls.push((id, create_failed_call(id, error_message))); - continue; - } - }; - - let ss_bytes: &[u8] = ss.as_ref(); - if ss_bytes.len() != 32 { - let error_message = "shared secret length != 32"; - log::debug!( - target: "mev-shield", - " id=0x{}: {} (len={})", - hex::encode(id.as_bytes()), - error_message, - ss_bytes.len() - ); - failed_calls.push((id, create_failed_call(id, error_message))); - continue; - } - let mut ss32 = [0u8; 32]; - ss32.copy_from_slice(ss_bytes); - - let ss_hash = sp_core::hashing::blake2_256(&ss32); - let aead_key = crate::mev_shield::author::derive_aead_key(&ss32); - let key_hash_dbg = sp_core::hashing::blake2_256(&aead_key); - - log::debug!( - target: "mev-shield", - " id=0x{}: decapsulated shared_secret_len=32 shared_secret_hash=0x{}", - hex::encode(id.as_bytes()), - hex::encode(ss_hash) - ); - log::debug!( - target: "mev-shield", - " id=0x{}: derived AEAD key hash=0x{} (direct-from-ss)", - hex::encode(id.as_bytes()), - hex::encode(key_hash_dbg) - ); - - let mut nonce24 = [0u8; 24]; - nonce24.copy_from_slice(nonce_bytes); - - log::debug!( - target: "mev-shield", - " id=0x{}: attempting AEAD decrypt nonce=0x{} ct_len={}", - hex::encode(id.as_bytes()), - hex::encode(nonce24), - aead_body.len() - ); - - let plaintext = match crate::mev_shield::author::aead_decrypt( - aead_key, - nonce24, - aead_body, - &[], - ) { - Some(pt) => pt, - None => { - let error_message = "AEAD decrypt failed"; - log::debug!( - target: "mev-shield", - " id=0x{}: {}; ct_hash=0x{}", - hex::encode(id.as_bytes()), - error_message, - hex::encode(aead_body_hash), - ); - //failed_calls.push((id, create_failed_call(id, error_message))); - continue; - } - }; - - log::debug!( - target: "mev-shield", - " id=0x{}: AEAD decrypt OK, plaintext_len={}", - hex::encode(id.as_bytes()), - plaintext.len() - ); - - if plaintext.is_empty() { - let error_message = "plaintext too short"; - log::debug!( - target: "mev-shield", - " id=0x{}: {} (len={}, min={})", - hex::encode(id.as_bytes()), - error_message, - plaintext.len(), - 1 - ); - failed_calls.push((id, create_failed_call(id, error_message))); - continue; - } - - let signed_extrinsic_bytes = match plaintext.get(0..plaintext.len()) { - Some(s) if !s.is_empty() => s, - _ => { - let error_message = "missing signed extrinsic bytes"; - log::debug!( - target: "mev-shield", - " id=0x{}: {}", - hex::encode(id.as_bytes()), - error_message - ); - failed_calls.push((id, create_failed_call(id, error_message))); - continue; - } - }; - - let signed_extrinsic: node_subtensor_runtime::UncheckedExtrinsic = - match Decode::decode(&mut &signed_extrinsic_bytes[..]) { - Ok(c) => c, - Err(e) => { - let error_message = "failed to decode UncheckedExtrinsic"; - log::debug!( - target: "mev-shield", - " id=0x{}: {} (len={}): {:?}", - hex::encode(id.as_bytes()), - error_message, - signed_extrinsic_bytes.len(), - e - ); - failed_calls.push((id, create_failed_call(id, error_message))); - continue; - } - }; - - to_submit.push((id, signed_extrinsic)); - } - - // ── 4) submit decrypted extrinsics to pool ────────────────────────── - let at = client.info().best_hash; - log::debug!( - target: "mev-shield", - "revealer: submitting {} extrinsics to pool at best_hash={:?}", - to_submit.len(), - at - ); - - for (id, uxt) in to_submit.into_iter() { - let xt_bytes = uxt.encode(); - - log::debug!( - target: "mev-shield", - " id=0x{}: encoded UncheckedExtrinsic len={}", - hex::encode(id.as_bytes()), - xt_bytes.len() - ); - - match OpaqueExtrinsic::from_bytes(&xt_bytes) { - Ok(opaque) => { - match pool - .submit_one(at, TransactionSource::External, opaque) - .await - { - Ok(_) => { - let xt_hash = - sp_core::hashing::blake2_256(&xt_bytes); - log::debug!( - target: "mev-shield", - " id=0x{}: submit_one(...) OK, xt_hash=0x{}", - hex::encode(id.as_bytes()), - hex::encode(xt_hash) - ); - } - Err(e) => { - // Emit an on-chain failure event even when the *inner* - // transaction fails pre-dispatch validation in the pool. - let err_dbg = format!("{e:?}"); - let reason = truncate_utf8_to_bytes( - &format!( - "inner extrinsic rejected by tx-pool (pre-dispatch): {err_dbg}" - ), - 240, - ); - log::debug!( - target: "mev-shield", - " id=0x{}: submit_one(...) FAILED (will mark_decryption_failed): {:?}", - hex::encode(id.as_bytes()), - e - ); - failed_calls.push((id, create_failed_call(id, &reason))); - } - } - } - Err(e) => { - let err_dbg = format!("{e:?}"); - let reason = truncate_utf8_to_bytes( - &format!( - "invalid decrypted extrinsic bytes (OpaqueExtrinsic::from_bytes): {err_dbg}" - ), - 240, - ); - log::debug!( - target: "mev-shield", - " id=0x{}: OpaqueExtrinsic::from_bytes failed (will mark_decryption_failed): {:?}", - hex::encode(id.as_bytes()), - e - ); - failed_calls.push((id, create_failed_call(id, &reason))); - } - } - } - - // ── 5) submit decryption-failed markers ───────────────────────────── - if !failed_calls.is_empty() { - log::debug!( - target: "mev-shield", - "revealer: submitting {} mark_decryption_failed calls at best_hash={:?}", - failed_calls.len(), - at - ); - - for (id, call) in failed_calls.into_iter() { - let uxt: node_subtensor_runtime::UncheckedExtrinsic = - node_subtensor_runtime::UncheckedExtrinsic::new_bare(call); - let xt_bytes = uxt.encode(); - - log::debug!( - target: "mev-shield", - " id=0x{}: encoded mark_decryption_failed UncheckedExtrinsic len={}", - hex::encode(id.as_bytes()), - xt_bytes.len() - ); - - match OpaqueExtrinsic::from_bytes(&xt_bytes) { - Ok(opaque) => { - match pool - .submit_one(at, TransactionSource::Local, opaque) - .await - { - Ok(_) => { - let xt_hash = - sp_core::hashing::blake2_256(&xt_bytes); - log::debug!( - target: "mev-shield", - " id=0x{}: submit_one(mark_decryption_failed) OK, xt_hash=0x{}", - hex::encode(id.as_bytes()), - hex::encode(xt_hash) - ); - } - Err(e) => { - log::warn!( - target: "mev-shield", - " id=0x{}: submit_one(mark_decryption_failed) FAILED: {:?}", - hex::encode(id.as_bytes()), - e - ); - } - } - } - Err(e) => { - log::warn!( - target: "mev-shield", - " id=0x{}: OpaqueExtrinsic::from_bytes(mark_decryption_failed) failed: {:?}", - hex::encode(id.as_bytes()), - e - ); - } - } - } - } - } - }, - ); - } -} diff --git a/node/src/service.rs b/node/src/service.rs index 7b2ee0e75f..f33931d210 100644 --- a/node/src/service.rs +++ b/node/src/service.rs @@ -21,11 +21,13 @@ use sp_core::crypto::KeyTypeId; use sp_keystore::Keystore; use sp_runtime::key_types; use sp_runtime::traits::{Block as BlockT, NumberFor}; +use stc_shield::{self, MemoryShieldKeystore}; use std::collections::HashSet; use std::str::FromStr; use std::sync::atomic::AtomicBool; use std::{cell::RefCell, path::Path}; use std::{sync::Arc, time::Duration}; +use stp_shield::ShieldKeystorePtr; use substrate_prometheus_endpoint::Registry; use crate::cli::Sealing; @@ -34,7 +36,6 @@ use crate::ethereum::{ BackendType, EthConfiguration, FrontierBackend, FrontierPartialComponents, StorageOverride, StorageOverrideHandler, db_config_dir, new_frontier_partial, spawn_frontier_tasks, }; -use crate::mev_shield::{author, proposer}; const LOG_TARGET: &str = "node-service"; @@ -452,9 +453,12 @@ where prometheus_registry.clone(), )); + let shield_keystore = Arc::new(MemoryShieldKeystore::new()); let slot_duration = consensus_mechanism.slot_duration(&client)?; - let pending_create_inherent_data_providers = - move |_, ()| async move { CM::pending_create_inherent_data_providers(slot_duration) }; + let pending_create_inherent_data_providers = move |_, ()| { + let keystore = shield_keystore.clone(); + async move { CM::pending_create_inherent_data_providers(slot_duration, keystore) } + }; let rpc_methods = consensus_mechanism.rpc_methods( client.clone(), @@ -483,7 +487,8 @@ where fee_history_cache_limit, execute_gas_limit_multiplier, forced_parent_hashes: None, - pending_create_inherent_data_providers, + pending_create_inherent_data_providers: pending_create_inherent_data_providers + .clone(), }; let deps = crate::rpc::FullDeps { client: client.clone(), @@ -535,49 +540,9 @@ where ) .await; - // ==== MEV-SHIELD HOOKS ==== - let mut mev_timing: Option = None; - if role.is_authority() { - let slot_duration = consensus_mechanism.slot_duration(&client)?; - let slot_duration_ms: u64 = u64::try_from(slot_duration.as_millis()).unwrap_or(u64::MAX); - - // For 12s blocks: announce ≈ 7s, decrypt window ≈ 3s. - // For 250ms blocks: announce ≈ 145ms, decrypt window ≈ 62ms, etc. - let announce_at_ms_raw = slot_duration_ms.saturating_mul(7).saturating_div(12); - - let decrypt_window_ms = slot_duration_ms.saturating_mul(3).saturating_div(12); - - // Ensure announce_at_ms + decrypt_window_ms never exceeds slot_ms. - let max_announce = slot_duration_ms.saturating_sub(decrypt_window_ms); - let announce_at_ms = announce_at_ms_raw.min(max_announce); - - let timing = author::TimeParams { - slot_ms: slot_duration_ms, - announce_at_ms, - decrypt_window_ms, - }; - mev_timing = Some(timing.clone()); - - // Start author-side tasks with dynamic timing. - let mev_ctx = author::spawn_author_tasks::( - &task_manager.spawn_handle(), - client.clone(), - transaction_pool.clone(), - keystore_container.keystore(), - timing.clone(), - ); - - // Start last-portion-of-slot revealer (decrypt -> submit_one). - proposer::spawn_revealer::( - &task_manager.spawn_handle(), - client.clone(), - transaction_pool.clone(), - mev_ctx.clone(), - ); - } + let shield_keystore = Arc::new(MemoryShieldKeystore::new()); - if role.is_authority() { // manual-seal authorship if let Some(sealing) = sealing { run_manual_seal_authorship( @@ -590,43 +555,34 @@ where prometheus_registry.as_ref(), telemetry.as_ref(), commands_stream, + shield_keystore.clone(), )?; log::info!("Manual Seal Ready"); return Ok(task_manager); } + stc_shield::spawn_key_rotation_on_own_import( + &task_manager.spawn_handle(), + client.clone(), + shield_keystore.clone(), + ); + let proposer_factory = sc_basic_authorship::ProposerFactory::new( task_manager.spawn_handle(), client.clone(), transaction_pool.clone(), prometheus_registry.as_ref(), telemetry.as_ref().map(|x| x.handle()), + shield_keystore.clone(), ); let slot_duration = consensus_mechanism.slot_duration(&client)?; - let start_fraction: f32 = { - let (slot_ms, decrypt_ms) = mev_timing - .as_ref() - .map(|t| (t.slot_ms, t.decrypt_window_ms)) - .unwrap_or((slot_duration.as_millis(), 3_000)); - - let guard_ms: u64 = 200; // small cushion so reveals hit the pool first - let after_decrypt_ms = slot_ms.saturating_sub(decrypt_ms).saturating_add(guard_ms); - - let f_raw = if slot_ms > 0 { - (after_decrypt_ms as f32) / (slot_ms as f32) - } else { - // Extremely defensive fallback; should never happen in practice. - 0.75 - }; - - f_raw.clamp(0.50, 0.98) + let create_inherent_data_providers = move |_, ()| { + let keystore = shield_keystore.clone(); + async move { CM::create_inherent_data_providers(slot_duration, keystore) } }; - let create_inherent_data_providers = - move |_, ()| async move { CM::create_inherent_data_providers(slot_duration) }; - consensus_mechanism.start_authoring( &mut task_manager, crate::consensus::StartAuthoringParams { @@ -641,7 +597,7 @@ where force_authoring, backoff_authoring_blocks, keystore: keystore_container.keystore(), - block_proposal_slot_portion: SlotProportion::new(start_fraction), + block_proposal_slot_portion: SlotProportion::new(2f32 / 3f32), max_block_proposal_slot_portion: None, telemetry: telemetry.as_ref().map(|x| x.handle()), }, @@ -766,6 +722,7 @@ fn run_manual_seal_authorship( commands_stream: mpsc::Receiver< sc_consensus_manual_seal::rpc::EngineCommand<::Hash>, >, + shield_keystore: ShieldKeystorePtr, ) -> Result<(), ServiceError> { let proposer_factory = sc_basic_authorship::ProposerFactory::new( task_manager.spawn_handle(), @@ -773,6 +730,7 @@ fn run_manual_seal_authorship( transaction_pool.clone(), prometheus_registry, telemetry.as_ref().map(|x| x.handle()), + shield_keystore, ); thread_local!(static TIMESTAMP: RefCell = const { RefCell::new(0) }); diff --git a/pallets/admin-utils/Cargo.toml b/pallets/admin-utils/Cargo.toml index 61cdba4cbf..a97ef6fabc 100644 --- a/pallets/admin-utils/Cargo.toml +++ b/pallets/admin-utils/Cargo.toml @@ -89,6 +89,7 @@ runtime-benchmarks = [ "pallet-preimage/runtime-benchmarks", "pallet-subtensor-swap/runtime-benchmarks", "sp-runtime/runtime-benchmarks", + "subtensor-runtime-common/runtime-benchmarks", ] try-runtime = [ "frame-support/try-runtime", diff --git a/pallets/admin-utils/src/lib.rs b/pallets/admin-utils/src/lib.rs index 532bb50227..7f882fcf9c 100644 --- a/pallets/admin-utils/src/lib.rs +++ b/pallets/admin-utils/src/lib.rs @@ -32,7 +32,7 @@ pub mod pallet { }; use sp_runtime::BoundedVec; use substrate_fixed::types::{I64F64, I96F32, U64F64}; - use subtensor_runtime_common::{MechId, NetUid, TaoCurrency}; + use subtensor_runtime_common::{MechId, NetUid, TaoBalance}; /// The main data structure of the module. #[pallet::pallet] @@ -739,7 +739,7 @@ pub mod pallet { pub fn sudo_set_min_burn( origin: OriginFor, netuid: NetUid, - min_burn: TaoCurrency, + min_burn: TaoBalance, ) -> DispatchResult { let maybe_owner = pallet_subtensor::Pallet::::ensure_sn_owner_or_root_with_limits( origin, @@ -780,7 +780,7 @@ pub mod pallet { pub fn sudo_set_max_burn( origin: OriginFor, netuid: NetUid, - max_burn: TaoCurrency, + max_burn: TaoBalance, ) -> DispatchResult { let maybe_owner = pallet_subtensor::Pallet::::ensure_sn_owner_or_root_with_limits( origin, @@ -1031,7 +1031,7 @@ pub mod pallet { .saturating_add(T::DbWeight::get().writes(1_u64)))] pub fn sudo_set_total_issuance( origin: OriginFor, - total_issuance: TaoCurrency, + total_issuance: TaoBalance, ) -> DispatchResult { ensure_root(origin)?; @@ -1067,7 +1067,7 @@ pub mod pallet { .saturating_add(::DbWeight::get().writes(1)))] pub fn sudo_set_network_min_lock_cost( origin: OriginFor, - lock_cost: TaoCurrency, + lock_cost: TaoBalance, ) -> DispatchResult { ensure_root(origin)?; @@ -1120,7 +1120,7 @@ pub mod pallet { pub fn sudo_set_rao_recycled( origin: OriginFor, netuid: NetUid, - rao_recycled: TaoCurrency, + rao_recycled: TaoBalance, ) -> DispatchResult { ensure_root(origin)?; ensure!( diff --git a/pallets/admin-utils/src/tests/mock.rs b/pallets/admin-utils/src/tests/mock.rs index 2d51ecf105..35f8f6f784 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::{AuthorshipInfo, NetUid, TaoCurrency}; +use subtensor_runtime_common::{AuthorshipInfo, ConstTao, NetUid, TaoBalance}; type Block = frame_system::mocking::MockBlock; // Configure a mock runtime to test the pallet. @@ -65,7 +65,7 @@ pub type Address = AccountId; // Balance of an account. #[allow(dead_code)] -pub type Balance = u64; +pub type Balance = TaoBalance; // An index to a block. #[allow(dead_code)] @@ -89,8 +89,8 @@ parameter_types! { Weight::from_parts(2_000_000_000_000, u64::MAX), Perbill::from_percent(75), ); - pub const ExistentialDeposit: Balance = 1; - pub const TransactionByteFee: Balance = 100; + pub const ExistentialDeposit: Balance = TaoBalance::new(1); + pub const TransactionByteFee: Balance = TaoBalance::new(100); pub const SDebug:u64 = 1; pub const InitialRho: u16 = 30; pub const InitialAlphaSigmoidSteepness: i16 = 1000; @@ -115,15 +115,15 @@ parameter_types! { pub const InitialTxRateLimit: u64 = 0; // Disable rate limit for testing pub const InitialTxDelegateTakeRateLimit: u64 = 0; // Disable rate limit for testing pub const InitialTxChildKeyTakeRateLimit: u64 = 0; // Disable rate limit for testing - pub const InitialBurn: u64 = 0; - pub const InitialMinBurn: u64 = 500_000; - pub const InitialMaxBurn: u64 = 1_000_000_000; - pub const MinBurnUpperBound: TaoCurrency = TaoCurrency::new(1_000_000_000); // 1 TAO - pub const MaxBurnLowerBound: TaoCurrency = TaoCurrency::new(100_000_000); // 0.1 TAO + pub const InitialBurn: TaoBalance = TaoBalance::new(0); + pub const InitialMinBurn: TaoBalance = TaoBalance::new(500_000); + pub const InitialMaxBurn: TaoBalance = TaoBalance::new(1_000_000_000); + pub const MinBurnUpperBound: TaoBalance = TaoBalance::new(1_000_000_000); // 1 TAO + pub const MaxBurnLowerBound: TaoBalance = TaoBalance::new(100_000_000); // 0.1 TAO pub const InitialValidatorPruneLen: u64 = 0; pub const InitialScalingLawPower: u16 = 50; pub const InitialMaxAllowedValidators: u16 = 100; - pub const InitialIssuance: u64 = 0; + pub const InitialIssuance: TaoBalance = TaoBalance::new(0); pub const InitialDifficulty: u64 = 10000; pub const InitialActivityCutoff: u16 = 5000; pub const InitialAdjustmentInterval: u16 = 100; @@ -134,13 +134,13 @@ parameter_types! { pub const InitialRegistrationRequirement: u16 = u16::MAX; // Top 100% pub const InitialMinDifficulty: u64 = 1; pub const InitialMaxDifficulty: u64 = u64::MAX; - pub const InitialRAORecycledForRegistration: u64 = 0; + pub const InitialRAORecycledForRegistration: TaoBalance = TaoBalance::new(0); pub const InitialNetworkImmunityPeriod: u64 = 1_296_000; - pub const InitialNetworkMinLockCost: u64 = 100_000_000_000; + pub const InitialNetworkMinLockCost: TaoBalance = TaoBalance::new(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 InitialNetworkRateLimit: u64 = 0; - pub const InitialKeySwapCost: u64 = 1_000_000_000; + pub const InitialKeySwapCost: TaoBalance = TaoBalance::new(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 @@ -151,7 +151,7 @@ parameter_types! { pub const InitialTaoWeight: u64 = u64::MAX/10; // 10% global weight. pub const InitialEmaPriceHalvingPeriod: u64 = 201_600_u64; // 4 weeks pub const InitialStartCallDelay: u64 = 0; // 0 days - pub const InitialKeySwapOnSubnetCost: u64 = 10_000_000; + pub const InitialKeySwapOnSubnetCost: TaoBalance = TaoBalance::new(10_000_000); pub const HotkeySwapOnSubnetInterval: u64 = 7 * 24 * 60 * 60 / 12; // 7 days pub const LeaseDividendsDistributionInterval: u32 = 100; // 100 blocks pub const MaxImmuneUidsPercentage: Percent = Percent::from_percent(80); @@ -235,8 +235,8 @@ impl pallet_subtensor::Config for Test { parameter_types! { pub const PreimageMaxSize: u32 = 4096 * 1024; - pub const PreimageBaseDeposit: Balance = 1; - pub const PreimageByteDeposit: Balance = 1; + pub const PreimageBaseDeposit: Balance = TaoBalance::new(1); + pub const PreimageByteDeposit: Balance = TaoBalance::new(1); } impl pallet_preimage::Config for Test { @@ -249,8 +249,8 @@ impl pallet_preimage::Config for Test { parameter_types! { pub const CrowdloanPalletId: PalletId = PalletId(*b"bt/cloan"); - pub const MinimumDeposit: u64 = 50; - pub const AbsoluteMinimumContribution: u64 = 10; + pub const MinimumDeposit: TaoBalance = TaoBalance::new(50); + pub const AbsoluteMinimumContribution: TaoBalance = TaoBalance::new(10); pub const MinimumBlockDuration: u64 = 20; pub const MaximumBlockDuration: u64 = 100; pub const RefundContributorsLimit: u32 = 5; @@ -287,7 +287,7 @@ impl system::Config for Test { type BlockHashCount = BlockHashCount; type Version = (); type PalletInfo = PalletInfo; - type AccountData = pallet_balances::AccountData; + type AccountData = pallet_balances::AccountData; type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); @@ -316,10 +316,10 @@ impl pallet_balances::Config for Test { type MaxLocks = (); type MaxReserves = (); type ReserveIdentifier = [u8; 8]; - type Balance = u64; + type Balance = TaoBalance; type RuntimeEvent = RuntimeEvent; type DustRemoval = (); - type ExistentialDeposit = ConstU64<1>; + type ExistentialDeposit = ConstTao<1>; type AccountStore = System; type WeightInfo = (); type FreezeIdentifier = (); diff --git a/pallets/admin-utils/src/tests/mod.rs b/pallets/admin-utils/src/tests/mod.rs index be86489446..7977c69c5f 100644 --- a/pallets/admin-utils/src/tests/mod.rs +++ b/pallets/admin-utils/src/tests/mod.rs @@ -17,7 +17,7 @@ use pallet_subtensor::{ use sp_consensus_grandpa::AuthorityId as GrandpaId; use sp_core::{Get, Pair, U256, ed25519}; use substrate_fixed::types::I96F32; -use subtensor_runtime_common::{Currency, MechId, NetUid, TaoCurrency}; +use subtensor_runtime_common::{MechId, NetUid, TaoBalance, Token}; use crate::Error; use crate::pallet::PrecompileEnable; @@ -397,7 +397,7 @@ fn test_sudo_subnet_owner_cut() { #[test] fn test_sudo_set_issuance() { new_test_ext().execute_with(|| { - let to_be_set = TaoCurrency::from(10); + let to_be_set = TaoBalance::from(10); assert_eq!( AdminUtils::sudo_set_total_issuance( <::RuntimeOrigin>::signed(U256::from(0)), @@ -920,7 +920,7 @@ fn test_sudo_set_bonds_penalty() { fn test_sudo_set_rao_recycled() { new_test_ext().execute_with(|| { let netuid = NetUid::from(1); - let to_be_set = TaoCurrency::from(10); + let to_be_set = TaoBalance::from(10); add_network(netuid, 10); let init_value = SubtensorModule::get_rao_recycled(netuid); @@ -1274,7 +1274,7 @@ fn test_sudo_get_set_alpha() { pallet_subtensor::migrations::migrate_create_root_network::migrate_create_root_network::< Test, >(); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, 1_000_000_000_000_000); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, 1_000_000_000_000_000_u64.into()); assert_ok!(SubtensorModule::root_register(signer.clone(), hotkey,)); // Should fail as signer does not own the subnet @@ -2091,7 +2091,7 @@ fn test_freeze_window_blocks_root_and_owner() { fn test_sudo_set_min_burn() { new_test_ext().execute_with(|| { let netuid = NetUid::from(1); - let to_be_set = TaoCurrency::from(1_000_000); + let to_be_set = TaoBalance::from(1_000_000); add_network(netuid, 10); let init_value = SubtensorModule::get_min_burn(netuid); @@ -2099,7 +2099,7 @@ fn test_sudo_set_min_burn() { assert_ok!(AdminUtils::sudo_set_min_burn( <::RuntimeOrigin>::root(), netuid, - TaoCurrency::from(to_be_set) + TaoBalance::from(to_be_set) )); assert_ne!(SubtensorModule::get_min_burn(netuid), init_value); assert_eq!(SubtensorModule::get_min_burn(netuid), to_be_set); @@ -2109,7 +2109,7 @@ fn test_sudo_set_min_burn() { AdminUtils::sudo_set_min_burn( <::RuntimeOrigin>::root(), NetUid::from(42), - TaoCurrency::from(to_be_set) + TaoBalance::from(to_be_set) ), Error::::SubnetDoesNotExist ); @@ -2119,7 +2119,7 @@ fn test_sudo_set_min_burn() { AdminUtils::sudo_set_min_burn( <::RuntimeOrigin>::signed(U256::from(1)), netuid, - TaoCurrency::from(to_be_set) + TaoBalance::from(to_be_set) ), DispatchError::BadOrigin ); @@ -2327,7 +2327,7 @@ fn test_owner_hyperparam_rate_limit_independent_per_param() { fn test_sudo_set_max_burn() { new_test_ext().execute_with(|| { let netuid = NetUid::from(1); - let to_be_set = TaoCurrency::from(100_000_001); + let to_be_set = TaoBalance::from(100_000_001); add_network(netuid, 10); let init_value = SubtensorModule::get_max_burn(netuid); @@ -2335,7 +2335,7 @@ fn test_sudo_set_max_burn() { assert_ok!(AdminUtils::sudo_set_max_burn( <::RuntimeOrigin>::root(), netuid, - TaoCurrency::from(to_be_set) + TaoBalance::from(to_be_set) )); assert_ne!(SubtensorModule::get_max_burn(netuid), init_value); assert_eq!(SubtensorModule::get_max_burn(netuid), to_be_set); @@ -2345,7 +2345,7 @@ fn test_sudo_set_max_burn() { AdminUtils::sudo_set_max_burn( <::RuntimeOrigin>::root(), NetUid::from(42), - TaoCurrency::from(to_be_set) + TaoBalance::from(to_be_set) ), Error::::SubnetDoesNotExist ); @@ -2355,7 +2355,7 @@ fn test_sudo_set_max_burn() { AdminUtils::sudo_set_max_burn( <::RuntimeOrigin>::signed(U256::from(1)), netuid, - TaoCurrency::from(to_be_set) + TaoBalance::from(to_be_set) ), DispatchError::BadOrigin ); diff --git a/pallets/commitments/Cargo.toml b/pallets/commitments/Cargo.toml index d2873673bc..47bbaec7cd 100644 --- a/pallets/commitments/Cargo.toml +++ b/pallets/commitments/Cargo.toml @@ -73,6 +73,7 @@ runtime-benchmarks = [ "sp-runtime/runtime-benchmarks", "pallet-balances/runtime-benchmarks", "pallet-drand/runtime-benchmarks", + "subtensor-runtime-common/runtime-benchmarks", ] try-runtime = [ "frame-support/try-runtime", diff --git a/pallets/commitments/src/mock.rs b/pallets/commitments/src/mock.rs index 24e259b23c..b5bf07ccf4 100644 --- a/pallets/commitments/src/mock.rs +++ b/pallets/commitments/src/mock.rs @@ -12,6 +12,7 @@ use sp_runtime::{ testing::Header, traits::{BlakeTwo256, ConstU16, IdentityLookup}, }; +use subtensor_runtime_common::{ConstTao, TaoBalance}; pub type Block = sp_runtime::generic::Block; pub type UncheckedExtrinsic = @@ -45,7 +46,7 @@ impl frame_system::Config for Test { type BlockHashCount = ConstU64<250>; type Version = (); type PalletInfo = PalletInfo; - type AccountData = pallet_balances::AccountData; + type AccountData = pallet_balances::AccountData; type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); @@ -61,10 +62,10 @@ impl pallet_balances::Config for Test { type MaxLocks = (); type MaxReserves = (); type ReserveIdentifier = [u8; 8]; - type Balance = u64; + type Balance = TaoBalance; type RuntimeEvent = RuntimeEvent; type DustRemoval = (); - type ExistentialDeposit = ConstU64<1>; + type ExistentialDeposit = ConstTao<1>; type AccountStore = System; type WeightInfo = (); type FreezeIdentifier = (); @@ -99,8 +100,8 @@ impl pallet_commitments::Config for Test { type WeightInfo = (); type MaxFields = TestMaxFields; type CanCommit = TestCanCommit; - type FieldDeposit = ConstU64<0>; - type InitialDeposit = ConstU64<0>; + type FieldDeposit = ConstTao<0>; + type InitialDeposit = ConstTao<0>; type TempoInterface = MockTempoInterface; type OnMetadataCommitment = (); } diff --git a/pallets/commitments/src/tests.rs b/pallets/commitments/src/tests.rs index 9270a84bb7..8050b455fa 100644 --- a/pallets/commitments/src/tests.rs +++ b/pallets/commitments/src/tests.rs @@ -2,7 +2,7 @@ use codec::Encode; use sp_std::prelude::*; -use subtensor_runtime_common::NetUid; +use subtensor_runtime_common::{NetUid, TaoBalance}; #[cfg(test)] use crate::{ @@ -133,7 +133,7 @@ fn set_commitment_works() { let commitment = Pallet::::commitment_of(NetUid::from(1), 1).expect("Expected not to panic"); - let initial_deposit: u64 = ::InitialDeposit::get(); + let initial_deposit = ::InitialDeposit::get(); assert_eq!(commitment.deposit, initial_deposit); assert_eq!(commitment.block, 1); assert_eq!(Pallet::::last_commitment(NetUid::from(1), 1), Some(1)); @@ -179,9 +179,9 @@ fn set_commitment_updates_deposit() { 1.into(), info1 )); - let initial_deposit: u64 = ::InitialDeposit::get(); - let field_deposit: u64 = ::FieldDeposit::get(); - let expected_deposit1: u64 = initial_deposit + 2u64 * field_deposit; + let initial_deposit = ::InitialDeposit::get(); + let field_deposit = ::FieldDeposit::get(); + let expected_deposit1 = initial_deposit + field_deposit * 2.into(); assert_eq!( Pallet::::commitment_of(NetUid::from(1), 1) .expect("Expected not to panic") @@ -194,7 +194,7 @@ fn set_commitment_updates_deposit() { 1.into(), info2 )); - let expected_deposit2: u64 = initial_deposit + 3u64 * field_deposit; + let expected_deposit2 = initial_deposit + field_deposit * 3.into(); assert_eq!( Pallet::::commitment_of(NetUid::from(1), 1) .expect("Expected not to panic") @@ -1169,13 +1169,13 @@ fn set_commitment_unreserve_leftover_fails() { let netuid = NetUid::from(999); let who = 99; - Balances::make_free_balance_be(&who, 10_000); + Balances::make_free_balance_be(&who, 10_000.into()); - let fake_deposit = 100; - let dummy_info = CommitmentInfo { + let fake_deposit: TaoBalance = 100.into(); + let dummy_info = CommitmentInfo:: { fields: BoundedVec::try_from(vec![]).expect("empty fields is fine"), }; - let registration = Registration { + let registration = Registration:: { deposit: fake_deposit, info: dummy_info, block: 0u64.into(), @@ -1184,10 +1184,10 @@ fn set_commitment_unreserve_leftover_fails() { CommitmentOf::::insert(netuid, who, registration); assert_ok!(Balances::reserve(&who, fake_deposit)); - assert_eq!(Balances::reserved_balance(who), 100); + assert_eq!(Balances::reserved_balance(who), 100.into()); - Balances::unreserve(&who, 10_000); - assert_eq!(Balances::reserved_balance(who), 0); + Balances::unreserve(&who, 10_000.into()); + assert_eq!(Balances::reserved_balance(who), 0.into()); let commit_small = Box::new(CommitmentInfo { fields: BoundedVec::try_from(vec![]).expect("no fields is fine"), @@ -1775,7 +1775,7 @@ fn set_commitment_works_with_multiple_raw_fields() { Box::new(info_multiple) )); - let expected_deposit: BalanceOf = initial_deposit + 3u64 * field_deposit; + let expected_deposit: BalanceOf = initial_deposit + field_deposit * 3u64.into(); let stored = CommitmentOf::::get(NetUid::from(99), 12345).expect("Should be stored"); assert_eq!( stored.deposit, expected_deposit, @@ -1805,7 +1805,7 @@ fn set_commitment_works_with_multiple_raw_fields() { Box::new(info_two_fields) )); - let expected_deposit2: BalanceOf = initial_deposit + 2u64 * field_deposit; + let expected_deposit2: BalanceOf = initial_deposit + field_deposit * 2u64.into(); let stored2 = CommitmentOf::::get(NetUid::from(99), 12345).expect("Should be stored"); assert_eq!( stored2.deposit, expected_deposit2, diff --git a/pallets/crowdloan/Cargo.toml b/pallets/crowdloan/Cargo.toml index dcde4504f4..1bba723fe2 100644 --- a/pallets/crowdloan/Cargo.toml +++ b/pallets/crowdloan/Cargo.toml @@ -19,9 +19,10 @@ codec = { workspace = true, features = ["max-encoded-len"] } frame-benchmarking = { optional = true, workspace = true } frame-support.workspace = true frame-system.workspace = true +log.workspace = true sp-runtime.workspace = true sp-std.workspace = true -log.workspace = true +subtensor-runtime-common.workspace = true [dev-dependencies] pallet-balances = { workspace = true, default-features = true } @@ -42,6 +43,7 @@ std = [ "sp-io/std", "log/std", "sp-core/std", + "subtensor-runtime-common/std", "pallet-balances/std", "pallet-preimage/std", ] @@ -50,6 +52,7 @@ runtime-benchmarks = [ "frame-support/runtime-benchmarks", "frame-system/runtime-benchmarks", "sp-runtime/runtime-benchmarks", + "subtensor-runtime-common/runtime-benchmarks", "pallet-balances/runtime-benchmarks", "pallet-preimage/runtime-benchmarks", ] diff --git a/pallets/crowdloan/src/benchmarking.rs b/pallets/crowdloan/src/benchmarking.rs index a0e59de221..84283a09c7 100644 --- a/pallets/crowdloan/src/benchmarking.rs +++ b/pallets/crowdloan/src/benchmarking.rs @@ -9,6 +9,7 @@ use crate::{BalanceOf, CrowdloanId, CrowdloanInfo, CurrencyOf, pallet::*}; use frame_benchmarking::{account, v2::*}; use frame_support::traits::{Get, StorePreimage, fungible::*}; use frame_system::{RawOrigin, pallet_prelude::BlockNumberFor}; +use subtensor_runtime_common::{TaoBalance, Token}; extern crate alloc; @@ -74,7 +75,7 @@ mod benchmarks { }) ); // ensure the creator has been deducted the deposit - assert!(CurrencyOf::::balance(&creator) == 0); + assert!(CurrencyOf::::balance(&creator) == TaoBalance::ZERO); // ensure the initial deposit is stored correctly as contribution assert_eq!( Contributions::::get(crowdloan_id, &creator), @@ -136,7 +137,7 @@ mod benchmarks { Some(amount) ); // ensure the contributor has been deducted the amount - assert!(CurrencyOf::::balance(&contributor) == 0); + assert!(CurrencyOf::::balance(&contributor) == TaoBalance::ZERO); // ensure the crowdloan raised amount is updated correctly assert!(Crowdloans::::get(crowdloan_id).is_some_and(|c| c.raised == deposit + amount)); // ensure the contribution is present in the crowdloan account @@ -310,7 +311,7 @@ mod benchmarks { _(RawOrigin::Signed(creator.clone()), crowdloan_id); // ensure the creator has not been refunded and contribution is the actual initial deposit - assert_eq!(CurrencyOf::::balance(&creator), 0); + assert_eq!(CurrencyOf::::balance(&creator), TaoBalance::ZERO); assert_eq!( Contributions::::get(crowdloan_id, &creator), Some(deposit) diff --git a/pallets/crowdloan/src/lib.rs b/pallets/crowdloan/src/lib.rs index 82b1402bc6..ae8c8742a0 100644 --- a/pallets/crowdloan/src/lib.rs +++ b/pallets/crowdloan/src/lib.rs @@ -14,7 +14,7 @@ use frame_support::{ dispatch::GetDispatchInfo, pallet_prelude::*, sp_runtime::{ - RuntimeDebug, + RuntimeDebug, Saturating, traits::{AccountIdConversion, Dispatchable, Zero}, }, traits::{ @@ -26,6 +26,7 @@ use frame_system::pallet_prelude::*; use scale_info::TypeInfo; use sp_runtime::traits::CheckedSub; use sp_std::vec::Vec; +use subtensor_runtime_common::TaoBalance; use weights::WeightInfo; pub use pallet::*; @@ -107,7 +108,7 @@ pub mod pallet { + IsType<::RuntimeCall>; /// The currency mechanism. - type Currency: fungible::Balanced + type Currency: fungible::Balanced + fungible::Mutate; /// The weight information for the pallet. @@ -440,7 +441,7 @@ pub mod pallet { // and it does not exceed the cap let left_to_raise = crowdloan .cap - .checked_sub(crowdloan.raised) + .checked_sub(&crowdloan.raised) .ok_or(Error::::Underflow)?; // If the contribution would raise the amount above the cap, @@ -450,7 +451,7 @@ pub mod pallet { // Ensure contribution does not overflow the actual raised amount crowdloan.raised = crowdloan .raised - .checked_add(amount) + .checked_add(&amount) .ok_or(Error::::Overflow)?; // Compute the new total contribution and ensure it does not overflow, we @@ -458,7 +459,7 @@ pub mod pallet { let contribution = if let Some(contribution) = Contributions::::get(crowdloan_id, &contributor) { contribution - .checked_add(amount) + .checked_add(&amount) .ok_or(Error::::Overflow)? } else { // We have a new contribution diff --git a/pallets/crowdloan/src/migrations/migrate_add_contributors_count.rs b/pallets/crowdloan/src/migrations/migrate_add_contributors_count.rs index 5d76aa60e5..604e99d4e3 100644 --- a/pallets/crowdloan/src/migrations/migrate_add_contributors_count.rs +++ b/pallets/crowdloan/src/migrations/migrate_add_contributors_count.rs @@ -170,6 +170,7 @@ mod tests { put_raw(&key, &crowdloan.encode()); for (contributor, amount) in contributions { + let amount = TaoBalance::from(amount); Contributions::::insert(id as u32, contributor, amount); } } diff --git a/pallets/crowdloan/src/mock.rs b/pallets/crowdloan/src/mock.rs index fa2f5533d2..0cfd9cfafc 100644 --- a/pallets/crowdloan/src/mock.rs +++ b/pallets/crowdloan/src/mock.rs @@ -12,6 +12,7 @@ use frame_support::{ use frame_system::{EnsureRoot, pallet_prelude::BlockNumberFor}; use sp_core::U256; use sp_runtime::{BuildStorage, traits::IdentityLookup}; +use subtensor_runtime_common::TaoBalance; use crate::{BalanceOf, CrowdloanId, pallet as pallet_crowdloan, weights::WeightInfo}; @@ -36,11 +37,11 @@ pub(crate) fn new_test_ext() -> sp_io::TestExternalities { .expect("Expected to not panic"); pallet_balances::GenesisConfig:: { balances: vec![ - (U256::from(1), 10), - (U256::from(2), 10), - (U256::from(3), 10), - (U256::from(4), 10), - (U256::from(5), 3), + (U256::from(1), 10.into()), + (U256::from(2), 10.into()), + (U256::from(3), 10.into()), + (U256::from(4), 10.into()), + (U256::from(5), 3.into()), ], dev_accounts: None, } @@ -55,13 +56,23 @@ pub(crate) fn new_test_ext() -> sp_io::TestExternalities { impl frame_system::Config for Test { type Block = Block; type AccountId = U256; - type AccountData = pallet_balances::AccountData; + type AccountData = pallet_balances::AccountData; type Lookup = IdentityLookup; } +// Existential deposit. +pub struct ExistentialDeposit; +impl frame_support::traits::Get for ExistentialDeposit { + fn get() -> TaoBalance { + TaoBalance::new(1) + } +} + #[derive_impl(pallet_balances::config_preludes::TestDefaultConfig)] impl pallet_balances::Config for Test { type AccountStore = System; + type Balance = TaoBalance; + type ExistentialDeposit = ExistentialDeposit; } pub struct TestWeightInfo; @@ -97,8 +108,8 @@ impl WeightInfo for TestWeightInfo { parameter_types! { pub const PreimageMaxSize: u32 = 4096 * 1024; - pub const PreimageBaseDeposit: u64 = 1; - pub const PreimageByteDeposit: u64 = 1; + pub const PreimageBaseDeposit: TaoBalance = TaoBalance::new(1); + pub const PreimageByteDeposit: TaoBalance = TaoBalance::new(1); } impl pallet_preimage::Config for Test { @@ -111,8 +122,8 @@ impl pallet_preimage::Config for Test { parameter_types! { pub const CrowdloanPalletId: PalletId = PalletId(*b"bt/cloan"); - pub const MinimumDeposit: u64 = 50; - pub const AbsoluteMinimumContribution: u64 = 10; + pub const MinimumDeposit: TaoBalance = TaoBalance::new(50); + pub const AbsoluteMinimumContribution: TaoBalance = TaoBalance::new(10); pub const MinimumBlockDuration: u64 = 20; pub const MaximumBlockDuration: u64 = 100; pub const RefundContributorsLimit: u32 = 5; @@ -143,13 +154,14 @@ pub(crate) mod pallet_test { pallet_prelude::{OptionQuery, StorageValue}, }; use frame_system::pallet_prelude::OriginFor; + use subtensor_runtime_common::TaoBalance; #[pallet::pallet] pub struct Pallet(_); #[pallet::config] pub trait Config: frame_system::Config + pallet_crowdloan::Config { - type Currency: fungible::Balanced + type Currency: fungible::Balanced + fungible::Mutate; } diff --git a/pallets/crowdloan/src/tests.rs b/pallets/crowdloan/src/tests.rs index 67d097e1e1..8a706ece29 100644 --- a/pallets/crowdloan/src/tests.rs +++ b/pallets/crowdloan/src/tests.rs @@ -5,18 +5,19 @@ use frame_support::{StorageDoubleMap, assert_err, assert_ok, traits::StorePreima use frame_system::pallet_prelude::BlockNumberFor; use sp_core::U256; use sp_runtime::DispatchError; +use subtensor_runtime_common::TaoBalance; use crate::{BalanceOf, CrowdloanId, CrowdloanInfo, mock::*, pallet as pallet_crowdloan}; #[test] fn test_create_succeeds() { TestState::default() - .with_balance(U256::from(1), 100) + .with_balance(U256::from(1), 100.into()) .build_and_execute(|| { let creator: AccountOf = U256::from(1); - let deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 300; + let deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 300.into(); let end: BlockNumberFor = 50; assert_ok!(Crowdloan::create( @@ -52,7 +53,10 @@ fn test_create_succeeds() { // ensure the crowdloan account has the deposit assert_eq!(Balances::free_balance(funds_account), deposit); // ensure the creator has been deducted the deposit - assert_eq!(Balances::free_balance(creator), 100 - deposit); + assert_eq!( + Balances::free_balance(creator), + TaoBalance::from(100) - deposit + ); // ensure the contributions have been updated assert_eq!( pallet_crowdloan::Contributions::::iter_prefix(crowdloan_id) @@ -86,9 +90,9 @@ fn test_create_succeeds() { #[test] fn test_create_fails_if_bad_origin() { TestState::default().build_and_execute(|| { - let deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 300; + let deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 300.into(); let end: BlockNumberFor = 50; assert_err!( @@ -122,12 +126,12 @@ fn test_create_fails_if_bad_origin() { #[test] fn test_create_fails_if_deposit_is_too_low() { TestState::default() - .with_balance(U256::from(1), 100) + .with_balance(U256::from(1), 100.into()) .build_and_execute(|| { let creator: AccountOf = U256::from(1); - let deposit: BalanceOf = 20; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 300; + let deposit: BalanceOf = 20.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 300.into(); let end: BlockNumberFor = 50; assert_err!( @@ -148,12 +152,12 @@ fn test_create_fails_if_deposit_is_too_low() { #[test] fn test_create_fails_if_cap_is_not_greater_than_deposit() { TestState::default() - .with_balance(U256::from(1), 100) + .with_balance(U256::from(1), 100.into()) .build_and_execute(|| { let creator: AccountOf = U256::from(1); - let deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 40; + let deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 40.into(); let end: BlockNumberFor = 50; assert_err!( @@ -174,12 +178,12 @@ fn test_create_fails_if_cap_is_not_greater_than_deposit() { #[test] fn test_create_fails_if_min_contribution_is_too_low() { TestState::default() - .with_balance(U256::from(1), 100) + .with_balance(U256::from(1), 100.into()) .build_and_execute(|| { let creator: AccountOf = U256::from(1); - let deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 5; - let cap: BalanceOf = 300; + let deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 5.into(); + let cap: BalanceOf = 300.into(); let end: BlockNumberFor = 50; assert_err!( @@ -203,12 +207,12 @@ fn test_create_fails_if_end_is_in_the_past() { TestState::default() .with_block_number(current_block_number) - .with_balance(U256::from(1), 100) + .with_balance(U256::from(1), 100.into()) .build_and_execute(|| { let creator: AccountOf = U256::from(1); - let deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 300; + let deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 300.into(); let end: BlockNumberFor = current_block_number - 5; assert_err!( @@ -229,12 +233,12 @@ fn test_create_fails_if_end_is_in_the_past() { #[test] fn test_create_fails_if_block_duration_is_too_short() { TestState::default() - .with_balance(U256::from(1), 100) + .with_balance(U256::from(1), 100.into()) .build_and_execute(|| { let creator: AccountOf = U256::from(1); - let deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 300; + let deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 300.into(); let end: BlockNumberFor = 11; assert_err!( @@ -255,12 +259,12 @@ fn test_create_fails_if_block_duration_is_too_short() { #[test] fn test_create_fails_if_block_duration_is_too_long() { TestState::default() - .with_balance(U256::from(1), 100) + .with_balance(U256::from(1), 100.into()) .build_and_execute(|| { let creator: AccountOf = U256::from(1); - let deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 300; + let deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 300.into(); let end: BlockNumberFor = 1000; assert_err!( @@ -281,12 +285,12 @@ fn test_create_fails_if_block_duration_is_too_long() { #[test] fn test_create_fails_if_creator_has_insufficient_balance() { TestState::default() - .with_balance(U256::from(1), 100) + .with_balance(U256::from(1), 100.into()) .build_and_execute(|| { let creator: AccountOf = U256::from(1); - let deposit: BalanceOf = 200; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 300; + let deposit: BalanceOf = 200.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 300.into(); let end: BlockNumberFor = 50; assert_err!( @@ -307,15 +311,15 @@ fn test_create_fails_if_creator_has_insufficient_balance() { #[test] fn test_contribute_succeeds() { TestState::default() - .with_balance(U256::from(1), 200) - .with_balance(U256::from(2), 500) - .with_balance(U256::from(3), 200) + .with_balance(U256::from(1), 200.into()) + .with_balance(U256::from(2), 500.into()) + .with_balance(U256::from(3), 200.into()) .build_and_execute(|| { // create a crowdloan let creator: AccountOf = U256::from(1); - let initial_deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 300; + let initial_deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 300.into(); let end: BlockNumberFor = 50; assert_ok!(Crowdloan::create( @@ -340,7 +344,7 @@ fn test_contribute_succeeds() { ); // first contribution to the crowdloan from creator - let amount: BalanceOf = 50; + let amount: BalanceOf = 50.into(); assert_ok!(Crowdloan::contribute( RuntimeOrigin::signed(creator), crowdloan_id, @@ -357,7 +361,7 @@ fn test_contribute_succeeds() { ); assert_eq!( pallet_crowdloan::Contributions::::get(crowdloan_id, creator), - Some(100) + Some(100.into()) ); assert!( pallet_crowdloan::Crowdloans::::get(crowdloan_id) @@ -365,12 +369,12 @@ fn test_contribute_succeeds() { ); assert_eq!( Balances::free_balance(creator), - 200 - amount - initial_deposit + TaoBalance::from(200) - amount - initial_deposit ); // second contribution to the crowdloan let contributor1: AccountOf = U256::from(2); - let amount: BalanceOf = 100; + let amount: BalanceOf = 100.into(); assert_ok!(Crowdloan::contribute( RuntimeOrigin::signed(contributor1), crowdloan_id, @@ -387,17 +391,20 @@ fn test_contribute_succeeds() { ); assert_eq!( pallet_crowdloan::Contributions::::get(crowdloan_id, contributor1), - Some(100) + Some(100.into()) ); assert!( pallet_crowdloan::Crowdloans::::get(crowdloan_id) .is_some_and(|c| c.contributors_count == 2) ); - assert_eq!(Balances::free_balance(contributor1), 500 - amount); + assert_eq!( + Balances::free_balance(contributor1), + TaoBalance::from(500) - amount + ); // third contribution to the crowdloan let contributor2: AccountOf = U256::from(3); - let amount: BalanceOf = 50; + let amount: BalanceOf = 50.into(); assert_ok!(Crowdloan::contribute( RuntimeOrigin::signed(contributor2), crowdloan_id, @@ -414,22 +421,25 @@ fn test_contribute_succeeds() { ); assert_eq!( pallet_crowdloan::Contributions::::get(crowdloan_id, contributor2), - Some(50) + Some(50.into()) ); assert!( pallet_crowdloan::Crowdloans::::get(crowdloan_id) .is_some_and(|c| c.contributors_count == 3) ); - assert_eq!(Balances::free_balance(contributor2), 200 - amount); + assert_eq!( + Balances::free_balance(contributor2), + TaoBalance::from(200) - amount + ); // ensure the contributions are present in the funds account let funds_account = pallet_crowdloan::Pallet::::funds_account(crowdloan_id); - assert_eq!(Balances::free_balance(funds_account), 250); + assert_eq!(Balances::free_balance(funds_account), 250.into()); // ensure the crowdloan raised amount is updated correctly assert!( pallet_crowdloan::Crowdloans::::get(crowdloan_id) - .is_some_and(|c| c.raised == 250) + .is_some_and(|c| c.raised == 250.into()) ); }); } @@ -437,14 +447,14 @@ fn test_contribute_succeeds() { #[test] fn test_contribute_succeeds_if_contribution_will_make_the_raised_amount_exceed_the_cap() { TestState::default() - .with_balance(U256::from(1), 200) - .with_balance(U256::from(2), 500) + .with_balance(U256::from(1), 200.into()) + .with_balance(U256::from(2), 500.into()) .build_and_execute(|| { // create a crowdloan let creator: AccountOf = U256::from(1); - let initial_deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 300; + let initial_deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 300.into(); let end: BlockNumberFor = 50; assert_ok!(Crowdloan::create( @@ -462,7 +472,7 @@ fn test_contribute_succeeds_if_contribution_will_make_the_raised_amount_exceed_t // first contribution to the crowdloan from creator let crowdloan_id: CrowdloanId = 0; - let amount: BalanceOf = 50; + let amount: BalanceOf = 50.into(); assert_ok!(Crowdloan::contribute( RuntimeOrigin::signed(creator), crowdloan_id, @@ -479,16 +489,16 @@ fn test_contribute_succeeds_if_contribution_will_make_the_raised_amount_exceed_t ); assert_eq!( pallet_crowdloan::Contributions::::get(crowdloan_id, creator), - Some(100) + Some(100.into()) ); assert_eq!( Balances::free_balance(creator), - 200 - amount - initial_deposit + TaoBalance::from(200) - amount - initial_deposit ); // second contribution to the crowdloan above the cap let contributor1: AccountOf = U256::from(2); - let amount: BalanceOf = 300; + let amount: BalanceOf = 300.into(); assert_ok!(Crowdloan::contribute( RuntimeOrigin::signed(contributor1), crowdloan_id, @@ -499,24 +509,24 @@ fn test_contribute_succeeds_if_contribution_will_make_the_raised_amount_exceed_t pallet_crowdloan::Event::::Contributed { crowdloan_id, contributor: contributor1, - amount: 200, // the amount is capped at the cap + amount: 200.into(), // the amount is capped at the cap } .into() ); assert_eq!( pallet_crowdloan::Contributions::::get(crowdloan_id, contributor1), - Some(200) + Some(200.into()) ); - assert_eq!(Balances::free_balance(contributor1), 500 - 200); + assert_eq!(Balances::free_balance(contributor1), (500 - 200).into()); // ensure the contributions are present in the crowdloan account up to the cap let funds_account = pallet_crowdloan::Pallet::::funds_account(crowdloan_id); - assert_eq!(Balances::free_balance(funds_account), 300); + assert_eq!(Balances::free_balance(funds_account), 300.into()); // ensure the crowdloan raised amount is updated correctly assert!( pallet_crowdloan::Crowdloans::::get(crowdloan_id) - .is_some_and(|c| c.raised == 300) + .is_some_and(|c| c.raised == 300.into()) ); }); } @@ -525,7 +535,7 @@ fn test_contribute_succeeds_if_contribution_will_make_the_raised_amount_exceed_t fn test_contribute_fails_if_bad_origin() { TestState::default().build_and_execute(|| { let crowdloan_id: CrowdloanId = 0; - let amount: BalanceOf = 100; + let amount: BalanceOf = 100.into(); assert_err!( Crowdloan::contribute(RuntimeOrigin::none(), crowdloan_id, amount), @@ -542,11 +552,11 @@ fn test_contribute_fails_if_bad_origin() { #[test] fn test_contribute_fails_if_crowdloan_does_not_exist() { TestState::default() - .with_balance(U256::from(1), 100) + .with_balance(U256::from(1), 100.into()) .build_and_execute(|| { let contributor: AccountOf = U256::from(1); let crowdloan_id: CrowdloanId = 0; - let amount: BalanceOf = 20; + let amount: BalanceOf = 20.into(); assert_err!( Crowdloan::contribute(RuntimeOrigin::signed(contributor), crowdloan_id, amount), @@ -558,14 +568,14 @@ fn test_contribute_fails_if_crowdloan_does_not_exist() { #[test] fn test_contribute_fails_if_contribution_period_ended() { TestState::default() - .with_balance(U256::from(1), 100) - .with_balance(U256::from(2), 100) + .with_balance(U256::from(1), 100.into()) + .with_balance(U256::from(2), 100.into()) .build_and_execute(|| { // create a crowdloan let creator: AccountOf = U256::from(1); - let initial_deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 300; + let initial_deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 300.into(); let end: BlockNumberFor = 50; assert_ok!(Crowdloan::create( @@ -584,7 +594,7 @@ fn test_contribute_fails_if_contribution_period_ended() { // contribute to the crowdloan let contributor: AccountOf = U256::from(2); let crowdloan_id: CrowdloanId = 0; - let amount: BalanceOf = 20; + let amount: BalanceOf = 20.into(); assert_err!( Crowdloan::contribute(RuntimeOrigin::signed(contributor), crowdloan_id, amount), pallet_crowdloan::Error::::ContributionPeriodEnded @@ -595,15 +605,15 @@ fn test_contribute_fails_if_contribution_period_ended() { #[test] fn test_contribute_fails_if_cap_has_been_raised() { TestState::default() - .with_balance(U256::from(1), 100) - .with_balance(U256::from(2), 1000) - .with_balance(U256::from(3), 100) + .with_balance(U256::from(1), 100.into()) + .with_balance(U256::from(2), 1000.into()) + .with_balance(U256::from(3), 100.into()) .build_and_execute(|| { // create a crowdloan let creator: AccountOf = U256::from(1); - let initial_deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 300; + let initial_deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 300.into(); let end: BlockNumberFor = 50; assert_ok!(Crowdloan::create( @@ -631,7 +641,7 @@ fn test_contribute_fails_if_cap_has_been_raised() { // second contribution to the crowdloan let contributor2: AccountOf = U256::from(3); - let amount: BalanceOf = 10; + let amount: BalanceOf = 10.into(); assert_err!( Crowdloan::contribute(RuntimeOrigin::signed(contributor2), crowdloan_id, amount), pallet_crowdloan::Error::::CapRaised @@ -642,14 +652,14 @@ fn test_contribute_fails_if_cap_has_been_raised() { #[test] fn test_contribute_fails_if_contribution_is_below_minimum_contribution() { TestState::default() - .with_balance(U256::from(1), 100) - .with_balance(U256::from(2), 100) + .with_balance(U256::from(1), 100.into()) + .with_balance(U256::from(2), 100.into()) .build_and_execute(|| { // create a crowdloan let creator: AccountOf = U256::from(1); - let initial_deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 300; + let initial_deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 300.into(); let end: BlockNumberFor = 50; assert_ok!(Crowdloan::create( @@ -668,7 +678,7 @@ fn test_contribute_fails_if_contribution_is_below_minimum_contribution() { // contribute to the crowdloan let contributor: AccountOf = U256::from(2); let crowdloan_id: CrowdloanId = 0; - let amount: BalanceOf = 5; + let amount: BalanceOf = 5.into(); assert_err!( Crowdloan::contribute(RuntimeOrigin::signed(contributor), crowdloan_id, amount), pallet_crowdloan::Error::::ContributionTooLow @@ -679,23 +689,23 @@ fn test_contribute_fails_if_contribution_is_below_minimum_contribution() { #[test] fn test_contribute_fails_if_max_contributors_has_been_reached() { TestState::default() - .with_balance(U256::from(1), 100) - .with_balance(U256::from(2), 100) - .with_balance(U256::from(3), 100) - .with_balance(U256::from(4), 100) - .with_balance(U256::from(5), 100) - .with_balance(U256::from(6), 100) - .with_balance(U256::from(7), 100) - .with_balance(U256::from(8), 100) - .with_balance(U256::from(9), 100) - .with_balance(U256::from(10), 100) - .with_balance(U256::from(11), 100) + .with_balance(U256::from(1), 100.into()) + .with_balance(U256::from(2), 100.into()) + .with_balance(U256::from(3), 100.into()) + .with_balance(U256::from(4), 100.into()) + .with_balance(U256::from(5), 100.into()) + .with_balance(U256::from(6), 100.into()) + .with_balance(U256::from(7), 100.into()) + .with_balance(U256::from(8), 100.into()) + .with_balance(U256::from(9), 100.into()) + .with_balance(U256::from(10), 100.into()) + .with_balance(U256::from(11), 100.into()) .build_and_execute(|| { // create a crowdloan let creator: AccountOf = U256::from(1); - let initial_deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 1000; + let initial_deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 1000.into(); let end: BlockNumberFor = 50; assert_ok!(Crowdloan::create( @@ -713,7 +723,7 @@ fn test_contribute_fails_if_max_contributors_has_been_reached() { // contribute to the crowdloan let crowdloan_id: CrowdloanId = 0; - let amount: BalanceOf = 20; + let amount: BalanceOf = 20.into(); for i in 2..=10 { let contributor: AccountOf = U256::from(i); assert_ok!(Crowdloan::contribute( @@ -735,14 +745,14 @@ fn test_contribute_fails_if_max_contributors_has_been_reached() { #[test] fn test_contribute_fails_if_contributor_has_insufficient_balance() { TestState::default() - .with_balance(U256::from(1), 100) - .with_balance(U256::from(2), 50) + .with_balance(U256::from(1), 100.into()) + .with_balance(U256::from(2), 50.into()) .build_and_execute(|| { // create a crowdloan let creator: AccountOf = U256::from(1); - let initial_deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 300; + let initial_deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 300.into(); let end: BlockNumberFor = 50; assert_ok!(Crowdloan::create( @@ -761,7 +771,7 @@ fn test_contribute_fails_if_contributor_has_insufficient_balance() { // contribute to the crowdloan let crowdloan_id: CrowdloanId = 0; let contributor: AccountOf = U256::from(2); - let amount: BalanceOf = 100; + let amount: BalanceOf = 100.into(); assert_err!( Crowdloan::contribute(RuntimeOrigin::signed(contributor), crowdloan_id, amount), @@ -773,15 +783,15 @@ fn test_contribute_fails_if_contributor_has_insufficient_balance() { #[test] fn test_withdraw_from_contributor_succeeds() { TestState::default() - .with_balance(U256::from(1), 100) - .with_balance(U256::from(2), 100) - .with_balance(U256::from(3), 100) + .with_balance(U256::from(1), 100.into()) + .with_balance(U256::from(2), 100.into()) + .with_balance(U256::from(3), 100.into()) .build_and_execute(|| { // create a crowdloan let creator: AccountOf = U256::from(1); - let initial_deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 300; + let initial_deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 300.into(); let end: BlockNumberFor = 50; assert_ok!(Crowdloan::create( @@ -801,7 +811,7 @@ fn test_withdraw_from_contributor_succeeds() { let crowdloan_id: CrowdloanId = 0; let contributor1: AccountOf = U256::from(2); - let amount1: BalanceOf = 100; + let amount1: BalanceOf = 100.into(); assert_ok!(Crowdloan::contribute( RuntimeOrigin::signed(contributor1), crowdloan_id, @@ -809,7 +819,7 @@ fn test_withdraw_from_contributor_succeeds() { )); let contributor2: AccountOf = U256::from(3); - let amount2: BalanceOf = 100; + let amount2: BalanceOf = 100.into(); assert_ok!(Crowdloan::contribute( RuntimeOrigin::signed(contributor2), crowdloan_id, @@ -842,7 +852,7 @@ fn test_withdraw_from_contributor_succeeds() { // ensure the contributor1 has the correct amount assert_eq!( pallet_balances::Pallet::::free_balance(contributor1), - 100 + 100.into() ); // withdraw from contributor2 @@ -862,7 +872,7 @@ fn test_withdraw_from_contributor_succeeds() { // ensure the contributor2 has the correct amount assert_eq!( pallet_balances::Pallet::::free_balance(contributor2), - 100 + 100.into() ); // ensure the crowdloan account has the correct amount @@ -879,13 +889,13 @@ fn test_withdraw_from_contributor_succeeds() { #[test] fn test_withdraw_from_creator_with_contribution_over_deposit_succeeds() { TestState::default() - .with_balance(U256::from(1), 200) + .with_balance(U256::from(1), 200.into()) .build_and_execute(|| { // create a crowdloan let creator: AccountOf = U256::from(1); - let initial_deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 300; + let initial_deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 300.into(); let end: BlockNumberFor = 50; assert_ok!(Crowdloan::create( @@ -901,7 +911,7 @@ fn test_withdraw_from_creator_with_contribution_over_deposit_succeeds() { // contribute to the crowdloan as the creator let crowdloan_id: CrowdloanId = 0; - let amount: BalanceOf = 100; + let amount: BalanceOf = 100.into(); assert_ok!(Crowdloan::contribute( RuntimeOrigin::signed(creator), crowdloan_id, @@ -924,7 +934,7 @@ fn test_withdraw_from_creator_with_contribution_over_deposit_succeeds() { // ensure the creator has the correct amount assert_eq!( pallet_balances::Pallet::::free_balance(creator), - 200 - initial_deposit + TaoBalance::from(200) - initial_deposit ); // ensure the creator contribution has been removed assert_eq!( @@ -950,14 +960,14 @@ fn test_withdraw_from_creator_with_contribution_over_deposit_succeeds() { #[test] fn test_withdraw_fails_from_creator_with_no_contribution_over_deposit() { TestState::default() - .with_balance(U256::from(1), 100) - .with_balance(U256::from(2), 200) + .with_balance(U256::from(1), 100.into()) + .with_balance(U256::from(2), 200.into()) .build_and_execute(|| { // create a crowdloan let creator: AccountOf = U256::from(1); - let initial_deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 300; + let initial_deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 300.into(); let end: BlockNumberFor = 50; assert_ok!(Crowdloan::create( @@ -1021,14 +1031,14 @@ fn test_withdraw_fails_if_crowdloan_does_not_exists() { #[test] fn test_withdraw_fails_if_crowdloan_has_already_been_finalized() { TestState::default() - .with_balance(U256::from(1), 100) - .with_balance(U256::from(2), 200) + .with_balance(U256::from(1), 100.into()) + .with_balance(U256::from(2), 200.into()) .build_and_execute(|| { // create a crowdloan let creator: AccountOf = U256::from(1); - let deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 100; + let deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 100.into(); let end: BlockNumberFor = 50; assert_ok!(Crowdloan::create( @@ -1044,7 +1054,7 @@ fn test_withdraw_fails_if_crowdloan_has_already_been_finalized() { // some contribution let crowdloan_id: CrowdloanId = 0; let contributor: AccountOf = U256::from(2); - let amount: BalanceOf = 50; + let amount: BalanceOf = 50.into(); assert_ok!(Crowdloan::contribute( RuntimeOrigin::signed(contributor), @@ -1072,14 +1082,14 @@ fn test_withdraw_fails_if_crowdloan_has_already_been_finalized() { #[test] fn test_withdraw_fails_if_no_contribution_exists() { TestState::default() - .with_balance(U256::from(1), 100) - .with_balance(U256::from(2), 200) + .with_balance(U256::from(1), 100.into()) + .with_balance(U256::from(2), 200.into()) .build_and_execute(|| { // create a crowdloan let creator: AccountOf = U256::from(1); - let initial_deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 300; + let initial_deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 300.into(); let end: BlockNumberFor = 50; assert_ok!(Crowdloan::create( @@ -1108,14 +1118,14 @@ fn test_withdraw_fails_if_no_contribution_exists() { #[test] fn test_finalize_succeeds() { TestState::default() - .with_balance(U256::from(1), 100) - .with_balance(U256::from(2), 100) + .with_balance(U256::from(1), 100.into()) + .with_balance(U256::from(2), 100.into()) .build_and_execute(|| { // create a crowdloan let creator: AccountOf = U256::from(1); - let deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 100; + let deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 100.into(); let end: BlockNumberFor = 50; let call = Box::new(RuntimeCall::TestPallet( pallet_test::Call::::transfer_funds { @@ -1139,7 +1149,7 @@ fn test_finalize_succeeds() { // some contribution let crowdloan_id: CrowdloanId = 0; let contributor: AccountOf = U256::from(2); - let amount: BalanceOf = 50; + let amount: BalanceOf = 50.into(); assert_ok!(Crowdloan::contribute( RuntimeOrigin::signed(contributor), @@ -1156,7 +1166,7 @@ fn test_finalize_succeeds() { // ensure the transfer was a success from the dispatched call assert_eq!( pallet_balances::Pallet::::free_balance(U256::from(42)), - 100 + 100.into() ); // ensure the crowdloan is marked as finalized @@ -1182,14 +1192,14 @@ fn test_finalize_succeeds() { #[test] fn test_finalize_succeeds_with_target_address() { TestState::default() - .with_balance(U256::from(1), 100) - .with_balance(U256::from(2), 100) + .with_balance(U256::from(1), 100.into()) + .with_balance(U256::from(2), 100.into()) .build_and_execute(|| { // create a crowdloan let creator: AccountOf = U256::from(1); - let deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 100; + let deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 100.into(); let end: BlockNumberFor = 50; let target_address: AccountOf = U256::from(42); let call = Box::new(RuntimeCall::TestPallet( @@ -1212,7 +1222,7 @@ fn test_finalize_succeeds_with_target_address() { // some contribution let crowdloan_id: CrowdloanId = 0; let contributor: AccountOf = U256::from(2); - let amount: BalanceOf = 50; + let amount: BalanceOf = 50.into(); assert_ok!(Crowdloan::contribute( RuntimeOrigin::signed(contributor), @@ -1232,7 +1242,7 @@ fn test_finalize_succeeds_with_target_address() { // ensure the target address has received the funds assert_eq!( pallet_balances::Pallet::::free_balance(target_address), - 100 + 100.into() ); // ensure the crowdloan is marked as finalized @@ -1258,7 +1268,7 @@ fn test_finalize_succeeds_with_target_address() { #[test] fn test_finalize_fails_if_bad_origin() { TestState::default() - .with_balance(U256::from(1), 100) + .with_balance(U256::from(1), 100.into()) .build_and_execute(|| { let crowdloan_id: CrowdloanId = 0; @@ -1277,7 +1287,7 @@ fn test_finalize_fails_if_bad_origin() { #[test] fn test_finalize_fails_if_crowdloan_does_not_exist() { TestState::default() - .with_balance(U256::from(1), 100) + .with_balance(U256::from(1), 100.into()) .build_and_execute(|| { let creator: AccountOf = U256::from(1); let crowdloan_id: CrowdloanId = 0; @@ -1293,14 +1303,14 @@ fn test_finalize_fails_if_crowdloan_does_not_exist() { #[test] fn test_finalize_fails_if_not_creator_origin() { TestState::default() - .with_balance(U256::from(1), 100) - .with_balance(U256::from(2), 100) + .with_balance(U256::from(1), 100.into()) + .with_balance(U256::from(2), 100.into()) .build_and_execute(|| { // create a crowdloan let creator: AccountOf = U256::from(1); - let deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 100; + let deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 100.into(); let end: BlockNumberFor = 50; assert_ok!(Crowdloan::create( @@ -1319,7 +1329,7 @@ fn test_finalize_fails_if_not_creator_origin() { // some contribution let crowdloan_id: CrowdloanId = 0; let contributor: AccountOf = U256::from(2); - let amount: BalanceOf = 50; + let amount: BalanceOf = 50.into(); assert_ok!(Crowdloan::contribute( RuntimeOrigin::signed(contributor), crowdloan_id, @@ -1340,14 +1350,14 @@ fn test_finalize_fails_if_not_creator_origin() { #[test] fn test_finalize_fails_if_crowdloan_cap_is_not_raised() { TestState::default() - .with_balance(U256::from(1), 100) - .with_balance(U256::from(2), 100) + .with_balance(U256::from(1), 100.into()) + .with_balance(U256::from(2), 100.into()) .build_and_execute(|| { // create a crowdloan let creator: AccountOf = U256::from(1); - let deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 100; + let deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 100.into(); let end: BlockNumberFor = 50; assert_ok!(Crowdloan::create( @@ -1366,7 +1376,7 @@ fn test_finalize_fails_if_crowdloan_cap_is_not_raised() { // some contribution let crowdloan_id: CrowdloanId = 0; let contributor: AccountOf = U256::from(2); - let amount: BalanceOf = 49; // below cap + let amount: BalanceOf = 49.into(); // below cap assert_ok!(Crowdloan::contribute( RuntimeOrigin::signed(contributor), @@ -1388,14 +1398,14 @@ fn test_finalize_fails_if_crowdloan_cap_is_not_raised() { #[test] fn test_finalize_fails_if_crowdloan_has_already_been_finalized() { TestState::default() - .with_balance(U256::from(1), 100) - .with_balance(U256::from(2), 100) + .with_balance(U256::from(1), 100.into()) + .with_balance(U256::from(2), 100.into()) .build_and_execute(|| { // create a crowdloan let creator: AccountOf = U256::from(1); - let deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 100; + let deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 100.into(); let end: BlockNumberFor = 50; assert_ok!(Crowdloan::create( @@ -1411,7 +1421,7 @@ fn test_finalize_fails_if_crowdloan_has_already_been_finalized() { // some contribution let crowdloan_id: CrowdloanId = 0; let contributor: AccountOf = U256::from(2); - let amount: BalanceOf = 50; + let amount: BalanceOf = 50.into(); assert_ok!(Crowdloan::contribute( RuntimeOrigin::signed(contributor), @@ -1439,14 +1449,14 @@ fn test_finalize_fails_if_crowdloan_has_already_been_finalized() { #[test] fn test_finalize_fails_if_call_fails() { TestState::default() - .with_balance(U256::from(1), 100) - .with_balance(U256::from(2), 100) + .with_balance(U256::from(1), 100.into()) + .with_balance(U256::from(2), 100.into()) .build_and_execute(|| { // create a crowdloan let creator: AccountOf = U256::from(1); - let deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 100; + let deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 100.into(); let end: BlockNumberFor = 50; let call = Box::new(RuntimeCall::TestPallet( pallet_test::Call::::failing_extrinsic {}, @@ -1468,7 +1478,7 @@ fn test_finalize_fails_if_call_fails() { // some contribution let crowdloan_id: CrowdloanId = 0; let contributor: AccountOf = U256::from(2); - let amount: BalanceOf = 50; + let amount: BalanceOf = 50.into(); assert_ok!(Crowdloan::contribute( RuntimeOrigin::signed(contributor), crowdloan_id, @@ -1489,19 +1499,19 @@ fn test_finalize_fails_if_call_fails() { #[test] fn test_refund_succeeds() { TestState::default() - .with_balance(U256::from(1), 100) - .with_balance(U256::from(2), 100) - .with_balance(U256::from(3), 100) - .with_balance(U256::from(4), 100) - .with_balance(U256::from(5), 100) - .with_balance(U256::from(6), 100) - .with_balance(U256::from(7), 100) + .with_balance(U256::from(1), 100.into()) + .with_balance(U256::from(2), 100.into()) + .with_balance(U256::from(3), 100.into()) + .with_balance(U256::from(4), 100.into()) + .with_balance(U256::from(5), 100.into()) + .with_balance(U256::from(6), 100.into()) + .with_balance(U256::from(7), 100.into()) .build_and_execute(|| { // create a crowdloan let creator: AccountOf = U256::from(1); - let initial_deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 400; + let initial_deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 400.into(); let end: BlockNumberFor = 50; assert_ok!(Crowdloan::create( RuntimeOrigin::signed(creator), @@ -1518,7 +1528,7 @@ fn test_refund_succeeds() { // make 6 contributions to reach 350 raised amount (initial deposit + contributions) let crowdloan_id: CrowdloanId = 0; - let amount: BalanceOf = 50; + let amount: BalanceOf = 50.into(); for i in 2..8 { let contributor: AccountOf = U256::from(i); assert_ok!(Crowdloan::contribute( @@ -1551,11 +1561,15 @@ fn test_refund_succeeds() { // ensure the crowdloan account has the correct amount let funds_account = pallet_crowdloan::Pallet::::funds_account(crowdloan_id); - assert_eq!(Balances::free_balance(funds_account), 350 - 5 * amount); + assert_eq!( + Balances::free_balance(funds_account), + TaoBalance::from(350) - TaoBalance::from(5) * amount + ); // ensure raised amount is updated correctly assert!( - pallet_crowdloan::Crowdloans::::get(crowdloan_id) - .is_some_and(|c| c.raised == 350 - 5 * amount) + pallet_crowdloan::Crowdloans::::get(crowdloan_id).is_some_and( + |c| c.raised == TaoBalance::from(350) - TaoBalance::from(5) * amount + ) ); // ensure the event is emitted assert_eq!( @@ -1601,7 +1615,7 @@ fn test_refund_succeeds() { let contributor: AccountOf = U256::from(i); assert_eq!( pallet_balances::Pallet::::free_balance(contributor), - 100 + 100.into() ); assert_eq!( pallet_crowdloan::Contributions::::get(crowdloan_id, contributor), @@ -1620,14 +1634,14 @@ fn test_refund_succeeds() { #[test] fn test_refund_fails_if_bad_or_invalid_origin() { TestState::default() - .with_balance(U256::from(1), 100) + .with_balance(U256::from(1), 100.into()) .build_and_execute(|| { // create a crowdloan let crowdloan_id: CrowdloanId = 0; let creator: AccountOf = U256::from(1); - let initial_deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 300; + let initial_deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 300.into(); let end: BlockNumberFor = 50; assert_ok!(Crowdloan::create( RuntimeOrigin::signed(creator), @@ -1664,7 +1678,7 @@ fn test_refund_fails_if_bad_or_invalid_origin() { #[test] fn test_refund_fails_if_crowdloan_does_not_exist() { TestState::default() - .with_balance(U256::from(1), 100) + .with_balance(U256::from(1), 100.into()) .build_and_execute(|| { let creator: AccountOf = U256::from(1); let crowdloan_id: CrowdloanId = 0; @@ -1679,13 +1693,13 @@ fn test_refund_fails_if_crowdloan_does_not_exist() { #[test] fn test_dissolve_succeeds() { TestState::default() - .with_balance(U256::from(1), 100) + .with_balance(U256::from(1), 100.into()) .build_and_execute(|| { // create a crowdloan let creator: AccountOf = U256::from(1); - let deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 100; + let deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 100.into(); let end: BlockNumberFor = 50; assert_ok!(Crowdloan::create( @@ -1762,13 +1776,13 @@ fn test_dissolve_fails_if_crowdloan_does_not_exist() { #[test] fn test_dissolve_fails_if_crowdloan_has_been_finalized() { TestState::default() - .with_balance(U256::from(1), 100) - .with_balance(U256::from(2), 100) + .with_balance(U256::from(1), 100.into()) + .with_balance(U256::from(2), 100.into()) .build_and_execute(|| { let creator: AccountOf = U256::from(1); - let deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 100; + let deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 100.into(); let end: BlockNumberFor = 50; assert_ok!(Crowdloan::create( @@ -1787,7 +1801,7 @@ fn test_dissolve_fails_if_crowdloan_has_been_finalized() { // some contribution let crowdloan_id: CrowdloanId = 0; let contributor: AccountOf = U256::from(2); - let amount: BalanceOf = 50; + let amount: BalanceOf = 50.into(); assert_ok!(Crowdloan::contribute( RuntimeOrigin::signed(contributor), @@ -1815,12 +1829,12 @@ fn test_dissolve_fails_if_crowdloan_has_been_finalized() { #[test] fn test_dissolve_fails_if_origin_is_not_creator() { TestState::default() - .with_balance(U256::from(1), 100) + .with_balance(U256::from(1), 100.into()) .build_and_execute(|| { let creator: AccountOf = U256::from(1); - let deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 100; + let deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 100.into(); let end: BlockNumberFor = 50; assert_ok!(Crowdloan::create( @@ -1850,14 +1864,14 @@ fn test_dissolve_fails_if_origin_is_not_creator() { #[test] fn test_dissolve_fails_if_not_everyone_has_been_refunded() { TestState::default() - .with_balance(U256::from(1), 100) - .with_balance(U256::from(2), 100) + .with_balance(U256::from(1), 100.into()) + .with_balance(U256::from(2), 100.into()) .build_and_execute(|| { // create a crowdloan let creator: AccountOf = U256::from(1); - let deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 100; + let deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 100.into(); let end: BlockNumberFor = 50; assert_ok!(Crowdloan::create( @@ -1876,7 +1890,7 @@ fn test_dissolve_fails_if_not_everyone_has_been_refunded() { // some contribution let crowdloan_id: CrowdloanId = 0; let contributor: AccountOf = U256::from(2); - let amount: BalanceOf = 50; + let amount: BalanceOf = 50.into(); assert_ok!(Crowdloan::contribute( RuntimeOrigin::signed(contributor), crowdloan_id, @@ -1898,13 +1912,13 @@ fn test_dissolve_fails_if_not_everyone_has_been_refunded() { #[test] fn test_update_min_contribution_succeeds() { TestState::default() - .with_balance(U256::from(1), 100) + .with_balance(U256::from(1), 100.into()) .build_and_execute(|| { // create a crowdloan let creator: AccountOf = U256::from(1); - let deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 100; + let deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 100.into(); let end: BlockNumberFor = 50; assert_ok!(Crowdloan::create( @@ -1918,7 +1932,7 @@ fn test_update_min_contribution_succeeds() { )); let crowdloan_id: CrowdloanId = 0; - let new_min_contribution: BalanceOf = 20; + let new_min_contribution: BalanceOf = 20.into(); // update the min contribution assert_ok!(Crowdloan::update_min_contribution( @@ -1950,12 +1964,12 @@ fn test_update_min_contribution_fails_if_bad_origin() { let crowdloan_id: CrowdloanId = 0; assert_err!( - Crowdloan::update_min_contribution(RuntimeOrigin::none(), crowdloan_id, 20), + Crowdloan::update_min_contribution(RuntimeOrigin::none(), crowdloan_id, 20.into()), DispatchError::BadOrigin ); assert_err!( - Crowdloan::update_min_contribution(RuntimeOrigin::root(), crowdloan_id, 20), + Crowdloan::update_min_contribution(RuntimeOrigin::root(), crowdloan_id, 20.into()), DispatchError::BadOrigin ); }); @@ -1970,7 +1984,7 @@ fn test_update_min_contribution_fails_if_crowdloan_does_not_exist() { Crowdloan::update_min_contribution( RuntimeOrigin::signed(U256::from(1)), crowdloan_id, - 20 + 20.into() ), pallet_crowdloan::Error::::InvalidCrowdloanId ); @@ -1980,13 +1994,13 @@ fn test_update_min_contribution_fails_if_crowdloan_does_not_exist() { #[test] fn test_update_min_contribution_fails_if_crowdloan_has_been_finalized() { TestState::default() - .with_balance(U256::from(1), 100) - .with_balance(U256::from(2), 100) + .with_balance(U256::from(1), 100.into()) + .with_balance(U256::from(2), 100.into()) .build_and_execute(|| { let creator: AccountOf = U256::from(1); - let deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 100; + let deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 100.into(); let end: BlockNumberFor = 50; assert_ok!(Crowdloan::create( @@ -2002,7 +2016,7 @@ fn test_update_min_contribution_fails_if_crowdloan_has_been_finalized() { // some contribution let crowdloan_id: CrowdloanId = 0; let contributor: AccountOf = U256::from(2); - let amount: BalanceOf = 50; + let amount: BalanceOf = 50.into(); assert_ok!(Crowdloan::contribute( RuntimeOrigin::signed(contributor), crowdloan_id, @@ -2020,7 +2034,7 @@ fn test_update_min_contribution_fails_if_crowdloan_has_been_finalized() { )); // try update the min contribution - let new_min_contribution: BalanceOf = 20; + let new_min_contribution: BalanceOf = 20.into(); assert_err!( Crowdloan::update_min_contribution( RuntimeOrigin::signed(creator), @@ -2035,13 +2049,13 @@ fn test_update_min_contribution_fails_if_crowdloan_has_been_finalized() { #[test] fn test_update_min_contribution_fails_if_not_creator() { TestState::default() - .with_balance(U256::from(1), 100) - .with_balance(U256::from(2), 100) + .with_balance(U256::from(1), 100.into()) + .with_balance(U256::from(2), 100.into()) .build_and_execute(|| { let creator: AccountOf = U256::from(1); - let deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 100; + let deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 100.into(); let end: BlockNumberFor = 50; assert_ok!(Crowdloan::create( @@ -2055,7 +2069,7 @@ fn test_update_min_contribution_fails_if_not_creator() { )); let crowdloan_id: CrowdloanId = 0; - let new_min_contribution: BalanceOf = 20; + let new_min_contribution: BalanceOf = 20.into(); // try update the min contribution assert_err!( @@ -2072,12 +2086,12 @@ fn test_update_min_contribution_fails_if_not_creator() { #[test] fn test_update_min_contribution_fails_if_new_min_contribution_is_too_low() { TestState::default() - .with_balance(U256::from(1), 100) + .with_balance(U256::from(1), 100.into()) .build_and_execute(|| { let creator: AccountOf = U256::from(1); - let deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 100; + let deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 100.into(); let end: BlockNumberFor = 50; assert_ok!(Crowdloan::create( @@ -2091,7 +2105,7 @@ fn test_update_min_contribution_fails_if_new_min_contribution_is_too_low() { )); let crowdloan_id: CrowdloanId = 0; - let new_min_contribution: BalanceOf = 9; + let new_min_contribution: BalanceOf = 9.into(); // try update the min contribution assert_err!( @@ -2108,12 +2122,12 @@ fn test_update_min_contribution_fails_if_new_min_contribution_is_too_low() { #[test] fn test_update_end_succeeds() { TestState::default() - .with_balance(U256::from(1), 100) + .with_balance(U256::from(1), 100.into()) .build_and_execute(|| { let creator: AccountOf = U256::from(1); - let deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 100; + let deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 100.into(); let end: BlockNumberFor = 50; assert_ok!(Crowdloan::create( @@ -2185,13 +2199,13 @@ fn test_update_end_fails_if_crowdloan_does_not_exist() { #[test] fn test_update_end_fails_if_crowdloan_has_been_finalized() { TestState::default() - .with_balance(U256::from(1), 100) - .with_balance(U256::from(2), 100) + .with_balance(U256::from(1), 100.into()) + .with_balance(U256::from(2), 100.into()) .build_and_execute(|| { let creator: AccountOf = U256::from(1); - let deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 100; + let deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 100.into(); let end: BlockNumberFor = 50; assert_ok!(Crowdloan::create( @@ -2208,7 +2222,7 @@ fn test_update_end_fails_if_crowdloan_has_been_finalized() { // some contribution let contributor: AccountOf = U256::from(2); - let amount: BalanceOf = 50; + let amount: BalanceOf = 50.into(); assert_ok!(Crowdloan::contribute( RuntimeOrigin::signed(contributor), crowdloan_id, @@ -2236,13 +2250,13 @@ fn test_update_end_fails_if_crowdloan_has_been_finalized() { #[test] fn test_update_end_fails_if_not_creator() { TestState::default() - .with_balance(U256::from(1), 100) - .with_balance(U256::from(2), 100) + .with_balance(U256::from(1), 100.into()) + .with_balance(U256::from(2), 100.into()) .build_and_execute(|| { let creator: AccountOf = U256::from(1); - let deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 100; + let deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 100.into(); let end: BlockNumberFor = 50; assert_ok!(Crowdloan::create( @@ -2270,12 +2284,12 @@ fn test_update_end_fails_if_not_creator() { fn test_update_end_fails_if_new_end_is_in_past() { TestState::default() .with_block_number(50) - .with_balance(U256::from(1), 100) + .with_balance(U256::from(1), 100.into()) .build_and_execute(|| { let creator: AccountOf = U256::from(1); - let deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 100; + let deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 100.into(); let end: BlockNumberFor = 100; assert_ok!(Crowdloan::create( @@ -2302,12 +2316,12 @@ fn test_update_end_fails_if_new_end_is_in_past() { #[test] fn test_update_end_fails_if_block_duration_is_too_short() { TestState::default() - .with_balance(U256::from(1), 100) + .with_balance(U256::from(1), 100.into()) .build_and_execute(|| { let creator: AccountOf = U256::from(1); - let deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 100; + let deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 100.into(); let end: BlockNumberFor = 50; assert_ok!(Crowdloan::create( @@ -2337,12 +2351,12 @@ fn test_update_end_fails_if_block_duration_is_too_short() { #[test] fn test_update_end_fails_if_block_duration_is_too_long() { TestState::default() - .with_balance(U256::from(1), 100) + .with_balance(U256::from(1), 100.into()) .build_and_execute(|| { let creator: AccountOf = U256::from(1); - let deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 100; + let deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 100.into(); let end: BlockNumberFor = 50; assert_ok!(Crowdloan::create( @@ -2369,12 +2383,12 @@ fn test_update_end_fails_if_block_duration_is_too_long() { #[test] fn test_update_cap_succeeds() { TestState::default() - .with_balance(U256::from(1), 100) + .with_balance(U256::from(1), 100.into()) .build_and_execute(|| { let creator: AccountOf = U256::from(1); - let deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 100; + let deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 100.into(); let end: BlockNumberFor = 50; assert_ok!(Crowdloan::create( @@ -2389,7 +2403,7 @@ fn test_update_cap_succeeds() { // try update the cap let crowdloan_id: CrowdloanId = 0; - let new_cap: BalanceOf = 200; + let new_cap: BalanceOf = 200.into(); assert_ok!(Crowdloan::update_cap( RuntimeOrigin::signed(creator), crowdloan_id, @@ -2419,12 +2433,12 @@ fn test_update_cap_fails_if_bad_origin() { let crowdloan_id: CrowdloanId = 0; assert_err!( - Crowdloan::update_cap(RuntimeOrigin::none(), crowdloan_id, 200), + Crowdloan::update_cap(RuntimeOrigin::none(), crowdloan_id, 200.into()), DispatchError::BadOrigin ); assert_err!( - Crowdloan::update_cap(RuntimeOrigin::root(), crowdloan_id, 200), + Crowdloan::update_cap(RuntimeOrigin::root(), crowdloan_id, 200.into()), DispatchError::BadOrigin ); }); @@ -2436,7 +2450,11 @@ fn test_update_cap_fails_if_crowdloan_does_not_exist() { let crowdloan_id: CrowdloanId = 0; assert_err!( - Crowdloan::update_cap(RuntimeOrigin::signed(U256::from(1)), crowdloan_id, 200), + Crowdloan::update_cap( + RuntimeOrigin::signed(U256::from(1)), + crowdloan_id, + 200.into() + ), pallet_crowdloan::Error::::InvalidCrowdloanId ); }); @@ -2445,13 +2463,13 @@ fn test_update_cap_fails_if_crowdloan_does_not_exist() { #[test] fn test_update_cap_fails_if_crowdloan_has_been_finalized() { TestState::default() - .with_balance(U256::from(1), 100) - .with_balance(U256::from(2), 100) + .with_balance(U256::from(1), 100.into()) + .with_balance(U256::from(2), 100.into()) .build_and_execute(|| { let creator: AccountOf = U256::from(1); - let deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 100; + let deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 100.into(); let end: BlockNumberFor = 50; assert_ok!(Crowdloan::create( @@ -2467,7 +2485,7 @@ fn test_update_cap_fails_if_crowdloan_has_been_finalized() { // some contribution let crowdloan_id: CrowdloanId = 0; let contributor: AccountOf = U256::from(2); - let amount: BalanceOf = 50; + let amount: BalanceOf = 50.into(); assert_ok!(Crowdloan::contribute( RuntimeOrigin::signed(contributor), crowdloan_id, @@ -2485,7 +2503,7 @@ fn test_update_cap_fails_if_crowdloan_has_been_finalized() { )); // try update the cap - let new_cap: BalanceOf = 200; + let new_cap: BalanceOf = 200.into(); assert_err!( Crowdloan::update_cap(RuntimeOrigin::signed(creator), crowdloan_id, new_cap), pallet_crowdloan::Error::::AlreadyFinalized @@ -2496,13 +2514,13 @@ fn test_update_cap_fails_if_crowdloan_has_been_finalized() { #[test] fn test_update_cap_fails_if_not_creator() { TestState::default() - .with_balance(U256::from(1), 100) - .with_balance(U256::from(2), 100) + .with_balance(U256::from(1), 100.into()) + .with_balance(U256::from(2), 100.into()) .build_and_execute(|| { let creator: AccountOf = U256::from(1); - let deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 100; + let deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 100.into(); let end: BlockNumberFor = 50; assert_ok!(Crowdloan::create( @@ -2517,7 +2535,7 @@ fn test_update_cap_fails_if_not_creator() { // try update the cap let crowdloan_id: CrowdloanId = 0; - let new_cap: BalanceOf = 200; + let new_cap: BalanceOf = 200.into(); assert_err!( Crowdloan::update_cap(RuntimeOrigin::signed(U256::from(2)), crowdloan_id, new_cap), pallet_crowdloan::Error::::InvalidOrigin @@ -2528,12 +2546,12 @@ fn test_update_cap_fails_if_not_creator() { #[test] fn test_update_cap_fails_if_new_cap_is_too_low() { TestState::default() - .with_balance(U256::from(1), 100) + .with_balance(U256::from(1), 100.into()) .build_and_execute(|| { let creator: AccountOf = U256::from(1); - let deposit: BalanceOf = 50; - let min_contribution: BalanceOf = 10; - let cap: BalanceOf = 100; + let deposit: BalanceOf = 50.into(); + let min_contribution: BalanceOf = 10.into(); + let cap: BalanceOf = 100.into(); let end: BlockNumberFor = 50; assert_ok!(Crowdloan::create( @@ -2548,7 +2566,7 @@ fn test_update_cap_fails_if_new_cap_is_too_low() { // try update the cap let crowdloan_id: CrowdloanId = 0; - let new_cap: BalanceOf = 49; + let new_cap: BalanceOf = 49.into(); assert_err!( Crowdloan::update_cap(RuntimeOrigin::signed(creator), crowdloan_id, new_cap), pallet_crowdloan::Error::::CapTooLow diff --git a/pallets/shield/Cargo.toml b/pallets/shield/Cargo.toml index 1a0d9ef1f5..8888b249b9 100644 --- a/pallets/shield/Cargo.toml +++ b/pallets/shield/Cargo.toml @@ -15,8 +15,10 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { workspace = true, features = ["derive", "max-encoded-len"] } scale-info = { workspace = true, features = ["derive"] } +log.workspace = true subtensor-macros.workspace = true +subtensor-runtime-common.workspace = true # FRAME core frame-support.workspace = true @@ -29,13 +31,28 @@ sp-runtime.workspace = true sp-io.workspace = true sp-std.workspace = true sp-weights.workspace = true +sp-inherents.workspace = true -# Pallets used in Config +# Subtensor primitives +stp-shield.workspace = true + +# Crypto (ML-KEM-768 + XChaCha20-Poly1305 for unshielding) +ml-kem.workspace = true +chacha20poly1305.workspace = true + +# Benchmark-only (optional, activated by runtime-benchmarks feature) +pallet-aura = { workspace = true, optional = true } +sp-consensus-aura = { workspace = true, optional = true } +rand_chacha = { workspace = true, optional = true } + +[dev-dependencies] +stc-shield.workspace = true +pallet-subtensor-utility.workspace = true +rand_chacha.workspace = true pallet-timestamp.workspace = true pallet-aura.workspace = true sp-consensus-aura.workspace = true - -[dev-dependencies] +sp-keystore.workspace = true [features] default = ["std"] @@ -43,6 +60,7 @@ default = ["std"] std = [ "codec/std", "scale-info/std", + "log/std", "frame-support/std", "frame-system/std", "frame-benchmarking?/std", @@ -51,9 +69,18 @@ std = [ "sp-io/std", "sp-std/std", "sp-weights/std", + "sp-inherents/std", + "stp-shield/std", + "ml-kem/std", + "chacha20poly1305/std", + "pallet-aura?/std", + "sp-consensus-aura?/std", + "rand_chacha?/std", + "pallet-subtensor-utility/std", + "stc-shield/std", + "subtensor-runtime-common/std", + "sp-keystore/std", "pallet-timestamp/std", - "pallet-aura/std", - "sp-consensus-aura/std", ] runtime-benchmarks = [ @@ -61,7 +88,12 @@ runtime-benchmarks = [ "frame-support/runtime-benchmarks", "frame-system/runtime-benchmarks", "sp-runtime/runtime-benchmarks", + "pallet-subtensor-utility/runtime-benchmarks", + "subtensor-runtime-common/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", + "pallet-aura", + "sp-consensus-aura", + "rand_chacha", ] try-runtime = [ @@ -69,5 +101,6 @@ try-runtime = [ "frame-system/try-runtime", "sp-runtime/try-runtime", "pallet-aura/try-runtime", + "pallet-subtensor-utility/try-runtime", "pallet-timestamp/try-runtime", ] diff --git a/pallets/shield/README.md b/pallets/shield/README.md new file mode 100644 index 0000000000..d3e67d82f5 --- /dev/null +++ b/pallets/shield/README.md @@ -0,0 +1,58 @@ +# pallet-shield + +FRAME pallet for opt-in, per-block ephemeral-key encrypted transactions (MEV shielding). + +## Overview + +Block authors rotate ML-KEM-768 key pairs every slot via a mandatory inherent. Users encrypt their extrinsics to the next block author's encapsulation key, preventing front-running and sandwich attacks. + +### Key rotation + +Each block includes an `announce_next_key` inherent that rotates the key pipeline in four steps: + +1. `CurrentKey <- PendingKey` (proposer's decryption target). +2. `PendingKey <- NextKey` (staged one block ahead). +3. `NextKey <- AuthorKeys[next_next_author]` (user-facing, N+2 author's key). +4. `AuthorKeys[current_author] <- announced key` (updated after rotations for consistent reads). + +This gives users a full 12-24s submission window (two block periods) instead of 0-12s, eliminating block-boundary timing issues. + +### Key expiration + +`PendingKeyExpiresAt` and `NextKeyExpiresAt` expose the block number at which each user-facing key stops being valid (exclusive upper bound). Clients can read these directly to know how long a key remains usable. + +### Encrypted transaction flow + +1. User reads `NextKey` from storage (ML-KEM-768 encapsulation key, 1184 bytes). +2. User encrypts a signed extrinsic with ML-KEM-768 + XChaCha20-Poly1305, producing: + + ``` + ciphertext = key_hash(16) || kem_len(2) || kem_ct || nonce(24) || aead_ct + ``` + +3. User submits `submit_encrypted(ciphertext)` signed with their account, using a short mortal era (<=8 blocks). +4. The block author decrypts and includes the inner extrinsic in the same block. + +### Transaction extension + +`CheckShieldedTxValidity` rejects malformed ciphertext (unparseable structure) at pool validation time. Key hash matching is handled by the block proposer, not the extension. + +### Mortal era enforcement + +`CheckMortality` (in the runtime) wraps Substrate's `CheckMortality` and rejects `submit_encrypted` calls with immortal or >8-block eras. This ensures stale encrypted transactions are evicted from the pool within a few blocks. + +## Storage + +| Item | Description | +|------|-------------| +| `CurrentKey` | Current block author's encapsulation key (internal, not for encryption) | +| `PendingKey` | N+1 block author's key, staged before promoting to `CurrentKey` | +| `NextKey` | N+2 block author's key (user-facing, encrypt to this) | +| `AuthorKeys` | Per-authority latest announced encapsulation key | +| `PendingKeyExpiresAt` | Block number at which `PendingKey` is no longer valid | +| `NextKeyExpiresAt` | Block number at which `NextKey` is no longer valid | + +## Dependencies + +- [`stp-shield`](https://github.com/opentensor/polkadot-sdk) — shared types (`ShieldedTransaction`, `ShieldEncKey`, `InherentType`) +- `ml-kem` / `chacha20poly1305` — cryptographic primitives for in-WASM decryption diff --git a/pallets/shield/src/benchmarking.rs b/pallets/shield/src/benchmarking.rs index e3890bae76..3fbf564f85 100644 --- a/pallets/shield/src/benchmarking.rs +++ b/pallets/shield/src/benchmarking.rs @@ -2,145 +2,191 @@ use super::*; use frame_benchmarking::v2::*; use frame_support::{BoundedVec, pallet_prelude::ConstU32}; -use frame_system::{RawOrigin, pallet_prelude::BlockNumberFor}; +use frame_system::RawOrigin; use sp_core::sr25519; -use sp_runtime::{AccountId32, traits::Hash as HashT}; -use sp_std::vec; - -// /// Helper to build bounded bytes (public key) of a given length. -// fn bounded_pk(len: usize) -> BoundedVec> { -// let v = vec![7u8; len]; -// BoundedVec::>::try_from(v).expect("within bound; qed") -// } - -/// Helper to build bounded bytes (ciphertext) of a given length. -fn bounded_ct(len: usize) -> BoundedVec> { - let v = vec![0u8; len]; - BoundedVec::>::try_from(v).expect("within bound; qed") +use sp_std::{vec, vec::Vec}; + +use chacha20poly1305::{ + KeyInit, XChaCha20Poly1305, XNonce, + aead::{Aead, Payload}, +}; +use ml_kem::{ + Ciphertext, KemCore, MlKem768, MlKem768Params, + kem::{Decapsulate, DecapsulationKey, Encapsulate}, +}; +use rand_chacha::{ChaCha20Rng, rand_core::SeedableRng}; +use stp_shield::ShieldedTransaction; + +use codec::Encode; +use sp_consensus_aura::AURA_ENGINE_ID; +use sp_core::crypto::KeyTypeId; +use sp_io::crypto::sr25519_generate; + +/// Set Aura authorities directly from sr25519 public keys. +fn set_aura_authorities(pubkeys: &[sr25519::Public]) +where + T: pallet::Config + pallet_aura::Config, + ::AuthorityId: From, +{ + let auths: BoundedVec< + ::AuthorityId, + ::MaxAuthorities, + > = BoundedVec::truncate_from(pubkeys.iter().map(|pk| (*pk).into()).collect()); + pallet_aura::Authorities::::put(auths); } -// /// Seed Aura authorities so `EnsureAuraAuthority` passes for a given sr25519 pubkey. -// /// -// /// We avoid requiring `ByteArray` on `AuthorityId` by relying on: -// /// `::AuthorityId: From`. -// fn seed_aura_authority_from_sr25519(pubkey: &sr25519::Public) -// where -// T: pallet::Config + pallet_aura::Config, -// ::AuthorityId: From, -// { -// let auth_id: ::AuthorityId = (*pubkey).into(); -// pallet_aura::Authorities::::mutate(|auths| { -// let _ = auths.try_push(auth_id); -// }); -// } +/// Initialize a block with an Aura pre-runtime digest for the given slot. +/// +/// Uses `System::initialize` (like real block production) so the digest +/// survives `commit_db()` in the benchmark framework. +fn initialize_block_with_slot(slot: u64) { + let digest = sp_runtime::Digest { + logs: vec![sp_runtime::DigestItem::PreRuntime( + AURA_ENGINE_ID, + slot.encode(), + )], + }; + frame_system::Pallet::::initialize(&1u32.into(), &Default::default(), &digest); +} + +/// Build a real max-size encrypted ciphertext (8192 bytes wire format). +/// +/// Returns `(wire_ciphertext, dec_key)` so the benchmark can measure decryption. +fn build_max_encrypted_payload() -> (Vec, DecapsulationKey) { + let mut rng = ChaCha20Rng::from_seed([42u8; 32]); + let (dec_key, enc_key) = MlKem768::generate(&mut rng); + let (kem_ct, shared_secret) = enc_key.encapsulate(&mut rng).unwrap(); + + // Wire overhead: key_hash(16) + kem_ct_len(2) + kem_ct(1088) + nonce(24) = 1130. + // Max aead_ct = 8192 − 1130 = 7062. + // Poly1305 tag = 16 bytes ⇒ max plaintext = 7046. + let plaintext = vec![0x42u8; 7046]; + + let nonce = [0u8; 24]; + let cipher = XChaCha20Poly1305::new(shared_secret.as_slice().into()); + let aead_ct = cipher + .encrypt( + XNonce::from_slice(&nonce), + Payload { + msg: &plaintext, + aad: &[], + }, + ) + .expect("AEAD encryption must succeed in benchmark setup"); + + let kem_ct_bytes = kem_ct.as_slice(); + let key_hash = [0u8; 16]; + + let mut wire = Vec::with_capacity(8192); + wire.extend_from_slice(&key_hash); + wire.extend_from_slice(&(kem_ct_bytes.len() as u16).to_le_bytes()); + wire.extend_from_slice(kem_ct_bytes); + wire.extend_from_slice(&nonce); + wire.extend_from_slice(&aead_ct); + + debug_assert_eq!(wire.len(), 8192); + + (wire, dec_key) +} #[benchmarks( where - // Needed to build a concrete inner call and convert into T::RuntimeCall. - ::RuntimeCall: From>, - // Needed so we can seed Authorities from a dev sr25519 pubkey. + T: pallet_aura::Config, ::AuthorityId: From, - ::AccountId: From + Into, - ::RuntimeOrigin: From> + ::AuthorityId: From, )] mod benches { use super::*; - // We use the custom value for announce_next_key to charge a higher fee, not the benchmark result. - // /// Benchmark `announce_next_key`. - // #[benchmark] - // fn announce_next_key() { - // // Generate a deterministic dev key in the host keystore (for benchmarks). - // // Any 4-byte KeyTypeId works for generation; it does not affect AccountId derivation. - // const KT: KeyTypeId = KeyTypeId(*b"benc"); - // let alice_pub: sr25519::Public = sr25519_generate(KT, Some("//Alice".as_bytes().to_vec())); - // let alice_acc: AccountId32 = alice_pub.into(); - - // // Make this account an Aura authority for the generic runtime. - // seed_aura_authority_from_sr25519::(&alice_pub); - - // // Valid Kyber768 public key length per pallet check. - // const KYBER768_PK_LEN: usize = 1184; - // let public_key: BoundedVec> = bounded_pk::<2048>(KYBER768_PK_LEN); - - // // Measure: dispatch the extrinsic. - // #[extrinsic_call] - // announce_next_key(RawOrigin::Signed(alice_acc.clone()), public_key.clone()); - - // // Assert: NextKey should be set exactly. - // let stored = NextKey::::get().expect("must be set by announce_next_key"); - // assert_eq!(stored, public_key); - // } - - /// Benchmark `submit_encrypted`. + /// Worst-case `announce_next_key`: all 4 rotation steps write storage. + /// 1. CurrentKey ← PendingKey (pre-populated) + /// 2. PendingKey ← NextKey (pre-populated) + /// 3. NextKey ← charlie's AuthorKey (next-next author) + /// 4. AuthorKeys[alice] ← announced key #[benchmark] - fn submit_encrypted() { - // Any whitelisted caller is fine (no authority requirement). - let who: T::AccountId = whitelisted_caller(); + fn announce_next_key() { + let alice = sr25519_generate(KeyTypeId(*b"aura"), Some("//Alice".as_bytes().to_vec())); + let bob = sr25519_generate(KeyTypeId(*b"aura"), Some("//Bob".as_bytes().to_vec())); + let charlie = sr25519_generate(KeyTypeId(*b"aura"), Some("//Charlie".as_bytes().to_vec())); + + // Set Aura authorities directly: [alice, bob, charlie]. + set_aura_authorities::(&[alice, bob, charlie]); + + // Initialize block with slot 0 digest via System::initialize. + // This survives commit_db() unlike deposit_log(). + // Slot 0 → current=alice(0%3), next_next=charlie(2%3). + initialize_block_with_slot::(0); - // Dummy commitment and ciphertext (bounded to 8192). - let commitment: T::Hash = ::Hashing::hash(b"bench-commitment"); - const CT_DEFAULT_LEN: usize = 256; - let ciphertext: BoundedVec> = super::bounded_ct::<8192>(CT_DEFAULT_LEN); + // Pre-populate PendingKey so CurrentKey ← PendingKey writes. + let old_pending: ShieldEncKey = BoundedVec::truncate_from(vec![0x99; MLKEM768_ENC_KEY_LEN]); + PendingKey::::put(old_pending.clone()); - // Pre-compute expected id to assert postconditions. - let id: T::Hash = - ::Hashing::hash_of(&(who.clone(), commitment, &ciphertext)); + // Pre-populate NextKey so PendingKey ← NextKey writes. + let old_next: ShieldEncKey = BoundedVec::truncate_from(vec![0x77; MLKEM768_ENC_KEY_LEN]); + NextKey::::put(old_next.clone()); + + // Pre-populate AuthorKeys for charlie (next-next) so NextKey gets set. + let charlie_key: ShieldEncKey = BoundedVec::truncate_from(vec![0x55; MLKEM768_ENC_KEY_LEN]); + let charlie_id: ::AuthorityId = charlie.into(); + AuthorKeys::::insert(&charlie_id, charlie_key.clone()); + + let enc_key: ShieldEncKey = BoundedVec::truncate_from(vec![0x42; MLKEM768_ENC_KEY_LEN]); - // Measure: dispatch the extrinsic. #[extrinsic_call] - submit_encrypted( - RawOrigin::Signed(who.clone()), - commitment, - ciphertext.clone(), - ); - - // Assert: stored under expected id. - let got = Submissions::::get(id).expect("submission must exist"); - assert_eq!(got.author, who); - assert_eq!( - got.commitment, - ::Hashing::hash(b"bench-commitment") - ); - assert_eq!(got.ciphertext.as_slice(), ciphertext.as_slice()); + announce_next_key(RawOrigin::None, Some(enc_key.clone())); + + assert_eq!(CurrentKey::::get(), Some(old_pending)); + assert_eq!(PendingKey::::get(), Some(old_next)); + assert_eq!(NextKey::::get(), Some(charlie_key)); + let alice_id: ::AuthorityId = alice.into(); + assert_eq!(AuthorKeys::::get(&alice_id), Some(enc_key)); } - /// Benchmark `mark_decryption_failed`. + /// Worst-case `submit_encrypted`: max-size ciphertext (8192 bytes) with + /// real ML-KEM-768 + XChaCha20-Poly1305 decryption to account for the + /// block proposer's off-chain decrypt cost. #[benchmark] - fn mark_decryption_failed() { - // Any account can be the author of the submission. + fn submit_encrypted() { let who: T::AccountId = whitelisted_caller(); - let submitted_in: BlockNumberFor = frame_system::Pallet::::block_number(); - - // Build a dummy commitment and ciphertext. - let commitment: T::Hash = - ::Hashing::hash(b"bench-mark-decryption-failed"); - const CT_DEFAULT_LEN: usize = 32; - let ciphertext: BoundedVec> = - BoundedVec::truncate_from(vec![0u8; CT_DEFAULT_LEN]); - - // Compute the submission id exactly like `submit_encrypted` does. - let id: T::Hash = - ::Hashing::hash_of(&(who.clone(), commitment, &ciphertext)); - - // Seed Submissions with an entry for this id. - let sub = Submission::, ::Hash> { - author: who, - commitment, - ciphertext: ciphertext.clone(), - submitted_in, - }; - Submissions::::insert(id, sub); - - // Reason for failure. - let reason: BoundedVec> = - BoundedVec::truncate_from(b"benchmark-decryption-failed".to_vec()); - - // Measure: dispatch the unsigned extrinsic. - #[extrinsic_call] - mark_decryption_failed(RawOrigin::None, id, reason); - // Assert: submission is removed. - assert!(Submissions::::get(id).is_none()); + // Build a real max-size encrypted payload. + let (wire, dec_key) = build_max_encrypted_payload(); + let ciphertext: BoundedVec> = BoundedVec::truncate_from(wire); + + #[block] + { + // 1. On-chain dispatch (event deposit). + Pallet::::submit_encrypted( + RawOrigin::Signed(who.clone()).into(), + ciphertext.clone(), + ) + .expect("submit_encrypted dispatch must succeed"); + + // 2. Parse wire-format ciphertext (proposer decode). + let shielded_tx = + ShieldedTransaction::parse(&ciphertext).expect("wire format must be valid"); + + // 3. ML-KEM-768 decapsulate (proposer crypto). + let ct = Ciphertext::::try_from(shielded_tx.kem_ct.as_slice()) + .expect("kem_ct must be valid ML-KEM-768 ciphertext"); + let shared_secret = dec_key + .decapsulate(&ct) + .expect("decapsulation must succeed"); + let ss: [u8; 32] = shared_secret.into(); + + // 4. AEAD decrypt (proposer crypto). + let aead = XChaCha20Poly1305::new((&ss).into()); + let _plaintext = aead + .decrypt( + XNonce::from_slice(&shielded_tx.nonce), + Payload { + msg: &shielded_tx.aead_ct, + aad: &[], + }, + ) + .expect("AEAD decryption must succeed"); + } } + + impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Test); } diff --git a/pallets/shield/src/extension.rs b/pallets/shield/src/extension.rs new file mode 100644 index 0000000000..5e5a85f7af --- /dev/null +++ b/pallets/shield/src/extension.rs @@ -0,0 +1,198 @@ +use crate::{Call, Config, ShieldedTransaction}; +use codec::{Decode, DecodeWithMemTracking, Encode}; +use frame_support::pallet_prelude::*; +use frame_support::traits::IsSubType; +use scale_info::TypeInfo; +use sp_runtime::impl_tx_ext_default; +use sp_runtime::traits::{ + AsSystemOriginSigner, DispatchInfoOf, Dispatchable, Implication, TransactionExtension, + ValidateResult, +}; +use sp_runtime::transaction_validity::TransactionSource; +use subtensor_macros::freeze_struct; +use subtensor_runtime_common::CustomTransactionError; + +#[freeze_struct("dabd89c6963de25d")] +#[derive(Default, Encode, Decode, DecodeWithMemTracking, Clone, Eq, PartialEq, TypeInfo)] +pub struct CheckShieldedTxValidity(PhantomData); + +impl CheckShieldedTxValidity { + pub fn new() -> Self { + Self(Default::default()) + } +} + +impl sp_std::fmt::Debug for CheckShieldedTxValidity { + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + write!(f, "CheckShieldedTxValidity") + } +} + +impl + TransactionExtension<::RuntimeCall> for CheckShieldedTxValidity +where + ::RuntimeCall: Dispatchable + IsSubType>, + ::RuntimeOrigin: AsSystemOriginSigner, +{ + const IDENTIFIER: &'static str = "CheckShieldedTxValidity"; + + type Implicit = (); + type Val = (); + type Pre = (); + + impl_tx_ext_default!(::RuntimeCall; prepare); + + fn weight(&self, _call: &::RuntimeCall) -> Weight { + // Some arbitrary weight added to account for the cost + // of reading the PendingKey from the proposer. + Weight::from_parts(1_000_000, 0).saturating_add(T::DbWeight::get().reads(1)) + } + + fn validate( + &self, + origin: ::RuntimeOrigin, + call: &::RuntimeCall, + _info: &DispatchInfoOf<::RuntimeCall>, + _len: usize, + _self_implicit: Self::Implicit, + _inherited_implication: &impl Implication, + _source: TransactionSource, + ) -> ValidateResult::RuntimeCall> { + // Ensure the transaction is signed, else we just skip the extension. + let Some(_who) = origin.as_system_origin_signer() else { + return Ok((Default::default(), (), origin)); + }; + + // Ensure the transaction is a shielded transaction, else we just skip the extension. + let Some(Call::submit_encrypted { ciphertext }) = IsSubType::>::is_sub_type(call) + else { + return Ok((Default::default(), (), origin)); + }; + + // Reject malformed ciphertext regardless of source. + let Some(ShieldedTransaction { .. }) = ShieldedTransaction::parse(ciphertext) else { + return Err(CustomTransactionError::FailedShieldedTxParsing.into()); + }; + + Ok((Default::default(), (), origin)) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::mock::*; + use frame_support::dispatch::GetDispatchInfo; + use frame_support::pallet_prelude::{BoundedVec, ConstU32}; + use sp_runtime::traits::TxBaseImplication; + use sp_runtime::transaction_validity::{TransactionValidityError, ValidTransaction}; + + /// Build wire-format ciphertext with a given key_hash. + /// Layout: key_hash(16) || kem_ct_len(2 LE) || kem_ct(N) || nonce(24) || aead_ct(rest) + fn build_ciphertext(key_hash: [u8; 16]) -> BoundedVec> { + let kem_ct = [0xAA; 4]; + let nonce = [0xBB; 24]; + let aead_ct = [0xDD; 16]; + + let mut buf = Vec::new(); + buf.extend_from_slice(&key_hash); + buf.extend_from_slice(&(kem_ct.len() as u16).to_le_bytes()); + buf.extend_from_slice(&kem_ct); + buf.extend_from_slice(&nonce); + buf.extend_from_slice(&aead_ct); + + BoundedVec::truncate_from(buf) + } + + fn make_submit_call(key_hash: [u8; 16]) -> RuntimeCall { + RuntimeCall::MevShield(crate::Call::submit_encrypted { + ciphertext: build_ciphertext(key_hash), + }) + } + + fn validate_ext( + who: Option, + call: &RuntimeCall, + source: TransactionSource, + ) -> Result { + let ext = CheckShieldedTxValidity::::new(); + let info = call.get_dispatch_info(); + let origin = match who { + Some(id) => RuntimeOrigin::signed(id), + None => RuntimeOrigin::none(), + }; + ext.validate(origin, call, &info, 0, (), &TxBaseImplication(call), source) + .map(|(validity, _, _)| validity) + } + + #[test] + fn non_shield_call_passes_through() { + new_test_ext().execute_with(|| { + let call = RuntimeCall::System(frame_system::Call::remark { remark: vec![] }); + let validity = validate_ext(Some(1), &call, TransactionSource::InBlock).unwrap(); + assert_eq!(validity.longevity, u64::MAX); + }); + } + + #[test] + fn unsigned_origin_passes_through() { + new_test_ext().execute_with(|| { + let call = make_submit_call([0xFF; 16]); + let validity = validate_ext(None, &call, TransactionSource::InBlock).unwrap(); + assert_eq!(validity.longevity, u64::MAX); + }); + } + + #[test] + fn malformed_ciphertext_rejected_inblock() { + new_test_ext().execute_with(|| { + let call = RuntimeCall::MevShield(crate::Call::submit_encrypted { + ciphertext: BoundedVec::truncate_from(vec![0u8; 5]), + }); + assert_eq!( + validate_ext(Some(1), &call, TransactionSource::InBlock), + Err(CustomTransactionError::FailedShieldedTxParsing.into()) + ); + }); + } + + #[test] + fn malformed_ciphertext_rejected_from_pool() { + new_test_ext().execute_with(|| { + let call = RuntimeCall::MevShield(crate::Call::submit_encrypted { + ciphertext: BoundedVec::truncate_from(vec![0u8; 5]), + }); + assert_eq!( + validate_ext(Some(1), &call, TransactionSource::External), + Err(CustomTransactionError::FailedShieldedTxParsing.into()) + ); + }); + } + + #[test] + fn wellformed_ciphertext_accepted_inblock() { + new_test_ext().execute_with(|| { + let call = make_submit_call([0xFF; 16]); + let validity = validate_ext(Some(1), &call, TransactionSource::InBlock).unwrap(); + assert_eq!(validity, ValidTransaction::default()); + }); + } + + #[test] + fn wellformed_ciphertext_accepted_external() { + new_test_ext().execute_with(|| { + let call = make_submit_call([0xFF; 16]); + let validity = validate_ext(Some(1), &call, TransactionSource::External).unwrap(); + assert_eq!(validity, ValidTransaction::default()); + }); + } + + #[test] + fn wellformed_ciphertext_accepted_local() { + new_test_ext().execute_with(|| { + let call = make_submit_call([0xFF; 16]); + let validity = validate_ext(Some(1), &call, TransactionSource::Local).unwrap(); + assert_eq!(validity, ValidTransaction::default()); + }); + } +} diff --git a/pallets/shield/src/lib.rs b/pallets/shield/src/lib.rs index e0fc250058..6b742687f5 100644 --- a/pallets/shield/src/lib.rs +++ b/pallets/shield/src/lib.rs @@ -1,7 +1,29 @@ // pallets/mev-shield/src/lib.rs #![cfg_attr(not(feature = "std"), no_std)] +extern crate alloc; + +use chacha20poly1305::{ + KeyInit, XChaCha20Poly1305, XNonce, + aead::{Aead, Payload}, +}; +use frame_support::{pallet_prelude::*, traits::IsSubType}; +use frame_system::{ensure_none, ensure_signed, pallet_prelude::*}; +use ml_kem::{ + Ciphertext, EncodedSizeUser, MlKem768, MlKem768Params, + kem::{Decapsulate, DecapsulationKey}, +}; +use sp_io::hashing::twox_128; +use sp_runtime::traits::{Applyable, Block as BlockT, Checkable, Hash}; +use stp_shield::{ + INHERENT_IDENTIFIER, InherentType, LOG_TARGET, MLKEM768_ENC_KEY_LEN, ShieldEncKey, + ShieldedTransaction, +}; + +use alloc::vec; + pub use pallet::*; + #[cfg(feature = "runtime-benchmarks")] mod benchmarking; @@ -11,460 +33,322 @@ pub mod mock; #[cfg(test)] mod tests; -#[frame_support::pallet] -pub mod pallet { - use super::*; - use codec::Encode; - use frame_support::{ - dispatch::{DispatchInfo, GetDispatchInfo, PostDispatchInfo}, - pallet_prelude::*, - traits::ConstU32, - traits::IsSubType, - weights::Weight, - }; - use frame_system::pallet_prelude::*; - use sp_consensus_aura::sr25519::AuthorityId as AuraAuthorityId; - use sp_core::ByteArray; - use sp_runtime::{ - AccountId32, DispatchErrorWithPostInfo, RuntimeDebug, Saturating, - traits::{ - BadOrigin, DispatchInfoOf, DispatchOriginOf, Dispatchable, Hash, Implication, - TransactionExtension, - }, - transaction_validity::{InvalidTransaction, TransactionSource, ValidTransaction}, - }; - use sp_std::{marker::PhantomData, prelude::*}; - use subtensor_macros::freeze_struct; - - /// Origin helper: ensure the signer is an Aura authority (no session/authorship). - pub struct EnsureAuraAuthority(PhantomData); - - pub trait AuthorityOriginExt { - type AccountId; - - fn ensure_validator(origin: Origin) -> Result; - } - - impl AuthorityOriginExt> for EnsureAuraAuthority - where - T: frame_system::Config - + pallet_aura::Config, - { - type AccountId = AccountId32; - - fn ensure_validator(origin: OriginFor) -> Result { - let who: AccountId32 = frame_system::ensure_signed(origin)?; +mod extension; +mod migrations; +pub use extension::CheckShieldedTxValidity; - let aura_id = - ::from_slice(who.as_ref()).map_err(|_| BadOrigin)?; +type MigrationKeyMaxLen = ConstU32<128>; - let is_validator = pallet_aura::Authorities::::get() - .into_iter() - .any(|id| id == aura_id); +type ExtrinsicOf = ::Extrinsic; +type CheckedOf = >::Checked; +type ApplyableCallOf = ::Call; - if is_validator { - Ok(who) - } else { - Err(BadOrigin) - } - } - } - - // ----------------- Types ----------------- +const MAX_EXTRINSIC_DEPTH: u32 = 8; - /// AEAD‑independent commitment over the revealed payload. - #[freeze_struct("66e393c88124f360")] - #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] - pub struct Submission { - pub author: AccountId, - pub commitment: Hash, - pub ciphertext: BoundedVec>, - pub submitted_in: BlockNumber, - } - - // ----------------- Config ----------------- +#[frame_support::pallet] +pub mod pallet { + use super::*; #[pallet::config] - pub trait Config: - frame_system::Config>> + pallet_aura::Config - { - type RuntimeCall: Parameter - + sp_runtime::traits::Dispatchable< - RuntimeOrigin = Self::RuntimeOrigin, - PostInfo = PostDispatchInfo, - > + GetDispatchInfo; + pub trait Config: frame_system::Config { + /// The identifier type for an authority. + type AuthorityId: Member + Parameter + MaybeSerializeDeserialize + MaxEncodedLen; - type AuthorityOrigin: AuthorityOriginExt; + /// A way to find the current and next block author. + type FindAuthors: FindAuthors; } #[pallet::pallet] pub struct Pallet(_); - // ----------------- Storage ----------------- + /// Current block author's ML-KEM-768 encapsulation key (internal, not for encryption). + #[pallet::storage] + pub type CurrentKey = StorageValue<_, ShieldEncKey, OptionQuery>; - /// Current ML‑KEM‑768 public key bytes (encoded form). + /// Next block author's key, staged here before promoting to `CurrentKey`. #[pallet::storage] - pub type CurrentKey = StorageValue<_, BoundedVec>, OptionQuery>; + pub type PendingKey = StorageValue<_, ShieldEncKey, OptionQuery>; - /// Next ML‑KEM‑768 public key bytes, announced by the block author. + /// Key users should encrypt with (N+2 author's key). #[pallet::storage] - pub type NextKey = StorageValue<_, BoundedVec>, OptionQuery>; + pub type NextKey = StorageValue<_, ShieldEncKey, OptionQuery>; - /// Buffered encrypted submissions, indexed by wrapper id. + /// Per-author ML-KEM-768 encapsulation key, updated each time the author produces a block. #[pallet::storage] - pub type Submissions = StorageMap< - _, - Blake2_128Concat, - T::Hash, - Submission, T::Hash>, - OptionQuery, - >; - - /// Hash(CurrentKey) per block, used to bind `key_hash` to the epoch at submit time. + pub type AuthorKeys = + StorageMap<_, Twox64Concat, T::AuthorityId, ShieldEncKey, OptionQuery>; + + /// Block number at which `PendingKey` is no longer valid (exclusive upper bound). + /// Updated every block during rotation. #[pallet::storage] - pub type KeyHashByBlock = - StorageMap<_, Blake2_128Concat, BlockNumberFor, T::Hash, OptionQuery>; + pub type PendingKeyExpiresAt = StorageValue<_, BlockNumberFor, OptionQuery>; - /// How many recent blocks of key-epoch hashes we retain. - const KEY_EPOCH_HISTORY: u32 = 100; + /// Block number at which `NextKey` is no longer valid (exclusive upper bound). + /// Updated every block during rotation. + #[pallet::storage] + pub type NextKeyExpiresAt = StorageValue<_, BlockNumberFor, OptionQuery>; - // ----------------- Events & Errors ----------------- + /// Stores whether some migration has been run. + #[pallet::storage] + pub type HasMigrationRun = + StorageMap<_, Identity, BoundedVec, bool, ValueQuery>; #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { /// Encrypted wrapper accepted. EncryptedSubmitted { id: T::Hash, who: T::AccountId }, - /// Decrypted call executed. - DecryptedExecuted { id: T::Hash, signer: T::AccountId }, - /// Decrypted execution rejected. - DecryptedRejected { - id: T::Hash, - reason: DispatchErrorWithPostInfo, - }, - /// Decryption failed - validator could not decrypt the submission. - DecryptionFailed { - id: T::Hash, - reason: BoundedVec>, - }, } #[pallet::error] pub enum Error { - /// A submission with the same id already exists in `Submissions`. - SubmissionAlreadyExists, - /// The referenced submission id does not exist in `Submissions`. - MissingSubmission, - /// The recomputed commitment does not match the stored commitment. - CommitmentMismatch, - /// The provided signature over the payload is invalid. - SignatureInvalid, - /// The announced ML‑KEM public key length is invalid. - BadPublicKeyLen, - /// The MEV‑Shield key epoch for this submission has expired and is no longer accepted. - KeyExpired, - /// The provided `key_hash` does not match the expected epoch key hash. - KeyHashMismatch, + /// The announced ML‑KEM encapsulation key length is invalid. + BadEncKeyLen, + /// Unreachable. + Unreachable, } - // ----------------- Hooks ----------------- - #[pallet::hooks] impl Hooks> for Pallet { - fn on_initialize(n: BlockNumberFor) -> Weight { - let db_weight = T::DbWeight::get(); - let mut reads: u64 = 0; - let mut writes: u64 = 0; - - // 1) Roll NextKey -> CurrentKey if a next key is present. - reads = reads.saturating_add(1); - writes = writes.saturating_add(1); - let mut current_opt: Option>> = - if let Some(next) = NextKey::::take() { - CurrentKey::::put(&next); - writes = writes.saturating_add(1); - Some(next) - } else { - None - }; - - // 2) If we didn't roll, read the existing CurrentKey exactly once. - if current_opt.is_none() { - reads = reads.saturating_add(1); - current_opt = CurrentKey::::get(); - } - - // 3) Maintain KeyHashByBlock entry for this block: - match current_opt { - Some(current) => { - let epoch_hash: T::Hash = T::Hashing::hash(current.as_ref()); - KeyHashByBlock::::insert(n, epoch_hash); - writes = writes.saturating_add(1); - } - None => { - KeyHashByBlock::::remove(n); - writes = writes.saturating_add(1); - } - } - - // 4) Prune old epoch hashes with a sliding window of size KEY_EPOCH_HISTORY. - let depth: BlockNumberFor = KEY_EPOCH_HISTORY.into(); - if n >= depth { - let prune_bn = n.saturating_sub(depth); - KeyHashByBlock::::remove(prune_bn); - writes = writes.saturating_add(1); - } - - // 5) TTL-based pruning of stale submissions. - let ttl: BlockNumberFor = KEY_EPOCH_HISTORY.into(); - let threshold: BlockNumberFor = n.saturating_sub(ttl); - - let mut to_remove: Vec = Vec::new(); + fn on_runtime_upgrade() -> frame_support::weights::Weight { + let mut weight = frame_support::weights::Weight::from_parts(0, 0); - for (id, sub) in Submissions::::iter() { - reads = reads.saturating_add(1); - if sub.submitted_in < threshold { - to_remove.push(id); - } - } - - for id in to_remove { - Submissions::::remove(id); - writes = writes.saturating_add(1); - } + weight = weight.saturating_add( + migrations::migrate_clear_v1_storage::migrate_clear_v1_storage::(), + ); - db_weight.reads_writes(reads, writes) + weight } } - // ----------------- Calls ----------------- - #[pallet::call] impl Pallet { - /// Announce the ML‑KEM public key that will become `CurrentKey` in - /// the following block. + /// Rotate the key chain and announce the current author's ML-KEM encapsulation key. + /// + /// Called as an inherent every block. `enc_key` is `None` on node failure, + /// which removes the author from future shielded tx eligibility. + /// + /// Key rotation order (using pre-update AuthorKeys): + /// 1. CurrentKey ← PendingKey + /// 2. PendingKey ← NextKey + /// 3. NextKey ← next-next author's key (user-facing) + /// 4. AuthorKeys[current] ← announced key #[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)))] - #[allow(clippy::useless_conversion)] + #[pallet::weight(Weight::from_parts(33_230_000, 0) + .saturating_add(T::DbWeight::get().reads(4_u64)) + .saturating_add(T::DbWeight::get().writes(6_u64)))] pub fn announce_next_key( origin: OriginFor, - public_key: BoundedVec>, - ) -> DispatchResultWithPostInfo { - // Only a current Aura validator may call this (signed account ∈ Aura authorities) - T::AuthorityOrigin::ensure_validator(origin)?; - - const MAX_KYBER768_PK_LENGTH: usize = 1184; - ensure!( - public_key.len() == MAX_KYBER768_PK_LENGTH, - Error::::BadPublicKeyLen - ); + enc_key: Option, + ) -> DispatchResult { + ensure_none(origin)?; + + let author = T::FindAuthors::find_current_author().ok_or(Error::::Unreachable)?; + let now = >::block_number(); + + // 1. CurrentKey ← PendingKey + if let Some(pending_key) = PendingKey::::take() { + CurrentKey::::put(pending_key); + } else { + CurrentKey::::kill(); + } + + // 2. PendingKey ← NextKey (what was N+2 last block is now N+1) + if let Some(next_key) = NextKey::::take() { + PendingKey::::put(next_key); + } else { + PendingKey::::kill(); + } + + // 3. NextKey ← next-next author's key + if let Some(next_next_author) = T::FindAuthors::find_next_next_author() + && let Some(key) = AuthorKeys::::get(&next_next_author) + { + NextKey::::put(key); + } else { + NextKey::::kill(); + } - NextKey::::put(public_key); + // 4. Update AuthorKeys after rotations for consistent reads above. + if let Some(enc_key) = &enc_key { + ensure!( + enc_key.len() == MLKEM768_ENC_KEY_LEN, + Error::::BadEncKeyLen + ); + AuthorKeys::::insert(&author, enc_key.clone()); + } else { + AuthorKeys::::remove(&author); + } + + // 5. Set expiration blocks for user-facing keys. + if PendingKey::::get().is_some() { + PendingKeyExpiresAt::::put(now + 2u32.into()); + } else { + PendingKeyExpiresAt::::kill(); + } + if NextKey::::get().is_some() { + NextKeyExpiresAt::::put(now + 3u32.into()); + } else { + NextKeyExpiresAt::::kill(); + } - // Refund the fee on success by setting pays_fee = Pays::No - Ok(PostDispatchInfo { - actual_weight: None, - pays_fee: Pays::No, - }) + Ok(()) } /// Users submit an encrypted wrapper. /// /// Client‑side: /// - /// 1. Read `NextKey` (ML‑KEM public key bytes) from storage. + /// 1. Read `NextKey` (ML‑KEM encapsulation key bytes) from storage. /// 2. Sign your extrinsic so that it can be executed when added to the pool, /// i.e. you may need to increment the nonce if you submit using the same account. - /// 3. `commitment = Hashing::hash(signed_extrinsic)`. - /// 4. Encrypt: + /// 3. Encrypt: /// /// plaintext = signed_extrinsic + /// key_hash = xxhash128(NextKey) + /// kem_len = Length of kem_ct in bytes (u16) + /// kem_ct = Ciphertext from ML‑KEM‑768 + /// nonce = Random 24 bytes used for XChaCha20‑Poly1305 + /// aead_ct = Ciphertext from XChaCha20‑Poly1305 /// /// with ML‑KEM‑768 + XChaCha20‑Poly1305, producing /// - /// ciphertext = [u16 kem_len] || kem_ct || nonce24 || aead_ct + /// ciphertext = key_hash || kem_len || kem_ct || nonce || aead_ct /// #[pallet::call_index(1)] - #[pallet::weight(( - Weight::from_parts(13_980_000, 0) - .saturating_add(T::DbWeight::get().reads(1_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)), - DispatchClass::Normal, - Pays::Yes, - ))] + #[pallet::weight(Weight::from_parts(207_500_000, 0) + .saturating_add(T::DbWeight::get().reads(0_u64)) + .saturating_add(T::DbWeight::get().writes(0_u64)))] pub fn submit_encrypted( origin: OriginFor, - commitment: T::Hash, ciphertext: BoundedVec>, ) -> DispatchResult { let who = ensure_signed(origin)?; + let id: T::Hash = T::Hashing::hash_of(&(who.clone(), &ciphertext)); - let id: T::Hash = T::Hashing::hash_of(&(who.clone(), commitment, &ciphertext)); - let sub = Submission::, T::Hash> { - author: who.clone(), - commitment, - ciphertext, - submitted_in: >::block_number(), - }; - ensure!( - !Submissions::::contains_key(id), - Error::::SubmissionAlreadyExists - ); - Submissions::::insert(id, sub); Self::deposit_event(Event::EncryptedSubmitted { id, who }); Ok(()) } - - /// Marks a submission as failed to decrypt and removes it from storage. - /// - /// Called by the block author when decryption fails at any stage (e.g., ML-KEM decapsulate - /// failed, AEAD decrypt failed, invalid ciphertext format, etc.). This allows clients to be - /// notified of decryption failures through on-chain events. - /// - /// # Arguments - /// - /// * `id` - The wrapper id (hash of (author, commitment, ciphertext)) - /// * `reason` - Human-readable reason for the decryption failure (e.g., "ML-KEM decapsulate failed") - #[pallet::call_index(3)] - #[pallet::weight(( - Weight::from_parts(13_260_000, 0) - .saturating_add(T::DbWeight::get().reads(1_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)), - DispatchClass::Normal, - Pays::No - ))] - pub fn mark_decryption_failed( - origin: OriginFor, - id: T::Hash, - reason: BoundedVec>, - ) -> DispatchResult { - // Unsigned: only the author node may inject this via ValidateUnsigned. - ensure_none(origin)?; - - // Load and consume the submission. - let Some(_sub) = Submissions::::take(id) else { - return Err(Error::::MissingSubmission.into()); - }; - - // Emit event to notify clients - Self::deposit_event(Event::DecryptionFailed { id, reason }); - - Ok(()) - } } - #[pallet::validate_unsigned] - impl ValidateUnsigned for Pallet { + #[pallet::inherent] + impl ProvideInherent for Pallet { type Call = Call; - - fn validate_unsigned(source: TransactionSource, call: &Self::Call) -> TransactionValidity { - match call { - Call::mark_decryption_failed { id, .. } => { - match source { - TransactionSource::Local | TransactionSource::InBlock => { - ValidTransaction::with_tag_prefix("mev-shield-failed") - .priority(1u64) - .longevity(64) // long because propagate(false) - .and_provides(id) // dedupe by wrapper id - .propagate(false) // CRITICAL: no gossip, stays on author node - .build() - } - _ => InvalidTransaction::Call.into(), - } - } - _ => InvalidTransaction::Call.into(), - } + type Error = sp_inherents::MakeFatalError<()>; + + const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER; + + fn create_inherent(data: &InherentData) -> Option { + let enc_key = data + .get_data::(&INHERENT_IDENTIFIER) + .inspect_err( + |e| log::debug!(target: LOG_TARGET, "Failed to get shielded enc key inherent data: {:?}", e), + ) + .ok()??; + Some(Call::announce_next_key { enc_key }) } - } - - #[freeze_struct("51f74eb54f5ab1fe")] - #[derive(Default, Encode, Decode, DecodeWithMemTracking, Clone, Eq, PartialEq, TypeInfo)] - pub struct MevShieldDecryptionFilter(pub PhantomData); - impl sp_std::fmt::Debug for MevShieldDecryptionFilter { - fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { - write!(f, "MevShieldDecryptionFilter") - } - } - - impl MevShieldDecryptionFilter { - pub fn new() -> Self { - Self(PhantomData) - } - - #[inline] - fn mev_failed_priority() -> TransactionPriority { - 1u64 + fn is_inherent(call: &Self::Call) -> bool { + matches!(call, Call::announce_next_key { .. }) } } +} - impl TransactionExtension> - for MevShieldDecryptionFilter +impl Pallet { + pub fn try_decode_shielded_tx( + uxt: ExtrinsicOf, + ) -> Option where - ::RuntimeCall: - Dispatchable, - ::RuntimeCall: IsSubType>, + Block::Extrinsic: Checkable, + CheckedOf: Applyable, + ApplyableCallOf>: IsSubType>, { - const IDENTIFIER: &'static str = "MevShieldDecryptionFilter"; + // Prevent stack overflows by limiting the depth of the extrinsic. + let encoded = uxt.encode(); + let uxt = ::decode_all_with_depth_limit( + MAX_EXTRINSIC_DEPTH, + &mut &encoded[..], + ) + .inspect_err( + |e| log::debug!(target: LOG_TARGET, "Failed to decode shielded extrinsic: {:?}", e), + ) + .ok()?; + + // Verify that the signature is correct. + let xt = ExtrinsicOf::::check(uxt, &Context::default()) + .inspect_err( + |e| log::debug!(target: LOG_TARGET, "Failed to check shielded extrinsic: {:?}", e), + ) + .ok()?; + let call = xt.call(); + + let Some(Call::submit_encrypted { ciphertext }) = IsSubType::>::is_sub_type(call) + else { + return None; + }; + + ShieldedTransaction::parse(ciphertext) + } - type Implicit = (); - type Val = (); - type Pre = (); + pub fn is_shielded_using_current_key(key_hash: &[u8; 16]) -> bool { + let pending = PendingKey::::get(); + let pending_hash = pending.as_ref().map(|k| twox_128(&k[..])); + pending_hash.as_ref() == Some(key_hash) + } - fn weight(&self, _call: &RuntimeCallFor) -> Weight { - // Only does light pattern matching; treat as free. - Weight::zero() + pub fn try_unshield_tx( + dec_key_bytes: alloc::vec::Vec, + shielded_tx: ShieldedTransaction, + ) -> Option<::Extrinsic> { + let plaintext = unshield(&dec_key_bytes, &shielded_tx).or_else(|| { + log::debug!(target: LOG_TARGET, "Failed to unshield transaction"); + None + })?; + + if plaintext.is_empty() { + return None; } - fn validate( - &self, - origin: DispatchOriginOf>, - call: &RuntimeCallFor, - _info: &DispatchInfoOf>, - _len: usize, - _self_implicit: Self::Implicit, - _inherited_implication: &impl Implication, - source: TransactionSource, - ) -> ValidateResult> { - match call.is_sub_type() { - Some(Call::mark_decryption_failed { id, .. }) => { - match source { - TransactionSource::Local | TransactionSource::InBlock => { - let validity_res = - ValidTransaction::with_tag_prefix("mev-shield-failed") - .priority(Self::mev_failed_priority()) - .longevity(64) - .and_provides(id) - .propagate(false) - .build(); - - match validity_res { - Ok(validity) => Ok((validity, (), origin)), - Err(e) => Err(e), - } - } - - // Anything coming from the outside world (including *signed* - // transactions) is rejected at the pool boundary. - _ => Err(InvalidTransaction::Call.into()), - } - } - - _ => Ok((Default::default(), (), origin)), - } - } + ExtrinsicOf::::decode(&mut &plaintext[..]).inspect_err( + |e| log::debug!(target: LOG_TARGET, "Failed to decode shielded transaction: {:?}", e), + ).ok() + } +} - fn prepare( - self, - _val: Self::Val, - _origin: &DispatchOriginOf>, - _call: &RuntimeCallFor, - _info: &DispatchInfoOf>, - _len: usize, - ) -> Result { - Ok(()) - } +pub trait FindAuthors { + fn find_current_author() -> Option; + fn find_next_next_author() -> Option; +} + +impl FindAuthors for () { + fn find_current_author() -> Option { + None + } + fn find_next_next_author() -> Option { + None } } + +/// Decrypt a shielded transaction using the raw decapsulation key bytes. +/// +/// Performs ML-KEM-768 decapsulation followed by XChaCha20-Poly1305 AEAD decryption. +/// Runs entirely in WASM — no host functions needed. +fn unshield( + dec_key_bytes: &[u8], + shielded_tx: &ShieldedTransaction, +) -> Option> { + let dec_key = DecapsulationKey::::from_bytes(dec_key_bytes.try_into().ok()?); + let ciphertext = Ciphertext::::try_from(shielded_tx.kem_ct.as_slice()).ok()?; + let shared_secret = dec_key.decapsulate(&ciphertext).ok()?; + + let aead = XChaCha20Poly1305::new(shared_secret.as_slice().into()); + let nonce = XNonce::from_slice(&shielded_tx.nonce); + aead.decrypt( + nonce, + Payload { + msg: &shielded_tx.aead_ct, + aad: &[], + }, + ) + .ok() +} diff --git a/pallets/shield/src/migrations/migrate_clear_v1_storage.rs b/pallets/shield/src/migrations/migrate_clear_v1_storage.rs new file mode 100644 index 0000000000..e3c55d8713 --- /dev/null +++ b/pallets/shield/src/migrations/migrate_clear_v1_storage.rs @@ -0,0 +1,49 @@ +use super::*; +use frame_support::storage::unhashed; +use scale_info::prelude::string::String; +use sp_io::hashing::twox_128; + +/// Clears removed v1 storage items (`Submissions`, `KeyHashByBlock`) and resets `CurrentKey`. +pub fn migrate_clear_v1_storage() -> Weight { + let migration_name = b"migrate_clear_v1_storage".to_vec(); + let bounded_name = BoundedVec::truncate_from(migration_name.clone()); + let mut weight = T::DbWeight::get().reads(1); + + if HasMigrationRun::::get(&bounded_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) + ); + + let pallet_prefix = twox_128("MevShield".as_bytes()); + + // Clear removed storage maps. + for name in ["Submissions", "KeyHashByBlock"] { + let prefix = [pallet_prefix.as_slice(), &twox_128(name.as_bytes())].concat(); + let result = unhashed::clear_prefix(&prefix, Some(u32::MAX), None); + weight = weight.saturating_add(T::DbWeight::get().writes(result.backend as u64)); + + log::info!("Removed {} entries from {name:?}.", result.backend,); + } + + // Reset current key. + CurrentKey::::kill(); + weight = weight.saturating_add(T::DbWeight::get().writes(1)); + + HasMigrationRun::::insert(&bounded_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/shield/src/migrations/mod.rs b/pallets/shield/src/migrations/mod.rs new file mode 100644 index 0000000000..1069de5297 --- /dev/null +++ b/pallets/shield/src/migrations/mod.rs @@ -0,0 +1,4 @@ +use crate::*; +use frame_support::{traits::Get, weights::Weight}; + +pub mod migrate_clear_v1_storage; diff --git a/pallets/shield/src/mock.rs b/pallets/shield/src/mock.rs index 0732670406..5a2aef7d80 100644 --- a/pallets/shield/src/mock.rs +++ b/pallets/shield/src/mock.rs @@ -1,145 +1,141 @@ -use crate as pallet_mev_shield; - -use frame_support::{construct_runtime, derive_impl, parameter_types, traits::Everything}; -use frame_system as system; +use crate as pallet_shield; +use stp_shield::MLKEM768_ENC_KEY_LEN; +use frame_support::traits::{ConstBool, ConstU64}; +use frame_support::{BoundedVec, construct_runtime, derive_impl, parameter_types}; use sp_consensus_aura::sr25519::AuthorityId as AuraId; -use sp_core::{ConstU32, H256}; -use sp_runtime::traits::BadOrigin; -use sp_runtime::{ - AccountId32, BuildStorage, - traits::{BlakeTwo256, IdentityLookup}, -}; +use sp_core::sr25519; +use sp_runtime::{BuildStorage, generic, testing::TestSignature}; +use std::cell::RefCell; +use stp_shield::ShieldEncKey; -// ----------------------------------------------------------------------------- -// Mock runtime -// ----------------------------------------------------------------------------- +pub type Block = frame_system::mocking::MockBlock; -pub type UncheckedExtrinsic = system::mocking::MockUncheckedExtrinsic; -pub type Block = system::mocking::MockBlock; +pub type DecodableExtrinsic = generic::UncheckedExtrinsic; +pub type DecodableBlock = + generic::Block, DecodableExtrinsic>; construct_runtime!( pub enum Test { System: frame_system = 0, Timestamp: pallet_timestamp = 1, Aura: pallet_aura = 2, - MevShield: pallet_mev_shield = 3, + MevShield: pallet_shield = 3, + Utility: pallet_subtensor_utility = 4, } ); -// A concrete nonce type used in tests. -pub type TestNonce = u64; - -#[derive_impl(frame_system::config_preludes::TestDefaultConfig)] -impl system::Config for Test { - // Basic system config - type BaseCallFilter = Everything; - type BlockWeights = (); - type BlockLength = (); - type DbWeight = (); - - type RuntimeOrigin = RuntimeOrigin; - type RuntimeCall = RuntimeCall; - type RuntimeEvent = RuntimeEvent; - - type Nonce = TestNonce; - type Hash = H256; - type Hashing = BlakeTwo256; +const SLOT_DURATION: u64 = 6000; - type AccountId = AccountId32; - type Lookup = IdentityLookup; - type Block = Block; - - type BlockHashCount = (); - type Version = (); - type PalletInfo = PalletInfo; - - type AccountData = (); - type OnNewAccount = (); - type OnKilledAccount = (); - type SystemWeightInfo = (); - type SS58Prefix = (); - type OnSetCode = (); - - // Max number of consumer refs per account. - type MaxConsumers = ConstU32<16>; +parameter_types! { + pub const SlotDuration: u64 = SLOT_DURATION; + pub const MaxAuthorities: u32 = 32; } -parameter_types! { - pub const MinimumPeriod: u64 = 1; +#[derive_impl(frame_system::config_preludes::TestDefaultConfig)] +impl frame_system::Config for Test { + type Block = Block; } impl pallet_timestamp::Config for Test { type Moment = u64; type OnTimestampSet = (); - type MinimumPeriod = MinimumPeriod; + type MinimumPeriod = ConstU64<{ SLOT_DURATION / 2 }>; type WeightInfo = (); } -// Aura mock configuration -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 AllowMultipleBlocksPerSlot = ConstBool; type SlotDuration = SlotDuration; } -// ----------------------------------------------------------------------------- -// Authority origin for tests – root-only -// ----------------------------------------------------------------------------- - -/// For tests, treat Root as the “validator set” and return a dummy AccountId. -pub struct TestAuthorityOrigin; - -impl pallet_mev_shield::AuthorityOriginExt for TestAuthorityOrigin { - type AccountId = AccountId32; +impl pallet_subtensor_utility::Config for Test { + type RuntimeCall = RuntimeCall; + type PalletsOrigin = OriginCaller; + type WeightInfo = (); +} - fn ensure_validator(origin: RuntimeOrigin) -> Result { - // Must be a signed origin. - let who: AccountId32 = frame_system::ensure_signed(origin).map_err(|_| BadOrigin)?; +thread_local! { + static MOCK_CURRENT: RefCell> = const { RefCell::new(None) }; + static MOCK_NEXT_NEXT: RefCell>> = const { RefCell::new(None) }; +} - // Interpret the AccountId bytes as an AuraId, just like the real pallet. - let aura_id = - ::from_slice(who.as_ref()).map_err(|_| BadOrigin)?; +pub struct MockFindAuthors; - // Check membership in the Aura validator set. - let is_validator = pallet_aura::Authorities::::get() - .into_iter() - .any(|id| id == aura_id); +impl pallet_shield::FindAuthors for MockFindAuthors { + fn find_current_author() -> Option { + // Thread-local override (unit tests) → Aura fallback (benchmarks). + MOCK_CURRENT.with(|c| c.borrow().clone()).or_else(|| { + let slot = Aura::current_slot_from_digests()?; + let auths = pallet_aura::Authorities::::get().into_inner(); + auths.get(*slot as usize % auths.len()).cloned() + }) + } - if is_validator { - Ok(who) - } else { - Err(BadOrigin) + fn find_next_next_author() -> Option { + if let Some(val) = MOCK_NEXT_NEXT.with(|n| n.borrow().clone()) { + return val; } + let slot = Aura::current_slot_from_digests()?.checked_add(2)?; + let auths = pallet_aura::Authorities::::get().into_inner(); + auths.get(slot as usize % auths.len()).cloned() } } -// ----------------------------------------------------------------------------- -// MevShield Config -// ----------------------------------------------------------------------------- - -impl pallet_mev_shield::Config for Test { - type RuntimeCall = RuntimeCall; - type AuthorityOrigin = TestAuthorityOrigin; +impl pallet_shield::Config for Test { + type AuthorityId = AuraId; + type FindAuthors = MockFindAuthors; } -// ----------------------------------------------------------------------------- -// new_test_ext -// ----------------------------------------------------------------------------- - pub fn new_test_ext() -> sp_io::TestExternalities { - // Use the construct_runtime!-generated genesis config. - RuntimeGenesisConfig::default() + let mut ext: sp_io::TestExternalities = RuntimeGenesisConfig::default() .build_storage() - .expect("RuntimeGenesisConfig builds valid default genesis storage") - .into() + .expect("valid genesis") + .into(); + ext.register_extension(sp_keystore::KeystoreExt::new( + sp_keystore::testing::MemoryKeystore::new(), + )); + ext +} + +pub fn valid_pk() -> ShieldEncKey { + BoundedVec::truncate_from(vec![0x42; MLKEM768_ENC_KEY_LEN]) +} + +pub fn valid_pk_b() -> ShieldEncKey { + BoundedVec::truncate_from(vec![0x99; MLKEM768_ENC_KEY_LEN]) +} + +/// Create a deterministic `AuraId` from a simple index for tests. +pub fn author(n: u8) -> AuraId { + AuraId::from(sr25519::Public::from_raw([n; 32])) +} + +pub fn set_authors(current: Option, next_next: Option) { + MOCK_CURRENT.with(|c| *c.borrow_mut() = current); + MOCK_NEXT_NEXT.with(|n| *n.borrow_mut() = Some(next_next)); +} + +pub fn nest_call(call: RuntimeCall, depth: usize) -> RuntimeCall { + (0..depth).fold(call, |inner, _| { + RuntimeCall::Utility(pallet_subtensor_utility::Call::batch { calls: vec![inner] }) + }) +} + +pub fn build_wire_ciphertext( + key_hash: &[u8; 16], + kem_ct: &[u8], + nonce: &[u8; 24], + aead_ct: &[u8], +) -> Vec { + let mut buf = Vec::new(); + buf.extend_from_slice(key_hash); + buf.extend_from_slice(&(kem_ct.len() as u16).to_le_bytes()); + buf.extend_from_slice(kem_ct); + buf.extend_from_slice(nonce); + buf.extend_from_slice(aead_ct); + buf } diff --git a/pallets/shield/src/tests.rs b/pallets/shield/src/tests.rs index 18eda7eacc..04eb29126b 100644 --- a/pallets/shield/src/tests.rs +++ b/pallets/shield/src/tests.rs @@ -1,443 +1,462 @@ -use crate as pallet_mev_shield; use crate::mock::*; - -use frame_support::{ - BoundedVec, assert_noop, assert_ok, - traits::{ConstU32 as FrameConstU32, Hooks}, -}; -use frame_system::pallet_prelude::BlockNumberFor; -use pallet_mev_shield::{ - Call as MevShieldCall, CurrentKey, Event as MevShieldEvent, KeyHashByBlock, NextKey, - Submissions, +use crate::{ + AuthorKeys, CurrentKey, Error, HasMigrationRun, NextKey, NextKeyExpiresAt, PendingKey, + PendingKeyExpiresAt, }; -use sp_core::{Pair, sr25519}; -use sp_runtime::{ - AccountId32, - traits::{Hash, SaturatedConversion}, -}; - -// Type aliases for convenience in tests. -type TestHash = ::Hash; -type TestBlockNumber = BlockNumberFor; -// ----------------------------------------------------------------------------- -// Helpers -// ----------------------------------------------------------------------------- +use codec::Encode; +use frame_support::{BoundedVec, assert_noop, assert_ok}; +use sp_runtime::testing::TestSignature; +use sp_runtime::traits::{Block as BlockT, Hash}; +use stp_shield::{MLKEM768_ENC_KEY_LEN, ShieldEncKey, ShieldKeystore, ShieldedTransaction}; -/// Deterministic sr25519 pair for tests (acts as "Alice"). -fn test_sr25519_pair() -> sr25519::Pair { - sr25519::Pair::from_seed(&[1u8; 32]) -} - -// ----------------------------------------------------------------------------- -// Tests -// ----------------------------------------------------------------------------- +use chacha20poly1305::{ + KeyInit, XChaCha20Poly1305, XNonce, + aead::{Aead, Payload}, +}; +use ml_kem::{ + EncodedSizeUser, MlKem768Params, + kem::{Encapsulate, EncapsulationKey}, +}; +use rand_chacha::{ChaChaRng, rand_core::SeedableRng}; +use stc_shield::MemoryShieldKeystore; +/// Simulates a 3-validator round-robin (authors 1, 2, 3) over 5 blocks. +/// Each block calls `announce_next_key` and verifies the full pipeline: +/// CurrentKey, PendingKey, NextKey, AuthorKeys, expirations, and +/// `is_shielded_using_current_key`. #[test] -fn authority_can_announce_next_key_and_on_initialize_rolls_it_and_records_epoch_hash() { +fn key_rotation_round_robin() { new_test_ext().execute_with(|| { - const KYBER_PK_LEN: usize = 1184; - let pk_bytes = vec![7u8; KYBER_PK_LEN]; - let bounded_pk: BoundedVec> = - BoundedVec::truncate_from(pk_bytes.clone()); - - // Seed Aura authorities with a single validator and derive the matching account. - let validator_pair = test_sr25519_pair(); - let validator_account: AccountId32 = validator_pair.public().into(); - let validator_aura_id: ::AuthorityId = - validator_pair.public().into(); - - // Authorities storage expects a BoundedVec. - let authorities: BoundedVec< - ::AuthorityId, - ::MaxAuthorities, - > = BoundedVec::truncate_from(vec![validator_aura_id.clone()]); - pallet_aura::Authorities::::put(authorities); + let key_of = + |n: u8| -> ShieldEncKey { BoundedVec::truncate_from(vec![n; MLKEM768_ENC_KEY_LEN]) }; + let hash_of = |pk: &ShieldEncKey| sp_io::hashing::twox_128(&pk[..]); + + // 3 validators in round-robin: 1, 2, 3, 1, 2. + let authors = [1u8, 2, 3, 1, 2]; + let next_next = |block: usize| -> Option { authors.get(block + 2).copied() }; + + // ── Block 1: author=1, next_next=3 ────────────────────────────── + // Pipeline is empty; author(3) has no AuthorKeys yet. + System::set_block_number(1); + set_authors(Some(author(1)), next_next(0).map(author)); + assert_ok!(MevShield::announce_next_key( + RuntimeOrigin::none(), + Some(key_of(1)), + )); assert!(CurrentKey::::get().is_none()); + assert!(PendingKey::::get().is_none()); assert!(NextKey::::get().is_none()); - - // Signed by an Aura validator -> passes TestAuthorityOrigin::ensure_validator. + assert_eq!(AuthorKeys::::get(author(1)), Some(key_of(1))); + assert!(PendingKeyExpiresAt::::get().is_none()); + assert!(NextKeyExpiresAt::::get().is_none()); + // Nothing in PendingKey → is_shielded always false. + assert!(!MevShield::is_shielded_using_current_key(&[0xFF; 16])); + + // ── Block 2: author=2, next_next=1 ────────────────────────────── + // author(1) registered in block 1 → NextKey picks up key_of(1). + System::set_block_number(2); + set_authors(Some(author(2)), next_next(1).map(author)); assert_ok!(MevShield::announce_next_key( - RuntimeOrigin::signed(validator_account.clone()), - bounded_pk.clone(), + RuntimeOrigin::none(), + Some(key_of(2)), )); - // NextKey storage updated - let next = NextKey::::get().expect("NextKey should be set"); - assert_eq!(next, pk_bytes); + assert!(CurrentKey::::get().is_none()); + assert!(PendingKey::::get().is_none()); + assert_eq!(NextKey::::get(), Some(key_of(1))); + assert_eq!(AuthorKeys::::get(author(2)), Some(key_of(2))); + assert!(PendingKeyExpiresAt::::get().is_none()); + assert_eq!(NextKeyExpiresAt::::get(), Some(5)); // 2 + 3 + + // ── Block 3: author=3, next_next=2 ────────────────────────────── + // NextKey(key_of(1)) → PendingKey; next_next=author(2) has key_of(2) → NextKey. + System::set_block_number(3); + set_authors(Some(author(3)), next_next(2).map(author)); + assert_ok!(MevShield::announce_next_key( + RuntimeOrigin::none(), + Some(key_of(3)), + )); - // Simulate beginning of block #2. - let block_two: TestBlockNumber = 2u64.saturated_into(); - MevShield::on_initialize(block_two); + assert!(CurrentKey::::get().is_none()); + assert_eq!(PendingKey::::get(), Some(key_of(1))); + assert_eq!(NextKey::::get(), Some(key_of(2))); + assert_eq!(AuthorKeys::::get(author(3)), Some(key_of(3))); + assert_eq!(PendingKeyExpiresAt::::get(), Some(5)); // 3 + 2 + assert_eq!(NextKeyExpiresAt::::get(), Some(6)); // 3 + 3 + // PendingKey = key_of(1) → is_shielded matches its hash. + assert!(MevShield::is_shielded_using_current_key(&hash_of(&key_of( + 1 + )))); + assert!(!MevShield::is_shielded_using_current_key(&hash_of( + &key_of(2) + ))); + assert!(!MevShield::is_shielded_using_current_key(&[0xFF; 16])); + + // ── Block 4: author=1, next_next=out of bounds ────────────────── + // Full pipeline: PendingKey(key_of(1)) → CurrentKey, NextKey(key_of(2)) → PendingKey. + System::set_block_number(4); + set_authors(Some(author(1)), next_next(3).map(author)); + assert_ok!(MevShield::announce_next_key( + RuntimeOrigin::none(), + Some(key_of(1)), + )); - // CurrentKey should now equal the previously announced NextKey. - let curr = CurrentKey::::get().expect("CurrentKey should be set"); - assert_eq!(curr, pk_bytes); + assert_eq!(CurrentKey::::get(), Some(key_of(1))); + assert_eq!(PendingKey::::get(), Some(key_of(2))); + assert!(NextKey::::get().is_none()); + assert_eq!(AuthorKeys::::get(author(1)), Some(key_of(1))); + assert_eq!(PendingKeyExpiresAt::::get(), Some(6)); // 4 + 2 + assert!(NextKeyExpiresAt::::get().is_none()); + // PendingKey = key_of(2). + assert!(MevShield::is_shielded_using_current_key(&hash_of(&key_of( + 2 + )))); + assert!(!MevShield::is_shielded_using_current_key(&hash_of( + &key_of(1) + ))); + + // ── Block 5: author=2, next_next=none ─────────────────────────── + // PendingKey(key_of(2)) → CurrentKey; pipeline drains. + System::set_block_number(5); + set_authors(Some(author(2)), None); + assert_ok!(MevShield::announce_next_key( + RuntimeOrigin::none(), + Some(key_of(2)), + )); - // And NextKey cleared. + assert_eq!(CurrentKey::::get(), Some(key_of(2))); + assert!(PendingKey::::get().is_none()); assert!(NextKey::::get().is_none()); + assert!(PendingKeyExpiresAt::::get().is_none()); + assert!(NextKeyExpiresAt::::get().is_none()); + }); +} + +/// AuthorKeys is read *before* being updated, so when current == next_next +/// the NextKey picks up the old key, not the newly announced one. +#[test] +fn announce_rotations_use_pre_update_author_keys() { + new_test_ext().execute_with(|| { + set_authors(Some(author(1)), Some(author(1))); + + let old_pk = valid_pk(); + let new_pk = valid_pk_b(); + AuthorKeys::::insert(author(1), old_pk.clone()); + + assert_ok!(MevShield::announce_next_key( + RuntimeOrigin::none(), + Some(new_pk.clone()), + )); - // Key hash for this block should be recorded and equal hash(CurrentKey_bytes). - let expected_hash: TestHash = ::Hashing::hash(curr.as_ref()); - let recorded = - KeyHashByBlock::::get(block_two).expect("epoch key hash must be recorded"); - assert_eq!(recorded, expected_hash); + assert_eq!(NextKey::::get(), Some(old_pk)); + assert_eq!(AuthorKeys::::get(author(1)), Some(new_pk)); }); } #[test] -fn announce_next_key_rejects_non_validator_origins() { +fn announce_rejects_signed_origin() { new_test_ext().execute_with(|| { - const KYBER_PK_LEN: usize = 1184; - - // Validator account: bytes match the Aura authority we put into storage. - let validator_pair = test_sr25519_pair(); - let validator_account: AccountId32 = validator_pair.public().into(); - let validator_aura_id: ::AuthorityId = - validator_pair.public().into(); - - // Non‑validator is some other key (not in Aura::Authorities). - let non_validator_pair = sr25519::Pair::from_seed(&[2u8; 32]); - let non_validator: AccountId32 = non_validator_pair.public().into(); - - // Only the validator is in the Aura validator set. - let authorities: BoundedVec< - ::AuthorityId, - ::MaxAuthorities, - > = BoundedVec::truncate_from(vec![validator_aura_id.clone()]); - pallet_aura::Authorities::::put(authorities); - - let pk_bytes = vec![9u8; KYBER_PK_LEN]; - let bounded_pk: BoundedVec> = - BoundedVec::truncate_from(pk_bytes.clone()); - - // 1) Signed non‑validator origin must fail with BadOrigin. + set_authors(Some(author(1)), None); assert_noop!( - MevShield::announce_next_key( - RuntimeOrigin::signed(non_validator.clone()), - bounded_pk.clone(), - ), + MevShield::announce_next_key(RuntimeOrigin::signed(1), Some(valid_pk())), sp_runtime::DispatchError::BadOrigin ); + }); +} + +#[test] +fn announce_rejects_bad_pk_length() { + new_test_ext().execute_with(|| { + set_authors(Some(author(1)), None); + let bad_pk: ShieldEncKey = BoundedVec::truncate_from(vec![0x01; 100]); - // 2) Unsigned origin must also fail with BadOrigin. assert_noop!( - MevShield::announce_next_key(RuntimeOrigin::none(), bounded_pk.clone(),), - sp_runtime::DispatchError::BadOrigin + MevShield::announce_next_key(RuntimeOrigin::none(), Some(bad_pk)), + Error::::BadEncKeyLen ); + }); +} - // 3) Signed validator origin succeeds (sanity check). - assert_ok!(MevShield::announce_next_key( - RuntimeOrigin::signed(validator_account.clone()), - bounded_pk.clone(), - )); +#[test] +fn announce_none_pk_removes_author_key() { + new_test_ext().execute_with(|| { + set_authors(Some(author(1)), None); + AuthorKeys::::insert(author(1), valid_pk()); + + assert_ok!(MevShield::announce_next_key(RuntimeOrigin::none(), None)); - let next = NextKey::::get().expect("NextKey must be set by validator"); - assert_eq!(next, pk_bytes); + assert!(AuthorKeys::::get(author(1)).is_none()); }); } #[test] -fn submit_encrypted_stores_submission_and_emits_event() { +fn announce_fails_when_no_current_author() { new_test_ext().execute_with(|| { - let pair = test_sr25519_pair(); - let who: AccountId32 = pair.public().into(); + set_authors(None, None); + + assert_noop!( + MevShield::announce_next_key(RuntimeOrigin::none(), Some(valid_pk())), + Error::::Unreachable + ); + }); +} - System::set_block_number(10); +#[test] +fn submit_encrypted_emits_event() { + new_test_ext().execute_with(|| { + System::set_block_number(1); - let commitment = - ::Hashing::hash(b"test-mevshield-commitment"); - let ciphertext_bytes = vec![1u8, 2, 3, 4]; - let ciphertext: BoundedVec> = - BoundedVec::truncate_from(ciphertext_bytes.clone()); + let ciphertext = BoundedVec::truncate_from(vec![0xAA; 64]); + let who: u64 = 1; assert_ok!(MevShield::submit_encrypted( - RuntimeOrigin::signed(who.clone()), - commitment, + RuntimeOrigin::signed(who), ciphertext.clone(), )); - let id = ::Hashing::hash_of(&( - who.clone(), - commitment, - &ciphertext, - )); + let expected_id = ::Hashing::hash_of(&(who, &ciphertext)); - let stored = Submissions::::get(id).expect("submission stored"); - assert_eq!(stored.author, who); - assert_eq!(stored.commitment, commitment); - assert_eq!(stored.ciphertext.to_vec(), ciphertext_bytes); - assert_eq!(stored.submitted_in, 10); - - let events = System::events(); - let last = events.last().expect("at least one event").event.clone(); - - assert!( - matches!( - last, - RuntimeEvent::MevShield( - MevShieldEvent::::EncryptedSubmitted { id: ev_id, who: ev_who } - ) - if ev_id == id && ev_who == who - ), - "expected EncryptedSubmitted event with correct id & who", + System::assert_last_event( + crate::Event::::EncryptedSubmitted { + id: expected_id, + who, + } + .into(), ); }); } #[test] -fn key_hash_by_block_prunes_old_entries() { +fn submit_encrypted_rejects_unsigned() { new_test_ext().execute_with(|| { - // This must match the constant configured in the pallet. - const KEEP: u64 = 100; - const TOTAL: u64 = KEEP + 5; - - // For each block n, set a CurrentKey and call on_initialize(n), - // which will record KeyHashByBlock[n] and prune old entries. - for n in 1..=TOTAL { - let key_bytes = vec![n as u8; 32]; - let bounded: BoundedVec> = - BoundedVec::truncate_from(key_bytes.clone()); - - CurrentKey::::put(bounded.clone()); - - let bn: TestBlockNumber = n.saturated_into(); - MevShield::on_initialize(bn); - } - - // The oldest block that should still be kept after TOTAL blocks. - let oldest_kept: u64 = if TOTAL > KEEP { TOTAL - KEEP + 1 } else { 1 }; - - // Blocks strictly before oldest_kept must be pruned. - for old in 0..oldest_kept { - let bn: TestBlockNumber = old.saturated_into(); - assert!( - KeyHashByBlock::::get(bn).is_none(), - "block {bn:?} should have been pruned" - ); - } - - // Blocks from oldest_kept..=TOTAL must still have entries. - for recent in oldest_kept..=TOTAL { - let bn: TestBlockNumber = recent.saturated_into(); - assert!( - KeyHashByBlock::::get(bn).is_some(), - "block {bn:?} should be retained" - ); - } + let ciphertext = BoundedVec::truncate_from(vec![0xAA; 64]); - // Additionally, assert we never exceed the configured cap. - let mut count: u64 = 0; - for bn in 0..=TOTAL { - let bn_t: TestBlockNumber = bn.saturated_into(); - if KeyHashByBlock::::get(bn_t).is_some() { - count += 1; - } - } - let expected = KEEP.min(TOTAL); - assert_eq!( - count, expected, - "expected at most {expected} entries in KeyHashByBlock after pruning, got {count}" + assert_noop!( + MevShield::submit_encrypted(RuntimeOrigin::none(), ciphertext), + sp_runtime::DispatchError::BadOrigin ); }); } #[test] -fn submissions_pruned_after_ttl_window() { +fn try_decode_shielded_tx_parses_bare_submit_encrypted() { new_test_ext().execute_with(|| { - // This must match KEY_EPOCH_HISTORY in the pallet. - const KEEP: u64 = 100; - const TOTAL: u64 = KEEP + 5; - - let pair = test_sr25519_pair(); - let who: AccountId32 = pair.public().into(); - - // Helper: create a submission at a specific block with a tagged commitment. - let make_submission = |block: u64, tag: &[u8]| -> TestHash { - System::set_block_number(block); - let commitment: TestHash = ::Hashing::hash(tag); - let ciphertext_bytes = vec![block as u8; 4]; - let ciphertext: BoundedVec> = - BoundedVec::truncate_from(ciphertext_bytes); - - assert_ok!(MevShield::submit_encrypted( - RuntimeOrigin::signed(who.clone()), - commitment, - ciphertext.clone(), - )); - - ::Hashing::hash_of(&( - who.clone(), - commitment, - &ciphertext, - )) - }; - - // With n = TOTAL and depth = KEEP, prune_before = n - KEEP = 5. - let stale_block1: u64 = 1; // < 5, should be pruned - let stale_block2: u64 = 4; // < 5, should be pruned - let keep_block1: u64 = 5; // == prune_before, should be kept - let keep_block2: u64 = TOTAL; // latest, should be kept - - let id_stale1 = make_submission(stale_block1, b"stale-1"); - let id_stale2 = make_submission(stale_block2, b"stale-2"); - let id_keep1 = make_submission(keep_block1, b"keep-1"); - let id_keep2 = make_submission(keep_block2, b"keep-2"); - - // Sanity: all are present before pruning. - assert!(Submissions::::get(id_stale1).is_some()); - assert!(Submissions::::get(id_stale2).is_some()); - assert!(Submissions::::get(id_keep1).is_some()); - assert!(Submissions::::get(id_keep2).is_some()); - - // Run on_initialize at block TOTAL, triggering TTL pruning over Submissions. - let n_final: TestBlockNumber = TOTAL.saturated_into(); - MevShield::on_initialize(n_final); - - // Submissions with submitted_in < prune_before (5) should be gone. - assert!(Submissions::::get(id_stale1).is_none()); - assert!(Submissions::::get(id_stale2).is_none()); - - // Submissions at or after prune_before should remain. - assert!(Submissions::::get(id_keep1).is_some()); - assert!(Submissions::::get(id_keep2).is_some()); + let key_hash = [0xAB; 16]; + let kem_ct = vec![0xCC; 32]; + let nonce = [0xDD; 24]; + let aead_ct = vec![0xEE; 64]; + + let ciphertext = build_wire_ciphertext(&key_hash, &kem_ct, &nonce, &aead_ct); + let call = RuntimeCall::MevShield(crate::Call::submit_encrypted { + ciphertext: BoundedVec::truncate_from(ciphertext), + }); + let uxt = DecodableExtrinsic::new_bare(call); + + let result = crate::Pallet::::try_decode_shielded_tx::< + DecodableBlock, + frame_system::ChainContext, + >(uxt); + assert!(result.is_some()); + + let shielded = result.unwrap(); + assert_eq!(shielded.key_hash, key_hash); + assert_eq!(shielded.kem_ct, kem_ct); + assert_eq!(shielded.nonce, nonce); + assert_eq!(shielded.aead_ct, aead_ct); }); } #[test] -fn mark_decryption_failed_removes_submission_and_emits_event() { +fn try_decode_shielded_tx_returns_none_for_non_shield_call() { new_test_ext().execute_with(|| { - System::set_block_number(42); - let pair = test_sr25519_pair(); - let who: AccountId32 = pair.public().into(); - - let commitment: TestHash = - ::Hashing::hash(b"failed-decryption-commitment"); - let ciphertext_bytes = vec![5u8; 8]; - let ciphertext: BoundedVec> = - BoundedVec::truncate_from(ciphertext_bytes.clone()); - - assert_ok!(MevShield::submit_encrypted( - RuntimeOrigin::signed(who.clone()), - commitment, - ciphertext.clone(), - )); - - let id: TestHash = ::Hashing::hash_of(&( - who.clone(), - commitment, - &ciphertext, - )); - - // Sanity: submission exists. - assert!(Submissions::::get(id).is_some()); - - // Reason we will pass into mark_decryption_failed. - let reason_bytes = b"AEAD decrypt failed".to_vec(); - let reason: BoundedVec> = - BoundedVec::truncate_from(reason_bytes.clone()); + let call = RuntimeCall::System(frame_system::Call::remark { remark: vec![] }); + let uxt = DecodableExtrinsic::new_bare(call); + + let result = crate::Pallet::::try_decode_shielded_tx::< + DecodableBlock, + frame_system::ChainContext, + >(uxt); + assert!(result.is_none()); + }); +} - // Call mark_decryption_failed as unsigned (RuntimeOrigin::none()). - assert_ok!(MevShield::mark_decryption_failed( - RuntimeOrigin::none(), - id, - reason.clone(), - )); +#[test] +fn try_decode_shielded_tx_returns_none_for_bad_signature() { + new_test_ext().execute_with(|| { + let ciphertext = build_wire_ciphertext(&[0xAB; 16], &[0xCC; 32], &[0xDD; 24], &[0xEE; 64]); + let call = RuntimeCall::MevShield(crate::Call::submit_encrypted { + ciphertext: BoundedVec::truncate_from(ciphertext), + }); + let bad_sig = TestSignature(1, vec![0xFF; 32]); + let uxt = DecodableExtrinsic::new_signed(call, 1u64, bad_sig, ()); + + let result = crate::Pallet::::try_decode_shielded_tx::< + DecodableBlock, + frame_system::ChainContext, + >(uxt); + assert!(result.is_none()); + }); +} - // Submission should be removed. - assert!(Submissions::::get(id).is_none()); - - // Last event should be DecryptionFailed with the correct id and reason. - let events = System::events(); - let last = events - .last() - .expect("an event should be emitted") - .event - .clone(); - - assert!( - matches!( - last, - RuntimeEvent::MevShield( - MevShieldEvent::::DecryptionFailed { id: ev_id, reason: ev_reason } - ) - if ev_id == id && ev_reason.to_vec() == reason_bytes - ), - "expected DecryptionFailed event with correct id & reason" - ); +#[test] +fn try_decode_shielded_tx_returns_none_for_malformed_ciphertext() { + new_test_ext().execute_with(|| { + let call = RuntimeCall::MevShield(crate::Call::submit_encrypted { + ciphertext: BoundedVec::truncate_from(vec![0u8; 5]), + }); + let uxt = DecodableExtrinsic::new_bare(call); - // A second call with the same id should now fail with MissingSubmission. - let res = MevShield::mark_decryption_failed(RuntimeOrigin::none(), id, reason); - assert_noop!(res, pallet_mev_shield::Error::::MissingSubmission); + let result = crate::Pallet::::try_decode_shielded_tx::< + DecodableBlock, + frame_system::ChainContext, + >(uxt); + assert!(result.is_none()); }); } #[test] -fn announce_next_key_charges_then_refunds_fee() { +fn try_decode_shielded_tx_returns_none_when_depth_exceeded() { new_test_ext().execute_with(|| { - const KYBER_PK_LEN: usize = 1184; - - // --------------------------------------------------------------------- - // 1. Seed Aura authorities with a single validator and derive account. - // --------------------------------------------------------------------- - let validator_pair = test_sr25519_pair(); - let validator_account: AccountId32 = validator_pair.public().into(); - let validator_aura_id: ::AuthorityId = - validator_pair.public().into(); - - let authorities: BoundedVec< - ::AuthorityId, - ::MaxAuthorities, - > = BoundedVec::truncate_from(vec![validator_aura_id]); - pallet_aura::Authorities::::put(authorities); - - // --------------------------------------------------------------------- - // 2. Build a valid Kyber public key and the corresponding RuntimeCall. - // --------------------------------------------------------------------- - let pk_bytes = vec![42u8; KYBER_PK_LEN]; - let bounded_pk: BoundedVec> = - BoundedVec::truncate_from(pk_bytes.clone()); - - let runtime_call = RuntimeCall::MevShield(MevShieldCall::::announce_next_key { - public_key: bounded_pk.clone(), + let ciphertext = build_wire_ciphertext(&[0xAB; 16], &[0xCC; 32], &[0xDD; 24], &[0xEE; 64]); + let inner = RuntimeCall::MevShield(crate::Call::submit_encrypted { + ciphertext: BoundedVec::truncate_from(ciphertext), }); + let call = nest_call(inner, 8); + let uxt = DecodableExtrinsic::new_bare(call); + + let result = crate::Pallet::::try_decode_shielded_tx::< + DecodableBlock, + frame_system::ChainContext, + >(uxt); + assert!(result.is_none()); + }); +} - // --------------------------------------------------------------------- - // 3. Pre-dispatch: DispatchInfo must say Pays::Yes. - // --------------------------------------------------------------------- - let pre_info = ::get_dispatch_info( - &runtime_call, - ); +#[test] +fn try_unshield_tx_decrypts_extrinsic() { + let mut rng = ChaChaRng::from_seed([42u8; 32]); + let keystore = MemoryShieldKeystore::new(); + + // Client side: read the announced encapsulation key and encapsulate. + let pk_bytes = keystore.next_enc_key().unwrap(); + let enc_key = + EncapsulationKey::::from_bytes(pk_bytes.as_slice().try_into().unwrap()); + let (kem_ct, shared_secret) = enc_key.encapsulate(&mut rng).unwrap(); + + // Build the inner extrinsic that we'll encrypt. + let inner_call = RuntimeCall::System(frame_system::Call::remark { + remark: vec![1, 2, 3], + }); + let inner_uxt = ::Extrinsic::new_bare(inner_call); + let plaintext = inner_uxt.encode(); + + // AEAD encrypt the extrinsic bytes. + let nonce = [42u8; 24]; + let cipher = XChaCha20Poly1305::new(shared_secret.as_slice().into()); + let aead_ct = cipher + .encrypt( + XNonce::from_slice(&nonce), + Payload { + msg: &plaintext, + aad: &[], + }, + ) + .unwrap(); - assert_eq!( - pre_info.pays_fee, - frame_support::dispatch::Pays::Yes, - "announce_next_key must be declared as fee-paying at pre-dispatch" - ); + // Roll keystore so next -> current (author side). + keystore.roll_for_next_slot().unwrap(); + let dec_key_bytes = keystore.current_dec_key().unwrap(); - // --------------------------------------------------------------------- - // 4. Dispatch via the pallet function. - // --------------------------------------------------------------------- - let post = MevShield::announce_next_key( - RuntimeOrigin::signed(validator_account.clone()), - bounded_pk.clone(), - ) - .expect("announce_next_key should succeed for an Aura validator"); + let shielded_tx = ShieldedTransaction { + key_hash: [0u8; 16], + kem_ct: kem_ct.as_slice().to_vec(), + nonce, + aead_ct, + }; - // Post-dispatch info should switch pays_fee from Yes -> No (refund). - assert_eq!( - post.pays_fee, - frame_support::dispatch::Pays::No, - "announce_next_key must refund the previously chargeable fee" - ); + let result = crate::Pallet::::try_unshield_tx::(dec_key_bytes, shielded_tx); + assert!(result.is_some()); - // And we don't override the actual weight (None => use pre-dispatch weight). - assert!( - post.actual_weight.is_none(), - "announce_next_key should not override actual_weight in PostDispatchInfo" - ); - let next = NextKey::::get().expect("NextKey should be set by announce_next_key"); - assert_eq!(next, pk_bytes); - }); + let decoded = result.unwrap(); + assert_eq!(decoded.encode(), inner_uxt.encode()); +} + +// --------------------------------------------------------------------------- +// Migration tests +// --------------------------------------------------------------------------- + +mod migration_tests { + use super::*; + use crate::migrations::migrate_clear_v1_storage::migrate_clear_v1_storage; + use sp_io::hashing::twox_128; + + #[test] + fn migrate_clear_v1_storage_works() { + new_test_ext().execute_with(|| { + // Seed legacy storage that should be cleared. + seed_legacy_map("Submissions", 5); + seed_legacy_map("KeyHashByBlock", 3); + CurrentKey::::put(valid_pk()); + + // Current storage that must survive. + NextKey::::put(valid_pk()); + AuthorKeys::::insert(author(1), valid_pk_b()); + + // Sanity: legacy values exist. + assert_eq!(count_keys("Submissions"), 5); + assert_eq!(count_keys("KeyHashByBlock"), 3); + assert!(CurrentKey::::get().is_some()); + + migrate_clear_v1_storage::(); + + // Legacy storage cleared. + assert_eq!(count_keys("Submissions"), 0); + assert_eq!(count_keys("KeyHashByBlock"), 0); + assert!(CurrentKey::::get().is_none()); + + // Current storage untouched. + assert_eq!(NextKey::::get(), Some(valid_pk())); + assert_eq!(AuthorKeys::::get(author(1)), Some(valid_pk_b())); + + // Migration was recorded. + let mig_key = BoundedVec::truncate_from(b"migrate_clear_v1_storage".to_vec()); + assert!(HasMigrationRun::::get(&mig_key)); + + // Idempotent: re-run doesn't touch new data. + CurrentKey::::put(valid_pk_b()); + migrate_clear_v1_storage::(); + assert_eq!(CurrentKey::::get(), Some(valid_pk_b())); + }); + } + + fn seed_legacy_map(storage_name: &str, count: u32) { + let mut prefix = Vec::new(); + prefix.extend_from_slice(&twox_128(b"MevShield")); + prefix.extend_from_slice(&twox_128(storage_name.as_bytes())); + + for i in 0..count { + let mut key = prefix.clone(); + key.extend_from_slice(&i.to_le_bytes()); + sp_io::storage::set(&key, &[1u8; 32]); + } + } + + fn count_keys(storage_name: &str) -> u32 { + let mut prefix = Vec::new(); + prefix.extend_from_slice(&twox_128(b"MevShield")); + prefix.extend_from_slice(&twox_128(storage_name.as_bytes())); + + let mut count = 0u32; + let mut next_key = sp_io::storage::next_key(&prefix); + while let Some(key) = next_key { + if !key.starts_with(&prefix) { + break; + } + count += 1; + next_key = sp_io::storage::next_key(&key); + } + count + } } diff --git a/pallets/subtensor/Cargo.toml b/pallets/subtensor/Cargo.toml index a6fadec1f4..7ed0d8e28a 100644 --- a/pallets/subtensor/Cargo.toml +++ b/pallets/subtensor/Cargo.toml @@ -62,20 +62,19 @@ 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 # Substrate sp-tracing.workspace = true -rand.workspace = true +rand = { workspace = true, features = ["thread_rng"] } sp-core.workspace = true sp-std.workspace = true pallet-preimage.workspace = true tracing.workspace = true tracing-log.workspace = true tracing-subscriber = { workspace = true, features = ["fmt", "env-filter"] } +pallet-shield = { workspace = true, features = ["std"] } [features] try-runtime = [ @@ -93,7 +92,6 @@ try-runtime = [ "pallet-subtensor-proxy/try-runtime", "pallet-subtensor-utility/try-runtime", "pallet-shield/try-runtime", - "pallet-timestamp/try-runtime", "pallet-aura/try-runtime", ] default = ["std"] @@ -123,9 +121,7 @@ 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", @@ -141,7 +137,8 @@ std = [ "scale-info/std", "serde/std", "serde_json/std", - "sha2/std" + "sha2/std", + "rand/std", ] runtime-benchmarks = [ "frame-benchmarking/runtime-benchmarks", @@ -160,7 +157,7 @@ runtime-benchmarks = [ "pallet-subtensor-swap/runtime-benchmarks", "pallet-subtensor-utility/runtime-benchmarks", "pallet-shield/runtime-benchmarks", - "pallet-timestamp/runtime-benchmarks" + "subtensor-runtime-common/runtime-benchmarks", ] pow-faucet = [] fast-runtime = ["subtensor-runtime-common/fast-runtime"] diff --git a/pallets/subtensor/rpc/src/lib.rs b/pallets/subtensor/rpc/src/lib.rs index b5749988ee..98e2df2f62 100644 --- a/pallets/subtensor/rpc/src/lib.rs +++ b/pallets/subtensor/rpc/src/lib.rs @@ -9,7 +9,7 @@ use jsonrpsee::{ use sp_blockchain::HeaderBackend; use sp_runtime::{AccountId32, traits::Block as BlockT}; use std::sync::Arc; -use subtensor_runtime_common::{MechId, NetUid, TaoCurrency}; +use subtensor_runtime_common::{MechId, NetUid, TaoBalance}; use sp_api::ProvideRuntimeApi; @@ -84,7 +84,7 @@ pub trait SubtensorCustomApi { #[method(name = "subnetInfo_getSubnetState")] fn get_subnet_state(&self, netuid: NetUid, at: Option) -> RpcResult>; #[method(name = "subnetInfo_getLockCost")] - fn get_network_lock_cost(&self, at: Option) -> RpcResult; + fn get_network_lock_cost(&self, at: Option) -> RpcResult; #[method(name = "subnetInfo_getSelectiveMetagraph")] fn get_selective_metagraph( &self, @@ -455,7 +455,7 @@ where } } - fn get_network_lock_cost(&self, at: Option<::Hash>) -> RpcResult { + fn get_network_lock_cost(&self, at: Option<::Hash>) -> RpcResult { let api = self.client.runtime_api(); let at = at.unwrap_or_else(|| self.client.info().best_hash); diff --git a/pallets/subtensor/runtime-api/src/lib.rs b/pallets/subtensor/runtime-api/src/lib.rs index f1107bad08..84da95cd36 100644 --- a/pallets/subtensor/runtime-api/src/lib.rs +++ b/pallets/subtensor/runtime-api/src/lib.rs @@ -12,7 +12,7 @@ use pallet_subtensor::rpc_info::{ subnet_info::{SubnetHyperparams, SubnetHyperparamsV2, SubnetInfo, SubnetInfov2}, }; use sp_runtime::AccountId32; -use subtensor_runtime_common::{AlphaCurrency, MechId, NetUid, TaoCurrency}; +use subtensor_runtime_common::{AlphaBalance, MechId, NetUid, TaoBalance}; // Here we declare the runtime API. It is implemented it the `impl` block in // src/neuron_info.rs, src/subnet_info.rs, and src/delegate_info.rs @@ -20,7 +20,7 @@ sp_api::decl_runtime_apis! { pub trait DelegateInfoRuntimeApi { fn get_delegates() -> Vec>; fn get_delegate( delegate_account: AccountId32 ) -> Option>; - fn get_delegated( delegatee_account: AccountId32 ) -> Vec<(DelegateInfo, (Compact, Compact))>; + fn get_delegated( delegatee_account: AccountId32 ) -> Vec<(DelegateInfo, (Compact, Compact))>; } pub trait NeuronInfoRuntimeApi { @@ -58,6 +58,6 @@ sp_api::decl_runtime_apis! { } pub trait SubnetRegistrationRuntimeApi { - fn get_network_registration_cost() -> TaoCurrency; + fn get_network_registration_cost() -> TaoBalance; } } diff --git a/pallets/subtensor/src/benchmarks.rs b/pallets/subtensor/src/benchmarks.rs index b9abd4e3ee..98bb64c263 100644 --- a/pallets/subtensor/src/benchmarks.rs +++ b/pallets/subtensor/src/benchmarks.rs @@ -16,29 +16,31 @@ use sp_runtime::{ }; use sp_std::collections::btree_set::BTreeSet; use sp_std::vec; -use subtensor_runtime_common::{AlphaCurrency, NetUid, TaoCurrency}; +use substrate_fixed::types::U96F32; +use subtensor_runtime_common::{AlphaBalance, NetUid, TaoBalance}; +use subtensor_swap_interface::SwapHandler; #[benchmarks( where T: pallet_balances::Config, - ::ExistentialDeposit: Get, + ::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); + let tao_reserve = TaoBalance::from(150_000_000_000_u64); + let alpha_in = AlphaBalance::from(100_000_000_000_u64); set_reserves::(netuid, tao_reserve, alpha_in); } - fn set_reserves(netuid: NetUid, tao_reserve: TaoCurrency, alpha_in: AlphaCurrency) { + fn set_reserves(netuid: NetUid, tao_reserve: TaoBalance, alpha_in: AlphaBalance) { SubnetTAO::::insert(netuid, tao_reserve); SubnetAlphaIn::::insert(netuid, alpha_in); } - fn benchmark_registration_burn() -> TaoCurrency { - TaoCurrency::from(1_000_000) + fn benchmark_registration_burn() -> TaoBalance { + TaoBalance::from(1_000_000) } #[benchmark] @@ -82,6 +84,8 @@ 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); + SubnetTAO::::insert(netuid, TaoBalance::from(1_000_000_000_000_u64)); + SubnetAlphaIn::::insert(netuid, AlphaBalance::from(1_000_000_000_000_000_u64)); Subtensor::::set_weights_set_rate_limit(netuid, 0); let mut seed: u32 = 1; @@ -97,7 +101,7 @@ mod pallet_benchmarks { 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); + Subtensor::::add_balance_to_coldkey_account(&coldkey, amount_to_be_staked.into()); assert_ok!(Subtensor::::do_burned_registration( RawOrigin::Signed(coldkey.clone()).into(), @@ -135,8 +139,8 @@ mod pallet_benchmarks { let seed: u32 = 1; let coldkey: T::AccountId = account("Test", 0, seed); let hotkey: T::AccountId = account("Alice", 0, seed); - let total_stake = TaoCurrency::from(1_000_000_000); - let amount = TaoCurrency::from(60_000_000); + let total_stake = TaoBalance::from(1_000_000_000); + let amount = TaoBalance::from(60_000_000); seed_swap_reserves::(netuid); Subtensor::::add_balance_to_coldkey_account(&coldkey, total_stake.into()); @@ -245,7 +249,7 @@ mod pallet_benchmarks { Subtensor::::set_burn(netuid, benchmark_registration_burn()); let amount: u64 = 1_000_000; - Subtensor::::add_balance_to_coldkey_account(&coldkey, amount); + Subtensor::::add_balance_to_coldkey_account(&coldkey, amount.into()); #[extrinsic_call] _(RawOrigin::Signed(coldkey.clone()), netuid, hotkey.clone()); @@ -272,7 +276,7 @@ mod pallet_benchmarks { let amount: u64 = 100_000_000_000_000; seed_swap_reserves::(netuid); - Subtensor::::add_balance_to_coldkey_account(&coldkey, amount); + Subtensor::::add_balance_to_coldkey_account(&coldkey, amount.into()); assert_ok!(Subtensor::::do_burned_registration( RawOrigin::Signed(coldkey.clone()).into(), @@ -292,7 +296,7 @@ mod pallet_benchmarks { Subtensor::::set_network_rate_limit(1); let amount: u64 = 100_000_000_000_000u64.saturating_mul(2); - Subtensor::::add_balance_to_coldkey_account(&coldkey, amount); + Subtensor::::add_balance_to_coldkey_account(&coldkey, amount.into()); #[extrinsic_call] _(RawOrigin::Signed(coldkey.clone()), hotkey.clone()); @@ -459,7 +463,7 @@ mod pallet_benchmarks { let ed = ::ExistentialDeposit::get(); let swap_cost = Subtensor::::get_key_swap_cost(); - Subtensor::::add_balance_to_coldkey_account(&coldkey, swap_cost.to_u64() + ed); + Subtensor::::add_balance_to_coldkey_account(&coldkey, swap_cost + ed); #[extrinsic_call] _(RawOrigin::Signed(coldkey), new_coldkey_hash); @@ -508,7 +512,7 @@ mod pallet_benchmarks { let ed = ::ExistentialDeposit::get(); let swap_cost = Subtensor::::get_key_swap_cost(); - Subtensor::::add_balance_to_coldkey_account(&old_coldkey, swap_cost.to_u64() + ed); + Subtensor::::add_balance_to_coldkey_account(&old_coldkey, swap_cost + ed); let netuid = NetUid::from(1); Subtensor::::init_new_network(netuid, 1); @@ -659,14 +663,14 @@ mod pallet_benchmarks { let amount_to_be_staked = 1_000_000_000; seed_swap_reserves::(netuid); - Subtensor::::add_balance_to_coldkey_account(&coldkey, amount_to_be_staked); + Subtensor::::add_balance_to_coldkey_account(&coldkey, amount_to_be_staked.into()); assert_ok!(Subtensor::::do_burned_registration( RawOrigin::Signed(coldkey.clone()).into(), netuid, hotkey.clone() )); - let alpha_amount = AlphaCurrency::from(1_000_000); + let alpha_amount = AlphaBalance::from(1_000_000); SubnetAlphaOut::::insert(netuid, alpha_amount * 2.into()); Subtensor::::increase_stake_for_hotkey_and_coldkey_on_subnet( @@ -703,7 +707,7 @@ mod pallet_benchmarks { 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); + Subtensor::::add_balance_to_coldkey_account(&coldkey, amount_to_be_staked.into()); assert_ok!(Subtensor::::do_burned_registration( RawOrigin::Signed(coldkey.clone()).into(), netuid, @@ -711,7 +715,7 @@ mod pallet_benchmarks { )); let alpha_amount = 1_000_000; - SubnetAlphaOut::::insert(netuid, AlphaCurrency::from(alpha_amount * 2)); + SubnetAlphaOut::::insert(netuid, AlphaBalance::from(alpha_amount * 2)); Subtensor::::increase_stake_for_hotkey_and_coldkey_on_subnet( &hotkey, &coldkey, @@ -745,7 +749,7 @@ mod pallet_benchmarks { 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); + Subtensor::::add_balance_to_coldkey_account(&coldkey, amount_to_be_staked.into()); SubnetOwner::::set(netuid, coldkey.clone()); assert_ok!(Subtensor::::do_burned_registration( @@ -783,13 +787,11 @@ mod pallet_benchmarks { let coldkey: T::AccountId = account("Test", 0, seed); let hotkey: T::AccountId = account("Alice", 0, seed); - let amount = 900_000_000_000; - let limit = TaoCurrency::from(6_000_000_000); - let amount_to_be_staked = TaoCurrency::from(44_000_000_000); - Subtensor::::add_balance_to_coldkey_account(&coldkey.clone(), amount); + let initial_balance = TaoBalance::from(900_000_000_000_u64); + Subtensor::::add_balance_to_coldkey_account(&coldkey.clone(), initial_balance); - let tao_reserve = TaoCurrency::from(150_000_000_000); - let alpha_in = AlphaCurrency::from(100_000_000_000); + let tao_reserve = TaoBalance::from(1_000_000_000_000_u64); + let alpha_in = AlphaBalance::from(100_000_000_000_000_u64); set_reserves::(netuid, tao_reserve, alpha_in); assert_ok!(Subtensor::::do_burned_registration( @@ -798,6 +800,16 @@ mod pallet_benchmarks { hotkey.clone() )); + // Read current price and set limit price 0.1% higher, which is certainly getting hit + // by swapping 100 TAO + let current_price = T::SwapInterface::current_alpha_price(netuid); + let limit = current_price + .saturating_mul(U96F32::saturating_from_num(1_001_000_000)) + .saturating_to_num::() + .into(); + let amount_to_be_staked = TaoBalance::from(100_000_000_000_u64); + + // Allow partial (worst case) #[extrinsic_call] _( RawOrigin::Signed(coldkey.clone()), @@ -805,7 +817,7 @@ mod pallet_benchmarks { netuid, amount_to_be_staked, limit, - false, + true, ); } @@ -830,7 +842,7 @@ mod pallet_benchmarks { origin.clone() )); - set_reserves::(netuid, deposit, AlphaCurrency::from(deposit.to_u64())); + set_reserves::(netuid, deposit, AlphaBalance::from(deposit.to_u64())); TotalStake::::set(deposit); assert_ok!(Subtensor::::add_stake_limit( @@ -838,7 +850,7 @@ mod pallet_benchmarks { origin.clone(), netuid, stake_tao, - TaoCurrency::MAX, + TaoBalance::MAX, false )); @@ -868,7 +880,7 @@ mod pallet_benchmarks { let seed: u32 = 1; // Set our total stake to 1000 TAO - Subtensor::::increase_total_stake(1_000_000_000_000.into()); + Subtensor::::increase_total_stake(1_000_000_000_000_u64.into()); Subtensor::::init_new_network(netuid, tempo); Subtensor::::set_network_registration_allowed(netuid, true); @@ -881,9 +893,8 @@ mod pallet_benchmarks { let hotkey: T::AccountId = account("Alice", 0, seed); 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); + let tao_reserve = TaoBalance::from(1_000_000_000_000_u64); + let alpha_in = AlphaBalance::from(100_000_000_000_000_u64); set_reserves::(netuid, tao_reserve, alpha_in); let wallet_bal = 1000000u32.into(); @@ -895,17 +906,24 @@ mod pallet_benchmarks { hotkey.clone() )); - let u64_staked_amt = 100_000_000_000; - Subtensor::::add_balance_to_coldkey_account(&coldkey.clone(), u64_staked_amt); + let staked_amt = TaoBalance::from(100_000_000_000_u64); + Subtensor::::add_balance_to_coldkey_account(&coldkey.clone(), staked_amt); assert_ok!(Subtensor::::add_stake( RawOrigin::Signed(coldkey.clone()).into(), hotkey.clone(), netuid, - u64_staked_amt.into() + staked_amt )); - let amount_unstaked = AlphaCurrency::from(30_000_000_000); + // Read current price and set limit price 0.01% lower, which is certainly getting hit + // by swapping 100 Alpha + let current_price = T::SwapInterface::current_alpha_price(netuid); + let limit = current_price + .saturating_mul(U96F32::saturating_from_num(999_900_000)) + .saturating_to_num::() + .into(); + let amount_unstaked = AlphaBalance::from(100_000_000_000_u64); // Remove stake limit for benchmark StakingOperationRateLimiter::::remove((hotkey.clone(), coldkey.clone(), netuid)); @@ -917,7 +935,7 @@ mod pallet_benchmarks { netuid, amount_unstaked, limit, - false, + true, ); } @@ -934,18 +952,18 @@ mod pallet_benchmarks { SubtokenEnabled::::insert(netuid2, true); Subtensor::::init_new_network(netuid2, 1); - let tao_reserve = TaoCurrency::from(150_000_000_000); - let alpha_in = AlphaCurrency::from(100_000_000_000); + let tao_reserve = TaoBalance::from(150_000_000_000_u64); + let alpha_in = AlphaBalance::from(100_000_000_000_u64); set_reserves::(netuid1, tao_reserve, alpha_in); SubnetTAO::::insert(netuid2, tao_reserve); - Subtensor::::increase_total_stake(1_000_000_000_000.into()); + Subtensor::::increase_total_stake(1_000_000_000_000_u64.into()); - let amount = 900_000_000_000; - let limit_stake = TaoCurrency::from(6_000_000_000); - let limit_swap = TaoCurrency::from(1_000_000_000); - let amount_to_be_staked = TaoCurrency::from(440_000_000_000); - let amount_swapped = AlphaCurrency::from(30_000_000_000); + let amount = TaoBalance::from(900_000_000_000_u64); + let limit_stake = TaoBalance::from(6_000_000_000_u64); + let limit_swap = TaoBalance::from(1_000_000_000_u64); + let amount_to_be_staked = TaoBalance::from(440_000_000_000_u64); + let amount_swapped = AlphaBalance::from(30_000_000_000_u64); Subtensor::::add_balance_to_coldkey_account(&coldkey.clone(), amount); assert_ok!(Subtensor::::burned_register( @@ -1005,7 +1023,7 @@ mod pallet_benchmarks { hot.clone() )); - set_reserves::(netuid, deposit, AlphaCurrency::from(deposit.to_u64())); + set_reserves::(netuid, deposit, AlphaBalance::from(deposit.to_u64())); TotalStake::::set(deposit); assert_ok!(Subtensor::::add_stake_limit( @@ -1013,7 +1031,7 @@ mod pallet_benchmarks { hot.clone(), netuid, stake_tao, - TaoCurrency::MAX, + TaoBalance::MAX, false )); @@ -1059,8 +1077,8 @@ mod pallet_benchmarks { hot.clone() )); - set_reserves::(netuid1, deposit, AlphaCurrency::from(deposit.to_u64())); - set_reserves::(netuid2, deposit, AlphaCurrency::from(deposit.to_u64())); + set_reserves::(netuid1, deposit, AlphaBalance::from(deposit.to_u64())); + set_reserves::(netuid2, deposit, AlphaBalance::from(deposit.to_u64())); TotalStake::::set(deposit); assert_ok!(Subtensor::::add_stake_limit( @@ -1068,7 +1086,7 @@ mod pallet_benchmarks { hot.clone(), netuid1, stake_tao, - TaoCurrency::MAX, + TaoBalance::MAX, false )); @@ -1102,7 +1120,7 @@ mod pallet_benchmarks { 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)); + Subtensor::::add_balance_to_coldkey_account(&hotkey, reg_fee.saturating_mul(2.into())); assert_ok!(Subtensor::::burned_register( RawOrigin::Signed(hotkey.clone()).into(), @@ -1142,7 +1160,7 @@ mod pallet_benchmarks { Subtensor::::set_commit_reveal_weights_enabled(netuid, false); let reg_fee = Subtensor::::get_burn(netuid); - Subtensor::::add_balance_to_coldkey_account(&hotkey, reg_fee.to_u64().saturating_mul(2)); + Subtensor::::add_balance_to_coldkey_account(&hotkey, reg_fee.saturating_mul(2.into())); assert_ok!(Subtensor::::burned_register( RawOrigin::Signed(hotkey.clone()).into(), @@ -1196,7 +1214,7 @@ mod pallet_benchmarks { Subtensor::::set_network_registration_allowed(1.into(), true); Subtensor::::set_network_rate_limit(1); let amount: u64 = 9_999_999_999_999; - Subtensor::::add_balance_to_coldkey_account(&coldkey, amount); + Subtensor::::add_balance_to_coldkey_account(&coldkey, amount.into()); #[extrinsic_call] _( @@ -1263,7 +1281,7 @@ mod pallet_benchmarks { Subtensor::::create_account_if_non_existent(&coldkey, &hotkey); Subtensor::::init_new_network(1.into(), 1); let deposit: u64 = 1_000_000_000u64.saturating_mul(2); - Subtensor::::add_balance_to_coldkey_account(&coldkey, deposit); + Subtensor::::add_balance_to_coldkey_account(&coldkey, deposit.into()); SubtokenEnabled::::insert(NetUid::from(1), true); assert_ok!(Subtensor::::burned_register( @@ -1372,8 +1390,8 @@ mod pallet_benchmarks { set_reserves::( netuid, - TaoCurrency::from(150_000_000_000), - AlphaCurrency::from(100_000_000_000), + TaoBalance::from(150_000_000_000_u64), + AlphaBalance::from(100_000_000_000_u64), ); Subtensor::::add_balance_to_coldkey_account(&coldkey.clone(), 1000000u32.into()); @@ -1384,14 +1402,14 @@ mod pallet_benchmarks { hotkey.clone() )); - let staked_amt = 100_000_000_000; + let staked_amt = TaoBalance::from(100_000_000_000_u64); Subtensor::::add_balance_to_coldkey_account(&coldkey.clone(), staked_amt); assert_ok!(Subtensor::::add_stake( RawOrigin::Signed(coldkey.clone()).into(), hotkey.clone(), netuid, - staked_amt.into() + staked_amt )); // Remove stake limit for benchmark @@ -1408,7 +1426,7 @@ mod pallet_benchmarks { let seed: u32 = 1; // Set our total stake to 1000 TAO - Subtensor::::increase_total_stake(1_000_000_000_000.into()); + Subtensor::::increase_total_stake(1_000_000_000_000_u64.into()); Subtensor::::init_new_network(netuid, tempo); Subtensor::::set_network_registration_allowed(netuid, true); @@ -1421,9 +1439,8 @@ mod pallet_benchmarks { let hotkey: T::AccountId = account("Alice", 0, seed); 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); + let tao_reserve = TaoBalance::from(1_000_000_000_000_u64); + let alpha_in = AlphaBalance::from(100_000_000_000_000_u64); set_reserves::(netuid, tao_reserve, alpha_in); let wallet_bal = 1000000u32.into(); @@ -1435,14 +1452,21 @@ mod pallet_benchmarks { hotkey.clone() )); - let u64_staked_amt = 100_000_000_000; - Subtensor::::add_balance_to_coldkey_account(&coldkey.clone(), u64_staked_amt); + // Read current price and set limit price 50% lower, which is not getting hit + // by swapping 1 TAO + let current_price = T::SwapInterface::current_alpha_price(netuid); + let limit = current_price + .saturating_mul(U96F32::saturating_from_num(500_000_000)) + .saturating_to_num::() + .into(); + let staked_amt = TaoBalance::from(1_000_000_000_u64); + Subtensor::::add_balance_to_coldkey_account(&coldkey.clone(), staked_amt); assert_ok!(Subtensor::::add_stake( RawOrigin::Signed(coldkey.clone()).into(), hotkey.clone(), netuid, - u64_staked_amt.into() + staked_amt )); StakingOperationRateLimiter::::remove((hotkey.clone(), coldkey.clone(), netuid)); @@ -1461,20 +1485,20 @@ mod pallet_benchmarks { // Setup a crowdloan let crowdloan_id = 0; let beneficiary: T::AccountId = whitelisted_caller(); - let deposit = 20_000_000_000; // 20 TAO + let deposit = TaoBalance::from(20_000_000_000_u64); // 20 TAO let now = frame_system::Pallet::::block_number(); // not really important here let end = now + T::MaximumBlockDuration::get(); - let cap = 2_000_000_000_000; // 2000 TAO + let cap = TaoBalance::from(2_000_000_000_000_u64); // 2000 TAO let funds_account: T::AccountId = account("funds", 0, 0); - Subtensor::::add_balance_to_coldkey_account(&funds_account, cap); + Subtensor::::add_balance_to_coldkey_account(&funds_account, cap.into()); pallet_crowdloan::Crowdloans::::insert( crowdloan_id, pallet_crowdloan::CrowdloanInfo { creator: beneficiary.clone(), deposit, - min_contribution: 0, + min_contribution: 0.into(), end, cap, raised: cap, @@ -1494,7 +1518,7 @@ mod pallet_benchmarks { // Simulate k - 1 contributions, the deposit is already taken into account let contributors = k - 1; - let amount = (cap - deposit) / contributors as u64; + let amount = (cap - deposit) / TaoBalance::from(contributors); for i in 0..contributors { let contributor = account::("contributor", i.try_into().unwrap(), 0); pallet_crowdloan::Contributions::::insert(crowdloan_id, contributor, amount); @@ -1527,10 +1551,10 @@ mod pallet_benchmarks { // Setup a crowdloan let crowdloan_id = 0; let beneficiary: T::AccountId = whitelisted_caller(); - let deposit = 20_000_000_000; // 20 TAO + let deposit = TaoBalance::from(20_000_000_000_u64); // 20 TAO let now = frame_system::Pallet::::block_number(); // not really important here let crowdloan_end = now + T::MaximumBlockDuration::get(); - let cap = 2_000_000_000_000; // 2000 TAO + let cap = TaoBalance::from(2_000_000_000_000_u64); // 2000 TAO let funds_account: T::AccountId = account("funds", 0, 0); Subtensor::::add_balance_to_coldkey_account(&funds_account, cap); @@ -1540,7 +1564,7 @@ mod pallet_benchmarks { pallet_crowdloan::CrowdloanInfo { creator: beneficiary.clone(), deposit, - min_contribution: 0, + min_contribution: 0.into(), end: crowdloan_end, cap, raised: cap, @@ -1560,7 +1584,7 @@ mod pallet_benchmarks { // Simulate k - 1 contributions, the deposit is already taken into account let contributors = k - 1; - let amount = (cap - deposit) / contributors as u64; + let amount = (cap - deposit) / TaoBalance::from(contributors); for i in 0..contributors { let contributor = account::("contributor", i.try_into().unwrap(), 0); pallet_crowdloan::Contributions::::insert(crowdloan_id, contributor, amount); @@ -1661,7 +1685,7 @@ mod pallet_benchmarks { let hotkey: T::AccountId = account("A", 0, 1); SubtokenEnabled::::insert(netuid, true); Subtensor::::init_new_network(netuid, 1); - let amount = 900_000_000_000; + let amount = TaoBalance::from(900_000_000_000_u64); Subtensor::::add_balance_to_coldkey_account(&coldkey.clone(), amount); @@ -1725,10 +1749,10 @@ mod pallet_benchmarks { let pending_root_alpha = 10_000_000u64; Subtensor::::distribute_emission( netuid, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, pending_root_alpha.into(), pending_root_alpha.into(), - AlphaCurrency::ZERO, + AlphaBalance::ZERO, ); let initial_stake = @@ -1791,13 +1815,13 @@ mod pallet_benchmarks { 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); + let balance_update = TaoBalance::from(900_000_000_000_u64); + let limit = TaoBalance::from(6_000_000_000_u64); + let amount = TaoBalance::from(44_000_000_000_u64); 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); + let tao_reserve = TaoBalance::from(150_000_000_000_u64); + let alpha_in = AlphaBalance::from(100_000_000_000_u64); set_reserves::(netuid, tao_reserve, alpha_in); assert_ok!(Subtensor::::do_burned_registration( diff --git a/pallets/subtensor/src/coinbase/block_emission.rs b/pallets/subtensor/src/coinbase/block_emission.rs index 3aefef927f..6d04c35cb8 100644 --- a/pallets/subtensor/src/coinbase/block_emission.rs +++ b/pallets/subtensor/src/coinbase/block_emission.rs @@ -1,8 +1,9 @@ use super::*; +// use frame_support::traits::{Currency as BalancesCurrency, Get, Imbalance}; use frame_support::traits::Get; use safe_math::*; use substrate_fixed::{transcendental::log2, types::I96F32}; -use subtensor_runtime_common::TaoCurrency; +use subtensor_runtime_common::TaoBalance; impl Pallet { /// Calculates the block emission based on the total issuance. @@ -16,7 +17,7 @@ impl Pallet { /// # Returns /// * 'Result': The calculated block emission rate or error. /// - pub fn get_block_emission() -> Result { + pub fn get_block_emission() -> Result { // Convert the total issuance to a fixed-point number for calculation. Self::get_block_emission_for_issuance(Self::get_total_issuance().into()).map(Into::into) } diff --git a/pallets/subtensor/src/coinbase/block_step.rs b/pallets/subtensor/src/coinbase/block_step.rs index 6081edad19..a030607995 100644 --- a/pallets/subtensor/src/coinbase/block_step.rs +++ b/pallets/subtensor/src/coinbase/block_step.rs @@ -1,7 +1,7 @@ use super::*; use safe_math::*; use substrate_fixed::types::{U96F32, U110F18}; -use subtensor_runtime_common::{NetUid, TaoCurrency}; +use subtensor_runtime_common::{NetUid, TaoBalance}; impl Pallet { /// Executes the necessary operations for each block. @@ -14,7 +14,7 @@ impl Pallet { // --- 2. Get the current coinbase emission. let block_emission: U96F32 = U96F32::saturating_from_num( Self::get_block_emission() - .unwrap_or(TaoCurrency::ZERO) + .unwrap_or(TaoBalance::ZERO) .to_u64(), ); log::debug!("Block emission: {block_emission:?}"); @@ -240,10 +240,10 @@ impl Pallet { /// pub fn upgraded_burn( netuid: NetUid, - current_burn: TaoCurrency, + current_burn: TaoBalance, registrations_this_interval: u16, target_registrations_per_interval: u16, - ) -> TaoCurrency { + ) -> TaoBalance { let updated_burn: U110F18 = U110F18::saturating_from_num(current_burn) .saturating_mul(U110F18::saturating_from_num( registrations_this_interval.saturating_add(target_registrations_per_interval), diff --git a/pallets/subtensor/src/coinbase/root.rs b/pallets/subtensor/src/coinbase/root.rs index 83567b6f57..e2714fba1b 100644 --- a/pallets/subtensor/src/coinbase/root.rs +++ b/pallets/subtensor/src/coinbase/root.rs @@ -19,7 +19,7 @@ use super::*; use crate::CommitmentsInterface; use safe_math::*; use substrate_fixed::types::{I64F64, U96F32}; -use subtensor_runtime_common::{AlphaCurrency, Currency, NetUid, NetUidStorageIndex, TaoCurrency}; +use subtensor_runtime_common::{AlphaBalance, NetUid, NetUidStorageIndex, TaoBalance, Token}; use subtensor_swap_interface::SwapHandler; impl Pallet { @@ -130,7 +130,7 @@ impl Pallet { } else { // --- 13.1.1 The network is full. Perform replacement. // Find the neuron with the lowest stake value to replace. - let mut lowest_stake = AlphaCurrency::MAX; + let mut lowest_stake = AlphaBalance::MAX; let mut lowest_uid: u16 = 0; // Iterate over all keys in the root network to find the neuron with the lowest stake. @@ -505,13 +505,13 @@ impl Pallet { /// * 'u64': /// - The lock cost for the network. /// - pub fn get_network_lock_cost() -> TaoCurrency { + pub fn get_network_lock_cost() -> TaoBalance { let last_lock = Self::get_network_last_lock(); let min_lock = Self::get_network_min_lock(); let last_lock_block = Self::get_network_last_lock_block(); let current_block = Self::get_current_block_as_u64(); let lock_reduction_interval = Self::get_lock_reduction_interval(); - let mult: TaoCurrency = if last_lock_block == 0 { 1 } else { 2 }.into(); + let mult: TaoBalance = if last_lock_block == 0 { 1 } else { 2 }.into(); let mut lock_cost = last_lock.saturating_mul(mult).saturating_sub( last_lock @@ -546,17 +546,17 @@ impl Pallet { StartCallDelay::::set(delay); Self::deposit_event(Event::StartCallDelaySet(delay)); } - pub fn set_network_min_lock(net_min_lock: TaoCurrency) { + pub fn set_network_min_lock(net_min_lock: TaoBalance) { NetworkMinLockCost::::set(net_min_lock); Self::deposit_event(Event::NetworkMinLockCostSet(net_min_lock)); } - pub fn get_network_min_lock() -> TaoCurrency { + pub fn get_network_min_lock() -> TaoBalance { NetworkMinLockCost::::get() } - pub fn set_network_last_lock(net_last_lock: TaoCurrency) { + pub fn set_network_last_lock(net_last_lock: TaoBalance) { NetworkLastLockCost::::set(net_last_lock); } - pub fn get_network_last_lock() -> TaoCurrency { + pub fn get_network_last_lock() -> TaoBalance { NetworkLastLockCost::::get() } pub fn get_network_last_lock_block() -> u64 { diff --git a/pallets/subtensor/src/coinbase/run_coinbase.rs b/pallets/subtensor/src/coinbase/run_coinbase.rs index 2091946598..d25f7ce170 100644 --- a/pallets/subtensor/src/coinbase/run_coinbase.rs +++ b/pallets/subtensor/src/coinbase/run_coinbase.rs @@ -2,7 +2,7 @@ use super::*; use alloc::collections::BTreeMap; use safe_math::*; use substrate_fixed::types::U96F32; -use subtensor_runtime_common::{AlphaCurrency, Currency, NetUid, TaoCurrency}; +use subtensor_runtime_common::{AlphaBalance, NetUid, TaoBalance, Token}; use subtensor_swap_interface::SwapHandler; // Distribute dividends to each hotkey @@ -60,16 +60,15 @@ impl Pallet { excess_tao: &BTreeMap, ) { for netuid_i in subnets_to_emit_to.iter() { - let tao_in_i: TaoCurrency = - tou64!(*tao_in.get(netuid_i).unwrap_or(&asfloat!(0))).into(); - let alpha_in_i: AlphaCurrency = + let tao_in_i: TaoBalance = tou64!(*tao_in.get(netuid_i).unwrap_or(&asfloat!(0))).into(); + let alpha_in_i: AlphaBalance = tou64!(*alpha_in.get(netuid_i).unwrap_or(&asfloat!(0))).into(); - let tao_to_swap_with: TaoCurrency = + let tao_to_swap_with: TaoBalance = tou64!(excess_tao.get(netuid_i).unwrap_or(&asfloat!(0))).into(); T::SwapInterface::adjust_protocol_liquidity(*netuid_i, tao_in_i, alpha_in_i); - if tao_to_swap_with > TaoCurrency::ZERO { + if tao_to_swap_with > TaoBalance::ZERO { let buy_swap_result = Self::swap_tao_for_alpha( *netuid_i, tao_to_swap_with, @@ -77,21 +76,21 @@ impl Pallet { true, ); if let Ok(buy_swap_result_ok) = buy_swap_result { - let bought_alpha: AlphaCurrency = buy_swap_result_ok.amount_paid_out.into(); + let bought_alpha: AlphaBalance = buy_swap_result_ok.amount_paid_out.into(); Self::recycle_subnet_alpha(*netuid_i, bought_alpha); } } // Inject Alpha in. let alpha_in_i = - AlphaCurrency::from(tou64!(*alpha_in.get(netuid_i).unwrap_or(&asfloat!(0)))); + AlphaBalance::from(tou64!(*alpha_in.get(netuid_i).unwrap_or(&asfloat!(0)))); SubnetAlphaInEmission::::insert(*netuid_i, alpha_in_i); SubnetAlphaIn::::mutate(*netuid_i, |total| { *total = total.saturating_add(alpha_in_i); }); // Inject TAO in. - let injected_tao: TaoCurrency = + let injected_tao: TaoBalance = tou64!(*tao_in.get(netuid_i).unwrap_or(&asfloat!(0))).into(); SubnetTaoInEmission::::insert(*netuid_i, injected_tao); SubnetTAO::::mutate(*netuid_i, |total| { @@ -126,7 +125,7 @@ impl Pallet { let mut excess_tao: BTreeMap = BTreeMap::new(); let tao_block_emission: U96F32 = U96F32::saturating_from_num( Self::get_block_emission() - .unwrap_or(TaoCurrency::ZERO) + .unwrap_or(TaoBalance::ZERO) .to_u64(), ); @@ -188,7 +187,7 @@ impl Pallet { // Get alpha_out for this block. let mut alpha_out_i: U96F32 = *alpha_out.get(netuid_i).unwrap_or(&asfloat!(0)); - let alpha_created: AlphaCurrency = AlphaCurrency::from(tou64!(alpha_out_i)); + let alpha_created: AlphaBalance = AlphaBalance::from(tou64!(alpha_out_i)); SubnetAlphaOutEmission::::insert(*netuid_i, alpha_created); SubnetAlphaOut::::mutate(*netuid_i, |total| { *total = total.saturating_add(alpha_created); @@ -241,7 +240,7 @@ impl Pallet { }); } else { // If we are not selling the root alpha, we should recycle it. - Self::recycle_subnet_alpha(*netuid_i, AlphaCurrency::from(tou64!(root_alpha))); + Self::recycle_subnet_alpha(*netuid_i, AlphaBalance::from(tou64!(root_alpha))); } } } @@ -249,11 +248,11 @@ impl Pallet { pub fn drain_pending( subnets: &[NetUid], current_block: u64, - ) -> BTreeMap { + ) -> BTreeMap { // Map of netuid to (pending_server_alpha, pending_validator_alpha, pending_root_alpha, pending_owner_cut). let mut emissions_to_distribute: BTreeMap< NetUid, - (AlphaCurrency, AlphaCurrency, AlphaCurrency, AlphaCurrency), + (AlphaBalance, AlphaBalance, AlphaBalance, AlphaBalance), > = BTreeMap::new(); // --- Drain pending emissions for all subnets hat are at their tempo. // Run the epoch for *all* subnets, even if we don't emit anything. @@ -271,18 +270,18 @@ impl Pallet { // Get and drain the subnet pending emission. let pending_server_alpha = PendingServerEmission::::get(netuid); - PendingServerEmission::::insert(netuid, AlphaCurrency::ZERO); + PendingServerEmission::::insert(netuid, AlphaBalance::ZERO); let pending_validator_alpha = PendingValidatorEmission::::get(netuid); - PendingValidatorEmission::::insert(netuid, AlphaCurrency::ZERO); + PendingValidatorEmission::::insert(netuid, AlphaBalance::ZERO); // Get and drain the pending Alpha for root divs. let pending_root_alpha = PendingRootAlphaDivs::::get(netuid); - PendingRootAlphaDivs::::insert(netuid, AlphaCurrency::ZERO); + PendingRootAlphaDivs::::insert(netuid, AlphaBalance::ZERO); // Get and drain the pending owner cut. let owner_cut = PendingOwnerCut::::get(netuid); - PendingOwnerCut::::insert(netuid, AlphaCurrency::ZERO); + PendingOwnerCut::::insert(netuid, AlphaBalance::ZERO); // Save the emissions to distribute. emissions_to_distribute.insert( @@ -302,7 +301,7 @@ impl Pallet { pub fn distribute_emissions_to_subnets( emissions_to_distribute: &BTreeMap< NetUid, - (AlphaCurrency, AlphaCurrency, AlphaCurrency, AlphaCurrency), + (AlphaBalance, AlphaBalance, AlphaBalance, AlphaBalance), >, ) { for ( @@ -334,13 +333,13 @@ impl Pallet { pub fn calculate_dividends_and_incentives( netuid: NetUid, - hotkey_emission: Vec<(T::AccountId, AlphaCurrency, AlphaCurrency)>, + hotkey_emission: Vec<(T::AccountId, AlphaBalance, AlphaBalance)>, ) -> ( - BTreeMap, + BTreeMap, BTreeMap, ) { // Accumulate emission of dividends and incentive per hotkey. - let mut incentives: BTreeMap = BTreeMap::new(); + let mut incentives: BTreeMap = BTreeMap::new(); let mut dividends: BTreeMap = BTreeMap::new(); for (hotkey, incentive, dividend) in hotkey_emission { // Accumulate incentives to miners. @@ -349,7 +348,7 @@ impl Pallet { .and_modify(|e| *e = e.saturating_add(incentive)) .or_insert(incentive); // Accumulate dividends to parents. - let div_tuples: Vec<(T::AccountId, AlphaCurrency)> = + let div_tuples: Vec<(T::AccountId, AlphaBalance)> = Self::get_parent_child_dividends_distribution(&hotkey, netuid, dividend); // Accumulate dividends per hotkey. for (parent, parent_div) in div_tuples { @@ -366,10 +365,10 @@ impl Pallet { } pub fn calculate_dividend_distribution( - pending_alpha: AlphaCurrency, - pending_root_alpha: AlphaCurrency, + pending_alpha: AlphaBalance, + pending_root_alpha: AlphaBalance, tao_weight: U96F32, - stake_map: BTreeMap, + stake_map: BTreeMap, dividends: BTreeMap, ) -> ( BTreeMap, @@ -503,8 +502,8 @@ impl Pallet { pub fn distribute_dividends_and_incentives( netuid: NetUid, - owner_cut: AlphaCurrency, - incentives: BTreeMap, + owner_cut: AlphaBalance, + incentives: BTreeMap, alpha_dividends: BTreeMap, root_alpha_dividends: BTreeMap, ) { @@ -641,8 +640,8 @@ impl Pallet { pub fn get_stake_map( netuid: NetUid, hotkeys: Vec<&T::AccountId>, - ) -> BTreeMap { - let mut stake_map: BTreeMap = BTreeMap::new(); + ) -> BTreeMap { + let mut stake_map: BTreeMap = BTreeMap::new(); for hotkey in hotkeys { // Get hotkey ALPHA on subnet. let alpha_stake = Self::get_stake_for_hotkey_on_subnet(hotkey, netuid); @@ -655,12 +654,12 @@ impl Pallet { pub fn calculate_dividend_and_incentive_distribution( netuid: NetUid, - pending_root_alpha: AlphaCurrency, - pending_validator_alpha: AlphaCurrency, - hotkey_emission: Vec<(T::AccountId, AlphaCurrency, AlphaCurrency)>, + pending_root_alpha: AlphaBalance, + pending_validator_alpha: AlphaBalance, + hotkey_emission: Vec<(T::AccountId, AlphaBalance, AlphaBalance)>, tao_weight: U96F32, ) -> ( - BTreeMap, + BTreeMap, ( BTreeMap, BTreeMap, @@ -684,10 +683,10 @@ impl Pallet { pub fn distribute_emission( netuid: NetUid, - pending_server_alpha: AlphaCurrency, - pending_validator_alpha: AlphaCurrency, - pending_root_alpha: AlphaCurrency, - pending_owner_cut: AlphaCurrency, + pending_server_alpha: AlphaBalance, + pending_validator_alpha: AlphaBalance, + pending_root_alpha: AlphaBalance, + pending_owner_cut: AlphaBalance, ) { log::debug!( "Draining pending alpha emission for netuid {netuid:?}, pending_server_alpha: {pending_server_alpha:?}, pending_validator_alpha: {pending_validator_alpha:?}, pending_root_alpha: {pending_root_alpha:?}, pending_owner_cut: {pending_owner_cut:?}" @@ -699,7 +698,7 @@ impl Pallet { .saturating_add(pending_root_alpha); // Run the epoch, using the alpha going to both the servers and the validators. - let hotkey_emission: Vec<(T::AccountId, AlphaCurrency, AlphaCurrency)> = + let hotkey_emission: Vec<(T::AccountId, AlphaBalance, AlphaBalance)> = Self::epoch_with_mechanisms(netuid, total_alpha_minus_owner_cut); log::debug!("hotkey_emission: {hotkey_emission:?}"); @@ -710,7 +709,7 @@ impl Pallet { // Important! If the incentives are 0, then Validators get 100% of the alpha. let incentive_sum = hotkey_emission .iter() - .fold(AlphaCurrency::default(), |acc, (_, incentive, _)| { + .fold(AlphaBalance::default(), |acc, (_, incentive, _)| { acc.saturating_add(*incentive) }); log::debug!("incentive_sum: {incentive_sum:?}"); @@ -791,10 +790,10 @@ impl Pallet { pub fn get_parent_child_dividends_distribution( hotkey: &T::AccountId, netuid: NetUid, - dividends: AlphaCurrency, - ) -> Vec<(T::AccountId, AlphaCurrency)> { + dividends: AlphaBalance, + ) -> Vec<(T::AccountId, AlphaBalance)> { // hotkey dividends. - let mut dividend_tuples: Vec<(T::AccountId, AlphaCurrency)> = vec![]; + let mut dividend_tuples: Vec<(T::AccountId, AlphaBalance)> = vec![]; // Calculate the hotkey's share of the validator emission based on its childkey take let validating_emission: U96F32 = U96F32::saturating_from_num(dividends); @@ -887,7 +886,7 @@ impl Pallet { Self::recycle_subnet_alpha( netuid, - AlphaCurrency::from(burn_take.saturating_to_num::()), + AlphaBalance::from(burn_take.saturating_to_num::()), ); }; log::debug!("burn_takee: {burn_take:?} for hotkey {hotkey:?}"); diff --git a/pallets/subtensor/src/coinbase/subnet_emissions.rs b/pallets/subtensor/src/coinbase/subnet_emissions.rs index 477a678864..17a40e820b 100644 --- a/pallets/subtensor/src/coinbase/subnet_emissions.rs +++ b/pallets/subtensor/src/coinbase/subnet_emissions.rs @@ -39,13 +39,13 @@ impl Pallet { .collect::>() } - pub fn record_tao_inflow(netuid: NetUid, tao: TaoCurrency) { + pub fn record_tao_inflow(netuid: NetUid, tao: TaoBalance) { SubnetTaoFlow::::mutate(netuid, |flow| { *flow = flow.saturating_add(u64::from(tao) as i64); }); } - pub fn record_tao_outflow(netuid: NetUid, tao: TaoCurrency) { + pub fn record_tao_outflow(netuid: NetUid, tao: TaoBalance) { SubnetTaoFlow::::mutate(netuid, |flow| { *flow = flow.saturating_sub(u64::from(tao) as i64) }); diff --git a/pallets/subtensor/src/epoch/run_epoch.rs b/pallets/subtensor/src/epoch/run_epoch.rs index 2290b49b8d..9f8fbc905b 100644 --- a/pallets/subtensor/src/epoch/run_epoch.rs +++ b/pallets/subtensor/src/epoch/run_epoch.rs @@ -6,23 +6,23 @@ use safe_math::*; use sp_std::collections::btree_map::IntoIter; use sp_std::vec; use substrate_fixed::types::{I32F32, I64F64, I96F32}; -use subtensor_runtime_common::{AlphaCurrency, MechId, NetUid, NetUidStorageIndex}; +use subtensor_runtime_common::{AlphaBalance, MechId, NetUid, NetUidStorageIndex}; #[derive(Debug, Default)] pub struct EpochTerms { pub uid: usize, pub dividend: u16, pub incentive: u16, - pub validator_emission: AlphaCurrency, - pub server_emission: AlphaCurrency, + pub validator_emission: AlphaBalance, + pub server_emission: AlphaBalance, pub stake_weight: u16, pub active: bool, - pub emission: AlphaCurrency, + pub emission: AlphaBalance, pub consensus: u16, pub validator_trust: u16, pub new_validator_permit: bool, pub bond: Vec<(u16, u16)>, - pub stake: AlphaCurrency, + pub stake: AlphaBalance, } pub struct EpochOutput(pub BTreeMap); @@ -61,8 +61,8 @@ impl Pallet { /// Legacy epoch function interface (TODO: Is only used for tests, remove) pub fn epoch( netuid: NetUid, - rao_emission: AlphaCurrency, - ) -> Vec<(T::AccountId, AlphaCurrency, AlphaCurrency)> { + rao_emission: AlphaBalance, + ) -> Vec<(T::AccountId, AlphaBalance, AlphaBalance)> { // Run mechanism-style epoch let output = Self::epoch_mechanism(netuid, MechId::MAIN, rao_emission); @@ -80,8 +80,8 @@ impl Pallet { /// Legacy epoch_dense function interface (TODO: Is only used for tests, remove) pub fn epoch_dense( netuid: NetUid, - rao_emission: AlphaCurrency, - ) -> Vec<(T::AccountId, AlphaCurrency, AlphaCurrency)> { + rao_emission: AlphaBalance, + ) -> Vec<(T::AccountId, AlphaBalance, AlphaBalance)> { Self::epoch_dense_mechanism(netuid, MechId::MAIN, rao_emission) } @@ -147,8 +147,8 @@ impl Pallet { pub fn epoch_dense_mechanism( netuid: NetUid, mecid: MechId, - rao_emission: AlphaCurrency, - ) -> Vec<(T::AccountId, AlphaCurrency, AlphaCurrency)> { + rao_emission: AlphaBalance, + ) -> Vec<(T::AccountId, AlphaBalance, AlphaBalance)> { // Calculate netuid storage index let netuid_index = Self::get_mechanism_storage_index(netuid, mecid); @@ -449,7 +449,7 @@ impl Pallet { .iter() .map(|se: &I32F32| I96F32::saturating_from_num(*se).saturating_mul(float_rao_emission)) .collect(); - let server_emission: Vec = server_emission + let server_emission: Vec = server_emission .iter() .map(|e: &I96F32| e.saturating_to_num::().into()) .collect(); @@ -458,7 +458,7 @@ impl Pallet { .iter() .map(|ve: &I32F32| I96F32::saturating_from_num(*ve).saturating_mul(float_rao_emission)) .collect(); - let validator_emission: Vec = validator_emission + let validator_emission: Vec = validator_emission .iter() .map(|e: &I96F32| e.saturating_to_num::().into()) .collect(); @@ -468,9 +468,9 @@ impl Pallet { .iter() .map(|ce: &I32F32| I96F32::saturating_from_num(*ce).saturating_mul(float_rao_emission)) .collect(); - let combined_emission: Vec = combined_emission + let combined_emission: Vec = combined_emission .iter() - .map(|e: &I96F32| AlphaCurrency::from(e.saturating_to_num::())) + .map(|e: &I96F32| AlphaBalance::from(e.saturating_to_num::())) .collect(); log::trace!("nSE: {:?}", &normalized_server_emission); @@ -560,7 +560,7 @@ impl Pallet { pub fn epoch_mechanism( netuid: NetUid, mecid: MechId, - rao_emission: AlphaCurrency, + rao_emission: AlphaBalance, ) -> EpochOutput { // Calculate netuid storage index let netuid_index = Self::get_mechanism_storage_index(netuid, mecid); @@ -925,7 +925,7 @@ impl Pallet { .iter() .map(|se: &I32F32| I96F32::saturating_from_num(*se).saturating_mul(float_rao_emission)) .collect(); - let server_emission: Vec = server_emission + let server_emission: Vec = server_emission .iter() .map(|e: &I96F32| e.saturating_to_num::().into()) .collect(); @@ -934,7 +934,7 @@ impl Pallet { .iter() .map(|ve: &I32F32| I96F32::saturating_from_num(*ve).saturating_mul(float_rao_emission)) .collect(); - let validator_emission: Vec = validator_emission + let validator_emission: Vec = validator_emission .iter() .map(|e: &I96F32| e.saturating_to_num::().into()) .collect(); @@ -944,9 +944,9 @@ impl Pallet { .iter() .map(|ce: &I32F32| I96F32::saturating_from_num(*ce).saturating_mul(float_rao_emission)) .collect(); - let combined_emission: Vec = combined_emission + let combined_emission: Vec = combined_emission .iter() - .map(|e: &I96F32| AlphaCurrency::from(e.saturating_to_num::())) + .map(|e: &I96F32| AlphaBalance::from(e.saturating_to_num::())) .collect(); log::trace!( diff --git a/pallets/subtensor/src/extensions/subtensor.rs b/pallets/subtensor/src/extensions/subtensor.rs index 950326c653..a5640e1736 100644 --- a/pallets/subtensor/src/extensions/subtensor.rs +++ b/pallets/subtensor/src/extensions/subtensor.rs @@ -1,4 +1,4 @@ -use crate::{BalancesCall, Call, Config, CustomTransactionError, Error, Pallet, TransactionType}; +use crate::{BalancesCall, Call, Config, Error, Pallet, TransactionType}; use codec::{Decode, DecodeWithMemTracking, Encode}; use frame_support::dispatch::{DispatchInfo, PostDispatchInfo}; use frame_support::traits::IsSubType; @@ -15,7 +15,7 @@ use sp_runtime::{ use sp_std::marker::PhantomData; use sp_std::vec::Vec; use subtensor_macros::freeze_struct; -use subtensor_runtime_common::{NetUid, NetUidStorageIndex}; +use subtensor_runtime_common::{CustomTransactionError, NetUid, NetUidStorageIndex}; const ADD_STAKE_BURN_PRIORITY_BOOST: u64 = 100; diff --git a/pallets/subtensor/src/guards/check_coldkey_swap.rs b/pallets/subtensor/src/guards/check_coldkey_swap.rs index 95a640b9dc..ab0a5e862a 100644 --- a/pallets/subtensor/src/guards/check_coldkey_swap.rs +++ b/pallets/subtensor/src/guards/check_coldkey_swap.rs @@ -118,7 +118,6 @@ mod tests { }), 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]), }), ] @@ -231,8 +230,8 @@ mod tests { 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); + SubtensorModule::add_balance_to_coldkey_account(&real, 1_000_000_000.into()); + SubtensorModule::add_balance_to_coldkey_account(&delegate, 1_000_000_000.into()); // Register proxy: delegate can act on behalf of real assert_ok!(Proxy::add_proxy( @@ -270,9 +269,9 @@ mod tests { 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); + SubtensorModule::add_balance_to_coldkey_account(&real, 1_000_000_000.into()); + SubtensorModule::add_balance_to_coldkey_account(&delegate1, 1_000_000_000.into()); + SubtensorModule::add_balance_to_coldkey_account(&delegate2, 1_000_000_000.into()); // delegate1 can proxy for real, delegate2 can proxy for delegate1 assert_ok!(Proxy::add_proxy( diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index c0000d2662..f27019989a 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -10,7 +10,6 @@ use frame_system::{self as system, ensure_signed}; pub use pallet::*; use codec::{Decode, Encode}; -use frame_support::sp_runtime::transaction_validity::InvalidTransaction; use frame_support::{ dispatch::{self, DispatchResult, DispatchResultWithPostInfo}, ensure, @@ -22,9 +21,9 @@ use pallet_balances::Call as BalancesCall; // use pallet_scheduler as Scheduler; use scale_info::TypeInfo; use sp_core::Get; -use sp_runtime::{DispatchError, transaction_validity::TransactionValidityError}; +use sp_runtime::DispatchError; use sp_std::marker::PhantomData; -use subtensor_runtime_common::{AlphaCurrency, Currency, CurrencyReserve, NetUid, TaoCurrency}; +use subtensor_runtime_common::{AlphaBalance, NetUid, TaoBalance, Token, TokenReserve}; // ============================ // ==== Benchmark Imports ===== @@ -103,7 +102,7 @@ pub mod pallet { use substrate_fixed::types::{I64F64, I96F32, U64F64, U96F32}; use subtensor_macros::freeze_struct; use subtensor_runtime_common::{ - AlphaCurrency, Currency, MechId, NetUid, NetUidStorageIndex, TaoCurrency, + AlphaBalance, MechId, NetUid, NetUidStorageIndex, TaoBalance, Token, }; /// Origin for the pallet @@ -118,7 +117,7 @@ pub mod pallet { const STORAGE_VERSION: StorageVersion = StorageVersion::new(7); /// Minimum balance required to perform a coldkey swap - pub const MIN_BALANCE_TO_PERFORM_COLDKEY_SWAP: TaoCurrency = TaoCurrency::new(100_000_000); // 0.1 TAO in RAO + pub const MIN_BALANCE_TO_PERFORM_COLDKEY_SWAP: TaoBalance = TaoBalance::new(100_000_000); // 0.1 TAO in RAO /// Minimum commit reveal periods pub const MIN_COMMIT_REVEAL_PEROIDS: u64 = 1; @@ -384,14 +383,14 @@ pub mod pallet { } /// Default value for Alpha currency. #[pallet::type_value] - pub fn DefaultZeroAlpha() -> AlphaCurrency { - AlphaCurrency::ZERO + pub fn DefaultZeroAlpha() -> AlphaBalance { + AlphaBalance::ZERO } /// Default value for Tao currency. #[pallet::type_value] - pub fn DefaultZeroTao() -> TaoCurrency { - TaoCurrency::ZERO + pub fn DefaultZeroTao() -> TaoBalance { + TaoBalance::ZERO } /// Default value for zero. @@ -480,7 +479,7 @@ pub mod pallet { /// Default total issuance. #[pallet::type_value] - pub fn DefaultTotalIssuance() -> TaoCurrency { + pub fn DefaultTotalIssuance() -> TaoBalance { T::InitialIssuance::get().into() } @@ -539,19 +538,19 @@ pub mod pallet { /// Default registrations this block. #[pallet::type_value] - pub fn DefaultBurn() -> TaoCurrency { + pub fn DefaultBurn() -> TaoBalance { T::InitialBurn::get().into() } /// Default burn token. #[pallet::type_value] - pub fn DefaultMinBurn() -> TaoCurrency { + pub fn DefaultMinBurn() -> TaoBalance { T::InitialMinBurn::get().into() } /// Default min burn token. #[pallet::type_value] - pub fn DefaultMaxBurn() -> TaoCurrency { + pub fn DefaultMaxBurn() -> TaoBalance { T::InitialMaxBurn::get().into() } @@ -581,7 +580,7 @@ pub mod pallet { /// Default max registrations per block. #[pallet::type_value] - pub fn DefaultRAORecycledForRegistration() -> TaoCurrency { + pub fn DefaultRAORecycledForRegistration() -> TaoBalance { T::InitialRAORecycledForRegistration::get().into() } @@ -629,7 +628,7 @@ pub mod pallet { /// Default value for network min lock cost. #[pallet::type_value] - pub fn DefaultNetworkMinLockCost() -> TaoCurrency { + pub fn DefaultNetworkMinLockCost() -> TaoBalance { T::InitialNetworkMinLockCost::get().into() } @@ -675,7 +674,7 @@ pub mod pallet { /// Default value for pending emission. #[pallet::type_value] - pub fn DefaultPendingEmission() -> AlphaCurrency { + pub fn DefaultPendingEmission() -> AlphaBalance { 0.into() } @@ -969,7 +968,7 @@ pub mod pallet { /// Default minimum stake. #[pallet::type_value] - pub fn DefaultMinStake() -> TaoCurrency { + pub fn DefaultMinStake() -> TaoBalance { 2_000_000.into() } @@ -1206,7 +1205,7 @@ pub mod pallet { NetUid, Blake2_128Concat, T::AccountId, - AlphaCurrency, + AlphaBalance, ValueQuery, DefaultZeroAlpha, >; @@ -1219,7 +1218,7 @@ pub mod pallet { NetUid, Blake2_128Concat, T::AccountId, - AlphaCurrency, + AlphaBalance, ValueQuery, DefaultZeroAlpha, >; @@ -1239,7 +1238,7 @@ pub mod pallet { T::AccountId, Identity, NetUid, - AlphaCurrency, + AlphaBalance, ValueQuery, DefaultZeroAlpha, >; @@ -1261,11 +1260,11 @@ pub mod pallet { /// --- ITEM ( total_issuance ) #[pallet::storage] - pub type TotalIssuance = StorageValue<_, TaoCurrency, ValueQuery, DefaultTotalIssuance>; + pub type TotalIssuance = StorageValue<_, TaoBalance, ValueQuery, DefaultTotalIssuance>; /// --- ITEM ( total_stake ) #[pallet::storage] - pub type TotalStake = StorageValue<_, TaoCurrency, ValueQuery, DefaultZeroTao>; + pub type TotalStake = StorageValue<_, TaoBalance, ValueQuery, DefaultZeroTao>; /// --- ITEM ( moving_alpha ) -- subnet moving alpha. #[pallet::storage] @@ -1289,42 +1288,42 @@ pub mod pallet { /// --- MAP ( netuid ) --> tao_in_subnet | Returns the amount of TAO in the subnet. #[pallet::storage] pub type SubnetTAO = - StorageMap<_, Identity, NetUid, TaoCurrency, ValueQuery, DefaultZeroTao>; + StorageMap<_, Identity, NetUid, TaoBalance, ValueQuery, DefaultZeroTao>; /// --- MAP ( netuid ) --> tao_in_user_subnet | Returns the amount of TAO in the subnet reserve provided by users as liquidity. #[pallet::storage] pub type SubnetTaoProvided = - StorageMap<_, Identity, NetUid, TaoCurrency, ValueQuery, DefaultZeroTao>; + StorageMap<_, Identity, NetUid, TaoBalance, ValueQuery, DefaultZeroTao>; /// --- MAP ( netuid ) --> alpha_in_emission | Returns the amount of alph in emission into the pool per block. #[pallet::storage] pub type SubnetAlphaInEmission = - StorageMap<_, Identity, NetUid, AlphaCurrency, ValueQuery, DefaultZeroAlpha>; + StorageMap<_, Identity, NetUid, AlphaBalance, ValueQuery, DefaultZeroAlpha>; /// --- MAP ( netuid ) --> alpha_out_emission | Returns the amount of alpha out emission into the network per block. #[pallet::storage] pub type SubnetAlphaOutEmission = - StorageMap<_, Identity, NetUid, AlphaCurrency, ValueQuery, DefaultZeroAlpha>; + StorageMap<_, Identity, NetUid, AlphaBalance, ValueQuery, DefaultZeroAlpha>; /// --- MAP ( netuid ) --> tao_in_emission | Returns the amount of tao emitted into this subent on the last block. #[pallet::storage] pub type SubnetTaoInEmission = - StorageMap<_, Identity, NetUid, TaoCurrency, ValueQuery, DefaultZeroTao>; + StorageMap<_, Identity, NetUid, TaoBalance, ValueQuery, DefaultZeroTao>; /// --- MAP ( netuid ) --> alpha_supply_in_pool | Returns the amount of alpha in the pool. #[pallet::storage] pub type SubnetAlphaIn = - StorageMap<_, Identity, NetUid, AlphaCurrency, ValueQuery, DefaultZeroAlpha>; + StorageMap<_, Identity, NetUid, AlphaBalance, ValueQuery, DefaultZeroAlpha>; /// --- MAP ( netuid ) --> alpha_supply_user_in_pool | Returns the amount of alpha in the pool provided by users as liquidity. #[pallet::storage] pub type SubnetAlphaInProvided = - StorageMap<_, Identity, NetUid, AlphaCurrency, ValueQuery, DefaultZeroAlpha>; + StorageMap<_, Identity, NetUid, AlphaBalance, ValueQuery, DefaultZeroAlpha>; /// --- MAP ( netuid ) --> alpha_supply_in_subnet | Returns the amount of alpha in the subnet. #[pallet::storage] pub type SubnetAlphaOut = - StorageMap<_, Identity, NetUid, AlphaCurrency, ValueQuery, DefaultZeroAlpha>; + StorageMap<_, Identity, NetUid, AlphaBalance, ValueQuery, DefaultZeroAlpha>; /// --- MAP ( cold ) --> Vec | Maps coldkey to hotkeys that stake to it #[pallet::storage] @@ -1390,7 +1389,7 @@ pub mod pallet { T::AccountId, Identity, NetUid, - AlphaCurrency, + AlphaBalance, ValueQuery, DefaultZeroAlpha, >; @@ -1403,7 +1402,7 @@ pub mod pallet { T::AccountId, Identity, NetUid, - AlphaCurrency, + AlphaBalance, ValueQuery, DefaultZeroAlpha, >; @@ -1518,12 +1517,12 @@ pub mod pallet { /// ITEM( min_network_lock_cost ) #[pallet::storage] pub type NetworkMinLockCost = - StorageValue<_, TaoCurrency, ValueQuery, DefaultNetworkMinLockCost>; + StorageValue<_, TaoBalance, ValueQuery, DefaultNetworkMinLockCost>; /// ITEM( last_network_lock_cost ) #[pallet::storage] pub type NetworkLastLockCost = - StorageValue<_, TaoCurrency, ValueQuery, DefaultNetworkMinLockCost>; + StorageValue<_, TaoBalance, ValueQuery, DefaultNetworkMinLockCost>; /// ITEM( network_lock_reduction_interval ) #[pallet::storage] @@ -1566,7 +1565,7 @@ pub mod pallet { /// --- MAP ( netuid ) --> total_subnet_locked #[pallet::storage] pub type SubnetLocked = - StorageMap<_, Identity, NetUid, TaoCurrency, ValueQuery, DefaultZeroTao>; + StorageMap<_, Identity, NetUid, TaoBalance, ValueQuery, DefaultZeroTao>; /// --- MAP ( netuid ) --> largest_locked #[pallet::storage] @@ -1633,22 +1632,22 @@ pub mod pallet { /// --- MAP ( netuid ) --> pending_server_emission #[pallet::storage] pub type PendingServerEmission = - StorageMap<_, Identity, NetUid, AlphaCurrency, ValueQuery, DefaultZeroAlpha>; + StorageMap<_, Identity, NetUid, AlphaBalance, ValueQuery, DefaultZeroAlpha>; /// --- MAP ( netuid ) --> pending_validator_emission #[pallet::storage] pub type PendingValidatorEmission = - StorageMap<_, Identity, NetUid, AlphaCurrency, ValueQuery, DefaultZeroAlpha>; + StorageMap<_, Identity, NetUid, AlphaBalance, ValueQuery, DefaultZeroAlpha>; /// --- MAP ( netuid ) --> pending_root_alpha_emission #[pallet::storage] pub type PendingRootAlphaDivs = - StorageMap<_, Identity, NetUid, AlphaCurrency, ValueQuery, DefaultZeroAlpha>; + StorageMap<_, Identity, NetUid, AlphaBalance, ValueQuery, DefaultZeroAlpha>; /// --- MAP ( netuid ) --> pending_owner_cut #[pallet::storage] pub type PendingOwnerCut = - StorageMap<_, Identity, NetUid, AlphaCurrency, ValueQuery, DefaultZeroAlpha>; + StorageMap<_, Identity, NetUid, AlphaBalance, ValueQuery, DefaultZeroAlpha>; /// --- MAP ( netuid ) --> blocks_since_last_step #[pallet::storage] @@ -1805,7 +1804,7 @@ pub mod pallet { /// --- MAP ( netuid ) --> Burn #[pallet::storage] - pub type Burn = StorageMap<_, Identity, NetUid, TaoCurrency, ValueQuery, DefaultBurn>; + pub type Burn = StorageMap<_, Identity, NetUid, TaoBalance, ValueQuery, DefaultBurn>; /// --- MAP ( netuid ) --> Difficulty #[pallet::storage] @@ -1814,12 +1813,12 @@ pub mod pallet { /// --- MAP ( netuid ) --> MinBurn #[pallet::storage] pub type MinBurn = - StorageMap<_, Identity, NetUid, TaoCurrency, ValueQuery, DefaultMinBurn>; + StorageMap<_, Identity, NetUid, TaoBalance, ValueQuery, DefaultMinBurn>; /// --- MAP ( netuid ) --> MaxBurn #[pallet::storage] pub type MaxBurn = - StorageMap<_, Identity, NetUid, TaoCurrency, ValueQuery, DefaultMaxBurn>; + StorageMap<_, Identity, NetUid, TaoBalance, ValueQuery, DefaultMaxBurn>; /// --- MAP ( netuid ) --> MinDifficulty #[pallet::storage] @@ -1852,7 +1851,7 @@ pub mod pallet { _, Identity, NetUid, - TaoCurrency, + TaoBalance, ValueQuery, DefaultRAORecycledForRegistration, >; @@ -2021,7 +2020,7 @@ pub mod pallet { /// --- MAP ( netuid ) --> emission #[pallet::storage] - pub type Emission = StorageMap<_, Identity, NetUid, Vec, ValueQuery>; + pub type Emission = StorageMap<_, Identity, NetUid, Vec, ValueQuery>; /// --- MAP ( netuid ) --> last_update #[pallet::storage] @@ -2343,7 +2342,7 @@ pub mod pallet { /// --- MAP ( lease_id ) --> accumulated_dividends | The accumulated dividends for a given lease that needs to be distributed. #[pallet::storage] pub type AccumulatedLeaseDividends = - StorageMap<_, Twox64Concat, LeaseId, AlphaCurrency, ValueQuery, DefaultZeroAlpha>; + StorageMap<_, Twox64Concat, LeaseId, AlphaBalance, ValueQuery, DefaultZeroAlpha>; /// --- ITEM ( CommitRevealWeightsVersion ) #[pallet::storage] @@ -2426,7 +2425,7 @@ pub mod pallet { /// Stakes record in genesis. pub stakes: Vec<(T::AccountId, Vec<(T::AccountId, (u64, u16))>)>, /// The total issued balance in genesis - pub balances_issuance: TaoCurrency, + pub balances_issuance: TaoBalance, /// The delay before a subnet can call start pub start_call_delay: Option, } @@ -2435,7 +2434,7 @@ pub mod pallet { fn default() -> Self { Self { stakes: Default::default(), - balances_issuance: TaoCurrency::ZERO, + balances_issuance: TaoBalance::ZERO, start_call_delay: None, } } @@ -2485,70 +2484,6 @@ pub mod pallet { } } -#[derive(Debug, PartialEq)] -pub enum CustomTransactionError { - /// Deprecated: coldkey swap now uses announcements and check moved to DispatchGuard - #[deprecated] - ColdkeyInSwapSchedule, - StakeAmountTooLow, - BalanceTooLow, - SubnetNotExists, - HotkeyAccountDoesntExist, - NotEnoughStakeToWithdraw, - RateLimitExceeded, - InsufficientLiquidity, - SlippageTooHigh, - TransferDisallowed, - HotKeyNotRegisteredInNetwork, - InvalidIpAddress, - ServingRateLimitExceeded, - InvalidPort, - BadRequest, - ZeroMaxAmount, - InvalidRevealRound, - CommitNotFound, - CommitBlockNotInRevealRange, - InputLengthsUnequal, - UidNotFound, - EvmKeyAssociateRateLimitExceeded, -} - -impl From for u8 { - fn from(variant: CustomTransactionError) -> u8 { - match variant { - #[allow(deprecated)] - CustomTransactionError::ColdkeyInSwapSchedule => 0, - CustomTransactionError::StakeAmountTooLow => 1, - CustomTransactionError::BalanceTooLow => 2, - CustomTransactionError::SubnetNotExists => 3, - CustomTransactionError::HotkeyAccountDoesntExist => 4, - CustomTransactionError::NotEnoughStakeToWithdraw => 5, - CustomTransactionError::RateLimitExceeded => 6, - CustomTransactionError::InsufficientLiquidity => 7, - CustomTransactionError::SlippageTooHigh => 8, - CustomTransactionError::TransferDisallowed => 9, - CustomTransactionError::HotKeyNotRegisteredInNetwork => 10, - CustomTransactionError::InvalidIpAddress => 11, - CustomTransactionError::ServingRateLimitExceeded => 12, - CustomTransactionError::InvalidPort => 13, - CustomTransactionError::BadRequest => 255, - CustomTransactionError::ZeroMaxAmount => 14, - CustomTransactionError::InvalidRevealRound => 15, - CustomTransactionError::CommitNotFound => 16, - CustomTransactionError::CommitBlockNotInRevealRange => 17, - CustomTransactionError::InputLengthsUnequal => 18, - CustomTransactionError::UidNotFound => 19, - CustomTransactionError::EvmKeyAssociateRateLimitExceeded => 20, - } - } -} - -impl From for TransactionValidityError { - fn from(variant: CustomTransactionError) -> Self { - TransactionValidityError::Invalid(InvalidTransaction::Custom(variant.into())) - } -} - use sp_std::vec; // TODO: unravel this rats nest, for some reason rustc thinks this is unused even though it's @@ -2560,17 +2495,17 @@ use subtensor_macros::freeze_struct; #[derive(Clone)] pub struct TaoCurrencyReserve(PhantomData); -impl CurrencyReserve for TaoCurrencyReserve { +impl TokenReserve for TaoCurrencyReserve { #![deny(clippy::expect_used)] - fn reserve(netuid: NetUid) -> TaoCurrency { + fn reserve(netuid: NetUid) -> TaoBalance { SubnetTAO::::get(netuid).saturating_add(SubnetTaoProvided::::get(netuid)) } - fn increase_provided(netuid: NetUid, tao: TaoCurrency) { + fn increase_provided(netuid: NetUid, tao: TaoBalance) { Pallet::::increase_provided_tao_reserve(netuid, tao); } - fn decrease_provided(netuid: NetUid, tao: TaoCurrency) { + fn decrease_provided(netuid: NetUid, tao: TaoBalance) { Pallet::::decrease_provided_tao_reserve(netuid, tao); } } @@ -2578,17 +2513,17 @@ impl CurrencyReserve for TaoCurrencyReserve { #[derive(Clone)] pub struct AlphaCurrencyReserve(PhantomData); -impl CurrencyReserve for AlphaCurrencyReserve { +impl TokenReserve for AlphaCurrencyReserve { #![deny(clippy::expect_used)] - fn reserve(netuid: NetUid) -> AlphaCurrency { + fn reserve(netuid: NetUid) -> AlphaBalance { SubnetAlphaIn::::get(netuid).saturating_add(SubnetAlphaInProvided::::get(netuid)) } - fn increase_provided(netuid: NetUid, alpha: AlphaCurrency) { + fn increase_provided(netuid: NetUid, alpha: AlphaBalance) { Pallet::::increase_provided_alpha_reserve(netuid, alpha); } - fn decrease_provided(netuid: NetUid, alpha: AlphaCurrency) { + fn decrease_provided(netuid: NetUid, alpha: AlphaBalance) { Pallet::::decrease_provided_alpha_reserve(netuid, alpha); } } @@ -2598,7 +2533,7 @@ pub type GetAlphaForTao = pub type GetTaoForAlpha = subtensor_swap_interface::GetTaoForAlpha, TaoCurrencyReserve>; -impl> +impl> subtensor_runtime_common::SubnetInfo for Pallet { #![deny(clippy::expect_used)] @@ -2631,11 +2566,11 @@ impl> } } -impl> +impl> subtensor_runtime_common::BalanceOps for Pallet { #![deny(clippy::expect_used)] - fn tao_balance(account_id: &T::AccountId) -> TaoCurrency { + fn tao_balance(account_id: &T::AccountId) -> TaoBalance { pallet_balances::Pallet::::free_balance(account_id).into() } @@ -2643,18 +2578,18 @@ impl> netuid: NetUid, coldkey: &T::AccountId, hotkey: &T::AccountId, - ) -> AlphaCurrency { + ) -> AlphaBalance { Self::get_stake_for_hotkey_and_coldkey_on_subnet(hotkey, coldkey, netuid) } - fn increase_balance(coldkey: &T::AccountId, tao: TaoCurrency) { + fn increase_balance(coldkey: &T::AccountId, tao: TaoBalance) { Self::add_balance_to_coldkey_account(coldkey, tao.into()) } fn decrease_balance( coldkey: &T::AccountId, - tao: TaoCurrency, - ) -> Result { + tao: TaoBalance, + ) -> Result { Self::remove_balance_from_coldkey_account(coldkey, tao.into()) } @@ -2662,7 +2597,7 @@ impl> coldkey: &T::AccountId, hotkey: &T::AccountId, netuid: NetUid, - alpha: AlphaCurrency, + alpha: AlphaBalance, ) -> Result<(), DispatchError> { ensure!( Self::hotkey_account_exists(hotkey), @@ -2683,8 +2618,8 @@ impl> coldkey: &T::AccountId, hotkey: &T::AccountId, netuid: NetUid, - alpha: AlphaCurrency, - ) -> Result { + alpha: AlphaBalance, + ) -> Result { ensure!( Self::hotkey_account_exists(hotkey), Error::::HotKeyAccountNotExists diff --git a/pallets/subtensor/src/macros/config.rs b/pallets/subtensor/src/macros/config.rs index 528e5c9fd5..1537de65b3 100644 --- a/pallets/subtensor/src/macros/config.rs +++ b/pallets/subtensor/src/macros/config.rs @@ -29,7 +29,7 @@ mod config { + GetDispatchInfo; /// Currency type that will be used to place deposits on neurons - type Currency: fungible::Balanced + type Currency: fungible::Balanced + fungible::Mutate; /// The scheduler type used for scheduling delayed calls. @@ -69,7 +69,7 @@ mod config { /// Initial currency issuance. #[pallet::constant] - type InitialIssuance: Get; + type InitialIssuance: Get; /// Initial min allowed weights setting. #[pallet::constant] type InitialMinAllowedWeights: Get; @@ -90,22 +90,22 @@ mod config { type InitialMinDifficulty: Get; /// Initial RAO Recycled. #[pallet::constant] - type InitialRAORecycledForRegistration: Get; + type InitialRAORecycledForRegistration: Get; /// Initial Burn. #[pallet::constant] - type InitialBurn: Get; + type InitialBurn: Get; /// Initial Max Burn. #[pallet::constant] - type InitialMaxBurn: Get; + type InitialMaxBurn: Get; /// Initial Min Burn. #[pallet::constant] - type InitialMinBurn: Get; + type InitialMinBurn: Get; /// Min burn upper bound. #[pallet::constant] - type MinBurnUpperBound: Get; + type MinBurnUpperBound: Get; /// Max burn lower bound. #[pallet::constant] - type MaxBurnLowerBound: Get; + type MaxBurnLowerBound: Get; /// Initial adjustment interval. #[pallet::constant] type InitialAdjustmentInterval: Get; @@ -195,7 +195,7 @@ mod config { type InitialNetworkImmunityPeriod: Get; /// Initial network minimum burn cost #[pallet::constant] - type InitialNetworkMinLockCost: Get; + type InitialNetworkMinLockCost: Get; /// Initial network subnet cut. #[pallet::constant] type InitialSubnetOwnerCut: Get; @@ -207,7 +207,7 @@ mod config { type InitialNetworkRateLimit: Get; /// Cost of swapping a hotkey. #[pallet::constant] - type KeySwapCost: Get; + type KeySwapCost: Get; /// The upper bound for the alpha parameter. Used for Liquid Alpha. #[pallet::constant] type AlphaHigh: Get; @@ -240,7 +240,7 @@ mod config { type InitialStartCallDelay: Get; /// Cost of swapping a hotkey in a subnet. #[pallet::constant] - type KeySwapOnSubnetCost: Get; + type KeySwapOnSubnetCost: Get; /// Block number for a coldkey swap the hotkey in specific subnet. #[pallet::constant] type HotkeySwapOnSubnetInterval: Get; diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 7656985819..19a8f635dc 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -712,12 +712,12 @@ mod dispatches { #[pallet::call_index(2)] #[pallet::weight((Weight::from_parts(340_800_000, 0) .saturating_add(T::DbWeight::get().reads(25_u64)) - .saturating_add(T::DbWeight::get().writes(16_u64)), DispatchClass::Normal, Pays::Yes))] + .saturating_add(T::DbWeight::get().writes(15_u64)), DispatchClass::Normal, Pays::Yes))] pub fn add_stake( origin: OriginFor, hotkey: T::AccountId, netuid: NetUid, - amount_staked: TaoCurrency, + amount_staked: TaoBalance, ) -> DispatchResult { Self::do_add_stake(origin, hotkey, netuid, amount_staked).map(|_| ()) } @@ -761,7 +761,7 @@ mod dispatches { origin: OriginFor, hotkey: T::AccountId, netuid: NetUid, - amount_unstaked: AlphaCurrency, + amount_unstaked: AlphaBalance, ) -> DispatchResult { Self::do_remove_stake(origin, hotkey, netuid, amount_unstaked) } @@ -1042,7 +1042,7 @@ mod dispatches { #[pallet::call_index(7)] #[pallet::weight((Weight::from_parts(354_200_000, 0) .saturating_add(T::DbWeight::get().reads(47_u64)) - .saturating_add(T::DbWeight::get().writes(40_u64)), DispatchClass::Normal, Pays::Yes))] + .saturating_add(T::DbWeight::get().writes(39_u64)), DispatchClass::Normal, Pays::Yes))] pub fn burned_register( origin: OriginFor, netuid: NetUid, @@ -1051,7 +1051,17 @@ mod dispatches { Self::do_burned_registration(origin, netuid, hotkey) } - /// The extrinsic for user to change its hotkey in subnet or all subnets. + /// ---- The extrinsic for user to change its hotkey in subnet or all subnets. + /// + /// # Arguments + /// * `origin` - The origin of the transaction (must be signed by the coldkey). + /// * `hotkey` - The old hotkey to be swapped. + /// * `new_hotkey` - The new hotkey to replace the old one. + /// * `netuid` - Optional subnet ID. If `Some`, swap only on that subnet; if `None`, swap on all subnets. + /// is transferred to the new hotkey. + #[deprecated( + note = "Please use swap_hotkey_v2 instead. This extrinsic will be removed some time after June 2026." + )] #[pallet::call_index(70)] #[pallet::weight((Weight::from_parts(275_300_000, 0) .saturating_add(T::DbWeight::get().reads(52_u64)) @@ -1062,7 +1072,32 @@ mod dispatches { new_hotkey: T::AccountId, netuid: Option, ) -> DispatchResultWithPostInfo { - Self::do_swap_hotkey(origin, &hotkey, &new_hotkey, netuid) + Self::do_swap_hotkey(origin, &hotkey, &new_hotkey, netuid, false) + } + + /// ---- The extrinsic for user to change its hotkey in subnet or all subnets. This extrinsic is + /// similar to swap_hotkey, but with keep_stake parameter bo be able to keep the stake when swapping + /// a root key to a child key + /// + /// # Arguments + /// * `origin` - The origin of the transaction (must be signed by the coldkey). + /// * `hotkey` - The old hotkey to be swapped. + /// * `new_hotkey` - The new hotkey to replace the old one. + /// * `netuid` - Optional subnet ID. If `Some`, swap only on that subnet; if `None`, swap on all subnets. + /// * `keep_stake` - If `true`, stake remains on the old hotkey and the rest metadata + /// is transferred to the new hotkey. + #[pallet::call_index(72)] + #[pallet::weight((Weight::from_parts(275_300_000, 0) + .saturating_add(T::DbWeight::get().reads(52_u64)) + .saturating_add(T::DbWeight::get().writes(35_u64)), DispatchClass::Normal, Pays::No))] + pub fn swap_hotkey_v2( + origin: OriginFor, + hotkey: T::AccountId, + new_hotkey: T::AccountId, + netuid: Option, + keep_stake: bool, + ) -> DispatchResultWithPostInfo { + Self::do_swap_hotkey(origin, &hotkey, &new_hotkey, netuid, keep_stake) } /// Performs an arbitrary coldkey swap for any coldkey. @@ -1076,7 +1111,7 @@ mod dispatches { origin: OriginFor, old_coldkey: T::AccountId, new_coldkey: T::AccountId, - swap_cost: TaoCurrency, + swap_cost: TaoBalance, ) -> DispatchResult { ensure_root(origin)?; @@ -1491,8 +1526,8 @@ mod dispatches { /// - Thrown if key has hit transaction rate limit #[pallet::call_index(84)] #[pallet::weight((Weight::from_parts(358_500_000, 0) - .saturating_add(T::DbWeight::get().reads(41_u64)) - .saturating_add(T::DbWeight::get().writes(26_u64)), DispatchClass::Normal, Pays::Yes))] + .saturating_add(T::DbWeight::get().reads(40_u64)) + .saturating_add(T::DbWeight::get().writes(24_u64)), DispatchClass::Normal, Pays::Yes))] pub fn unstake_all_alpha(origin: OriginFor, hotkey: T::AccountId) -> DispatchResult { Self::do_unstake_all_alpha(origin, hotkey) } @@ -1528,7 +1563,7 @@ mod dispatches { destination_hotkey: T::AccountId, origin_netuid: NetUid, destination_netuid: NetUid, - alpha_amount: AlphaCurrency, + alpha_amount: AlphaBalance, ) -> DispatchResult { Self::do_move_stake( origin, @@ -1571,7 +1606,7 @@ mod dispatches { hotkey: T::AccountId, origin_netuid: NetUid, destination_netuid: NetUid, - alpha_amount: AlphaCurrency, + alpha_amount: AlphaBalance, ) -> DispatchResult { Self::do_transfer_stake( origin, @@ -1605,8 +1640,8 @@ mod dispatches { #[pallet::call_index(87)] #[pallet::weight(( Weight::from_parts(351_300_000, 0) - .saturating_add(T::DbWeight::get().reads(37_u64)) - .saturating_add(T::DbWeight::get().writes(24_u64)), + .saturating_add(T::DbWeight::get().reads(36_u64)) + .saturating_add(T::DbWeight::get().writes(22_u64)), DispatchClass::Normal, Pays::Yes ))] @@ -1615,7 +1650,7 @@ mod dispatches { hotkey: T::AccountId, origin_netuid: NetUid, destination_netuid: NetUid, - alpha_amount: AlphaCurrency, + alpha_amount: AlphaBalance, ) -> DispatchResult { Self::do_swap_stake( origin, @@ -1671,13 +1706,13 @@ mod dispatches { #[pallet::call_index(88)] #[pallet::weight((Weight::from_parts(402_900_000, 0) .saturating_add(T::DbWeight::get().reads(25_u64)) - .saturating_add(T::DbWeight::get().writes(16_u64)), DispatchClass::Normal, Pays::Yes))] + .saturating_add(T::DbWeight::get().writes(15_u64)), DispatchClass::Normal, Pays::Yes))] pub fn add_stake_limit( origin: OriginFor, hotkey: T::AccountId, netuid: NetUid, - amount_staked: TaoCurrency, - limit_price: TaoCurrency, + amount_staked: TaoBalance, + limit_price: TaoBalance, allow_partial: bool, ) -> DispatchResult { Self::do_add_stake_limit( @@ -1736,13 +1771,13 @@ mod dispatches { #[pallet::call_index(89)] #[pallet::weight((Weight::from_parts(377_400_000, 0) .saturating_add(T::DbWeight::get().reads(28_u64)) - .saturating_add(T::DbWeight::get().writes(14_u64)), DispatchClass::Normal, Pays::Yes))] + .saturating_add(T::DbWeight::get().writes(13_u64)), DispatchClass::Normal, Pays::Yes))] pub fn remove_stake_limit( origin: OriginFor, hotkey: T::AccountId, netuid: NetUid, - amount_unstaked: AlphaCurrency, - limit_price: TaoCurrency, + amount_unstaked: AlphaBalance, + limit_price: TaoBalance, allow_partial: bool, ) -> DispatchResult { Self::do_remove_stake_limit( @@ -1779,8 +1814,8 @@ mod dispatches { #[pallet::call_index(90)] #[pallet::weight(( Weight::from_parts(411_500_000, 0) - .saturating_add(T::DbWeight::get().reads(37_u64)) - .saturating_add(T::DbWeight::get().writes(24_u64)), + .saturating_add(T::DbWeight::get().reads(36_u64)) + .saturating_add(T::DbWeight::get().writes(22_u64)), DispatchClass::Normal, Pays::Yes ))] @@ -1789,8 +1824,8 @@ mod dispatches { hotkey: T::AccountId, origin_netuid: NetUid, destination_netuid: NetUid, - alpha_amount: AlphaCurrency, - limit_price: TaoCurrency, + alpha_amount: AlphaBalance, + limit_price: TaoBalance, allow_partial: bool, ) -> DispatchResult { Self::do_swap_stake_limit( @@ -1908,7 +1943,7 @@ mod dispatches { pub fn recycle_alpha( origin: T::RuntimeOrigin, hotkey: T::AccountId, - amount: AlphaCurrency, + amount: AlphaBalance, netuid: NetUid, ) -> DispatchResult { Self::do_recycle_alpha(origin, hotkey, amount, netuid) @@ -1933,7 +1968,7 @@ mod dispatches { pub fn burn_alpha( origin: T::RuntimeOrigin, hotkey: T::AccountId, - amount: AlphaCurrency, + amount: AlphaBalance, netuid: NetUid, ) -> DispatchResult { Self::do_burn_alpha(origin, hotkey, amount, netuid) @@ -1958,12 +1993,12 @@ mod dispatches { #[pallet::call_index(103)] #[pallet::weight((Weight::from_parts(395_300_000, 10142) .saturating_add(T::DbWeight::get().reads(28_u64)) - .saturating_add(T::DbWeight::get().writes(14_u64)), DispatchClass::Normal, Pays::Yes))] + .saturating_add(T::DbWeight::get().writes(13_u64)), DispatchClass::Normal, Pays::Yes))] pub fn remove_stake_full_limit( origin: T::RuntimeOrigin, hotkey: T::AccountId, netuid: NetUid, - limit_price: Option, + limit_price: Option, ) -> DispatchResult { Self::do_remove_stake_full_limit(origin, hotkey, netuid, limit_price) } @@ -2082,7 +2117,7 @@ mod dispatches { /// * commit_reveal_version (`u16`): /// - The client (bittensor-drand) version #[pallet::call_index(113)] - #[pallet::weight((Weight::from_parts(63_160_000, 0) + #[pallet::weight((Weight::from_parts(94_980_000, 0) .saturating_add(T::DbWeight::get().reads(10_u64)) .saturating_add(T::DbWeight::get().writes(2)), DispatchClass::Normal, Pays::No))] pub fn commit_timelocked_weights( @@ -2556,7 +2591,7 @@ mod dispatches { #[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)), + .saturating_add(T::DbWeight::get().writes(16_u64)), DispatchClass::Normal, Pays::Yes ))] @@ -2564,8 +2599,8 @@ mod dispatches { origin: T::RuntimeOrigin, hotkey: T::AccountId, netuid: NetUid, - amount: TaoCurrency, - limit: Option, + amount: TaoBalance, + limit: Option, ) -> DispatchResult { Self::do_add_stake_burn(origin, hotkey, netuid, amount, limit) } diff --git a/pallets/subtensor/src/macros/events.rs b/pallets/subtensor/src/macros/events.rs index 65c33aee87..4363eb3f35 100644 --- a/pallets/subtensor/src/macros/events.rs +++ b/pallets/subtensor/src/macros/events.rs @@ -17,8 +17,8 @@ mod events { StakeAdded( T::AccountId, T::AccountId, - TaoCurrency, - AlphaCurrency, + TaoBalance, + AlphaBalance, NetUid, u64, ), @@ -26,8 +26,8 @@ mod events { StakeRemoved( T::AccountId, T::AccountId, - TaoCurrency, - AlphaCurrency, + TaoBalance, + AlphaBalance, NetUid, u64, ), @@ -38,7 +38,7 @@ mod events { NetUid, T::AccountId, NetUid, - TaoCurrency, + TaoBalance, ), /// a caller successfully sets their weights on a subnetwork. WeightsSet(NetUidStorageIndex, u16), @@ -104,11 +104,11 @@ mod events { /// setting the prometheus serving rate limit. ServingRateLimitSet(NetUid, u64), /// setting burn on a network. - BurnSet(NetUid, TaoCurrency), + BurnSet(NetUid, TaoBalance), /// setting max burn on a network. - MaxBurnSet(NetUid, TaoCurrency), + MaxBurnSet(NetUid, TaoBalance), /// setting min burn on a network. - MinBurnSet(NetUid, TaoCurrency), + MinBurnSet(NetUid, TaoBalance), /// setting the transaction rate limit. TxRateLimitSet(u64), /// setting the delegate take transaction rate limit. @@ -134,7 +134,7 @@ mod events { /// setting tempo on a network TempoSet(NetUid, u16), /// setting the RAO recycled for registration. - RAORecycledForRegistrationSet(NetUid, TaoCurrency), + RAORecycledForRegistrationSet(NetUid, TaoBalance), /// min stake is set for validators to set weights. StakeThresholdSet(u64), /// setting the adjustment alpha on a subnet. @@ -150,7 +150,7 @@ mod events { /// the start call delay is set. StartCallDelaySet(u64), /// the network minimum locking cost is set. - NetworkMinLockCostSet(TaoCurrency), + NetworkMinLockCostSet(TaoBalance), /// the maximum number of subnets is set SubnetLimitSet(u16), /// the lock cost reduction is set @@ -291,14 +291,14 @@ mod events { T::AccountId, NetUid, NetUid, - TaoCurrency, + TaoBalance, ), /// Stake has been swapped from one subnet to another for the same coldkey-hotkey pair. /// /// Parameters: /// (coldkey, hotkey, origin_netuid, destination_netuid, amount) - StakeSwapped(T::AccountId, T::AccountId, NetUid, NetUid, TaoCurrency), + StakeSwapped(T::AccountId, T::AccountId, NetUid, NetUid, TaoBalance), /// Event called when transfer is toggled on a subnet. /// @@ -322,13 +322,13 @@ mod events { /// /// Parameters: /// (coldkey, hotkey, amount, subnet_id) - AlphaRecycled(T::AccountId, T::AccountId, AlphaCurrency, NetUid), + AlphaRecycled(T::AccountId, T::AccountId, AlphaBalance, NetUid), /// Alpha have been burned without reducing AlphaOut. /// /// Parameters: /// (coldkey, hotkey, amount, subnet_id) - AlphaBurned(T::AccountId, T::AccountId, AlphaCurrency, NetUid), + AlphaBurned(T::AccountId, T::AccountId, AlphaBalance, NetUid), /// An EVM key has been associated with a hotkey. EvmKeyAssociated { @@ -429,7 +429,7 @@ mod events { /// Owner (coldkey) account associated with the hotkey. owner: T::AccountId, /// Amount of alpha auto-staked. - incentive: AlphaCurrency, + incentive: AlphaBalance, }, /// End-of-epoch miner incentive alpha by UID @@ -437,7 +437,7 @@ mod events { /// Subnet identifier. netuid: NetUidStorageIndex, /// UID-indexed array of miner incentive alpha; index equals UID. - emissions: Vec, + emissions: Vec, }, /// The minimum allowed UIDs for a subnet have been set. @@ -514,7 +514,7 @@ mod events { /// The contributor contributor: T::AccountId, /// The amount of alpha distributed - alpha: AlphaCurrency, + alpha: AlphaBalance, }, /// "Add stake and burn" event: alpha token was purchased and burned. @@ -524,9 +524,9 @@ mod events { /// hotky account ID hotkey: T::AccountId, /// Tao provided - amount: TaoCurrency, + amount: TaoBalance, /// Alpha burned - alpha: AlphaCurrency, + alpha: AlphaBalance, }, } } diff --git a/pallets/subtensor/src/macros/genesis.rs b/pallets/subtensor/src/macros/genesis.rs index f16f2f7a3a..d4e269391e 100644 --- a/pallets/subtensor/src/macros/genesis.rs +++ b/pallets/subtensor/src/macros/genesis.rs @@ -78,8 +78,8 @@ mod genesis { let hotkey = DefaultAccount::::get(); SubnetMechanism::::insert(netuid, 1); // Make dynamic. Owner::::insert(hotkey.clone(), hotkey.clone()); - SubnetAlphaIn::::insert(netuid, AlphaCurrency::from(10_000_000_000)); - SubnetTAO::::insert(netuid, TaoCurrency::from(10_000_000_000)); + SubnetAlphaIn::::insert(netuid, AlphaBalance::from(10_000_000_000_u64)); + SubnetTAO::::insert(netuid, TaoBalance::from(10_000_000_000_u64)); NetworksAdded::::insert(netuid, true); TotalNetworks::::mutate(|n| *n = n.saturating_add(1)); SubnetworkN::::insert(netuid, 0); @@ -89,7 +89,7 @@ mod genesis { Tempo::::insert(netuid, 100); NetworkRegistrationAllowed::::insert(netuid, true); SubnetOwner::::insert(netuid, hotkey.clone()); - SubnetLocked::::insert(netuid, TaoCurrency::from(1)); + SubnetLocked::::insert(netuid, TaoBalance::from(1)); LargestLocked::::insert(netuid, 1); Alpha::::insert( // Lock the initial funds making this key the owner. @@ -99,14 +99,14 @@ mod genesis { TotalHotkeyAlpha::::insert( hotkey.clone(), netuid, - AlphaCurrency::from(1_000_000_000), + AlphaBalance::from(1_000_000_000), ); TotalHotkeyShares::::insert( hotkey.clone(), netuid, U64F64::saturating_from_num(1_000_000_000), ); - SubnetAlphaOut::::insert(netuid, AlphaCurrency::from(1_000_000_000)); + SubnetAlphaOut::::insert(netuid, AlphaBalance::from(1_000_000_000)); let mut staking_hotkeys = StakingHotkeys::::get(hotkey.clone()); if !staking_hotkeys.contains(&hotkey) { staking_hotkeys.push(hotkey.clone()); diff --git a/pallets/subtensor/src/migrations/migrate_fix_root_subnet_tao.rs b/pallets/subtensor/src/migrations/migrate_fix_root_subnet_tao.rs index 60d300f29d..982e071ea3 100644 --- a/pallets/subtensor/src/migrations/migrate_fix_root_subnet_tao.rs +++ b/pallets/subtensor/src/migrations/migrate_fix_root_subnet_tao.rs @@ -19,7 +19,7 @@ pub fn migrate_fix_root_subnet_tao() -> Weight { String::from_utf8_lossy(&migration_name) ); - let mut total_stake = TaoCurrency::ZERO; + let mut total_stake = TaoBalance::ZERO; let mut hotkey_count: u64 = 0; // We accumulate the total stake for all hotkeys on the root subnet. for hotkey in Owner::::iter_keys() { diff --git a/pallets/subtensor/src/migrations/migrate_fix_root_tao_and_alpha_in.rs b/pallets/subtensor/src/migrations/migrate_fix_root_tao_and_alpha_in.rs index f20d71c302..10898f9eb2 100644 --- a/pallets/subtensor/src/migrations/migrate_fix_root_tao_and_alpha_in.rs +++ b/pallets/subtensor/src/migrations/migrate_fix_root_tao_and_alpha_in.rs @@ -25,19 +25,19 @@ pub fn migrate_fix_root_tao_and_alpha_in() -> Weight { let reserve_diff = total_unstaked.saturating_sub(total_staked); let volume_diff = (total_unstaked as u128).saturating_add(total_staked as u128); SubnetTAO::::mutate(NetUid::ROOT, |amount| { - *amount = amount.saturating_sub(TaoCurrency::from(reserve_diff)); + *amount = amount.saturating_sub(reserve_diff.into()); }); SubnetAlphaIn::::mutate(NetUid::ROOT, |amount| { - *amount = amount.saturating_add(AlphaCurrency::from(reserve_diff)); + *amount = amount.saturating_add(AlphaBalance::from(reserve_diff)); }); SubnetAlphaOut::::mutate(NetUid::ROOT, |amount| { - *amount = amount.saturating_sub(AlphaCurrency::from(reserve_diff)); + *amount = amount.saturating_sub(AlphaBalance::from(reserve_diff)); }); SubnetVolume::::mutate(NetUid::ROOT, |amount| { *amount = amount.saturating_add(volume_diff); }); TotalStake::::mutate(|amount| { - *amount = amount.saturating_sub(TaoCurrency::from(reserve_diff)); + *amount = amount.saturating_sub(reserve_diff.into()); }); weight = weight.saturating_add(T::DbWeight::get().writes(5)); diff --git a/pallets/subtensor/src/migrations/migrate_init_total_issuance.rs b/pallets/subtensor/src/migrations/migrate_init_total_issuance.rs index 6a05dc5a85..3d625aee30 100644 --- a/pallets/subtensor/src/migrations/migrate_init_total_issuance.rs +++ b/pallets/subtensor/src/migrations/migrate_init_total_issuance.rs @@ -27,7 +27,7 @@ pub(crate) fn migrate_init_total_issuance() -> Weight { // Calculate new total stake using the sum of all subnet TAO let total_subnet_tao = - crate::SubnetTAO::::iter().fold(TaoCurrency::ZERO, |acc, (_, v)| acc.saturating_add(v)); + crate::SubnetTAO::::iter().fold(TaoBalance::ZERO, |acc, (_, v)| acc.saturating_add(v)); let total_stake = total_subnet_tao; // Update the total stake in storage @@ -39,9 +39,7 @@ pub(crate) fn migrate_init_total_issuance() -> Weight { let prev_total_issuance = crate::TotalIssuance::::get(); // Calculate the new total issuance - let new_total_issuance: TaoCurrency = total_account_balances - .saturating_add(total_stake.to_u64()) - .into(); + let new_total_issuance: TaoBalance = total_account_balances.saturating_add(total_stake).into(); // Update the total issuance in storage crate::TotalIssuance::::put(new_total_issuance); diff --git a/pallets/subtensor/src/migrations/migrate_network_lock_cost_2500.rs b/pallets/subtensor/src/migrations/migrate_network_lock_cost_2500.rs index e12356f6ba..3206a27fbb 100644 --- a/pallets/subtensor/src/migrations/migrate_network_lock_cost_2500.rs +++ b/pallets/subtensor/src/migrations/migrate_network_lock_cost_2500.rs @@ -26,7 +26,7 @@ pub fn migrate_network_lock_cost_2500() -> Weight { let block_to_set = if current_block == 0 { 1 } else { current_block }; // Set last_lock so that price = 2 * last_lock = 2,500 TAO at this block - Pallet::::set_network_last_lock(TaoCurrency::from(NEW_LAST_LOCK_RAO)); + Pallet::::set_network_last_lock(NEW_LAST_LOCK_RAO.into()); weight = weight.saturating_add(T::DbWeight::get().writes(1)); // Start decay from "now" (no backdated decay) diff --git a/pallets/subtensor/src/migrations/migrate_network_lock_reduction_interval.rs b/pallets/subtensor/src/migrations/migrate_network_lock_reduction_interval.rs index 99bb5b6e97..9b67dfd583 100644 --- a/pallets/subtensor/src/migrations/migrate_network_lock_reduction_interval.rs +++ b/pallets/subtensor/src/migrations/migrate_network_lock_reduction_interval.rs @@ -30,7 +30,7 @@ pub fn migrate_network_lock_reduction_interval() -> Weight { NetworkRateLimit::::put(FOUR_DAYS); weight = weight.saturating_add(T::DbWeight::get().writes(1)); - Pallet::::set_network_last_lock(TaoCurrency::from(1_000_000_000_000)); + Pallet::::set_network_last_lock(TaoBalance::from(1_000_000_000_000_u64)); weight = weight.saturating_add(T::DbWeight::get().writes(1)); // Hold price at 2000 TAO until day 7, then begin linear decay diff --git a/pallets/subtensor/src/migrations/migrate_pending_emissions.rs b/pallets/subtensor/src/migrations/migrate_pending_emissions.rs index 416080f5b2..d93dcc6949 100644 --- a/pallets/subtensor/src/migrations/migrate_pending_emissions.rs +++ b/pallets/subtensor/src/migrations/migrate_pending_emissions.rs @@ -7,7 +7,7 @@ pub mod deprecated_pending_emission_format { #[storage_alias] pub(super) type PendingEmission = - StorageMap, Identity, NetUid, AlphaCurrency, ValueQuery>; + StorageMap, Identity, NetUid, AlphaBalance, ValueQuery>; } pub fn migrate_pending_emissions() -> Weight { @@ -39,8 +39,7 @@ pub fn migrate_pending_emissions() -> Weight { let server_emission_float: U96F32 = U96F32::saturating_from_num(pending_emission.to_u64()) .saturating_add(root_alpha) .saturating_div(U96F32::saturating_from_num(2)); - let server_emission: AlphaCurrency = - server_emission_float.saturating_to_num::().into(); + let server_emission: AlphaBalance = server_emission_float.saturating_to_num::().into(); let validator_emission = pending_emission.saturating_sub(server_emission); PendingValidatorEmission::::mutate(netuid, |total| { diff --git a/pallets/subtensor/src/migrations/migrate_rao.rs b/pallets/subtensor/src/migrations/migrate_rao.rs index 25e220b6d4..6092d41c6f 100644 --- a/pallets/subtensor/src/migrations/migrate_rao.rs +++ b/pallets/subtensor/src/migrations/migrate_rao.rs @@ -2,7 +2,7 @@ use alloc::{format, string::String}; use frame_support::IterableStorageMap; use frame_support::{traits::Get, weights::Weight}; -use subtensor_runtime_common::{AlphaCurrency, NetUid}; +use subtensor_runtime_common::{AlphaBalance, NetUid}; use super::*; @@ -59,13 +59,13 @@ pub fn migrate_rao() -> Weight { // Convert subnets and give them lock. // Set global weight to 18% from the start // Set min lock - NetworkMinLockCost::::set(TaoCurrency::from(1_000_000_000)); + NetworkMinLockCost::::set(TaoBalance::from(1_000_000_000)); // Set tao weight. TaoWeight::::set(3_320_413_933_267_719_290); for netuid in netuids.iter() { if netuid.is_root() { // Give root a single RAO in pool to avoid any catestrophic division by zero. - SubnetAlphaIn::::insert(netuid, AlphaCurrency::from(1_000_000_000)); + SubnetAlphaIn::::insert(netuid, AlphaBalance::from(1_000_000_000)); SubnetMechanism::::insert(netuid, 0); // Set to zero mechanism. TokenSymbol::::insert(netuid, Pallet::::get_symbol_for_subnet(NetUid::ROOT)); continue; @@ -92,13 +92,13 @@ pub fn migrate_rao() -> Weight { // .unwrap_or(I96F32::from_num(0.0)), // ); Pallet::::add_balance_to_coldkey_account(&owner, remaining_lock.into()); - SubnetLocked::::insert(netuid, TaoCurrency::ZERO); // Clear lock amount. + SubnetLocked::::insert(netuid, TaoBalance::ZERO); // Clear lock amount. SubnetTAO::::insert(netuid, pool_initial_tao); TotalStake::::mutate(|total| { *total = total.saturating_add(pool_initial_tao); }); // Increase total stake. - SubnetAlphaIn::::insert(netuid, AlphaCurrency::from(pool_initial_tao.to_u64())); // Set initial alpha to pool initial tao. - SubnetAlphaOut::::insert(netuid, AlphaCurrency::ZERO); // Set zero subnet alpha out. + SubnetAlphaIn::::insert(netuid, AlphaBalance::from(pool_initial_tao.to_u64())); // Set initial alpha to pool initial tao. + SubnetAlphaOut::::insert(netuid, AlphaBalance::ZERO); // Set zero subnet alpha out. SubnetMechanism::::insert(netuid, 1); // Convert to dynamic immediately with initialization. // Set the token symbol for this subnet using Self instead of Pallet:: diff --git a/pallets/subtensor/src/migrations/migrate_remove_zero_total_hotkey_alpha.rs b/pallets/subtensor/src/migrations/migrate_remove_zero_total_hotkey_alpha.rs index 94458a88b3..a9e7bd24b3 100644 --- a/pallets/subtensor/src/migrations/migrate_remove_zero_total_hotkey_alpha.rs +++ b/pallets/subtensor/src/migrations/migrate_remove_zero_total_hotkey_alpha.rs @@ -31,7 +31,7 @@ pub fn migrate_remove_zero_total_hotkey_alpha() -> Weight { // For each (hotkey, netuid, alpha) entry, remove if alpha == 0 for (hotkey, netuid, alpha) in TotalHotkeyAlpha::::iter() { - if alpha == 0.into() { + if alpha.is_zero() { TotalHotkeyAlpha::::remove(&hotkey, netuid); removed_entries_count = removed_entries_count.saturating_add(1); } diff --git a/pallets/subtensor/src/migrations/migrate_reset_max_burn.rs b/pallets/subtensor/src/migrations/migrate_reset_max_burn.rs index e52d15fb07..8016cd83ff 100644 --- a/pallets/subtensor/src/migrations/migrate_reset_max_burn.rs +++ b/pallets/subtensor/src/migrations/migrate_reset_max_burn.rs @@ -31,7 +31,7 @@ pub fn migrate_reset_max_burn() -> Weight { for netuid in MaxBurn::::iter_keys() { MaxBurn::::mutate(netuid, |max| { - *max = 100_000_000_000.into(); + *max = 100_000_000_000_u64.into(); }); reset_entries_count = reset_entries_count.saturating_add(1); } diff --git a/pallets/subtensor/src/migrations/migrate_reset_unactive_sn.rs b/pallets/subtensor/src/migrations/migrate_reset_unactive_sn.rs index e2e8ddc296..8c24cb0100 100644 --- a/pallets/subtensor/src/migrations/migrate_reset_unactive_sn.rs +++ b/pallets/subtensor/src/migrations/migrate_reset_unactive_sn.rs @@ -1,7 +1,7 @@ use super::*; pub fn get_unactive_sn_netuids( - pool_initial_alpha: AlphaCurrency, + pool_initial_alpha: AlphaBalance, ) -> (Vec, Weight) { // Loop over all subnets, if the AlphaIssuance is > pool_initial_alpha // but FirstEmissionBlockNumber is None @@ -42,8 +42,8 @@ pub fn migrate_reset_unactive_sn() -> Weight { ); // From init_new_network - let pool_initial_tao: TaoCurrency = Pallet::::get_network_min_lock(); - let pool_initial_alpha: AlphaCurrency = pool_initial_tao.to_u64().into(); + let pool_initial_tao: TaoBalance = Pallet::::get_network_min_lock(); + let pool_initial_alpha: AlphaBalance = pool_initial_tao.to_u64().into(); let (unactive_netuids, w) = get_unactive_sn_netuids::(pool_initial_alpha); weight = weight.saturating_add(w); diff --git a/pallets/subtensor/src/migrations/migrate_subnet_locked.rs b/pallets/subtensor/src/migrations/migrate_subnet_locked.rs index a430993f9d..69850e7daf 100644 --- a/pallets/subtensor/src/migrations/migrate_subnet_locked.rs +++ b/pallets/subtensor/src/migrations/migrate_subnet_locked.rs @@ -1,5 +1,5 @@ use super::*; -use crate::{Config, HasMigrationRun, SubnetLocked, TaoCurrency}; +use crate::{Config, HasMigrationRun, SubnetLocked, TaoBalance}; use frame_support::weights::Weight; use log; use scale_info::prelude::string::String; @@ -93,7 +93,7 @@ pub fn migrate_restore_subnet_locked() -> Weight { // ── 1) Re-insert the historical values ──────────────────────────────── for &(netuid_u16, amount_rao_u64) in SUBNET_LOCKED.iter() { let key: NetUid = NetUid::from(netuid_u16); - let amount: TaoCurrency = TaoCurrency::from(amount_rao_u64); + let amount: TaoBalance = amount_rao_u64.into(); SubnetLocked::::insert(key, amount); diff --git a/pallets/subtensor/src/migrations/migrate_total_issuance.rs b/pallets/subtensor/src/migrations/migrate_total_issuance.rs index e87337b74e..53dee0d622 100644 --- a/pallets/subtensor/src/migrations/migrate_total_issuance.rs +++ b/pallets/subtensor/src/migrations/migrate_total_issuance.rs @@ -45,7 +45,7 @@ pub fn migrate_total_issuance(test: bool) -> Weight { // Calculate the sum of all stake values let stake_sum = Owner::::iter() .map(|(hotkey, _coldkey)| Pallet::::get_total_stake_for_hotkey(&hotkey)) - .fold(TaoCurrency::ZERO, |acc, stake| acc.saturating_add(stake)); + .fold(TaoBalance::ZERO, |acc, stake| acc.saturating_add(stake)); // Add weight for reading all Owner and TotalHotkeyStake entries weight = weight.saturating_add( T::DbWeight::get().reads((Owner::::iter().count() as u64).saturating_mul(2)), diff --git a/pallets/subtensor/src/rpc_info/delegate_info.rs b/pallets/subtensor/src/rpc_info/delegate_info.rs index bf6dafd332..61c0286e7a 100644 --- a/pallets/subtensor/src/rpc_info/delegate_info.rs +++ b/pallets/subtensor/src/rpc_info/delegate_info.rs @@ -6,7 +6,7 @@ use substrate_fixed::types::U64F64; extern crate alloc; use alloc::collections::BTreeMap; use codec::Compact; -use subtensor_runtime_common::{AlphaCurrency, NetUid}; +use subtensor_runtime_common::{AlphaBalance, NetUid}; #[freeze_struct("1fafc4fcf28cba7a")] #[derive(Decode, Encode, PartialEq, Eq, Clone, Debug, TypeInfo)] @@ -158,11 +158,11 @@ impl Pallet { delegatee: T::AccountId, ) -> Vec<( DelegateInfo, - (Compact, Compact), + (Compact, Compact), )> { let mut delegates: Vec<( DelegateInfo, - (Compact, Compact), + (Compact, Compact), )> = Vec::new(); for delegate in as IterableStorageMap>::iter_keys() { // Staked to this delegate, so add to list diff --git a/pallets/subtensor/src/rpc_info/dynamic_info.rs b/pallets/subtensor/src/rpc_info/dynamic_info.rs index d4f99176ac..b143295425 100644 --- a/pallets/subtensor/src/rpc_info/dynamic_info.rs +++ b/pallets/subtensor/src/rpc_info/dynamic_info.rs @@ -4,9 +4,9 @@ use codec::Compact; use frame_support::pallet_prelude::{Decode, Encode}; use substrate_fixed::types::I96F32; use subtensor_macros::freeze_struct; -use subtensor_runtime_common::{AlphaCurrency, NetUid, TaoCurrency}; +use subtensor_runtime_common::{AlphaBalance, NetUid, TaoBalance}; -#[freeze_struct("e526a1c6d2303d32")] +#[freeze_struct("cf677afa654c96a6")] #[derive(Decode, Encode, PartialEq, Eq, Clone, Debug, TypeInfo)] pub struct DynamicInfo { netuid: Compact, @@ -18,14 +18,14 @@ pub struct DynamicInfo { last_step: Compact, blocks_since_last_step: Compact, emission: Compact, - alpha_in: Compact, - alpha_out: Compact, - tao_in: Compact, - alpha_out_emission: Compact, - alpha_in_emission: Compact, - tao_in_emission: Compact, - pending_alpha_emission: Compact, - pending_root_emission: Compact, + alpha_in: Compact, + alpha_out: Compact, + tao_in: Compact, + alpha_out_emission: Compact, + alpha_in_emission: Compact, + tao_in_emission: Compact, + pending_alpha_emission: Compact, + pending_root_emission: Compact, subnet_volume: Compact, network_registered_at: Compact, subnet_identity: Option, @@ -65,7 +65,7 @@ impl Pallet { pending_alpha_emission: PendingValidatorEmission::::get(netuid) .saturating_add(PendingServerEmission::::get(netuid)) .into(), - pending_root_emission: TaoCurrency::from(0u64).into(), + pending_root_emission: TaoBalance::ZERO.into(), subnet_volume: SubnetVolume::::get(netuid).into(), network_registered_at: NetworkRegisteredAt::::get(netuid).into(), subnet_identity: SubnetIdentitiesV3::::get(netuid), diff --git a/pallets/subtensor/src/rpc_info/metagraph.rs b/pallets/subtensor/src/rpc_info/metagraph.rs index ea24657aeb..4d82af629a 100644 --- a/pallets/subtensor/src/rpc_info/metagraph.rs +++ b/pallets/subtensor/src/rpc_info/metagraph.rs @@ -8,9 +8,9 @@ use pallet_commitments::GetCommitments; use substrate_fixed::types::I64F64; use substrate_fixed::types::I96F32; use subtensor_macros::freeze_struct; -use subtensor_runtime_common::{AlphaCurrency, MechId, NetUid, NetUidStorageIndex, TaoCurrency}; +use subtensor_runtime_common::{AlphaBalance, MechId, NetUid, NetUidStorageIndex, TaoBalance}; -#[freeze_struct("6fc49d5a7dc0e339")] +#[freeze_struct("fbab6d1e7f3c69ae")] #[derive(Decode, Encode, PartialEq, Eq, Clone, Debug, TypeInfo)] pub struct Metagraph { // Subnet index @@ -33,17 +33,17 @@ pub struct Metagraph { blocks_since_last_step: Compact, // blocks since last epoch. // Subnet emission terms - subnet_emission: Compact, // subnet emission via stao - alpha_in: Compact, // amount of alpha in reserve - alpha_out: Compact, // amount of alpha outstanding - tao_in: Compact, // amount of tao injected per block - alpha_out_emission: Compact, // amount injected in alpha reserves per block - alpha_in_emission: Compact, // amount injected outstanding per block - tao_in_emission: Compact, // amount of tao injected per block - pending_alpha_emission: Compact, // pending alpha to be distributed - pending_root_emission: Compact, // pending tao for root divs to be distributed - subnet_volume: Compact, // volume of the subnet in TAO - moving_price: I96F32, // subnet moving price. + subnet_emission: Compact, // subnet emission via stao + alpha_in: Compact, // amount of alpha in reserve + alpha_out: Compact, // amount of alpha outstanding + tao_in: Compact, // amount of tao injected per block + alpha_out_emission: Compact, // amount injected in alpha reserves per block + alpha_in_emission: Compact, // amount injected outstanding per block + tao_in_emission: Compact, // amount of tao injected per block + pending_alpha_emission: Compact, // pending alpha to be distributed + pending_root_emission: Compact, // pending tao for root divs to be distributed + subnet_volume: Compact, // volume of the subnet in TAO + moving_price: I96F32, // subnet moving price. // Hparams for epoch rho: Compact, // subnet rho param @@ -60,15 +60,15 @@ pub struct Metagraph { // Registration num_uids: Compact, max_uids: Compact, - burn: Compact, // current burn cost + burn: Compact, // current burn cost difficulty: Compact, // current difficulty registration_allowed: bool, // allows registrations pow_registration_allowed: bool, // pow registration enabled immunity_period: Compact, // subnet miner immunity period min_difficulty: Compact, // min pow difficulty max_difficulty: Compact, // max pow difficulty - min_burn: Compact, // min tao burn - max_burn: Compact, // max tao burn + min_burn: Compact, // min tao burn + max_burn: Compact, // max tao burn adjustment_alpha: Compact, // adjustment speed for registration params adjustment_interval: Compact, // pow and burn adjustment interval target_regs_per_interval: Compact, // target registrations per interval @@ -94,23 +94,23 @@ pub struct Metagraph { validator_permit: Vec, // Val permit per UID pruning_score: Vec>, // Pruning per UID last_update: Vec>, // Last update per UID - emission: Vec>, // Emission per UID + emission: Vec>, // Emission per UID dividends: Vec>, // Dividends per UID incentives: Vec>, // Mining incentives per UID consensus: Vec>, // Consensus per UID trust: Vec>, // Trust per UID rank: Vec>, // Rank per UID block_at_registration: Vec>, // Reg block per UID - alpha_stake: Vec>, // Alpha staked per UID - tao_stake: Vec>, // TAO staked per UID - total_stake: Vec>, // Total stake per UID + alpha_stake: Vec>, // Alpha staked per UID + tao_stake: Vec>, // TAO staked per UID + total_stake: Vec>, // Total stake per UID // Dividend break down. - tao_dividends_per_hotkey: Vec<(AccountId, Compact)>, // List of dividend payouts in tao via root. - alpha_dividends_per_hotkey: Vec<(AccountId, Compact)>, // List of dividend payout in alpha via subnet. + tao_dividends_per_hotkey: Vec<(AccountId, Compact)>, // List of dividend payouts in tao via root. + alpha_dividends_per_hotkey: Vec<(AccountId, Compact)>, // List of dividend payout in alpha via subnet. } -#[freeze_struct("56156d51c66190e8")] +#[freeze_struct("3ff2befdb7b393ea")] #[derive(Decode, Encode, PartialEq, Eq, Clone, Debug, TypeInfo)] pub struct SelectiveMetagraph { // Subnet index @@ -134,16 +134,16 @@ pub struct SelectiveMetagraph { // Subnet emission terms subnet_emission: Option>, // subnet emission via stao - alpha_in: Option>, // amount of alpha in reserve - alpha_out: Option>, // amount of alpha outstanding - tao_in: Option>, // amount of tao injected per block - alpha_out_emission: Option>, // amount injected in alpha reserves per block - alpha_in_emission: Option>, // amount injected outstanding per block - tao_in_emission: Option>, // amount of tao injected per block - pending_alpha_emission: Option>, // pending alpha to be distributed - pending_root_emission: Option>, // panding tao for root divs to be distributed - subnet_volume: Option>, // volume of the subnet in TAO - moving_price: Option, // subnet moving price. + alpha_in: Option>, // amount of alpha in reserve + alpha_out: Option>, // amount of alpha outstanding + tao_in: Option>, // amount of tao injected per block + alpha_out_emission: Option>, // amount injected in alpha reserves per block + alpha_in_emission: Option>, // amount injected outstanding per block + tao_in_emission: Option>, // amount of tao injected per block + pending_alpha_emission: Option>, // pending alpha to be distributed + pending_root_emission: Option>, // panding tao for root divs to be distributed + subnet_volume: Option>, // volume of the subnet in TAO + moving_price: Option, // subnet moving price. // Hparams for epoch rho: Option>, // subnet rho param @@ -160,15 +160,15 @@ pub struct SelectiveMetagraph { // Registration num_uids: Option>, max_uids: Option>, - burn: Option>, // current burn cost + burn: Option>, // current burn cost difficulty: Option>, // current difficulty registration_allowed: Option, // allows registrations pow_registration_allowed: Option, // pow registration enabled immunity_period: Option>, // subnet miner immunity period min_difficulty: Option>, // min pow difficulty max_difficulty: Option>, // max pow difficulty - min_burn: Option>, // min tao burn - max_burn: Option>, // max tao burn + min_burn: Option>, // min tao burn + max_burn: Option>, // max tao burn adjustment_alpha: Option>, // adjustment speed for registration params adjustment_interval: Option>, // pow and burn adjustment interval target_regs_per_interval: Option>, // target registrations per interval @@ -194,20 +194,20 @@ pub struct SelectiveMetagraph { validator_permit: Option>, // Val permit per UID pruning_score: Option>>, // Pruning per UID last_update: Option>>, // Last update per UID - emission: Option>>, // Emission per UID + emission: Option>>, // Emission per UID dividends: Option>>, // Dividends per UID incentives: Option>>, // Mining incentives per UID consensus: Option>>, // Consensus per UID trust: Option>>, // Trust per UID rank: Option>>, // Rank per UID block_at_registration: Option>>, // Reg block per UID - alpha_stake: Option>>, // Alpha staked per UID - tao_stake: Option>>, // TAO staked per UID - total_stake: Option>>, // Total stake per UID + alpha_stake: Option>>, // Alpha staked per UID + tao_stake: Option>>, // TAO staked per UID + total_stake: Option>>, // Total stake per UID // Dividend break down. - tao_dividends_per_hotkey: Option)>>, // List of dividend payouts in tao via root - alpha_dividends_per_hotkey: Option)>>, // List of dividend payout in alpha via subnet + tao_dividends_per_hotkey: Option)>>, // List of dividend payouts in tao via root + alpha_dividends_per_hotkey: Option)>>, // List of dividend payout in alpha via subnet // validators validators: Option>>, // List of validators @@ -641,11 +641,11 @@ impl Pallet { identities.push(IdentitiesV2::::get(coldkey.clone())); axons.push(Self::get_axon_info(netuid, &hotkey)); } - let mut tao_dividends_per_hotkey: Vec<(T::AccountId, Compact)> = vec![]; - let mut alpha_dividends_per_hotkey: Vec<(T::AccountId, Compact)> = vec![]; + let mut tao_dividends_per_hotkey: Vec<(T::AccountId, Compact)> = vec![]; + let mut alpha_dividends_per_hotkey: Vec<(T::AccountId, Compact)> = vec![]; for hotkey in hotkeys.clone() { // Tao dividends were removed - let tao_divs = TaoCurrency::ZERO; + let tao_divs = TaoBalance::ZERO; let alpha_divs = AlphaDividendsPerSubnet::::get(netuid, hotkey.clone()); tao_dividends_per_hotkey.push((hotkey.clone(), tao_divs.into())); alpha_dividends_per_hotkey.push((hotkey.clone(), alpha_divs.into())); @@ -697,7 +697,7 @@ impl Pallet { pending_alpha_emission: PendingValidatorEmission::::get(netuid) .saturating_add(PendingServerEmission::::get(netuid)) .into(), // pending alpha to be distributed - pending_root_emission: TaoCurrency::from(0u64).into(), // panding tao for root divs to be distributed + pending_root_emission: TaoBalance::ZERO.into(), // panding tao for root divs to be distributed subnet_volume: subnet_volume.into(), moving_price: SubnetMovingPrice::::get(netuid), @@ -783,16 +783,16 @@ impl Pallet { block_at_registration, // Reg block per UID alpha_stake: alpha_stake_fl .iter() - .map(|xi| Compact::from(AlphaCurrency::from(fixed64_to_u64(*xi)))) - .collect::>>(), // Alpha staked per UID + .map(|xi| Compact::from(AlphaBalance::from(fixed64_to_u64(*xi)))) + .collect::>>(), // Alpha staked per UID tao_stake: tao_stake_fl .iter() - .map(|xi| Compact::from(TaoCurrency::from(fixed64_to_u64(*xi)))) - .collect::>>(), // TAO staked per UID + .map(|xi| Compact::from(TaoBalance::from(fixed64_to_u64(*xi)))) + .collect::>>(), // TAO staked per UID total_stake: total_stake_fl .iter() - .map(|xi| Compact::from(TaoCurrency::from(fixed64_to_u64(*xi)))) - .collect::>>(), // Total stake per UID + .map(|xi| Compact::from(TaoBalance::from(fixed64_to_u64(*xi)))) + .collect::>>(), // Total stake per UID // Dividend break down. tao_dividends_per_hotkey, @@ -1011,7 +1011,7 @@ impl Pallet { }, Some(SelectiveMetagraphIndex::PendingRootEmission) => SelectiveMetagraph { netuid: netuid.into(), - pending_root_emission: Some(TaoCurrency::from(0u64).into()), + pending_root_emission: Some(TaoBalance::from(0u64).into()), ..Default::default() }, Some(SelectiveMetagraphIndex::SubnetVolume) => SelectiveMetagraph { @@ -1366,8 +1366,8 @@ impl Pallet { alpha_stake: Some( alpha_stake_fl .iter() - .map(|xi| Compact::from(AlphaCurrency::from(fixed64_to_u64(*xi)))) - .collect::>>(), + .map(|xi| Compact::from(AlphaBalance::from(fixed64_to_u64(*xi)))) + .collect::>>(), ), ..Default::default() } @@ -1380,8 +1380,8 @@ impl Pallet { tao_stake: Some( tao_stake_fl .iter() - .map(|xi| Compact::from(TaoCurrency::from(fixed64_to_u64(*xi)))) - .collect::>>(), + .map(|xi| Compact::from(TaoBalance::from(fixed64_to_u64(*xi)))) + .collect::>>(), ), ..Default::default() } @@ -1394,8 +1394,8 @@ impl Pallet { total_stake: Some( total_stake_fl .iter() - .map(|xi| Compact::from(TaoCurrency::from(fixed64_to_u64(*xi)))) - .collect::>>(), + .map(|xi| Compact::from(TaoBalance::from(fixed64_to_u64(*xi)))) + .collect::>>(), ), ..Default::default() } @@ -1409,11 +1409,10 @@ impl Pallet { let hotkey = Keys::::get(netuid, uid); hotkeys.push(hotkey.clone()); } - let mut tao_dividends_per_hotkey: Vec<(T::AccountId, Compact)> = - vec![]; + let mut tao_dividends_per_hotkey: Vec<(T::AccountId, Compact)> = vec![]; for hotkey in hotkeys.clone() { // Tao dividends were removed - let tao_divs = TaoCurrency::ZERO; + let tao_divs = TaoBalance::ZERO; tao_dividends_per_hotkey.push((hotkey.clone(), tao_divs.into())); } SelectiveMetagraph { @@ -1423,7 +1422,7 @@ impl Pallet { } } Some(SelectiveMetagraphIndex::AlphaDividendsPerHotkey) => { - let mut alpha_dividends_per_hotkey: Vec<(T::AccountId, Compact)> = + let mut alpha_dividends_per_hotkey: Vec<(T::AccountId, Compact)> = vec![]; let n: u16 = Self::get_subnetwork_n(netuid); let mut hotkeys: Vec = vec![]; diff --git a/pallets/subtensor/src/rpc_info/neuron_info.rs b/pallets/subtensor/src/rpc_info/neuron_info.rs index 6e29a51ef5..fc5d7cccde 100644 --- a/pallets/subtensor/src/rpc_info/neuron_info.rs +++ b/pallets/subtensor/src/rpc_info/neuron_info.rs @@ -2,9 +2,9 @@ use super::*; use frame_support::pallet_prelude::{Decode, Encode}; extern crate alloc; use codec::Compact; -use subtensor_runtime_common::{AlphaCurrency, NetUid, NetUidStorageIndex}; +use subtensor_runtime_common::{AlphaBalance, NetUid, NetUidStorageIndex}; -#[freeze_struct("9e5a291e7e71482d")] +#[freeze_struct("3879d37d31f5c442")] #[derive(Decode, Encode, PartialEq, Eq, Clone, Debug, TypeInfo)] pub struct NeuronInfo { hotkey: AccountId, @@ -14,9 +14,9 @@ pub struct NeuronInfo { active: bool, axon_info: AxonInfo, prometheus_info: PrometheusInfo, - stake: Vec<(AccountId, Compact)>, // map of coldkey to stake on this neuron/hotkey (includes delegations) + stake: Vec<(AccountId, Compact)>, // map of coldkey to stake on this neuron/hotkey (includes delegations) rank: Compact, - emission: Compact, + emission: Compact, incentive: Compact, consensus: Compact, trust: Compact, @@ -29,7 +29,7 @@ pub struct NeuronInfo { pruning_score: Compact, } -#[freeze_struct("b9fdff7fc6e023c7")] +#[freeze_struct("4c03ff614b2b938f")] #[derive(Decode, Encode, PartialEq, Eq, Clone, Debug, TypeInfo)] pub struct NeuronInfoLite { hotkey: AccountId, @@ -39,9 +39,9 @@ pub struct NeuronInfoLite { active: bool, axon_info: AxonInfo, prometheus_info: PrometheusInfo, - stake: Vec<(AccountId, Compact)>, // map of coldkey to stake on this neuron/hotkey (includes delegations) + stake: Vec<(AccountId, Compact)>, // map of coldkey to stake on this neuron/hotkey (includes delegations) rank: Compact, - emission: Compact, + emission: Compact, incentive: Compact, consensus: Compact, trust: Compact, @@ -117,7 +117,7 @@ impl Pallet { } }) .collect::, Compact)>>(); - let stake: Vec<(T::AccountId, Compact)> = vec![( + let stake: Vec<(T::AccountId, Compact)> = vec![( coldkey.clone(), Self::get_stake_for_hotkey_on_subnet(&hotkey, netuid).into(), )]; @@ -182,7 +182,7 @@ impl Pallet { let last_update = Self::get_last_update_for_uid(NetUidStorageIndex::from(netuid), uid); let validator_permit = Self::get_validator_permit_for_uid(netuid, uid); - let stake: Vec<(T::AccountId, Compact)> = vec![( + let stake: Vec<(T::AccountId, Compact)> = vec![( coldkey.clone(), Self::get_stake_for_hotkey_on_subnet(&hotkey, netuid).into(), )]; diff --git a/pallets/subtensor/src/rpc_info/show_subnet.rs b/pallets/subtensor/src/rpc_info/show_subnet.rs index abd9670bb8..bdc2a8cdd9 100644 --- a/pallets/subtensor/src/rpc_info/show_subnet.rs +++ b/pallets/subtensor/src/rpc_info/show_subnet.rs @@ -4,9 +4,9 @@ use crate::epoch::math::*; use codec::Compact; use frame_support::pallet_prelude::{Decode, Encode}; use substrate_fixed::types::I64F64; -use subtensor_runtime_common::{AlphaCurrency, NetUid, NetUidStorageIndex, TaoCurrency}; +use subtensor_runtime_common::{AlphaBalance, NetUid, NetUidStorageIndex, TaoBalance}; -#[freeze_struct("9354762261420485")] +#[freeze_struct("5214275026dc3f36")] #[derive(Decode, Encode, PartialEq, Eq, Clone, Debug, TypeInfo)] pub struct SubnetState { netuid: Compact, @@ -16,17 +16,17 @@ pub struct SubnetState { validator_permit: Vec, pruning_score: Vec>, last_update: Vec>, - emission: Vec>, + emission: Vec>, dividends: Vec>, incentives: Vec>, consensus: Vec>, trust: Vec>, rank: Vec>, block_at_registration: Vec>, - alpha_stake: Vec>, - tao_stake: Vec>, - total_stake: Vec>, - emission_history: Vec>>, + alpha_stake: Vec>, + tao_stake: Vec>, + total_stake: Vec>, + emission_history: Vec>>, // identities: Vec, // tao_stake: Compact, // incentive: Compact, @@ -51,12 +51,12 @@ impl Pallet { /// # Returns /// /// * `Vec>>` - A vector of vectors containing the emission history for each hotkey across all subnets. - pub fn get_emissions_history(hotkeys: Vec) -> Vec>> { - let mut result: Vec>> = vec![]; + pub fn get_emissions_history(hotkeys: Vec) -> Vec>> { + let mut result: Vec>> = vec![]; for netuid in Self::get_all_subnet_netuids() { - let mut hotkeys_emissions: Vec> = vec![]; + let mut hotkeys_emissions: Vec> = vec![]; for hotkey in hotkeys.clone() { - let last_emission: Compact = + let last_emission: Compact = LastHotkeyEmissionOnNetuid::::get(hotkey.clone(), netuid).into(); hotkeys_emissions.push(last_emission); } @@ -136,17 +136,17 @@ impl Pallet { Vec, Vec, ) = Self::get_stake_weights_for_network(netuid); - let alpha_stake: Vec> = alpha_stake_fl + let alpha_stake: Vec> = alpha_stake_fl .iter() - .map(|xi| Compact::from(AlphaCurrency::from(fixed64_to_u64(*xi)))) + .map(|xi| Compact::from(AlphaBalance::from(fixed64_to_u64(*xi)))) .collect(); - let tao_stake: Vec> = tao_stake_fl + let tao_stake: Vec> = tao_stake_fl .iter() - .map(|xi| Compact::from(TaoCurrency::from(fixed64_to_u64(*xi)))) + .map(|xi| Compact::from(TaoBalance::from(fixed64_to_u64(*xi)))) .collect(); - let total_stake: Vec> = total_stake_fl + let total_stake: Vec> = total_stake_fl .iter() - .map(|xi| Compact::from(TaoCurrency::from(fixed64_to_u64(*xi)))) + .map(|xi| Compact::from(TaoBalance::from(fixed64_to_u64(*xi)))) .collect(); let emission_history = Self::get_emissions_history(hotkeys.clone()); Some(SubnetState { diff --git a/pallets/subtensor/src/rpc_info/stake_info.rs b/pallets/subtensor/src/rpc_info/stake_info.rs index 83c0cfed8b..545edf6db6 100644 --- a/pallets/subtensor/src/rpc_info/stake_info.rs +++ b/pallets/subtensor/src/rpc_info/stake_info.rs @@ -2,21 +2,21 @@ extern crate alloc; use codec::Compact; use frame_support::pallet_prelude::{Decode, Encode}; -use subtensor_runtime_common::{AlphaCurrency, Currency, NetUid, TaoCurrency}; +use subtensor_runtime_common::{AlphaBalance, NetUid, TaoBalance, Token}; use subtensor_swap_interface::SwapHandler; use super::*; -#[freeze_struct("28269be895d7b5ba")] +#[freeze_struct("8cef3fae262a623e")] #[derive(Decode, Encode, PartialEq, Eq, Clone, Debug, TypeInfo)] pub struct StakeInfo { hotkey: AccountId, coldkey: AccountId, netuid: Compact, - stake: Compact, + stake: Compact, locked: Compact, - emission: Compact, - tao_emission: Compact, + emission: Compact, + tao_emission: Compact, drain: Compact, is_registered: bool, } @@ -44,7 +44,7 @@ impl Pallet { } let emission = AlphaDividendsPerSubnet::::get(*netuid_i, &hotkey_i); // Tao dividends were removed - let tao_emission = TaoCurrency::ZERO; + let tao_emission = TaoBalance::ZERO; let is_registered: bool = Self::is_hotkey_registered_on_network(*netuid_i, hotkey_i); stake_info_for_coldkey.push(StakeInfo { @@ -103,7 +103,7 @@ impl Pallet { ); let emission = AlphaDividendsPerSubnet::::get(netuid, &hotkey_account); // Tao dividends were removed - let tao_emission = TaoCurrency::ZERO; + let tao_emission = TaoBalance::ZERO; let is_registered: bool = Self::is_hotkey_registered_on_network(netuid, &hotkey_account); Some(StakeInfo { @@ -130,7 +130,7 @@ impl Pallet { 0_u64 } else { let netuid = destination.or(origin).map(|v| v.1).unwrap_or_default(); - T::SwapInterface::approx_fee_amount(netuid.into(), TaoCurrency::from(amount)).to_u64() + T::SwapInterface::approx_fee_amount(netuid.into(), TaoBalance::from(amount)).to_u64() } } } diff --git a/pallets/subtensor/src/rpc_info/subnet_info.rs b/pallets/subtensor/src/rpc_info/subnet_info.rs index 6a7966b4fb..db595eb98e 100644 --- a/pallets/subtensor/src/rpc_info/subnet_info.rs +++ b/pallets/subtensor/src/rpc_info/subnet_info.rs @@ -4,9 +4,9 @@ use frame_support::storage::IterableStorageMap; extern crate alloc; use codec::Compact; use substrate_fixed::types::I32F32; -use subtensor_runtime_common::{NetUid, TaoCurrency}; +use subtensor_runtime_common::{NetUid, TaoBalance}; -#[freeze_struct("edd6bd3273dfea76")] +#[freeze_struct("f691073111c39620")] #[derive(Decode, Encode, PartialEq, Eq, Clone, Debug, TypeInfo)] pub struct SubnetInfo { netuid: Compact, @@ -25,11 +25,11 @@ pub struct SubnetInfo { network_modality: Compact, network_connect: Vec<[u16; 2]>, emission_values: Compact, - burn: Compact, + burn: Compact, owner: AccountId, } -#[freeze_struct("e5f66b14b33331c3")] +#[freeze_struct("e8e028bf4fbc6741")] #[derive(Decode, Encode, PartialEq, Eq, Clone, Debug, TypeInfo)] pub struct SubnetInfov2 { netuid: Compact, @@ -48,12 +48,12 @@ pub struct SubnetInfov2 { network_modality: Compact, network_connect: Vec<[u16; 2]>, emission_value: Compact, - burn: Compact, + burn: Compact, owner: AccountId, identity: Option, } -#[freeze_struct("24f0815487879ed3")] +#[freeze_struct("fd2db338b156d251")] #[derive(Decode, Encode, PartialEq, Eq, Clone, Debug, TypeInfo)] pub struct SubnetHyperparams { rho: Compact, @@ -70,8 +70,8 @@ pub struct SubnetHyperparams { activity_cutoff: Compact, pub registration_allowed: bool, target_regs_per_interval: Compact, - min_burn: Compact, - max_burn: Compact, + min_burn: Compact, + max_burn: Compact, bonds_moving_avg: Compact, max_regs_per_block: Compact, serving_rate_limit: Compact, @@ -85,7 +85,7 @@ pub struct SubnetHyperparams { liquid_alpha_enabled: bool, } -#[freeze_struct("2153c3f3bb01ef66")] +#[freeze_struct("bb4666554020e789")] #[derive(Decode, Encode, PartialEq, Eq, Clone, Debug, TypeInfo)] pub struct SubnetHyperparamsV2 { rho: Compact, @@ -102,8 +102,8 @@ pub struct SubnetHyperparamsV2 { activity_cutoff: Compact, pub registration_allowed: bool, target_regs_per_interval: Compact, - min_burn: Compact, - max_burn: Compact, + min_burn: Compact, + max_burn: Compact, bonds_moving_avg: Compact, max_regs_per_block: Compact, serving_rate_limit: Compact, diff --git a/pallets/subtensor/src/staking/add_stake.rs b/pallets/subtensor/src/staking/add_stake.rs index b0c71a3a48..17dd9e2eb9 100644 --- a/pallets/subtensor/src/staking/add_stake.rs +++ b/pallets/subtensor/src/staking/add_stake.rs @@ -1,5 +1,5 @@ use substrate_fixed::types::I96F32; -use subtensor_runtime_common::{NetUid, TaoCurrency}; +use subtensor_runtime_common::{NetUid, TaoBalance}; use subtensor_swap_interface::{Order, SwapHandler}; use super::*; @@ -41,8 +41,8 @@ impl Pallet { origin: T::RuntimeOrigin, hotkey: T::AccountId, netuid: NetUid, - stake_to_be_added: TaoCurrency, - ) -> Result { + stake_to_be_added: TaoBalance, + ) -> 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!( @@ -124,10 +124,10 @@ impl Pallet { origin: T::RuntimeOrigin, hotkey: T::AccountId, netuid: NetUid, - stake_to_be_added: TaoCurrency, - limit_price: TaoCurrency, + stake_to_be_added: TaoBalance, + limit_price: TaoBalance, allow_partial: bool, - ) -> Result { + ) -> 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!( @@ -135,7 +135,7 @@ impl Pallet { ); // 2. Calculate the maximum amount that can be executed with price limit - let max_amount: TaoCurrency = Self::get_max_amount_add(netuid, limit_price)?.into(); + let max_amount: TaoBalance = Self::get_max_amount_add(netuid, limit_price)?.into(); let mut possible_stake = stake_to_be_added; if possible_stake > max_amount { possible_stake = max_amount; @@ -176,7 +176,7 @@ impl Pallet { // Returns the maximum amount of RAO that can be executed with price limit pub fn get_max_amount_add( netuid: NetUid, - limit_price: TaoCurrency, + limit_price: TaoBalance, ) -> Result { // Corner case: root and stao // There's no slippage for root or stable subnets, so if limit price is 1e9 rao or diff --git a/pallets/subtensor/src/staking/claim_root.rs b/pallets/subtensor/src/staking/claim_root.rs index 24a26d154c..58babb79a6 100644 --- a/pallets/subtensor/src/staking/claim_root.rs +++ b/pallets/subtensor/src/staking/claim_root.rs @@ -40,7 +40,7 @@ impl Pallet { pub fn increase_root_claimable_for_hotkey_and_subnet( hotkey: &T::AccountId, netuid: NetUid, - amount: AlphaCurrency, + amount: AlphaBalance, ) { // Get total stake on this hotkey on root. let total: I96F32 = @@ -168,7 +168,7 @@ impl Pallet { let owed_tao = match Self::swap_alpha_for_tao( netuid, owed_u64.into(), - T::SwapInterface::min_price::(), + T::SwapInterface::min_price::(), true, ) { Ok(owed_tao) => owed_tao, @@ -271,7 +271,7 @@ impl Pallet { pub fn remove_stake_adjust_root_claimed_for_hotkey_and_coldkey( hotkey: &T::AccountId, coldkey: &T::AccountId, - amount: AlphaCurrency, + amount: AlphaBalance, ) { // Iterate over all the subnets this hotkey is staked on for root. let root_claimable = RootClaimable::::get(hotkey); diff --git a/pallets/subtensor/src/staking/helpers.rs b/pallets/subtensor/src/staking/helpers.rs index 099f8e26b6..bfe34b2ab0 100644 --- a/pallets/subtensor/src/staking/helpers.rs +++ b/pallets/subtensor/src/staking/helpers.rs @@ -7,7 +7,7 @@ use frame_support::traits::{ }; use safe_math::*; use substrate_fixed::types::U96F32; -use subtensor_runtime_common::{NetUid, TaoCurrency}; +use subtensor_runtime_common::{NetUid, TaoBalance}; use subtensor_swap_interface::{Order, SwapHandler}; use super::*; @@ -27,24 +27,24 @@ impl Pallet { // Returns the total amount of stake in the staking table. // - pub fn get_total_stake() -> TaoCurrency { + pub fn get_total_stake() -> TaoBalance { TotalStake::::get() } // Increases the total amount of stake by the passed amount. // - pub fn increase_total_stake(increment: TaoCurrency) { + pub fn increase_total_stake(increment: TaoBalance) { TotalStake::::put(Self::get_total_stake().saturating_add(increment)); } // Decreases the total amount of stake by the passed amount. // - pub fn decrease_total_stake(decrement: TaoCurrency) { + pub fn decrease_total_stake(decrement: TaoBalance) { TotalStake::::put(Self::get_total_stake().saturating_sub(decrement)); } /// Returns the total amount of stake (in TAO) under a hotkey (delegative or otherwise) - pub fn get_total_stake_for_hotkey(hotkey: &T::AccountId) -> TaoCurrency { + pub fn get_total_stake_for_hotkey(hotkey: &T::AccountId) -> TaoBalance { Self::get_all_subnet_netuids() .into_iter() .map(|netuid| { @@ -63,7 +63,7 @@ impl Pallet { // Returns the total amount of stake under a coldkey // - pub fn get_total_stake_for_coldkey(coldkey: &T::AccountId) -> TaoCurrency { + pub fn get_total_stake_for_coldkey(coldkey: &T::AccountId) -> TaoBalance { let hotkeys = StakingHotkeys::::get(coldkey); hotkeys .iter() @@ -96,7 +96,7 @@ impl Pallet { pub fn get_total_stake_for_coldkey_on_subnet( coldkey: &T::AccountId, netuid: NetUid, - ) -> TaoCurrency { + ) -> TaoBalance { let hotkeys = StakingHotkeys::::get(coldkey); hotkeys .iter() @@ -305,9 +305,9 @@ impl Pallet { pub fn remove_balance_from_coldkey_account( coldkey: &T::AccountId, amount: <::Currency as fungible::Inspect<::AccountId>>::Balance, - ) -> Result { - if amount == 0 { - return Ok(TaoCurrency::ZERO); + ) -> Result { + if amount.is_zero() { + return Ok(TaoBalance::ZERO); } let credit = ::Currency::withdraw( @@ -320,7 +320,7 @@ impl Pallet { .map_err(|_| Error::::BalanceWithdrawalError)? .peek(); - if credit == 0 { + if credit.is_zero() { return Err(Error::::ZeroBalanceAfterWithdrawn.into()); } @@ -330,9 +330,9 @@ impl Pallet { pub fn kill_coldkey_account( coldkey: &T::AccountId, amount: <::Currency as fungible::Inspect<::AccountId>>::Balance, - ) -> Result { - if amount == 0 { - return Ok(0); + ) -> Result { + if amount.is_zero() { + return Ok(0.into()); } let credit = ::Currency::withdraw( @@ -345,7 +345,7 @@ impl Pallet { .map_err(|_| Error::::BalanceWithdrawalError)? .peek(); - if credit == 0 { + if credit.is_zero() { return Err(Error::::ZeroBalanceAfterWithdrawn.into()); } @@ -356,7 +356,7 @@ impl Pallet { T::SwapInterface::is_user_liquidity_enabled(netuid) } - pub fn recycle_subnet_alpha(netuid: NetUid, amount: AlphaCurrency) { + pub fn recycle_subnet_alpha(netuid: NetUid, amount: AlphaBalance) { // TODO: record recycled alpha in a tracker SubnetAlphaOut::::mutate(netuid, |total| { *total = total.saturating_sub(amount); @@ -413,7 +413,7 @@ impl Pallet { } } - pub fn burn_subnet_alpha(_netuid: NetUid, _amount: AlphaCurrency) { + pub fn burn_subnet_alpha(_netuid: NetUid, _amount: AlphaBalance) { // Do nothing; TODO: record burned alpha in a tracker } } diff --git a/pallets/subtensor/src/staking/move_stake.rs b/pallets/subtensor/src/staking/move_stake.rs index a1d9b46d5b..2cc08b4f02 100644 --- a/pallets/subtensor/src/staking/move_stake.rs +++ b/pallets/subtensor/src/staking/move_stake.rs @@ -2,7 +2,7 @@ use super::*; use safe_math::*; use sp_core::Get; use substrate_fixed::types::U64F64; -use subtensor_runtime_common::{AlphaCurrency, Currency, NetUid, TaoCurrency}; +use subtensor_runtime_common::{AlphaBalance, NetUid, TaoBalance, Token}; use subtensor_swap_interface::SwapHandler; impl Pallet { @@ -33,7 +33,7 @@ impl Pallet { destination_hotkey: T::AccountId, origin_netuid: NetUid, destination_netuid: NetUid, - alpha_amount: AlphaCurrency, + alpha_amount: AlphaBalance, ) -> dispatch::DispatchResult { // Check that the origin is signed by the origin_hotkey. let coldkey = ensure_signed(origin)?; @@ -124,7 +124,7 @@ impl Pallet { hotkey: T::AccountId, origin_netuid: NetUid, destination_netuid: NetUid, - alpha_amount: AlphaCurrency, + alpha_amount: AlphaBalance, ) -> dispatch::DispatchResult { // Ensure the extrinsic is signed by the origin_coldkey. let coldkey = ensure_signed(origin)?; @@ -189,7 +189,7 @@ impl Pallet { hotkey: T::AccountId, origin_netuid: NetUid, destination_netuid: NetUid, - alpha_amount: AlphaCurrency, + alpha_amount: AlphaBalance, ) -> dispatch::DispatchResult { // Ensure the extrinsic is signed by the coldkey. let coldkey = ensure_signed(origin)?; @@ -255,8 +255,8 @@ impl Pallet { hotkey: T::AccountId, origin_netuid: NetUid, destination_netuid: NetUid, - alpha_amount: AlphaCurrency, - limit_price: TaoCurrency, + alpha_amount: AlphaBalance, + limit_price: TaoBalance, allow_partial: bool, ) -> dispatch::DispatchResult { // Ensure the extrinsic is signed by the coldkey. @@ -302,12 +302,12 @@ impl Pallet { destination_hotkey: &T::AccountId, origin_netuid: NetUid, destination_netuid: NetUid, - alpha_amount: AlphaCurrency, - maybe_limit_price: Option, + alpha_amount: AlphaBalance, + maybe_limit_price: Option, maybe_allow_partial: Option, check_transfer_toggle: bool, set_limit: bool, - ) -> Result { + ) -> Result { // Cap the alpha_amount at available Alpha because user might be paying transaxtion fees // in Alpha and their total is already reduced by now. let alpha_available = Self::get_stake_for_hotkey_and_coldkey_on_subnet( @@ -423,8 +423,8 @@ impl Pallet { pub fn get_max_amount_move( origin_netuid: NetUid, destination_netuid: NetUid, - limit_price: TaoCurrency, - ) -> Result { + limit_price: TaoBalance, + ) -> Result { let tao = U64F64::saturating_from_num(1_000_000_000); // Corner case: both subnet IDs are root or stao @@ -436,7 +436,7 @@ impl Pallet { if limit_price > tao.saturating_to_num::().into() { return Err(Error::::ZeroMaxStakeAmount.into()); } else { - return Ok(AlphaCurrency::MAX); + return Ok(AlphaBalance::MAX); } } @@ -446,7 +446,7 @@ impl Pallet { && (SubnetMechanism::::get(destination_netuid) == 1) { if limit_price.is_zero() { - return Ok(AlphaCurrency::MAX); + return Ok(AlphaBalance::MAX); } else { // The destination price is reverted because the limit_price is origin_price / destination_price let destination_subnet_price = tao @@ -508,7 +508,7 @@ impl Pallet { // Corner case: limit_price is zero if limit_price.is_zero() { - return Ok(AlphaCurrency::MAX); + return Ok(AlphaBalance::MAX); } // Main case diff --git a/pallets/subtensor/src/staking/recycle_alpha.rs b/pallets/subtensor/src/staking/recycle_alpha.rs index b77982fa31..08627274aa 100644 --- a/pallets/subtensor/src/staking/recycle_alpha.rs +++ b/pallets/subtensor/src/staking/recycle_alpha.rs @@ -1,6 +1,6 @@ use super::*; use crate::{Error, system::ensure_signed}; -use subtensor_runtime_common::{AlphaCurrency, NetUid}; +use subtensor_runtime_common::{AlphaBalance, NetUid}; impl Pallet { /// Recycles alpha from a cold/hot key pair, reducing AlphaOut on a subnet @@ -18,7 +18,7 @@ impl Pallet { pub(crate) fn do_recycle_alpha( origin: T::RuntimeOrigin, hotkey: T::AccountId, - amount: AlphaCurrency, + amount: AlphaBalance, netuid: NetUid, ) -> DispatchResult { let coldkey: T::AccountId = ensure_signed(origin)?; @@ -85,7 +85,7 @@ impl Pallet { pub(crate) fn do_burn_alpha( origin: T::RuntimeOrigin, hotkey: T::AccountId, - amount: AlphaCurrency, + amount: AlphaBalance, netuid: NetUid, ) -> DispatchResult { let coldkey = ensure_signed(origin)?; @@ -140,8 +140,8 @@ impl Pallet { origin: T::RuntimeOrigin, hotkey: T::AccountId, netuid: NetUid, - amount: TaoCurrency, - limit: Option, + amount: TaoBalance, + limit: Option, ) -> DispatchResult { Self::ensure_subnet_owner(origin.clone(), netuid)?; diff --git a/pallets/subtensor/src/staking/remove_stake.rs b/pallets/subtensor/src/staking/remove_stake.rs index 74a6bf34a6..1a5238aeb3 100644 --- a/pallets/subtensor/src/staking/remove_stake.rs +++ b/pallets/subtensor/src/staking/remove_stake.rs @@ -1,6 +1,6 @@ use super::*; use substrate_fixed::types::U96F32; -use subtensor_runtime_common::{AlphaCurrency, Currency, NetUid, TaoCurrency}; +use subtensor_runtime_common::{AlphaBalance, NetUid, TaoBalance, Token}; use subtensor_swap_interface::{Order, SwapHandler}; impl Pallet { @@ -40,7 +40,7 @@ impl Pallet { origin: T::RuntimeOrigin, hotkey: T::AccountId, netuid: NetUid, - alpha_unstaked: AlphaCurrency, + alpha_unstaked: AlphaBalance, ) -> dispatch::DispatchResult { // 1. We check the transaction is signed by the caller and retrieve the T::AccountId coldkey information. let coldkey = ensure_signed(origin)?; @@ -228,7 +228,7 @@ impl Pallet { log::debug!("All subnet netuids: {netuids:?}"); // 4. Iterate through all subnets and remove stake. - let mut total_tao_unstaked = TaoCurrency::ZERO; + let mut total_tao_unstaked = TaoBalance::ZERO; for netuid in netuids.into_iter() { if !SubtokenEnabled::::get(netuid) { continue; @@ -333,8 +333,8 @@ impl Pallet { origin: T::RuntimeOrigin, hotkey: T::AccountId, netuid: NetUid, - alpha_unstaked: AlphaCurrency, - limit_price: TaoCurrency, + alpha_unstaked: AlphaBalance, + limit_price: TaoBalance, allow_partial: bool, ) -> dispatch::DispatchResult { // 1. We check the transaction is signed by the caller and retrieve the T::AccountId coldkey information. @@ -390,14 +390,14 @@ impl Pallet { // Returns the maximum amount of RAO that can be executed with price limit pub fn get_max_amount_remove( netuid: NetUid, - limit_price: TaoCurrency, - ) -> Result { + limit_price: TaoBalance, + ) -> Result { // Corner case: root and stao // There's no slippage for root or stable subnets, so if limit price is 1e9 rao or // lower, then max_amount equals u64::MAX, otherwise it is 0. if netuid.is_root() || SubnetMechanism::::get(netuid) == 0 { if limit_price <= 1_000_000_000.into() { - return Ok(AlphaCurrency::MAX); + return Ok(AlphaBalance::MAX); } else { return Err(Error::::ZeroMaxStakeAmount.into()); } @@ -419,7 +419,7 @@ impl Pallet { origin: T::RuntimeOrigin, hotkey: T::AccountId, netuid: NetUid, - limit_price: Option, + limit_price: Option, ) -> DispatchResult { let coldkey = ensure_signed(origin.clone())?; @@ -439,7 +439,7 @@ impl Pallet { // 2) Owner / lock cost. let owner_coldkey: T::AccountId = SubnetOwner::::get(netuid); - let lock_cost: TaoCurrency = Self::get_subnet_locked_balance(netuid); + let lock_cost: TaoBalance = Self::get_subnet_locked_balance(netuid); // Determine if this subnet is eligible for a lock refund (legacy). let reg_at: u64 = NetworkRegisteredAt::::get(netuid); @@ -451,7 +451,7 @@ impl Pallet { // - get the current alpha issuance, // - apply owner fraction to get owner α, // - price that α using a *simulated* AMM swap. - let mut owner_emission_tao = TaoCurrency::ZERO; + let mut owner_emission_tao = TaoBalance::ZERO; if should_refund_owner && !lock_cost.is_zero() { let total_emitted_alpha_u128: u128 = Self::get_alpha_issuance(netuid).to_u64() as u128; @@ -468,9 +468,9 @@ impl Pallet { .saturating_mul(cur_price) .floor() .saturating_to_num::(); - TaoCurrency::from(val_u64) + val_u64.into() } else { - TaoCurrency::ZERO + TaoBalance::ZERO }; } } @@ -515,7 +515,7 @@ impl Pallet { } // 5) Determine the TAO pot and pre-adjust accounting to avoid double counting. - let pot_tao: TaoCurrency = SubnetTAO::::get(netuid); + let pot_tao: TaoBalance = SubnetTAO::::get(netuid); let pot_u64: u64 = pot_tao.into(); if pot_u64 > 0 { @@ -564,7 +564,7 @@ impl Pallet { // Credit each share directly to coldkey free balance. for p in portions { if p.share > 0 { - Self::add_balance_to_coldkey_account(&p.cold, p.share); + Self::add_balance_to_coldkey_account(&p.cold, p.share.into()); } } } @@ -585,20 +585,20 @@ impl Pallet { SubnetAlphaOut::::remove(netuid); // Clear the locked balance on the subnet. - Self::set_subnet_locked_balance(netuid, TaoCurrency::ZERO); + Self::set_subnet_locked_balance(netuid, TaoBalance::ZERO); // 8) Finalize lock handling: // - Legacy subnets (registered before NetworkRegistrationStartBlock) receive: // refund = max(0, lock_cost(τ) − owner_received_emission_in_τ). // - New subnets: no refund. - let refund: TaoCurrency = if should_refund_owner { + let refund: TaoBalance = if should_refund_owner { lock_cost.saturating_sub(owner_emission_tao) } else { - TaoCurrency::ZERO + TaoBalance::ZERO }; if !refund.is_zero() { - Self::add_balance_to_coldkey_account(&owner_coldkey, refund.to_u64()); + Self::add_balance_to_coldkey_account(&owner_coldkey, refund); } Ok(()) diff --git a/pallets/subtensor/src/staking/stake_utils.rs b/pallets/subtensor/src/staking/stake_utils.rs index cf90131c4e..a4987bbd74 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, AuthorshipInfo, Currency, NetUid, TaoCurrency}; +use subtensor_runtime_common::{AlphaBalance, AuthorshipInfo, NetUid, TaoBalance, Token}; use subtensor_swap_interface::{Order, SwapHandler, SwapResult}; impl Pallet { @@ -17,14 +17,8 @@ impl Pallet { /// /// # Returns /// * `u64` - The total alpha issuance for the specified subnet. - pub fn get_alpha_issuance(netuid: NetUid) -> AlphaCurrency { - SubnetAlphaIn::::get(netuid) - .saturating_add(SubnetAlphaInProvided::::get(netuid)) - .saturating_add(SubnetAlphaOut::::get(netuid)) - } - - pub fn get_protocol_tao(netuid: NetUid) -> TaoCurrency { - T::SwapInterface::get_protocol_tao(netuid) + pub fn get_alpha_issuance(netuid: NetUid) -> AlphaBalance { + SubnetAlphaIn::::get(netuid).saturating_add(SubnetAlphaOut::::get(netuid)) } pub fn get_moving_alpha_price(netuid: NetUid) -> U96F32 { @@ -247,7 +241,7 @@ impl Pallet { pub fn get_tao_inherited_for_hotkey_on_subnet( hotkey: &T::AccountId, netuid: NetUid, - ) -> TaoCurrency { + ) -> TaoBalance { let initial_tao: U96F32 = U96F32::saturating_from_num(Self::get_stake_for_hotkey_on_subnet(hotkey, NetUid::ROOT)); @@ -315,7 +309,7 @@ impl Pallet { pub fn get_inherited_for_hotkey_on_subnet( hotkey: &T::AccountId, netuid: NetUid, - ) -> AlphaCurrency { + ) -> AlphaBalance { // Step 1: Retrieve the initial total stake (alpha) for the hotkey on the specified subnet. let initial_alpha: U96F32 = U96F32::saturating_from_num(Self::get_stake_for_hotkey_on_subnet(hotkey, netuid)); @@ -406,8 +400,8 @@ impl Pallet { hotkey: &T::AccountId, coldkey: &T::AccountId, netuid: NetUid, - decrement: AlphaCurrency, - ) -> Result> { + decrement: AlphaBalance, + ) -> Result> { // Retrieve the current stake for this hotkey-coldkey pair on the subnet let current_stake = Self::get_stake_for_hotkey_and_coldkey_on_subnet(hotkey, coldkey, netuid); @@ -442,7 +436,7 @@ impl Pallet { hotkey: &T::AccountId, coldkey: &T::AccountId, netuid: NetUid, - ) -> AlphaCurrency { + ) -> AlphaBalance { let alpha_share_pool = Self::get_alpha_share_pool(hotkey.clone(), netuid); alpha_share_pool.try_get_value(coldkey).unwrap_or(0).into() } @@ -461,7 +455,7 @@ impl Pallet { /// /// # Note /// This function returns the cumulative stake across all coldkeys associated with this hotkey on the subnet. - pub fn get_stake_for_hotkey_on_subnet(hotkey: &T::AccountId, netuid: NetUid) -> AlphaCurrency { + pub fn get_stake_for_hotkey_on_subnet(hotkey: &T::AccountId, netuid: NetUid) -> AlphaBalance { // Retrieve and return the total alpha this hotkey owns on this subnet. // This value represents the sum of stakes from all coldkeys associated with this hotkey. TotalHotkeyAlpha::::get(hotkey, netuid) @@ -479,7 +473,7 @@ impl Pallet { pub fn increase_stake_for_hotkey_on_subnet( hotkey: &T::AccountId, netuid: NetUid, - amount: AlphaCurrency, + amount: AlphaBalance, ) { let mut alpha_share_pool = Self::get_alpha_share_pool(hotkey.clone(), netuid); alpha_share_pool.update_value_for_all(amount.to_u64() as i64); @@ -513,8 +507,8 @@ impl Pallet { hotkey: &T::AccountId, coldkey: &T::AccountId, netuid: NetUid, - amount: AlphaCurrency, - ) -> AlphaCurrency { + amount: AlphaBalance, + ) -> AlphaBalance { if !amount.is_zero() { let mut staking_hotkeys = StakingHotkeys::::get(coldkey); if !staking_hotkeys.contains(hotkey) { @@ -536,7 +530,7 @@ impl Pallet { pub fn try_increase_stake_for_hotkey_and_coldkey_on_subnet( hotkey: &T::AccountId, netuid: NetUid, - amount: AlphaCurrency, + amount: AlphaBalance, ) -> bool { let mut alpha_share_pool = Self::get_alpha_share_pool(hotkey.clone(), netuid); let amount = amount.to_u64() as i64; @@ -557,8 +551,8 @@ impl Pallet { hotkey: &T::AccountId, coldkey: &T::AccountId, netuid: NetUid, - amount: AlphaCurrency, - ) -> AlphaCurrency { + amount: AlphaBalance, + ) -> AlphaBalance { let mut alpha_share_pool = Self::get_alpha_share_pool(hotkey.clone(), netuid); let amount = amount.to_u64(); @@ -581,10 +575,10 @@ impl Pallet { /// Updates TaoIn, AlphaIn, and AlphaOut pub fn swap_tao_for_alpha( netuid: NetUid, - tao: TaoCurrency, - price_limit: TaoCurrency, + tao: TaoBalance, + price_limit: TaoBalance, drop_fees: bool, - ) -> Result, DispatchError> { + ) -> Result, DispatchError> { // Step 1: Get the mechanism type for the subnet (0 for Stable, 1 for Dynamic) let mechanism_id: u16 = SubnetMechanism::::get(netuid); let swap_result = if mechanism_id == 1 { @@ -595,8 +589,8 @@ impl Pallet { SwapResult { amount_paid_in: tao, amount_paid_out: tao.to_u64().into(), - fee_paid: TaoCurrency::ZERO, - fee_to_block_author: TaoCurrency::ZERO, + fee_paid: TaoBalance::ZERO, + fee_to_block_author: TaoBalance::ZERO, } }; @@ -634,10 +628,10 @@ impl Pallet { /// Updates TaoIn, AlphaIn, and AlphaOut pub fn swap_alpha_for_tao( netuid: NetUid, - alpha: AlphaCurrency, - price_limit: TaoCurrency, + alpha: AlphaBalance, + price_limit: TaoBalance, drop_fees: bool, - ) -> Result, DispatchError> { + ) -> Result, DispatchError> { // Step 1: Get the mechanism type for the subnet (0 for Stable, 1 for Dynamic) let mechanism_id: u16 = SubnetMechanism::::get(netuid); // Step 2: Swap alpha and attain tao @@ -649,8 +643,8 @@ impl Pallet { SwapResult { amount_paid_in: alpha, amount_paid_out: alpha.to_u64().into(), - fee_paid: AlphaCurrency::ZERO, - fee_to_block_author: AlphaCurrency::ZERO, + fee_paid: AlphaBalance::ZERO, + fee_to_block_author: AlphaBalance::ZERO, } }; @@ -688,10 +682,10 @@ impl Pallet { hotkey: &T::AccountId, coldkey: &T::AccountId, netuid: NetUid, - alpha: AlphaCurrency, - price_limit: TaoCurrency, + alpha: AlphaBalance, + price_limit: TaoBalance, drop_fees: bool, - ) -> Result { + ) -> Result { // Decrease alpha on subnet let actual_alpha_decrease = Self::decrease_stake_for_hotkey_and_coldkey_on_subnet(hotkey, coldkey, netuid, alpha); @@ -718,7 +712,7 @@ impl Pallet { let bb_swap_result = Self::swap_alpha_for_tao( netuid, swap_result.fee_to_block_author, - T::SwapInterface::min_price::(), + T::SwapInterface::min_price::(), true, )?; Self::add_balance_to_coldkey_account( @@ -785,11 +779,11 @@ impl Pallet { hotkey: &T::AccountId, coldkey: &T::AccountId, netuid: NetUid, - tao: TaoCurrency, - price_limit: TaoCurrency, + tao: TaoBalance, + price_limit: TaoBalance, set_limit: bool, drop_fees: bool, - ) -> Result { + ) -> Result { // Swap the tao to alpha. let swap_result = Self::swap_tao_for_alpha(netuid, tao, price_limit, drop_fees)?; @@ -817,7 +811,7 @@ impl Pallet { .is_zero() || swap_result.amount_paid_out.is_zero() { - return Ok(AlphaCurrency::ZERO); + return Ok(AlphaBalance::ZERO); } // Step 4: Update the list of hotkeys staking for this coldkey @@ -892,8 +886,8 @@ impl Pallet { destination_coldkey: &T::AccountId, destination_hotkey: &T::AccountId, netuid: NetUid, - alpha: AlphaCurrency, - ) -> Result { + alpha: AlphaBalance, + ) -> Result { // Decrease alpha on origin keys let actual_alpha_decrease = Self::decrease_stake_for_hotkey_and_coldkey_on_subnet( origin_hotkey, @@ -928,7 +922,7 @@ impl Pallet { // there's no slippage in this move) let current_price = ::SwapInterface::current_alpha_price(netuid.into()); - let tao_equivalent: TaoCurrency = current_price + let tao_equivalent: TaoBalance = current_price .saturating_mul(U96F32::saturating_from_num(actual_alpha_moved)) .saturating_to_num::() .into(); @@ -987,8 +981,8 @@ impl Pallet { coldkey: &T::AccountId, hotkey: &T::AccountId, netuid: NetUid, - mut stake_to_be_added: TaoCurrency, - max_amount: TaoCurrency, + mut stake_to_be_added: TaoBalance, + max_amount: TaoBalance, allow_partial: bool, ) -> Result<(), Error> { // Ensure that the subnet exists. @@ -1065,8 +1059,8 @@ impl Pallet { coldkey: &T::AccountId, hotkey: &T::AccountId, netuid: NetUid, - alpha_unstaked: AlphaCurrency, - max_amount: AlphaCurrency, + alpha_unstaked: AlphaBalance, + max_amount: AlphaBalance, allow_partial: bool, ) -> Result<(), Error> { // Ensure that the subnet exists. @@ -1158,8 +1152,8 @@ impl Pallet { destination_hotkey: &T::AccountId, origin_netuid: NetUid, destination_netuid: NetUid, - alpha_amount: AlphaCurrency, - max_amount: AlphaCurrency, + alpha_amount: AlphaBalance, + max_amount: AlphaBalance, maybe_allow_partial: Option, check_transfer_toggle: bool, ) -> Result<(), Error> { @@ -1257,43 +1251,35 @@ impl Pallet { Ok(()) } - pub fn increase_provided_tao_reserve(netuid: NetUid, tao: TaoCurrency) { - SubnetTaoProvided::::mutate(netuid, |total| { - *total = total.saturating_add(tao); - }); + pub fn increase_provided_tao_reserve(netuid: NetUid, tao: TaoBalance) { + if !tao.is_zero() { + SubnetTAO::::mutate(netuid, |total| { + *total = total.saturating_add(tao); + }); + } } - pub fn decrease_provided_tao_reserve(netuid: NetUid, tao: TaoCurrency) { - // First, decrease SubnetTaoProvided, then deduct the rest from SubnetTAO - let subnet_tao = SubnetTAO::::get(netuid); - let subnet_tao_provided = SubnetTaoProvided::::get(netuid); - let remainder = subnet_tao_provided.saturating_sub(tao); - let carry_over = tao.saturating_sub(subnet_tao_provided); - if carry_over.is_zero() { - SubnetTaoProvided::::set(netuid, remainder); - } else { - SubnetTaoProvided::::set(netuid, TaoCurrency::ZERO); - SubnetTAO::::set(netuid, subnet_tao.saturating_sub(carry_over)); + pub fn decrease_provided_tao_reserve(netuid: NetUid, tao: TaoBalance) { + if !tao.is_zero() { + SubnetTAO::::mutate(netuid, |total| { + *total = total.saturating_sub(tao); + }); } } - pub fn increase_provided_alpha_reserve(netuid: NetUid, alpha: AlphaCurrency) { - SubnetAlphaInProvided::::mutate(netuid, |total| { - *total = total.saturating_add(alpha); - }); + pub fn increase_provided_alpha_reserve(netuid: NetUid, alpha: AlphaBalance) { + if !alpha.is_zero() { + SubnetAlphaIn::::mutate(netuid, |total| { + *total = total.saturating_add(alpha); + }); + } } - pub fn decrease_provided_alpha_reserve(netuid: NetUid, alpha: AlphaCurrency) { - // First, decrease SubnetAlphaInProvided, then deduct the rest from SubnetAlphaIn - let subnet_alpha = SubnetAlphaIn::::get(netuid); - let subnet_alpha_provided = SubnetAlphaInProvided::::get(netuid); - let remainder = subnet_alpha_provided.saturating_sub(alpha); - let carry_over = alpha.saturating_sub(subnet_alpha_provided); - if carry_over.is_zero() { - SubnetAlphaInProvided::::set(netuid, remainder); - } else { - SubnetAlphaInProvided::::set(netuid, AlphaCurrency::ZERO); - SubnetAlphaIn::::set(netuid, subnet_alpha.saturating_sub(carry_over)); + pub fn decrease_provided_alpha_reserve(netuid: NetUid, alpha: AlphaBalance) { + if !alpha.is_zero() { + SubnetAlphaIn::::mutate(netuid, |total| { + *total = total.saturating_sub(alpha); + }); } } @@ -1366,7 +1352,7 @@ impl SharePoolDataOperations> crate::TotalHotkeyAlpha::::insert( &(self.hotkey), self.netuid, - AlphaCurrency::from(value.saturating_to_num::()), + AlphaBalance::from(value.saturating_to_num::()), ); } else { crate::TotalHotkeyAlpha::::remove(&(self.hotkey), self.netuid); diff --git a/pallets/subtensor/src/subnets/leasing.rs b/pallets/subtensor/src/subnets/leasing.rs index a202a22a45..e7c10bf8ff 100644 --- a/pallets/subtensor/src/subnets/leasing.rs +++ b/pallets/subtensor/src/subnets/leasing.rs @@ -24,7 +24,7 @@ use frame_system::pallet_prelude::*; use sp_core::blake2_256; use sp_runtime::{Percent, traits::TrailingZeroInput}; use substrate_fixed::types::U64F64; -use subtensor_runtime_common::{AlphaCurrency, NetUid}; +use subtensor_runtime_common::{AlphaBalance, NetUid}; pub type LeaseId = u32; @@ -141,25 +141,26 @@ impl Pallet { let mut refunded_cap = 0u64; for (contributor, amount) in contributions { // Compute the share of the contributor to the lease - let share: U64F64 = U64F64::from(amount).saturating_div(U64F64::from(crowdloan.raised)); + let share: U64F64 = U64F64::from(u64::from(amount)) + .saturating_div(U64F64::from(u64::from(crowdloan.raised))); SubnetLeaseShares::::insert(lease_id, &contributor, share); // Refund the unused part of the cap to the contributor relative to their share let contributor_refund = share - .saturating_mul(U64F64::from(leftover_cap)) + .saturating_mul(U64F64::from(u64::from(leftover_cap))) .floor() .saturating_to_num::(); ::Currency::transfer( &lease_coldkey, &contributor, - contributor_refund, + contributor_refund.into(), Preservation::Expendable, )?; refunded_cap = refunded_cap.saturating_add(contributor_refund); } // Refund what's left after refunding the contributors to the beneficiary - let beneficiary_refund = leftover_cap.saturating_sub(refunded_cap); + let beneficiary_refund = leftover_cap.saturating_sub(refunded_cap.into()); ::Currency::transfer( &lease_coldkey, &who, @@ -253,7 +254,7 @@ impl Pallet { /// for the contributors and the beneficiary in shares relative to their initial contributions. /// It accumulates dividends to be distributed later when the interval for distribution is reached. /// Distribution is made in alpha and stake to the contributor coldkey and lease hotkey. - pub fn distribute_leased_network_dividends(lease_id: LeaseId, owner_cut_alpha: AlphaCurrency) { + pub fn distribute_leased_network_dividends(lease_id: LeaseId, owner_cut_alpha: AlphaBalance) { // Ensure the lease exists let Some(lease) = SubnetLeases::::get(lease_id) else { log::debug!("Lease {lease_id} doesn't exists so we can't distribute dividends"); @@ -293,7 +294,7 @@ impl Pallet { // We use a storage layer to ensure the distribution is atomic. if let Err(err) = frame_support::storage::with_storage_layer(|| { - let mut alpha_distributed = AlphaCurrency::ZERO; + let mut alpha_distributed = AlphaBalance::ZERO; // Distribute the contributors cut to the contributors and accumulate the alpha // distributed so far to obtain how much alpha is left to distribute to the beneficiary @@ -338,7 +339,7 @@ impl Pallet { }); // Reset the accumulated dividends - AccumulatedLeaseDividends::::insert(lease_id, AlphaCurrency::ZERO); + AccumulatedLeaseDividends::::insert(lease_id, AlphaBalance::ZERO); Ok::<(), DispatchError>(()) }) { diff --git a/pallets/subtensor/src/subnets/mechanism.rs b/pallets/subtensor/src/subnets/mechanism.rs index 55e459c9ba..2e425130d9 100644 --- a/pallets/subtensor/src/subnets/mechanism.rs +++ b/pallets/subtensor/src/subnets/mechanism.rs @@ -6,7 +6,7 @@ use crate::epoch::run_epoch::EpochTerms; use alloc::collections::BTreeMap; use safe_math::*; use substrate_fixed::types::U64F64; -use subtensor_runtime_common::{AlphaCurrency, MechId, NetUid, NetUidStorageIndex}; +use subtensor_runtime_common::{AlphaBalance, MechId, NetUid, NetUidStorageIndex}; pub type LeaseId = u32; @@ -227,16 +227,16 @@ impl Pallet { /// Split alpha emission in sub-subnet proportions /// stored in MechanismEmissionSplit /// - pub fn split_emissions(netuid: NetUid, alpha: AlphaCurrency) -> Vec { + pub fn split_emissions(netuid: NetUid, alpha: AlphaBalance) -> Vec { let mechanism_count = u64::from(MechanismCountCurrent::::get(netuid)); let maybe_split = MechanismEmissionSplit::::get(netuid); // Unset split means even distribution - let mut result: Vec = if let Some(split) = maybe_split { + let mut result: Vec = if let Some(split) = maybe_split { split .iter() .map(|s| { - AlphaCurrency::from( + AlphaBalance::from( (u64::from(alpha) as u128) .saturating_mul(*s as u128) .safe_div(u16::MAX as u128) as u64, @@ -245,19 +245,19 @@ impl Pallet { .collect() } else { let per_mechanism = u64::from(alpha).safe_div(mechanism_count); - vec![AlphaCurrency::from(per_mechanism); mechanism_count as usize] + vec![AlphaBalance::from(per_mechanism); mechanism_count as usize] }; // Trim / extend and pad with zeroes if result is shorter than mechanism_count if result.len() != mechanism_count as usize { - result.resize(mechanism_count as usize, 0u64.into()); // pad with AlphaCurrency::from(0) + result.resize(mechanism_count as usize, 0u64.into()); // pad with AlphaBalance::from(0) } // If there's any rounding error or lost due to truncation emission, credit it to mechanism 0 let rounding_err = u64::from(alpha).saturating_sub(result.iter().map(|s| u64::from(*s)).sum()); if let Some(cell) = result.first_mut() { - *cell = cell.saturating_add(AlphaCurrency::from(rounding_err)); + *cell = cell.saturating_add(AlphaBalance::from(rounding_err)); } result } @@ -269,10 +269,10 @@ impl Pallet { } fn weighted_acc_alpha( - existing: AlphaCurrency, - added: AlphaCurrency, + existing: AlphaBalance, + added: AlphaBalance, weight: U64F64, - ) -> AlphaCurrency { + ) -> AlphaBalance { U64F64::saturating_from_num(existing) .saturating_add(U64F64::saturating_from_num(added).saturating_mul(weight)) .saturating_to_num::() @@ -286,8 +286,8 @@ impl Pallet { /// pub fn epoch_with_mechanisms( netuid: NetUid, - rao_emission: AlphaCurrency, - ) -> Vec<(T::AccountId, AlphaCurrency, AlphaCurrency)> { + rao_emission: AlphaBalance, + ) -> Vec<(T::AccountId, AlphaBalance, AlphaBalance)> { let aggregated: BTreeMap = Self::split_emissions(netuid, rao_emission) .into_iter() @@ -396,7 +396,7 @@ impl Pallet { // 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 + // Remap BTreeMap back to Vec<(T::AccountId, AlphaBalance, AlphaBalance)> format // for processing emissions in run_coinbase // Emission tuples ( hotkeys, server_emission, validator_emission ) aggregated diff --git a/pallets/subtensor/src/subnets/registration.rs b/pallets/subtensor/src/subnets/registration.rs index a7771857bb..ccf32f6ac7 100644 --- a/pallets/subtensor/src/subnets/registration.rs +++ b/pallets/subtensor/src/subnets/registration.rs @@ -2,7 +2,7 @@ use super::*; use sp_core::{H256, U256}; use sp_io::hashing::{keccak_256, sha2_256}; use sp_runtime::Saturating; -use subtensor_runtime_common::{Currency, NetUid}; +use subtensor_runtime_common::{NetUid, Token}; use subtensor_swap_interface::SwapHandler; use system::pallet_prelude::BlockNumberFor; @@ -374,9 +374,9 @@ impl Pallet { // --- 5. Add Balance via faucet. let balance_to_add: u64 = 1_000_000_000_000; - Self::increase_issuance(100_000_000_000.into()); // We are creating tokens here from the coinbase. + Self::increase_issuance(100_000_000_000_u64.into()); // We are creating tokens here from the coinbase. - Self::add_balance_to_coldkey_account(&coldkey, balance_to_add); + Self::add_balance_to_coldkey_account(&coldkey, balance_to_add.into()); // --- 6. Deposit successful event. log::debug!("Faucet( coldkey:{coldkey:?} amount:{balance_to_add:?} ) "); @@ -458,7 +458,7 @@ impl Pallet { let owner_ck = SubnetOwner::::get(netuid); let immortal_hotkeys = Self::get_immune_owner_hotkeys(netuid, &owner_ck); - let emissions: Vec = Emission::::get(netuid); + let emissions: Vec = Emission::::get(netuid); // Single pass: // - count current non‑immortal & non‑immune UIDs, @@ -466,8 +466,8 @@ impl Pallet { let mut free_count: u16 = 0; // (emission, reg_block, uid) - let mut best_non_immune: Option<(AlphaCurrency, u64, u16)> = None; - let mut best_immune: Option<(AlphaCurrency, u64, u16)> = None; + let mut best_non_immune: Option<(AlphaBalance, u64, u16)> = None; + let mut best_immune: Option<(AlphaBalance, u64, u16)> = None; for uid in 0..n { let hk = match Self::get_hotkey_for_net_and_uid(netuid, uid) { @@ -484,11 +484,11 @@ impl Pallet { let emission = emissions .get(uid as usize) .cloned() - .unwrap_or(AlphaCurrency::ZERO); + .unwrap_or(AlphaBalance::ZERO); let reg_block = Self::get_neuron_block_at_registration(netuid, uid); // Helper to decide if (e, b, u) beats the current best. - let consider = |best: &mut Option<(AlphaCurrency, u64, u16)>| match best { + let consider = |best: &mut Option<(AlphaBalance, u64, u16)>| match best { None => *best = Some((emission, reg_block, uid)), Some((be, bb, bu)) => { let better = if emission != *be { diff --git a/pallets/subtensor/src/subnets/subnet.rs b/pallets/subtensor/src/subnets/subnet.rs index ecb5ce0452..769db17ebe 100644 --- a/pallets/subtensor/src/subnets/subnet.rs +++ b/pallets/subtensor/src/subnets/subnet.rs @@ -1,6 +1,6 @@ use super::*; use sp_core::Get; -use subtensor_runtime_common::{NetUid, TaoCurrency}; +use subtensor_runtime_common::{NetUid, TaoBalance}; impl Pallet { /// Returns true if the subnetwork exists. /// @@ -206,8 +206,8 @@ impl Pallet { // The initial TAO is the locked amount // Put initial TAO from lock into subnet TAO and produce numerically equal amount of Alpha. - let pool_initial_tao: TaoCurrency = Self::get_network_min_lock(); - let pool_initial_alpha: AlphaCurrency = pool_initial_tao.to_u64().into(); + let pool_initial_tao: TaoBalance = Self::get_network_min_lock(); + let pool_initial_alpha: AlphaBalance = pool_initial_tao.to_u64().into(); let actual_tao_lock_amount_less_pool_tao = actual_tao_lock_amount.saturating_sub(pool_initial_tao); @@ -217,20 +217,20 @@ impl Pallet { SubnetOwner::::insert(netuid_to_register, coldkey.clone()); SubnetOwnerHotkey::::insert(netuid_to_register, hotkey.clone()); SubnetLocked::::insert(netuid_to_register, actual_tao_lock_amount); - SubnetTaoProvided::::insert(netuid_to_register, TaoCurrency::ZERO); - SubnetAlphaInProvided::::insert(netuid_to_register, AlphaCurrency::ZERO); - SubnetAlphaOut::::insert(netuid_to_register, AlphaCurrency::ZERO); + SubnetTaoProvided::::insert(netuid_to_register, TaoBalance::ZERO); + SubnetAlphaInProvided::::insert(netuid_to_register, AlphaBalance::ZERO); + SubnetAlphaOut::::insert(netuid_to_register, AlphaBalance::ZERO); SubnetVolume::::insert(netuid_to_register, 0u128); RAORecycledForRegistration::::insert( netuid_to_register, actual_tao_lock_amount_less_pool_tao, ); - if actual_tao_lock_amount_less_pool_tao > TaoCurrency::ZERO { + if actual_tao_lock_amount_less_pool_tao > TaoBalance::ZERO { Self::recycle_tao(actual_tao_lock_amount_less_pool_tao); } - if actual_tao_lock_amount > TaoCurrency::ZERO && pool_initial_tao > TaoCurrency::ZERO { + if actual_tao_lock_amount > TaoBalance::ZERO && pool_initial_tao > TaoBalance::ZERO { // Record in TotalStake the initial TAO in the pool. Self::increase_total_stake(pool_initial_tao); } diff --git a/pallets/subtensor/src/subnets/uids.rs b/pallets/subtensor/src/subnets/uids.rs index 0a09017e64..5abf5586f9 100644 --- a/pallets/subtensor/src/subnets/uids.rs +++ b/pallets/subtensor/src/subnets/uids.rs @@ -223,7 +223,7 @@ impl Pallet { emissions.sort_by_key(|(uid, _)| *uid); // Extract the final uids and emissions after trimming and sorting - let (trimmed_uids, trimmed_emissions): (Vec, Vec) = + let (trimmed_uids, trimmed_emissions): (Vec, Vec) = emissions.into_iter().unzip(); // Get all current arrays from storage @@ -393,11 +393,11 @@ impl Pallet { /// Returns the stake of the uid on network or 0 if it doesnt exist. /// - pub fn get_stake_for_uid_and_subnetwork(netuid: NetUid, neuron_uid: u16) -> AlphaCurrency { + pub fn get_stake_for_uid_and_subnetwork(netuid: NetUid, neuron_uid: u16) -> AlphaBalance { if let Ok(hotkey) = Self::get_hotkey_for_net_and_uid(netuid, neuron_uid) { Self::get_stake_for_hotkey_on_subnet(&hotkey, netuid) } else { - AlphaCurrency::ZERO + AlphaBalance::ZERO } } diff --git a/pallets/subtensor/src/swap/swap_coldkey.rs b/pallets/subtensor/src/swap/swap_coldkey.rs index 54b07d9dbf..401b5989ec 100644 --- a/pallets/subtensor/src/swap/swap_coldkey.rs +++ b/pallets/subtensor/src/swap/swap_coldkey.rs @@ -34,7 +34,7 @@ impl Pallet { // Transfer any remaining balance from old_coldkey to new_coldkey let remaining_balance = Self::get_coldkey_balance(old_coldkey); - if remaining_balance > 0 { + if remaining_balance > 0.into() { Self::kill_coldkey_account(old_coldkey, remaining_balance)?; Self::add_balance_to_coldkey_account(new_coldkey, remaining_balance); } @@ -49,7 +49,7 @@ impl Pallet { } /// 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 { + pub fn charge_swap_cost(coldkey: &T::AccountId, swap_cost: TaoBalance) -> DispatchResult { let burn_amount = Self::remove_balance_from_coldkey_account(coldkey, swap_cost.into()) .map_err(|_| Error::::NotEnoughBalanceToPaySwapColdKey)?; diff --git a/pallets/subtensor/src/swap/swap_hotkey.rs b/pallets/subtensor/src/swap/swap_hotkey.rs index a54a02a750..488778e33e 100644 --- a/pallets/subtensor/src/swap/swap_hotkey.rs +++ b/pallets/subtensor/src/swap/swap_hotkey.rs @@ -2,7 +2,7 @@ use super::*; use frame_support::weights::Weight; use sp_core::Get; use substrate_fixed::types::U64F64; -use subtensor_runtime_common::{Currency, MechId, NetUid}; +use subtensor_runtime_common::{MechId, NetUid, Token}; impl Pallet { /// Swaps the hotkey of a coldkey account. @@ -13,6 +13,7 @@ impl Pallet { /// * `old_hotkey` - The old hotkey to be swapped. /// * `new_hotkey` - The new hotkey to replace the old one. /// * `netuid` - The hotkey swap in a subnet or all subnets. + /// * `keep_stake` - If `true`, stake remains on the old hotkey and the rest metadata /// /// # Returns /// @@ -30,6 +31,7 @@ impl Pallet { old_hotkey: &T::AccountId, new_hotkey: &T::AccountId, netuid: Option, + keep_stake: bool, ) -> DispatchResultWithPostInfo { // 1. Ensure the origin is signed and get the coldkey let coldkey = ensure_signed(origin)?; @@ -57,11 +59,22 @@ impl Pallet { weight.saturating_accrue(T::DbWeight::get().reads(2)); - // 7. Ensure the new hotkey is not already registered on any network - ensure!( - !Self::is_hotkey_registered_on_any_network(new_hotkey), - Error::::HotKeyAlreadyRegisteredInSubNet - ); + match netuid { + // 7. Ensure the hotkey is not registered on the network before, if netuid is provided + Some(netuid) => { + ensure!( + !Self::is_hotkey_registered_on_specific_network(new_hotkey, netuid), + Error::::HotKeyAlreadyRegisteredInSubNet + ); + } + // 7.1 Ensure the new hotkey is not already registered on any network, only if netuid is none + None => { + ensure!( + !Self::is_hotkey_registered_on_any_network(new_hotkey), + Error::::HotKeyAlreadyRegisteredInSubNet + ); + } + } // 8. Swap LastTxBlock let last_tx_block: u64 = Self::get_last_tx_block(old_hotkey); @@ -80,7 +93,9 @@ impl Pallet { // 11. fork for swap hotkey on a specific subnet case after do the common check if let Some(netuid) = netuid { - return Self::swap_hotkey_on_subnet(&coldkey, old_hotkey, new_hotkey, netuid, weight); + return Self::swap_hotkey_on_subnet( + &coldkey, old_hotkey, new_hotkey, netuid, weight, keep_stake, + ); }; // Start to do everything for swap hotkey on all subnets case @@ -105,7 +120,13 @@ impl Pallet { weight.saturating_accrue(T::DbWeight::get().reads_writes(0, 2)); // 19. Perform the hotkey swap - Self::perform_hotkey_swap_on_all_subnets(old_hotkey, new_hotkey, &coldkey, &mut weight)?; + Self::perform_hotkey_swap_on_all_subnets( + old_hotkey, + new_hotkey, + &coldkey, + &mut weight, + keep_stake, + )?; // 20. Update the last transaction block for the coldkey Self::set_last_tx_block(&coldkey, block); @@ -160,6 +181,7 @@ impl Pallet { new_hotkey: &T::AccountId, coldkey: &T::AccountId, weight: &mut Weight, + keep_stake: bool, ) -> DispatchResult { // 1. keep the old hotkey alpha values for the case where hotkey staked by multiple coldkeys. let old_alpha_values: Vec<((T::AccountId, NetUid), U64F64)> = @@ -188,7 +210,9 @@ impl Pallet { // 5. execute the hotkey swap on all subnets for netuid in Self::get_all_subnet_netuids() { - Self::perform_hotkey_swap_on_one_subnet(old_hotkey, new_hotkey, weight, netuid)?; + Self::perform_hotkey_swap_on_one_subnet( + old_hotkey, new_hotkey, weight, netuid, keep_stake, + )?; } // 6. Swap LastTxBlock @@ -217,18 +241,20 @@ impl Pallet { // 10. Alpha already update in perform_hotkey_swap_on_one_subnet // Update the StakingHotkeys for the case where hotkey staked by multiple coldkeys. - for ((coldkey, _netuid), _alpha) in old_alpha_values { - // Swap StakingHotkeys. - // StakingHotkeys( coldkey ) --> Vec -- the hotkeys that the coldkey stakes. - let mut staking_hotkeys = StakingHotkeys::::get(&coldkey); - weight.saturating_accrue(T::DbWeight::get().reads(1)); - if staking_hotkeys.contains(old_hotkey) { - staking_hotkeys.retain(|hk| *hk != *old_hotkey && *hk != *new_hotkey); - if !staking_hotkeys.contains(new_hotkey) { - staking_hotkeys.push(new_hotkey.clone()); + if !keep_stake { + for ((coldkey, _netuid), _alpha) in old_alpha_values { + // Swap StakingHotkeys. + // StakingHotkeys( coldkey ) --> Vec -- the hotkeys that the coldkey stakes. + let mut staking_hotkeys = StakingHotkeys::::get(&coldkey); + weight.saturating_accrue(T::DbWeight::get().reads(1)); + if staking_hotkeys.contains(old_hotkey) { + staking_hotkeys.retain(|hk| *hk != *old_hotkey && *hk != *new_hotkey); + if !staking_hotkeys.contains(new_hotkey) { + staking_hotkeys.push(new_hotkey.clone()); + } + StakingHotkeys::::insert(&coldkey, staking_hotkeys); + weight.saturating_accrue(T::DbWeight::get().writes(1)); } - StakingHotkeys::::insert(&coldkey, staking_hotkeys); - weight.saturating_accrue(T::DbWeight::get().writes(1)); } } @@ -242,6 +268,7 @@ impl Pallet { new_hotkey: &T::AccountId, netuid: NetUid, init_weight: Weight, + keep_stake: bool, ) -> DispatchResultWithPostInfo { // 1. Ensure coldkey not swap hotkey too frequently let mut weight: Weight = init_weight; @@ -299,7 +326,13 @@ impl Pallet { } // 9. Perform the hotkey swap - Self::perform_hotkey_swap_on_one_subnet(old_hotkey, new_hotkey, &mut weight, netuid)?; + Self::perform_hotkey_swap_on_one_subnet( + old_hotkey, + new_hotkey, + &mut weight, + netuid, + keep_stake, + )?; // 10. Update the last transaction block for the coldkey Self::set_last_tx_block(coldkey, block); @@ -323,24 +356,27 @@ impl Pallet { new_hotkey: &T::AccountId, weight: &mut Weight, netuid: NetUid, + keep_stake: bool, ) -> DispatchResult { // 1. Swap total hotkey alpha for all subnets it exists on. // TotalHotkeyAlpha( hotkey, netuid ) -> alpha -- the total alpha that the hotkey has on a specific subnet. - let alpha = TotalHotkeyAlpha::::take(old_hotkey, netuid); + // Only transfer stake when keep_stake is false. + if !keep_stake { + let alpha = TotalHotkeyAlpha::::take(old_hotkey, netuid); - TotalHotkeyAlpha::::mutate(new_hotkey, netuid, |value| { - *value = value.saturating_add(alpha) - }); - weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); + TotalHotkeyAlpha::::mutate(new_hotkey, netuid, |value| { + *value = value.saturating_add(alpha) + }); + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); - // 2. Swap total hotkey shares on all subnets it exists on. - // TotalHotkeyShares( hotkey, netuid ) -> alpha -- the total alpha that the hotkey has on a specific subnet. - let share = TotalHotkeyShares::::take(old_hotkey, netuid); - // TotalHotkeyAlpha::::remove(old_hotkey, netuid); - TotalHotkeyShares::::mutate(new_hotkey, netuid, |value| { - *value = value.saturating_add(share) - }); - weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); + // 2. Swap total hotkey shares on all subnets it exists on. + // TotalHotkeyShares( hotkey, netuid ) -> alpha -- the total alpha that the hotkey has on a specific subnet. + let share = TotalHotkeyShares::::take(old_hotkey, netuid); + TotalHotkeyShares::::mutate(new_hotkey, netuid, |value| { + *value = value.saturating_add(share) + }); + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); + } // 3. Swap all subnet specific info. @@ -424,6 +460,7 @@ impl Pallet { NeuronCertificates::::insert(netuid, new_hotkey, old_neuron_certificates); weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); } + // 4. Swap ChildKeys. // 5. Swap ParentKeys. // 6. Swap PendingChildKeys. @@ -469,69 +506,71 @@ impl Pallet { } // 8. Swap dividend records - // 8.1 Swap TotalHotkeyAlphaLastEpoch - let old_alpha = TotalHotkeyAlphaLastEpoch::::take(old_hotkey, netuid); - let new_total_hotkey_alpha = TotalHotkeyAlphaLastEpoch::::get(new_hotkey, netuid); - TotalHotkeyAlphaLastEpoch::::insert( - new_hotkey, - netuid, - old_alpha.saturating_add(new_total_hotkey_alpha), - ); - weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2)); - - // 8.2 Swap AlphaDividendsPerSubnet - let old_hotkey_alpha_dividends = AlphaDividendsPerSubnet::::get(netuid, old_hotkey); - let new_hotkey_alpha_dividends = AlphaDividendsPerSubnet::::get(netuid, new_hotkey); - AlphaDividendsPerSubnet::::remove(netuid, old_hotkey); - AlphaDividendsPerSubnet::::insert( - netuid, - new_hotkey, - old_hotkey_alpha_dividends.saturating_add(new_hotkey_alpha_dividends), - ); - weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2)); - - // 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)> = - Alpha::::iter_prefix((old_hotkey,)).collect(); - weight.saturating_accrue(T::DbWeight::get().reads(old_alpha_values.len() as u64)); - weight.saturating_accrue(T::DbWeight::get().writes(old_alpha_values.len() as u64)); + if !keep_stake { + // 8.1 Swap TotalHotkeyAlphaLastEpoch + let old_alpha = TotalHotkeyAlphaLastEpoch::::take(old_hotkey, netuid); + let new_total_hotkey_alpha = TotalHotkeyAlphaLastEpoch::::get(new_hotkey, netuid); + TotalHotkeyAlphaLastEpoch::::insert( + new_hotkey, + netuid, + old_alpha.saturating_add(new_total_hotkey_alpha), + ); + weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2)); - // 9.1. Transfer root claimable + // 8.2 Swap AlphaDividendsPerSubnet + let old_hotkey_alpha_dividends = AlphaDividendsPerSubnet::::get(netuid, old_hotkey); + let new_hotkey_alpha_dividends = AlphaDividendsPerSubnet::::get(netuid, new_hotkey); + AlphaDividendsPerSubnet::::remove(netuid, old_hotkey); + AlphaDividendsPerSubnet::::insert( + netuid, + new_hotkey, + old_hotkey_alpha_dividends.saturating_add(new_hotkey_alpha_dividends), + ); + weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2)); - Self::transfer_root_claimable_for_new_hotkey(old_hotkey, new_hotkey); + // 8.3 Swap TaoDividendsPerSubnet + // Tao dividends were removed - // 9.2. Insert the new alpha values. - for ((coldkey, netuid_alpha), alpha) in old_alpha_values { - if netuid == netuid_alpha { - Self::transfer_root_claimed_for_new_keys( - netuid, old_hotkey, new_hotkey, &coldkey, &coldkey, - ); + // 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)); - let new_alpha = Alpha::::take((new_hotkey, &coldkey, netuid)); - Alpha::::remove((old_hotkey, &coldkey, netuid)); - Alpha::::insert( - (new_hotkey, &coldkey, netuid), - alpha.saturating_add(new_alpha), - ); - weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); + // 9. Swap Alpha + // Alpha( hotkey, coldkey, netuid ) -> alpha + let old_alpha_values: Vec<((T::AccountId, NetUid), U64F64)> = + Alpha::::iter_prefix((old_hotkey,)).collect(); + weight.saturating_accrue(T::DbWeight::get().reads(old_alpha_values.len() as u64)); + weight.saturating_accrue(T::DbWeight::get().writes(old_alpha_values.len() as u64)); + + // 9.1. Transfer root claimable + Self::transfer_root_claimable_for_new_hotkey(old_hotkey, new_hotkey); + + // 9.2. Insert the new alpha values. + for ((coldkey, netuid_alpha), alpha) in old_alpha_values { + if netuid == netuid_alpha { + Self::transfer_root_claimed_for_new_keys( + netuid, old_hotkey, new_hotkey, &coldkey, &coldkey, + ); + + let new_alpha = Alpha::::take((new_hotkey, &coldkey, netuid)); + Alpha::::remove((old_hotkey, &coldkey, netuid)); + Alpha::::insert( + (new_hotkey, &coldkey, netuid), + alpha.saturating_add(new_alpha), + ); + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); - // Swap StakingHotkeys. - // StakingHotkeys( coldkey ) --> Vec -- the hotkeys that the coldkey stakes. - let mut staking_hotkeys = StakingHotkeys::::get(&coldkey); - weight.saturating_accrue(T::DbWeight::get().reads(1)); - if staking_hotkeys.contains(old_hotkey) && !staking_hotkeys.contains(new_hotkey) { - staking_hotkeys.push(new_hotkey.clone()); - StakingHotkeys::::insert(&coldkey, staking_hotkeys); - weight.saturating_accrue(T::DbWeight::get().writes(1)); + // Swap StakingHotkeys. + // StakingHotkeys( coldkey ) --> Vec -- the hotkeys that the coldkey stakes. + let mut staking_hotkeys = StakingHotkeys::::get(&coldkey); + weight.saturating_accrue(T::DbWeight::get().reads(1)); + if staking_hotkeys.contains(old_hotkey) && !staking_hotkeys.contains(new_hotkey) + { + staking_hotkeys.push(new_hotkey.clone()); + StakingHotkeys::::insert(&coldkey, staking_hotkeys); + weight.saturating_accrue(T::DbWeight::get().writes(1)); + } } } } diff --git a/pallets/subtensor/src/tests/batch_tx.rs b/pallets/subtensor/src/tests/batch_tx.rs index 33148e7eb5..07f63c9933 100644 --- a/pallets/subtensor/src/tests/batch_tx.rs +++ b/pallets/subtensor/src/tests/batch_tx.rs @@ -24,17 +24,17 @@ fn test_batch_txs() { vec![ RuntimeCall::Balances(BalanceCall::transfer_allow_death { dest: bob, - value: 1_000_000_000 + value: 1_000_000_000.into() }), RuntimeCall::Balances(BalanceCall::transfer_allow_death { dest: charlie, - value: 1_000_000_000 + value: 1_000_000_000.into() }) ] )); - assert_eq!(Balances::total_balance(&alice), 6_000_000_000); - assert_eq!(Balances::total_balance(&bob), 2_000_000_000); - assert_eq!(Balances::total_balance(&charlie), 2_000_000_000); + assert_eq!(Balances::total_balance(&alice), 6_000_000_000_u64.into()); + assert_eq!(Balances::total_balance(&bob), 2_000_000_000_u64.into()); + assert_eq!(Balances::total_balance(&charlie), 2_000_000_000_u64.into()); }); } @@ -48,12 +48,12 @@ fn test_cant_nest_batch_txs() { calls: vec![ RuntimeCall::Balances(BalanceCall::transfer_allow_death { dest: bob, - value: 1_000_000_000, + value: 1_000_000_000.into(), }), RuntimeCall::Utility(pallet_utility::Call::batch { calls: vec![RuntimeCall::Balances(BalanceCall::transfer_allow_death { dest: charlie, - value: 1_000_000_000, + value: 1_000_000_000.into(), })], }), ], @@ -71,7 +71,7 @@ fn test_can_batch_txs() { let call = RuntimeCall::Utility(pallet_utility::Call::batch { calls: vec![RuntimeCall::Balances(BalanceCall::transfer_allow_death { dest: bob, - value: 1_000_000_000, + value: 1_000_000_000.into(), })], }); @@ -88,7 +88,7 @@ fn test_cant_nest_batch_diff_batch_txs() { calls: vec![RuntimeCall::Utility(pallet_utility::Call::force_batch { calls: vec![RuntimeCall::Balances(BalanceCall::transfer_allow_death { dest: charlie, - value: 1_000_000_000, + value: 1_000_000_000.into(), })], })], }); @@ -99,7 +99,7 @@ fn test_cant_nest_batch_diff_batch_txs() { calls: vec![RuntimeCall::Utility(pallet_utility::Call::batch { calls: vec![RuntimeCall::Balances(BalanceCall::transfer_allow_death { dest: charlie, - value: 1_000_000_000, + value: 1_000_000_000.into(), })], })], }); @@ -110,7 +110,7 @@ fn test_cant_nest_batch_diff_batch_txs() { calls: vec![RuntimeCall::Utility(pallet_utility::Call::batch_all { calls: vec![RuntimeCall::Balances(BalanceCall::transfer_allow_death { dest: charlie, - value: 1_000_000_000, + value: 1_000_000_000.into(), })], })], }); diff --git a/pallets/subtensor/src/tests/children.rs b/pallets/subtensor/src/tests/children.rs index e8be57f021..1558c4cb6c 100644 --- a/pallets/subtensor/src/tests/children.rs +++ b/pallets/subtensor/src/tests/children.rs @@ -6,7 +6,7 @@ use super::mock::*; use approx::assert_abs_diff_eq; use frame_support::{assert_err, assert_noop, assert_ok}; use substrate_fixed::types::{I64F64, I96F32, U96F32}; -use subtensor_runtime_common::{AlphaCurrency, NetUidStorageIndex, TaoCurrency}; +use subtensor_runtime_common::{AlphaBalance, NetUidStorageIndex, TaoBalance}; use subtensor_swap_interface::SwapHandler; use crate::{utils::rate_limiting::TransactionType, *}; @@ -1468,7 +1468,7 @@ fn test_children_stake_values() { &hotkey, &coldkey, netuid, - 100_000_000_000_000.into(), + 100_000_000_000_000_u64.into(), ); // Set multiple children with proportions. @@ -1484,26 +1484,26 @@ fn test_children_stake_values() { assert_eq!( SubtensorModule::get_inherited_for_hotkey_on_subnet(&hotkey, netuid), - 25_000_000_069_849.into() + 25_000_000_069_849_u64.into() ); assert_eq!( SubtensorModule::get_inherited_for_hotkey_on_subnet(&child1, netuid), - 24_999_999_976_716.into() + 24_999_999_976_716_u64.into() ); assert_eq!( SubtensorModule::get_inherited_for_hotkey_on_subnet(&child2, netuid), - 24_999_999_976_716.into() + 24_999_999_976_716_u64.into() ); assert_eq!( SubtensorModule::get_inherited_for_hotkey_on_subnet(&child3, netuid), - 24_999_999_976_716.into() + 24_999_999_976_716_u64.into() ); assert_eq!( SubtensorModule::get_inherited_for_hotkey_on_subnet(&child3, netuid) + SubtensorModule::get_inherited_for_hotkey_on_subnet(&child2, netuid) + SubtensorModule::get_inherited_for_hotkey_on_subnet(&child1, netuid) + SubtensorModule::get_inherited_for_hotkey_on_subnet(&hotkey, netuid), - 99999999999997.into() + 99999999999997_u64.into() ); }); } @@ -1895,7 +1895,7 @@ fn test_get_stake_for_hotkey_on_subnet_edge_cases() { register_ok_neuron(netuid, child2, coldkey, 0); // Set above old value of network max stake - let network_max_stake = 600_000_000_000_000.into(); + let network_max_stake = 600_000_000_000_000_u64.into(); // Increase stake to the network max SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( @@ -2233,9 +2233,9 @@ fn test_do_remove_stake_clears_pending_childkeys() { // Add network and register hotkey add_network(netuid, 13, 0); register_ok_neuron(netuid, hotkey, coldkey, 0); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, 10_000_000_000_000); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, 10_000_000_000_000_u64.into()); - let reserve = 1_000_000_000_000_000; + let reserve = 1_000_000_000_000_000_u64; mock::setup_reserves(netuid, reserve.into(), reserve.into()); // Set non-default value for childkey stake threshold @@ -2447,7 +2447,7 @@ fn test_revoke_child_no_min_stake_check() { add_network(netuid, 13, 0); register_ok_neuron(netuid, parent, coldkey, 0); - let reserve = 1_000_000_000_000_000; + let reserve = 1_000_000_000_000_000_u64; mock::setup_reserves(netuid, reserve.into(), reserve.into()); mock::setup_reserves(NetUid::ROOT, reserve.into(), reserve.into()); @@ -2520,7 +2520,7 @@ fn test_do_set_child_registration_disabled() { add_network(netuid, 13, 0); register_ok_neuron(netuid, parent, coldkey, 0); - let reserve = 1_000_000_000_000_000; + let reserve = 1_000_000_000_000_000_u64; mock::setup_reserves(netuid, reserve.into(), reserve.into()); // Set minimum stake for setting children @@ -2639,12 +2639,16 @@ fn test_childkey_set_weights_single_parent() { let coldkey_child: U256 = U256::from(101); let coldkey_weight_setter: U256 = U256::from(102); - let stake_to_give_child = 109_999; + let balance_to_give_child = TaoBalance::from(109_999); + let stake_to_give_child = AlphaBalance::from(109_999); // Register parent with minimal stake and child with high stake - SubtensorModule::add_balance_to_coldkey_account(&coldkey_parent, 1); - SubtensorModule::add_balance_to_coldkey_account(&coldkey_child, stake_to_give_child + 10); - SubtensorModule::add_balance_to_coldkey_account(&coldkey_weight_setter, 1_000_000); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_parent, 1.into()); + SubtensorModule::add_balance_to_coldkey_account( + &coldkey_child, + balance_to_give_child + 10.into(), + ); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_weight_setter, 1_000_000.into()); // Add neurons for parent, child and weight_setter register_ok_neuron(netuid, parent, coldkey_parent, 1); @@ -2655,7 +2659,7 @@ fn test_childkey_set_weights_single_parent() { &parent, &coldkey_parent, netuid, - stake_to_give_child.into(), + stake_to_give_child, ); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &weight_setter, @@ -2684,7 +2688,7 @@ fn test_childkey_set_weights_single_parent() { )); // Set the min stake very high - SubtensorModule::set_stake_threshold(stake_to_give_child * 5); + SubtensorModule::set_stake_threshold(u64::from(stake_to_give_child) * 5); // Check the child has less stake than required assert!( @@ -2707,7 +2711,7 @@ fn test_childkey_set_weights_single_parent() { assert!(!SubtensorModule::check_weights_min_stake(&child, netuid)); // Set a minimum stake to set weights - SubtensorModule::set_stake_threshold(stake_to_give_child - 5); + SubtensorModule::set_stake_threshold(u64::from(stake_to_give_child) - 5); // Check if the stake for the child is above assert!( @@ -2744,9 +2748,13 @@ fn test_set_weights_no_parent() { let coldkey: U256 = U256::from(101); let spare_ck = U256::from(102); - let stake_to_give_child = 109_999; + let balance_to_give_child = TaoBalance::from(109_999); + let stake_to_give_child = AlphaBalance::from(109_999); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, stake_to_give_child + 10); + SubtensorModule::add_balance_to_coldkey_account( + &coldkey, + balance_to_give_child + 10.into(), + ); // Is registered register_ok_neuron(netuid, hotkey, coldkey, 1); @@ -2757,7 +2765,7 @@ fn test_set_weights_no_parent() { &hotkey, &coldkey, netuid, - stake_to_give_child.into(), + stake_to_give_child, ); SubtensorModule::set_weights_set_rate_limit(netuid, 0); @@ -2845,7 +2853,7 @@ fn test_childkey_take_drain() { let nominator = U256::from(7); let netuid = NetUid::from(1); let subnet_tempo = 10; - let stake = 100_000_000_000; + let stake = 100_000_000_000_u64; let proportion: u64 = u64::MAX / 2; // Add network, register hotkeys, and setup network parameters @@ -2857,11 +2865,11 @@ fn test_childkey_take_drain() { register_ok_neuron(netuid, miner_hotkey, miner_coldkey, 1); SubtensorModule::add_balance_to_coldkey_account( &parent_coldkey, - stake + ExistentialDeposit::get(), + TaoBalance::from(stake) + ExistentialDeposit::get(), ); SubtensorModule::add_balance_to_coldkey_account( &nominator, - stake + ExistentialDeposit::get(), + TaoBalance::from(stake) + ExistentialDeposit::get(), ); SubtensorModule::set_weights_set_rate_limit(netuid, 0); SubtensorModule::set_max_allowed_validators(netuid, 2); @@ -2940,7 +2948,7 @@ fn test_childkey_take_drain() { SubtensorModule::get_total_stake_for_coldkey(&nominator) - nominator_stake_before; let total_emission = child_emission + parent_emission + nominator_emission; - assert_abs_diff_eq!(child_emission, TaoCurrency::ZERO, epsilon = 10.into()); + assert_abs_diff_eq!(child_emission, TaoBalance::ZERO, epsilon = 10.into()); assert_abs_diff_eq!( parent_emission, total_emission * 9.into() / 20.into(), @@ -2974,8 +2982,8 @@ fn test_parent_child_chain_emission() { Tempo::::insert(netuid, 1); // Setup large LPs to prevent slippage - SubnetTAO::::insert(netuid, TaoCurrency::from(1_000_000_000_000_000)); - SubnetAlphaIn::::insert(netuid, AlphaCurrency::from(1_000_000_000_000_000)); + SubnetTAO::::insert(netuid, TaoBalance::from(1_000_000_000_000_000_u64)); + SubnetAlphaIn::::insert(netuid, AlphaBalance::from(1_000_000_000_000_000_u64)); // Set owner cut to 0 SubtensorModule::set_subnet_owner_cut(0_u16); @@ -2994,9 +3002,9 @@ fn test_parent_child_chain_emission() { register_ok_neuron(netuid, hotkey_c, coldkey_c, 0); // Add initial stakes - SubtensorModule::add_balance_to_coldkey_account(&coldkey_a, 1_000); - SubtensorModule::add_balance_to_coldkey_account(&coldkey_b, 1_000); - SubtensorModule::add_balance_to_coldkey_account(&coldkey_c, 1_000); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_a, 1_000.into()); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_b, 1_000.into()); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_c, 1_000.into()); // Swap to alpha let stake_a = 300_000_000_000_u64; @@ -3090,13 +3098,13 @@ fn test_parent_child_chain_emission() { let emission = U96F32::from_num( SubtensorModule::get_block_emission() - .unwrap_or(TaoCurrency::ZERO) + .unwrap_or(TaoBalance::ZERO) .to_u64(), ); // Set pending emission to 0 - PendingValidatorEmission::::insert(netuid, AlphaCurrency::ZERO); - PendingServerEmission::::insert(netuid, AlphaCurrency::ZERO); + PendingValidatorEmission::::insert(netuid, AlphaBalance::ZERO); + PendingServerEmission::::insert(netuid, AlphaBalance::ZERO); // Run epoch with emission value SubtensorModule::run_coinbase(emission); @@ -3153,7 +3161,7 @@ fn test_parent_child_chain_emission() { ); let hotkeys = [hotkey_a, hotkey_b, hotkey_c]; - let mut total_stake_now = AlphaCurrency::ZERO; + let mut total_stake_now = AlphaBalance::ZERO; for (hotkey, netuid, stake) in TotalHotkeyAlpha::::iter() { if hotkeys.contains(&hotkey) { total_stake_now += stake; @@ -3202,11 +3210,15 @@ fn test_parent_child_chain_epoch() { register_ok_neuron(netuid, hotkey_c, coldkey_c, 0); // Add initial stakes - SubtensorModule::add_balance_to_coldkey_account(&coldkey_a, 1_000); - SubtensorModule::add_balance_to_coldkey_account(&coldkey_b, 1_000); - SubtensorModule::add_balance_to_coldkey_account(&coldkey_c, 1_000); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_a, 1_000.into()); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_b, 1_000.into()); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_c, 1_000.into()); - mock::setup_reserves(netuid, 1_000_000_000_000.into(), 1_000_000_000_000.into()); + mock::setup_reserves( + netuid, + 1_000_000_000_000_u64.into(), + 1_000_000_000_000_u64.into(), + ); // Swap to alpha let total_tao = I96F32::from_num(300_000 + 100_000 + 50_000); @@ -3332,8 +3344,8 @@ fn test_dividend_distribution_with_children() { SubtensorModule::set_ck_burn(0); mock::setup_reserves( netuid, - 1_000_000_000_000_000.into(), - 1_000_000_000_000_000.into(), + 1_000_000_000_000_000_u64.into(), + 1_000_000_000_000_000_u64.into(), ); // Set owner cut to 0 SubtensorModule::set_subnet_owner_cut(0_u16); @@ -3352,9 +3364,9 @@ fn test_dividend_distribution_with_children() { register_ok_neuron(netuid, hotkey_c, coldkey_c, 0); // Add initial stakes - SubtensorModule::add_balance_to_coldkey_account(&coldkey_a, 1_000); - SubtensorModule::add_balance_to_coldkey_account(&coldkey_b, 1_000); - SubtensorModule::add_balance_to_coldkey_account(&coldkey_c, 1_000); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_a, 1_000.into()); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_b, 1_000.into()); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_c, 1_000.into()); // Swap to alpha let total_tao = I96F32::from_num(300_000 + 100_000 + 50_000); @@ -3586,11 +3598,11 @@ fn test_dynamic_parent_child_relationships() { log::info!("child take 2: {chk_take_2:?}"); // Add initial stakes - SubtensorModule::add_balance_to_coldkey_account(&coldkey_parent, 500_000 + 1_000); - SubtensorModule::add_balance_to_coldkey_account(&coldkey_child1, 50_000 + 1_000); - SubtensorModule::add_balance_to_coldkey_account(&coldkey_child2, 30_000 + 1_000); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_parent, (500_000 + 1_000).into()); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_child1, (50_000 + 1_000).into()); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_child2, (30_000 + 1_000).into()); - let reserve = 1_000_000_000_000; + let reserve = 1_000_000_000_000_u64; mock::setup_reserves(netuid, reserve.into(), reserve.into()); // Swap to alpha @@ -3867,7 +3879,11 @@ fn test_dividend_distribution_with_children_same_coldkey_owner() { add_network(netuid, 1, 0); // Set SN owner cut to 0 SubtensorModule::set_subnet_owner_cut(0_u16); - mock::setup_reserves(netuid, 1_000_000_000_000.into(), 1_000_000_000_000.into()); + mock::setup_reserves( + netuid, + 1_000_000_000_000_u64.into(), + 1_000_000_000_000_u64.into(), + ); // Define hotkeys and coldkeys let hotkey_a: U256 = U256::from(1); @@ -3879,8 +3895,8 @@ fn test_dividend_distribution_with_children_same_coldkey_owner() { register_ok_neuron(netuid, hotkey_b, coldkey_a, 0); // Add initial stakes - SubtensorModule::add_balance_to_coldkey_account(&coldkey_a, 1_000); - SubtensorModule::add_balance_to_coldkey_account(&coldkey_a, 1_000); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_a, 1_000.into()); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_a, 1_000.into()); // Swap to alpha let total_tao = 300_000 + 100_000; diff --git a/pallets/subtensor/src/tests/claim_root.rs b/pallets/subtensor/src/tests/claim_root.rs index 6bcaee2fca..0f628d6b86 100644 --- a/pallets/subtensor/src/tests/claim_root.rs +++ b/pallets/subtensor/src/tests/claim_root.rs @@ -20,7 +20,7 @@ use sp_core::{H256, U256}; use sp_runtime::DispatchError; use std::collections::BTreeSet; use substrate_fixed::types::{I96F32, U64F64, U96F32}; -use subtensor_runtime_common::{AlphaCurrency, Currency, NetUid, TaoCurrency}; +use subtensor_runtime_common::{AlphaBalance, NetUid, TaoBalance, Token}; use subtensor_swap_interface::SwapHandler; #[test] @@ -75,10 +75,10 @@ fn test_claim_root_with_drain_emissions() { let pending_root_alpha = 1_000_000u64; SubtensorModule::distribute_emission( netuid, - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, pending_root_alpha.into(), - AlphaCurrency::ZERO, + AlphaBalance::ZERO, ); // Check new validator stake @@ -144,10 +144,10 @@ fn test_claim_root_with_drain_emissions() { SubtensorModule::distribute_emission( netuid, - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, pending_root_alpha.into(), - AlphaCurrency::ZERO, + AlphaBalance::ZERO, ); // Check claimable (round 2) @@ -246,10 +246,10 @@ fn test_claim_root_adding_stake_proportionally_for_two_stakers() { let pending_root_alpha = 10_000_000u64; SubtensorModule::distribute_emission( netuid, - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, pending_root_alpha.into(), - AlphaCurrency::ZERO, + AlphaBalance::ZERO, ); assert_ok!(SubtensorModule::claim_root( @@ -348,10 +348,10 @@ fn test_claim_root_adding_stake_disproportionally_for_two_stakers() { let pending_root_alpha = 10_000_000u64; SubtensorModule::distribute_emission( netuid, - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, pending_root_alpha.into(), - AlphaCurrency::ZERO, + AlphaBalance::ZERO, ); assert_ok!(SubtensorModule::claim_root( @@ -440,10 +440,10 @@ fn test_claim_root_with_changed_stake() { let pending_root_alpha = 10_000_000u64; SubtensorModule::distribute_emission( netuid, - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, pending_root_alpha.into(), - AlphaCurrency::ZERO, + AlphaBalance::ZERO, ); assert_ok!(SubtensorModule::claim_root( @@ -493,10 +493,10 @@ fn test_claim_root_with_changed_stake() { let pending_root_alpha = 10_000_000u64; SubtensorModule::distribute_emission( netuid, - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, pending_root_alpha.into(), - AlphaCurrency::ZERO, + AlphaBalance::ZERO, ); assert_ok!(SubtensorModule::claim_root( @@ -547,10 +547,10 @@ fn test_claim_root_with_changed_stake() { let pending_root_alpha = 10_000_000u64; SubtensorModule::distribute_emission( netuid, - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, pending_root_alpha.into(), - AlphaCurrency::ZERO, + AlphaBalance::ZERO, ); assert_ok!(SubtensorModule::claim_root( @@ -600,8 +600,8 @@ fn test_claim_root_with_drain_emissions_and_swap_claim_type() { SubtensorModule::set_tao_weight(u64::MAX); // Set TAO weight to 1.0 SubnetMechanism::::insert(netuid, 1); - let tao_reserve = TaoCurrency::from(50_000_000_000); - let alpha_in = AlphaCurrency::from(100_000_000_000); + let tao_reserve = TaoBalance::from(50_000_000_000_u64); + let alpha_in = AlphaBalance::from(100_000_000_000_u64); SubnetTAO::::insert(netuid, tao_reserve); SubnetAlphaIn::::insert(netuid, alpha_in); let current_price = @@ -637,10 +637,10 @@ fn test_claim_root_with_drain_emissions_and_swap_claim_type() { let pending_root_alpha = 10_000_000u64; SubtensorModule::distribute_emission( netuid, - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, pending_root_alpha.into(), - AlphaCurrency::ZERO, + AlphaBalance::ZERO, ); // Claim root alpha @@ -682,10 +682,10 @@ fn test_claim_root_with_drain_emissions_and_swap_claim_type() { SubtensorModule::distribute_emission( netuid, - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, pending_root_alpha.into(), - AlphaCurrency::ZERO, + AlphaBalance::ZERO, ); assert_ok!(SubtensorModule::claim_root( @@ -719,10 +719,10 @@ fn test_claim_root_with_drain_emissions_and_swap_claim_type() { SubtensorModule::distribute_emission( netuid, - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, pending_root_alpha.into(), - AlphaCurrency::ZERO, + AlphaBalance::ZERO, ); assert_ok!(SubtensorModule::claim_root( @@ -770,7 +770,7 @@ fn test_claim_root_with_run_coinbase() { SubtensorModule::set_tao_weight(u64::MAX); // Set TAO weight to 1.0 let root_stake = 200_000_000u64; - SubnetTAO::::insert(NetUid::ROOT, TaoCurrency::from(root_stake)); + SubnetTAO::::insert(NetUid::ROOT, TaoBalance::from(root_stake)); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &hotkey, @@ -888,7 +888,7 @@ fn test_claim_root_with_block_emissions() { SubtensorModule::set_tao_weight(u64::MAX); // Set TAO weight to 1.0 let root_stake = 200_000_000u64; - SubnetTAO::::insert(NetUid::ROOT, TaoCurrency::from(root_stake)); + SubnetTAO::::insert(NetUid::ROOT, TaoBalance::from(root_stake)); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &hotkey, @@ -1003,7 +1003,7 @@ fn test_claim_root_coinbase_distribution() { let root_stake = 200_000_000u64; let initial_tao = 200_000_000u64; - SubnetTAO::::insert(NetUid::ROOT, TaoCurrency::from(initial_tao)); + SubnetTAO::::insert(NetUid::ROOT, TaoBalance::from(initial_tao)); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &hotkey, @@ -1021,7 +1021,7 @@ fn test_claim_root_coinbase_distribution() { ); let initial_alpha_issuance = SubtensorModule::get_alpha_issuance(netuid); - let alpha_emissions: AlphaCurrency = 1_000_000_000u64.into(); + let alpha_emissions: AlphaBalance = 1_000_000_000u64.into(); // Set moving price > 1.0 and price > 1.0 // So we turn ON root sell @@ -1148,10 +1148,10 @@ fn test_claim_root_with_swap_coldkey() { let pending_root_alpha = 1_000_000u64; SubtensorModule::distribute_emission( netuid, - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, pending_root_alpha.into(), - AlphaCurrency::ZERO, + AlphaBalance::ZERO, ); // Claim root alpha @@ -1233,10 +1233,10 @@ fn test_claim_root_with_swap_hotkey() { let pending_root_alpha = 1_000_000u64; SubtensorModule::distribute_emission( netuid, - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, pending_root_alpha.into(), - AlphaCurrency::ZERO, + AlphaBalance::ZERO, ); // Claim root alpha @@ -1280,7 +1280,8 @@ fn test_claim_root_with_swap_hotkey() { &hotkey, &new_hotkey, &mut weight, - netuid + netuid, + false, )); // Check swapped keys claimed values @@ -1314,8 +1315,8 @@ fn test_claim_root_on_network_deregistration() { SubtensorModule::set_tao_weight(u64::MAX); // Set TAO weight to 1.0 SubnetMechanism::::insert(netuid, 1); - let tao_reserve = TaoCurrency::from(50_000_000_000); - let alpha_in = AlphaCurrency::from(100_000_000_000); + let tao_reserve = TaoBalance::from(50_000_000_000_u64); + let alpha_in = AlphaBalance::from(100_000_000_000_u64); SubnetTAO::::insert(netuid, tao_reserve); SubnetAlphaIn::::insert(netuid, alpha_in); let current_price = @@ -1350,10 +1351,10 @@ fn test_claim_root_on_network_deregistration() { let pending_root_alpha = 10_000_000u64; SubtensorModule::distribute_emission( netuid, - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, pending_root_alpha.into(), - AlphaCurrency::ZERO, + AlphaBalance::ZERO, ); assert_ok!(SubtensorModule::claim_root( @@ -1491,10 +1492,10 @@ fn test_claim_root_with_unrelated_subnets() { let pending_root_alpha = 1_000_000u64; SubtensorModule::distribute_emission( netuid, - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, pending_root_alpha.into(), - AlphaCurrency::ZERO, + AlphaBalance::ZERO, ); // Claim root alpha @@ -1562,8 +1563,8 @@ fn test_claim_root_fill_root_alpha_dividends_per_subnet() { SubtensorModule::set_tao_weight(u64::MAX); // Set TAO weight to 1.0 SubnetMechanism::::insert(netuid, 1); - let tao_reserve = TaoCurrency::from(50_000_000_000); - let alpha_in = AlphaCurrency::from(100_000_000_000); + let tao_reserve = TaoBalance::from(50_000_000_000_u64); + let alpha_in = AlphaBalance::from(100_000_000_000_u64); SubnetTAO::::insert(netuid, tao_reserve); SubnetAlphaIn::::insert(netuid, alpha_in); @@ -1597,10 +1598,10 @@ fn test_claim_root_fill_root_alpha_dividends_per_subnet() { let pending_root_alpha = 10_000_000u64; SubtensorModule::distribute_emission( netuid, - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, pending_root_alpha.into(), - AlphaCurrency::ZERO, + AlphaBalance::ZERO, ); // Check RootAlphaDividendsPerSubnet value @@ -1618,10 +1619,10 @@ fn test_claim_root_fill_root_alpha_dividends_per_subnet() { SubtensorModule::distribute_emission( netuid, - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, pending_root_alpha.into(), - AlphaCurrency::ZERO, + AlphaBalance::ZERO, ); let root_claim_dividends2 = RootAlphaDividendsPerSubnet::::get(netuid, hotkey); @@ -1669,10 +1670,10 @@ fn test_claim_root_with_keep_subnets() { let pending_root_alpha = 1_000_000u64; SubtensorModule::distribute_emission( netuid, - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, pending_root_alpha.into(), - AlphaCurrency::ZERO, + AlphaBalance::ZERO, ); let claimable = *RootClaimable::::get(hotkey) @@ -1728,8 +1729,8 @@ fn test_claim_root_keep_subnets_swap_claim_type() { SubtensorModule::set_tao_weight(u64::MAX); // Set TAO weight to 1.0 SubnetMechanism::::insert(netuid, 1); - let tao_reserve = TaoCurrency::from(50_000_000_000); - let alpha_in = AlphaCurrency::from(100_000_000_000); + let tao_reserve = TaoBalance::from(50_000_000_000_u64); + let alpha_in = AlphaBalance::from(100_000_000_000_u64); SubnetTAO::::insert(netuid, tao_reserve); SubnetAlphaIn::::insert(netuid, alpha_in); let current_price = @@ -1765,10 +1766,10 @@ fn test_claim_root_keep_subnets_swap_claim_type() { let pending_root_alpha = 10_000_000u64; SubtensorModule::distribute_emission( netuid, - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, pending_root_alpha.into(), - AlphaCurrency::ZERO, + AlphaBalance::ZERO, ); // Claim root alpha @@ -1877,10 +1878,10 @@ fn test_claim_root_with_moved_stake() { let pending_root_alpha = 10_000_000u64; SubtensorModule::distribute_emission( netuid, - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, pending_root_alpha.into(), - AlphaCurrency::ZERO, + AlphaBalance::ZERO, ); assert_ok!(SubtensorModule::claim_root( @@ -1920,10 +1921,10 @@ fn test_claim_root_with_moved_stake() { let pending_root_alpha = 10_000_000u64; SubtensorModule::distribute_emission( netuid, - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, pending_root_alpha.into(), - AlphaCurrency::ZERO, + AlphaBalance::ZERO, ); // Transfer stake to other coldkey @@ -2011,10 +2012,10 @@ fn test_claim_root_with_moved_stake() { let pending_root_alpha = 10_000_000u64; SubtensorModule::distribute_emission( netuid, - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, pending_root_alpha.into(), - AlphaCurrency::ZERO, + AlphaBalance::ZERO, ); assert_ok!(SubtensorModule::claim_root( diff --git a/pallets/subtensor/src/tests/coinbase.rs b/pallets/subtensor/src/tests/coinbase.rs index 093444e955..a11cf317ff 100644 --- a/pallets/subtensor/src/tests/coinbase.rs +++ b/pallets/subtensor/src/tests/coinbase.rs @@ -18,7 +18,7 @@ use substrate_fixed::{ transcendental::sqrt, types::{I64F64, I96F32, U64F64, U96F32}, }; -use subtensor_runtime_common::{AlphaCurrency, NetUidStorageIndex}; +use subtensor_runtime_common::{AlphaBalance, NetUidStorageIndex}; use subtensor_swap_interface::{SwapEngine, SwapHandler}; #[allow(clippy::arithmetic_side_effects)] @@ -64,7 +64,7 @@ fn test_coinbase_basecase() { #[test] fn test_coinbase_tao_issuance_base() { new_test_ext(1).execute_with(|| { - let emission = TaoCurrency::from(1_234_567); + let emission = TaoBalance::from(1_234_567); let subnet_owner_ck = U256::from(1001); let subnet_owner_hk = U256::from(1002); let netuid = add_dynamic_network(&subnet_owner_hk, &subnet_owner_ck); @@ -88,9 +88,9 @@ fn test_coinbase_tao_issuance_base() { fn test_coinbase_tao_issuance_base_low() { new_test_ext(1).execute_with(|| { let netuid = NetUid::from(1); - let emission = TaoCurrency::from(1); + let emission = TaoBalance::from(1); add_network(netuid, 1, 0); - assert_eq!(SubnetTAO::::get(netuid), TaoCurrency::ZERO); + assert_eq!(SubnetTAO::::get(netuid), TaoBalance::ZERO); // Set subnet flow to non-zero SubnetTaoFlow::::insert(netuid, 33433_i64); SubtensorModule::run_coinbase(U96F32::from_num(emission)); @@ -104,11 +104,11 @@ fn test_coinbase_tao_issuance_base_low() { // #[test] // fn test_coinbase_tao_issuance_base_low_flow() { // new_test_ext(1).execute_with(|| { -// let emission = TaoCurrency::from(1_234_567); +// let emission = TaoBalance::from(1_234_567); // let subnet_owner_ck = U256::from(1001); // let subnet_owner_hk = U256::from(1002); // let netuid = add_dynamic_network(&subnet_owner_hk, &subnet_owner_ck); -// let emission = TaoCurrency::from(1); +// let emission = TaoBalance::from(1); // // 100% tao flow method // let block_num = FlowHalfLife::::get(); @@ -137,13 +137,13 @@ fn test_coinbase_tao_issuance_multiple() { let netuid1 = NetUid::from(1); let netuid2 = NetUid::from(2); let netuid3 = NetUid::from(3); - let emission = TaoCurrency::from(3_333_333); + let emission = TaoBalance::from(3_333_333); add_network(netuid1, 1, 0); add_network(netuid2, 1, 0); add_network(netuid3, 1, 0); - assert_eq!(SubnetTAO::::get(netuid1), TaoCurrency::ZERO); - assert_eq!(SubnetTAO::::get(netuid2), TaoCurrency::ZERO); - assert_eq!(SubnetTAO::::get(netuid3), TaoCurrency::ZERO); + assert_eq!(SubnetTAO::::get(netuid1), TaoBalance::ZERO); + assert_eq!(SubnetTAO::::get(netuid2), TaoBalance::ZERO); + assert_eq!(SubnetTAO::::get(netuid3), TaoBalance::ZERO); // Set Tao flows to equal and non-zero SubnetTaoFlow::::insert(netuid1, 100_000_000_i64); SubnetTaoFlow::::insert(netuid2, 100_000_000_i64); @@ -194,15 +194,15 @@ fn test_coinbase_tao_issuance_different_prices() { // Force the swap to initialize SubtensorModule::swap_tao_for_alpha( netuid1, - TaoCurrency::ZERO, - 1_000_000_000_000.into(), + TaoBalance::ZERO, + 1_000_000_000_000_u64.into(), false, ) .unwrap(); SubtensorModule::swap_tao_for_alpha( netuid2, - TaoCurrency::ZERO, - 1_000_000_000_000.into(), + TaoBalance::ZERO, + 1_000_000_000_000_u64.into(), false, ) .unwrap(); @@ -226,17 +226,17 @@ fn test_coinbase_tao_issuance_different_prices() { // Assert tao emission is split evenly. assert_abs_diff_eq!( SubnetTAO::::get(netuid1), - TaoCurrency::from(initial_tao + emission / 3), + TaoBalance::from(initial_tao + emission / 3), epsilon = 10.into(), ); assert_abs_diff_eq!( SubnetTAO::::get(netuid2), - TaoCurrency::from(initial_tao + 2 * emission / 3), + TaoBalance::from(initial_tao + 2 * emission / 3), epsilon = 10.into(), ); // Prices are low => we limit tao issued (buy alpha with it) - let tao_issued = TaoCurrency::from(((1.0) * emission as f64) as u64); + let tao_issued = TaoBalance::from(((1.0) * emission as f64) as u64); assert_abs_diff_eq!( TotalIssuance::::get(), tao_issued, @@ -270,14 +270,14 @@ fn test_coinbase_tao_issuance_different_prices() { // // Force the swap to initialize // SubtensorModule::swap_tao_for_alpha( // netuid1, -// TaoCurrency::ZERO, +// TaoBalance::ZERO, // 1_000_000_000_000.into(), // false, // ) // .unwrap(); // SubtensorModule::swap_tao_for_alpha( // netuid2, -// TaoCurrency::ZERO, +// TaoBalance::ZERO, // 1_000_000_000_000.into(), // false, // ) @@ -307,17 +307,17 @@ fn test_coinbase_tao_issuance_different_prices() { // // Assert tao emission is split evenly. // assert_abs_diff_eq!( // SubnetTAO::::get(netuid1), -// TaoCurrency::from(initial_tao + emission / 3), +// TaoBalance::from(initial_tao + emission / 3), // epsilon = 10.into(), // ); // assert_abs_diff_eq!( // SubnetTAO::::get(netuid2), -// TaoCurrency::from(initial_tao + 2 * emission / 3), +// TaoBalance::from(initial_tao + 2 * emission / 3), // epsilon = 10.into(), // ); // // Prices are low => we limit tao issued (buy alpha with it) -// let tao_issued = TaoCurrency::from(((0.1 + 0.2) * emission as f64) as u64); +// let tao_issued = TaoBalance::from(((0.1 + 0.2) * emission as f64) as u64); // assert_abs_diff_eq!( // TotalIssuance::::get(), // tao_issued, @@ -343,8 +343,8 @@ fn test_coinbase_moving_prices() { let netuid = NetUid::from(1); add_network(netuid, 1, 0); // Set price to 1.0 - SubnetTAO::::insert(netuid, TaoCurrency::from(1_000_000)); - SubnetAlphaIn::::insert(netuid, AlphaCurrency::from(1_000_000)); + SubnetTAO::::insert(netuid, TaoBalance::from(1_000_000)); + SubnetAlphaIn::::insert(netuid, AlphaBalance::from(1_000_000)); SubnetMechanism::::insert(netuid, 1); SubnetMovingPrice::::insert(netuid, I96F32::from_num(1)); FirstEmissionBlockNumber::::insert(netuid, 1); @@ -399,8 +399,8 @@ fn test_update_moving_price_initial() { let netuid = NetUid::from(1); add_network(netuid, 1, 0); // Set current price to 1.0 - SubnetTAO::::insert(netuid, TaoCurrency::from(1_000_000)); - SubnetAlphaIn::::insert(netuid, AlphaCurrency::from(1_000_000)); + SubnetTAO::::insert(netuid, TaoBalance::from(1_000_000)); + SubnetAlphaIn::::insert(netuid, AlphaBalance::from(1_000_000)); SubnetMechanism::::insert(netuid, 1); SubnetMovingAlpha::::set(I96F32::from_num(0.5)); SubnetMovingPrice::::insert(netuid, I96F32::from_num(0)); @@ -424,8 +424,8 @@ fn test_update_moving_price_after_time() { let netuid = NetUid::from(1); add_network(netuid, 1, 0); // Set current price to 1.0 - SubnetTAO::::insert(netuid, TaoCurrency::from(1_000_000)); - SubnetAlphaIn::::insert(netuid, AlphaCurrency::from(1_000_000)); + SubnetTAO::::insert(netuid, TaoBalance::from(1_000_000)); + SubnetAlphaIn::::insert(netuid, AlphaBalance::from(1_000_000)); SubnetMechanism::::insert(netuid, 1); SubnetMovingAlpha::::set(I96F32::from_num(0.5)); SubnetMovingPrice::::insert(netuid, I96F32::from_num(0)); @@ -457,10 +457,10 @@ fn test_coinbase_alpha_issuance_base() { add_network(netuid2, 1, 0); // Set up prices 1 and 1 let initial: u64 = 1_000_000; - SubnetTAO::::insert(netuid1, TaoCurrency::from(initial)); - SubnetAlphaIn::::insert(netuid1, AlphaCurrency::from(initial)); - SubnetTAO::::insert(netuid2, TaoCurrency::from(initial)); - SubnetAlphaIn::::insert(netuid2, AlphaCurrency::from(initial)); + SubnetTAO::::insert(netuid1, TaoBalance::from(initial)); + SubnetAlphaIn::::insert(netuid1, AlphaBalance::from(initial)); + SubnetTAO::::insert(netuid2, TaoBalance::from(initial)); + SubnetAlphaIn::::insert(netuid2, AlphaBalance::from(initial)); // Equal flow SubnetTaoFlow::::insert(netuid1, 100_000_000_i64); SubnetTaoFlow::::insert(netuid2, 100_000_000_i64); @@ -498,10 +498,10 @@ fn test_coinbase_alpha_issuance_different() { SubnetMechanism::::insert(netuid2, 1); // Setup prices 1 and 2 let initial: u64 = 1_000_000; - SubnetTAO::::insert(netuid1, TaoCurrency::from(initial)); - SubnetAlphaIn::::insert(netuid1, AlphaCurrency::from(initial)); - SubnetTAO::::insert(netuid2, TaoCurrency::from(2 * initial)); - SubnetAlphaIn::::insert(netuid2, AlphaCurrency::from(initial)); + SubnetTAO::::insert(netuid1, TaoBalance::from(initial)); + SubnetAlphaIn::::insert(netuid1, AlphaBalance::from(initial)); + SubnetTAO::::insert(netuid2, TaoBalance::from(2 * initial)); + SubnetAlphaIn::::insert(netuid2, AlphaBalance::from(initial)); // Set subnet TAO flows to non-zero and 1:2 ratio SubnetTaoFlow::::insert(netuid1, 100_000_000_i64); SubnetTaoFlow::::insert(netuid2, 200_000_000_i64); @@ -538,10 +538,10 @@ fn test_coinbase_alpha_issuance_with_cap_trigger() { // Setup prices 1000000 let initial: u64 = 1_000; let initial_alpha: u64 = initial * 1000000; - SubnetTAO::::insert(netuid1, TaoCurrency::from(initial)); - SubnetAlphaIn::::insert(netuid1, AlphaCurrency::from(initial_alpha)); // Make price extremely low. - SubnetTAO::::insert(netuid2, TaoCurrency::from(initial)); - SubnetAlphaIn::::insert(netuid2, AlphaCurrency::from(initial_alpha)); // Make price extremely low. + SubnetTAO::::insert(netuid1, TaoBalance::from(initial)); + SubnetAlphaIn::::insert(netuid1, AlphaBalance::from(initial_alpha)); // Make price extremely low. + SubnetTAO::::insert(netuid2, TaoBalance::from(initial)); + SubnetAlphaIn::::insert(netuid2, AlphaBalance::from(initial_alpha)); // Make price extremely low. // Set subnet prices. SubnetMovingPrice::::insert(netuid1, I96F32::from_num(1)); SubnetMovingPrice::::insert(netuid2, I96F32::from_num(2)); @@ -588,15 +588,15 @@ fn test_coinbase_alpha_issuance_with_cap_trigger_and_block_emission() { // Force the swap to initialize SubtensorModule::swap_tao_for_alpha( netuid1, - TaoCurrency::ZERO, - 1_000_000_000_000.into(), + TaoBalance::ZERO, + 1_000_000_000_000_u64.into(), false, ) .unwrap(); SubtensorModule::swap_tao_for_alpha( netuid2, - TaoCurrency::ZERO, - 1_000_000_000_000.into(), + TaoBalance::ZERO, + 1_000_000_000_000_u64.into(), false, ) .unwrap(); @@ -606,8 +606,8 @@ fn test_coinbase_alpha_issuance_with_cap_trigger_and_block_emission() { let price_2_before = ::SwapInterface::current_alpha_price(netuid2); // Set issuance at 21M - SubnetAlphaOut::::insert(netuid1, AlphaCurrency::from(21_000_000_000_000_000)); // Set issuance above 21M - SubnetAlphaOut::::insert(netuid2, AlphaCurrency::from(21_000_000_000_000_000)); // Set issuance above 21M + SubnetAlphaOut::::insert(netuid1, AlphaBalance::from(21_000_000_000_000_000_u64)); // Set issuance above 21M + SubnetAlphaOut::::insert(netuid2, AlphaBalance::from(21_000_000_000_000_000_u64)); // Set issuance above 21M // Run coinbase SubtensorModule::run_coinbase(U96F32::from_num(emission)); @@ -639,7 +639,11 @@ fn test_owner_cut_base() { new_test_ext(1).execute_with(|| { let netuid = NetUid::from(1); add_network(netuid, 1, 0); - mock::setup_reserves(netuid, 1_000_000_000_000.into(), 1_000_000_000_000.into()); + mock::setup_reserves( + netuid, + 1_000_000_000_000_u64.into(), + 1_000_000_000_000_u64.into(), + ); SubtensorModule::set_tempo(netuid, 10000); // Large number (dont drain) SubtensorModule::set_subnet_owner_cut(0); SubtensorModule::run_coinbase(U96F32::from_num(0)); @@ -663,7 +667,7 @@ fn test_pending_emission() { mock::setup_reserves(netuid, 1_000_000.into(), 1.into()); SubtensorModule::run_coinbase(U96F32::from_num(0)); - SubnetTAO::::insert(NetUid::ROOT, TaoCurrency::from(1_000_000_000)); // Add root weight. + SubnetTAO::::insert(NetUid::ROOT, TaoBalance::from(1_000_000_000)); // Add root weight. SubtensorModule::run_coinbase(U96F32::from_num(0)); SubtensorModule::set_tempo(netuid, 10000); // Large number (dont drain) SubtensorModule::set_tao_weight(u64::MAX); // Set TAO weight to 1.0 @@ -704,10 +708,10 @@ fn test_drain_base() { new_test_ext(1).execute_with(|| { SubtensorModule::distribute_emission( 0.into(), - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, ) }); } @@ -720,10 +724,10 @@ fn test_drain_base_with_subnet() { add_network(netuid, 1, 0); SubtensorModule::distribute_emission( netuid, - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, ) }); } @@ -736,20 +740,20 @@ fn test_drain_base_with_subnet_with_single_staker_not_registered() { add_network(netuid, 1, 0); let hotkey = U256::from(1); let coldkey = U256::from(2); - let stake_before = AlphaCurrency::from(1_000_000_000); + let stake_before = AlphaBalance::from(1_000_000_000); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &hotkey, &coldkey, netuid, stake_before, ); - let pending_alpha = AlphaCurrency::from(1_000_000_000); + let pending_alpha = AlphaBalance::from(1_000_000_000); SubtensorModule::distribute_emission( netuid, pending_alpha.saturating_div(2.into()).into(), pending_alpha.saturating_div(2.into()).into(), - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, ); let stake_after = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(&hotkey, &coldkey, netuid); @@ -765,7 +769,7 @@ fn test_drain_base_with_subnet_with_single_staker_registered() { add_network(netuid, 1, 0); let hotkey = U256::from(1); let coldkey = U256::from(2); - let stake_before = AlphaCurrency::from(1_000_000_000); + let stake_before = AlphaBalance::from(1_000_000_000); register_ok_neuron(netuid, hotkey, coldkey, 0); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &hotkey, @@ -773,13 +777,13 @@ fn test_drain_base_with_subnet_with_single_staker_registered() { netuid, stake_before, ); - let pending_alpha = AlphaCurrency::from(1_000_000_000); + let pending_alpha = AlphaBalance::from(1_000_000_000); SubtensorModule::distribute_emission( netuid, pending_alpha.saturating_div(2.into()).into(), pending_alpha.saturating_div(2.into()).into(), - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, ); let stake_after = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(&hotkey, &coldkey, netuid); @@ -799,7 +803,7 @@ fn test_drain_base_with_subnet_with_single_staker_registered_root_weight() { add_network(netuid, 1, 0); let hotkey = U256::from(1); let coldkey = U256::from(2); - let stake_before = AlphaCurrency::from(1_000_000_000); + let stake_before = AlphaBalance::from(1_000_000_000); // register_ok_neuron(root, hotkey, coldkey, 0); register_ok_neuron(netuid, hotkey, coldkey, 0); Delegates::::insert(hotkey, 0); @@ -816,15 +820,15 @@ fn test_drain_base_with_subnet_with_single_staker_registered_root_weight() { netuid, stake_before, ); - let pending_alpha = AlphaCurrency::from(1_000_000_000); - let pending_root_alpha = AlphaCurrency::from(1_000_000_000); - assert_eq!(SubnetTAO::::get(NetUid::ROOT), TaoCurrency::ZERO); + let pending_alpha = AlphaBalance::from(1_000_000_000); + let pending_root_alpha = AlphaBalance::from(1_000_000_000); + assert_eq!(SubnetTAO::::get(NetUid::ROOT), TaoBalance::ZERO); SubtensorModule::distribute_emission( netuid, pending_alpha.saturating_div(2.into()).into(), pending_alpha.saturating_div(2.into()).into(), pending_root_alpha, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, ); let stake_after = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(&hotkey, &coldkey, netuid); @@ -851,7 +855,7 @@ fn test_drain_base_with_subnet_with_two_stakers_registered() { let hotkey1 = U256::from(1); let hotkey2 = U256::from(2); let coldkey = U256::from(3); - let stake_before = AlphaCurrency::from(1_000_000_000); + let stake_before = AlphaBalance::from(1_000_000_000); register_ok_neuron(netuid, hotkey1, coldkey, 0); register_ok_neuron(netuid, hotkey2, coldkey, 0); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( @@ -866,13 +870,13 @@ fn test_drain_base_with_subnet_with_two_stakers_registered() { netuid, stake_before, ); - let pending_alpha = AlphaCurrency::from(1_000_000_000); + let pending_alpha = AlphaBalance::from(1_000_000_000); SubtensorModule::distribute_emission( netuid, pending_alpha.saturating_div(2.into()).into(), pending_alpha.saturating_div(2.into()).into(), - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, ); let stake_after1 = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(&hotkey1, &coldkey, netuid); @@ -900,7 +904,7 @@ fn test_drain_base_with_subnet_with_two_stakers_registered_and_root() { let hotkey1 = U256::from(1); let hotkey2 = U256::from(2); let coldkey = U256::from(3); - let stake_before = AlphaCurrency::from(1_000_000_000); + let stake_before = AlphaBalance::from(1_000_000_000); register_ok_neuron(netuid, hotkey1, coldkey, 0); register_ok_neuron(netuid, hotkey2, coldkey, 0); Delegates::::insert(hotkey1, 0); @@ -930,15 +934,15 @@ fn test_drain_base_with_subnet_with_two_stakers_registered_and_root() { NetUid::ROOT, stake_before, ); - let pending_tao = TaoCurrency::from(1_000_000_000); - let pending_alpha = AlphaCurrency::from(1_000_000_000); - assert_eq!(SubnetTAO::::get(NetUid::ROOT), TaoCurrency::ZERO); + let pending_tao = TaoBalance::from(1_000_000_000); + let pending_alpha = AlphaBalance::from(1_000_000_000); + assert_eq!(SubnetTAO::::get(NetUid::ROOT), TaoBalance::ZERO); SubtensorModule::distribute_emission( netuid, pending_alpha.saturating_div(2.into()).into(), pending_alpha.saturating_div(2.into()).into(), - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, ); let stake_after1 = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(&hotkey1, &coldkey, netuid); @@ -976,7 +980,7 @@ fn test_drain_base_with_subnet_with_two_stakers_registered_and_root_different_am let hotkey1 = U256::from(1); let hotkey2 = U256::from(2); let coldkey = U256::from(3); - let stake_before = AlphaCurrency::from(1_000_000_000); + let stake_before = AlphaBalance::from(1_000_000_000); Delegates::::insert(hotkey1, 0); Delegates::::insert(hotkey2, 0); register_ok_neuron(netuid, hotkey1, coldkey, 0); @@ -1006,15 +1010,15 @@ fn test_drain_base_with_subnet_with_two_stakers_registered_and_root_different_am NetUid::ROOT, stake_before, ); - let pending_tao = TaoCurrency::from(1_000_000_000); - let pending_alpha = AlphaCurrency::from(1_000_000_000); - assert_eq!(SubnetTAO::::get(NetUid::ROOT), TaoCurrency::ZERO); + let pending_tao = TaoBalance::from(1_000_000_000); + let pending_alpha = AlphaBalance::from(1_000_000_000); + assert_eq!(SubnetTAO::::get(NetUid::ROOT), TaoBalance::ZERO); SubtensorModule::distribute_emission( netuid, pending_alpha.saturating_div(2.into()).into(), pending_alpha.saturating_div(2.into()).into(), - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, ); let stake_after1 = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(&hotkey1, &coldkey, netuid); @@ -1057,7 +1061,7 @@ fn test_drain_base_with_subnet_with_two_stakers_registered_and_root_different_am let hotkey1 = U256::from(1); let hotkey2 = U256::from(2); let coldkey = U256::from(3); - let stake_before = AlphaCurrency::from(1_000_000_000); + let stake_before = AlphaBalance::from(1_000_000_000); Delegates::::insert(hotkey1, 0); Delegates::::insert(hotkey2, 0); register_ok_neuron(netuid, hotkey1, coldkey, 0); @@ -1087,15 +1091,15 @@ fn test_drain_base_with_subnet_with_two_stakers_registered_and_root_different_am NetUid::ROOT, stake_before, ); - let pending_tao = TaoCurrency::from(1_000_000_000); - let pending_alpha = AlphaCurrency::from(1_000_000_000); - assert_eq!(SubnetTAO::::get(NetUid::ROOT), TaoCurrency::ZERO); + let pending_tao = TaoBalance::from(1_000_000_000); + let pending_alpha = AlphaBalance::from(1_000_000_000); + assert_eq!(SubnetTAO::::get(NetUid::ROOT), TaoBalance::ZERO); SubtensorModule::distribute_emission( netuid, pending_alpha.saturating_div(2.into()).into(), pending_alpha.saturating_div(2.into()).into(), - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, ); let stake_after1 = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(&hotkey1, &coldkey, netuid); @@ -1138,7 +1142,7 @@ fn test_drain_alpha_childkey_parentkey() { let parent = U256::from(1); let child = U256::from(2); let coldkey = U256::from(3); - let stake_before = AlphaCurrency::from(1_000_000_000); + let stake_before = AlphaBalance::from(1_000_000_000); register_ok_neuron(netuid, child, coldkey, 0); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &parent, @@ -1151,13 +1155,13 @@ fn test_drain_alpha_childkey_parentkey() { // Childkey take is 10% ChildkeyTake::::insert(child, netuid, u16::MAX / 10); - let pending_alpha = AlphaCurrency::from(1_000_000_000); + let pending_alpha = AlphaBalance::from(1_000_000_000); SubtensorModule::distribute_emission( netuid, pending_alpha.saturating_div(2.into()).into(), pending_alpha.saturating_div(2.into()).into(), - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, ); let parent_stake_after = SubtensorModule::get_stake_for_hotkey_on_subnet(&parent, netuid); let child_stake_after = SubtensorModule::get_stake_for_hotkey_on_subnet(&child, netuid); @@ -1206,14 +1210,14 @@ fn test_get_root_children() { )); // Add stake for Alice and Bob on root. - let alice_root_stake = AlphaCurrency::from(1_000_000_000); + let alice_root_stake = AlphaBalance::from(1_000_000_000); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &alice, &cold, NetUid::ROOT, alice_root_stake, ); - let bob_root_stake = AlphaCurrency::from(1_000_000_000); + let bob_root_stake = AlphaBalance::from(1_000_000_000); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &bob, &cold, @@ -1222,14 +1226,14 @@ fn test_get_root_children() { ); // Add stake for Alice and Bob on netuid. - let alice_alpha_stake = AlphaCurrency::from(1_000_000_000); + let alice_alpha_stake = AlphaBalance::from(1_000_000_000); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &alice, &cold, alpha, alice_alpha_stake, ); - let bob_alpha_stake = AlphaCurrency::from(1_000_000_000); + let bob_alpha_stake = AlphaBalance::from(1_000_000_000); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &bob, &cold, @@ -1280,7 +1284,7 @@ fn test_get_root_children() { // Assert Alice and Bob TAO inherited stakes assert_eq!( SubtensorModule::get_tao_inherited_for_hotkey_on_subnet(&alice, alpha), - TaoCurrency::ZERO + TaoBalance::ZERO ); assert_eq!( SubtensorModule::get_tao_inherited_for_hotkey_on_subnet(&bob, alpha), @@ -1345,14 +1349,14 @@ fn test_get_root_children_drain() { bob_root_stake.into(), ); // Add stake for Alice and Bob on netuid. - let alice_alpha_stake = AlphaCurrency::from(1_000_000_000); + let alice_alpha_stake = AlphaBalance::from(1_000_000_000); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &alice, &cold_alice, alpha, alice_alpha_stake, ); - let bob_alpha_stake = AlphaCurrency::from(1_000_000_000); + let bob_alpha_stake = AlphaBalance::from(1_000_000_000); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &bob, &cold_bob, @@ -1374,16 +1378,16 @@ fn test_get_root_children_drain() { // Get Bob stake amounts on subnet alpha. let (bob_total, bob_alpha, bob_tao): (I64F64, I64F64, I64F64) = SubtensorModule::get_stake_weights_for_hotkey_on_subnet(&bob, alpha); - assert_eq!(bob_total, I64F64::from_num(4 * bob_root_stake)); + assert_eq!(bob_total, I64F64::from_num(4_u64 * bob_root_stake)); // Lets drain - let pending_alpha = AlphaCurrency::from(1_000_000_000); + let pending_alpha = AlphaBalance::from(1_000_000_000); SubtensorModule::distribute_emission( alpha, pending_alpha.saturating_div(2.into()).into(), pending_alpha.saturating_div(2.into()).into(), - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, ); // Alice and Bob both made half of the dividends. @@ -1397,47 +1401,47 @@ fn test_get_root_children_drain() { ); // There should be no TAO on the root subnet. - assert_eq!(SubnetTAO::::get(NetUid::ROOT), TaoCurrency::ZERO); + assert_eq!(SubnetTAO::::get(NetUid::ROOT), TaoBalance::ZERO); // Lets drain - let pending_alpha = AlphaCurrency::from(1_000_000_000); - let pending_root1 = TaoCurrency::from(1_000_000_000); + let pending_alpha = AlphaBalance::from(1_000_000_000); + let pending_root1 = TaoBalance::from(1_000_000_000); SubtensorModule::distribute_emission( alpha, pending_alpha.saturating_div(2.into()).into(), pending_alpha.saturating_div(2.into()).into(), - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, ); // Alice and Bob both made half of the dividends. assert_eq!( SubtensorModule::get_stake_for_hotkey_on_subnet(&alice, NetUid::ROOT), - AlphaCurrency::from(alice_root_stake) + AlphaBalance::from(alice_root_stake) ); assert_eq!( SubtensorModule::get_stake_for_hotkey_on_subnet(&bob, NetUid::ROOT), - AlphaCurrency::from(bob_root_stake) + AlphaBalance::from(bob_root_stake) ); // Lets change the take value. (Bob is greedy.) ChildkeyTake::::insert(bob, alpha, u16::MAX); // Lets drain - let pending_alpha = AlphaCurrency::from(1_000_000_000); - let pending_root2 = TaoCurrency::from(1_000_000_000); + let pending_alpha = AlphaBalance::from(1_000_000_000); + let pending_root2 = TaoBalance::from(1_000_000_000); SubtensorModule::distribute_emission( alpha, pending_alpha.saturating_div(2.into()).into(), pending_alpha.saturating_div(2.into()).into(), - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, ); // Alice makes nothing assert_eq!( AlphaDividendsPerSubnet::::get(alpha, alice), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); // Bob makes it all. assert_abs_diff_eq!( @@ -1476,14 +1480,14 @@ fn test_get_root_children_drain_half_proportion() { bob, )); // Add stake for Alice and Bob on root. - let alice_root_stake = AlphaCurrency::from(1_000_000_000); + let alice_root_stake = AlphaBalance::from(1_000_000_000); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &alice, &cold_alice, NetUid::ROOT, alice_root_stake, ); - let bob_root_stake = AlphaCurrency::from(1_000_000_000); + let bob_root_stake = AlphaBalance::from(1_000_000_000); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &bob, &cold_bob, @@ -1491,14 +1495,14 @@ fn test_get_root_children_drain_half_proportion() { alice_root_stake, ); // Add stake for Alice and Bob on netuid. - let alice_alpha_stake = AlphaCurrency::from(1_000_000_000); + let alice_alpha_stake = AlphaBalance::from(1_000_000_000); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &alice, &cold_alice, alpha, alice_alpha_stake, ); - let bob_alpha_stake = AlphaCurrency::from(1_000_000_000); + let bob_alpha_stake = AlphaBalance::from(1_000_000_000); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &bob, &cold_bob, @@ -1514,13 +1518,13 @@ fn test_get_root_children_drain_half_proportion() { Delegates::::insert(bob, 0); // Lets drain! - let pending_alpha = AlphaCurrency::from(1_000_000_000); + let pending_alpha = AlphaBalance::from(1_000_000_000); SubtensorModule::distribute_emission( alpha, pending_alpha.saturating_div(2.into()).into(), pending_alpha.saturating_div(2.into()).into(), - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, ); // Alice and Bob make the same amount. @@ -1564,14 +1568,14 @@ fn test_get_root_children_drain_with_take() { bob, )); // Add stake for Alice and Bob on root. - let alice_root_stake = AlphaCurrency::from(1_000_000_000); + let alice_root_stake = AlphaBalance::from(1_000_000_000); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &alice, &cold_alice, NetUid::ROOT, alice_root_stake, ); - let bob_root_stake = AlphaCurrency::from(1_000_000_000); + let bob_root_stake = AlphaBalance::from(1_000_000_000); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &bob, &cold_bob, @@ -1579,14 +1583,14 @@ fn test_get_root_children_drain_with_take() { alice_root_stake, ); // Add stake for Alice and Bob on netuid. - let alice_alpha_stake = AlphaCurrency::from(1_000_000_000); + let alice_alpha_stake = AlphaBalance::from(1_000_000_000); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &alice, &cold_alice, alpha, alice_alpha_stake, ); - let bob_alpha_stake = AlphaCurrency::from(1_000_000_000); + let bob_alpha_stake = AlphaBalance::from(1_000_000_000); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &bob, &cold_bob, @@ -1601,13 +1605,13 @@ fn test_get_root_children_drain_with_take() { Delegates::::insert(bob, 0); // Lets drain! - let pending_alpha = AlphaCurrency::from(1_000_000_000); + let pending_alpha = AlphaBalance::from(1_000_000_000); SubtensorModule::distribute_emission( alpha, pending_alpha.saturating_div(2.into()).into(), pending_alpha.saturating_div(2.into()).into(), - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, ); // Bob makes it all. @@ -1652,14 +1656,14 @@ fn test_get_root_children_drain_with_half_take() { bob, )); // Add stake for Alice and Bob on root. - let alice_root_stake = AlphaCurrency::from(1_000_000_000); + let alice_root_stake = AlphaBalance::from(1_000_000_000); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &alice, &cold_alice, NetUid::ROOT, alice_root_stake, ); - let bob_root_stake = AlphaCurrency::from(1_000_000_000); + let bob_root_stake = AlphaBalance::from(1_000_000_000); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &bob, &cold_bob, @@ -1667,14 +1671,14 @@ fn test_get_root_children_drain_with_half_take() { alice_root_stake, ); // Add stake for Alice and Bob on netuid. - let alice_alpha_stake = AlphaCurrency::from(1_000_000_000); + let alice_alpha_stake = AlphaBalance::from(1_000_000_000); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &alice, &cold_alice, alpha, alice_alpha_stake, ); - let bob_alpha_stake = AlphaCurrency::from(1_000_000_000); + let bob_alpha_stake = AlphaBalance::from(1_000_000_000); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &bob, &cold_bob, @@ -1689,13 +1693,13 @@ fn test_get_root_children_drain_with_half_take() { Delegates::::insert(bob, 0); // Lets drain! - let pending_alpha = AlphaCurrency::from(1_000_000_000); + let pending_alpha = AlphaBalance::from(1_000_000_000); SubtensorModule::distribute_emission( alpha, pending_alpha.saturating_div(2.into()).into(), pending_alpha.saturating_div(2.into()).into(), - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, ); // Alice and Bob make the same amount. @@ -1738,14 +1742,14 @@ fn test_get_root_children_drain_with_half_take() { // bob, // )); // // Add stake for Alice and Bob on root. -// let alice_root_stake = AlphaCurrency::from(1_000_000_000); +// let alice_root_stake = AlphaBalance::from(1_000_000_000); // SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( // &alice, // &cold, // NetUid::ROOT, // alice_root_stake, // ); -// let bob_root_stake = AlphaCurrency::from(1_000_000_000); +// let bob_root_stake = AlphaBalance::from(1_000_000_000); // SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( // &bob, // &cold, @@ -1753,14 +1757,14 @@ fn test_get_root_children_drain_with_half_take() { // alice_root_stake, // ); // // Add stake for Alice and Bob on netuid. -// let alice_alpha_stake = AlphaCurrency::from(1_000_000_000); +// let alice_alpha_stake = AlphaBalance::from(1_000_000_000); // SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( // &alice, // &cold, // alpha, // alice_alpha_stake, // ); -// let bob_alpha_stake = AlphaCurrency::from(1_000_000_000); +// let bob_alpha_stake = AlphaBalance::from(1_000_000_000); // SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( // &bob, // &cold, @@ -1792,7 +1796,7 @@ fn test_get_root_children_drain_with_half_take() { // )); // // Lets drain! -// let pending_alpha = AlphaCurrency::from(1_000_000_000); +// let pending_alpha = AlphaBalance::from(1_000_000_000); // SubtensorModule::distribute_emission(alpha, pending_alpha, 0, 0.into(), 0.into()); // // Alice and Bob make the same amount. @@ -1823,9 +1827,9 @@ fn test_incentive_to_subnet_owner_is_burned() { let netuid = add_dynamic_network(&subnet_owner_hk, &subnet_owner_ck); let pending_tao: u64 = 1_000_000_000; - let pending_alpha = AlphaCurrency::ZERO; // None to valis - let owner_cut = AlphaCurrency::ZERO; - let mut incentives: BTreeMap = BTreeMap::new(); + let pending_alpha = AlphaBalance::ZERO; // None to valis + let owner_cut = AlphaBalance::ZERO; + let mut incentives: BTreeMap = BTreeMap::new(); // Give incentive to other_hk incentives.insert(other_hk, 10_000_000.into()); @@ -1877,9 +1881,9 @@ fn test_incentive_to_subnet_owners_hotkey_is_burned() { ImmuneOwnerUidsLimit::::insert(netuid, 2); let pending_tao: u64 = 1_000_000_000; - let pending_alpha = AlphaCurrency::ZERO; // None to valis - let owner_cut = AlphaCurrency::ZERO; - let mut incentives: BTreeMap = BTreeMap::new(); + let pending_alpha = AlphaBalance::ZERO; // None to valis + let owner_cut = AlphaBalance::ZERO; + let mut incentives: BTreeMap = BTreeMap::new(); // Give incentive to other_hk incentives.insert(other_hk, 10_000_000.into()); @@ -1949,9 +1953,9 @@ fn test_burn_key_sorting() { Uids::::insert(netuid, other_hk_3, 2); let pending_tao: u64 = 1_000_000_000; - let pending_alpha = AlphaCurrency::ZERO; // None to valis - let owner_cut = AlphaCurrency::ZERO; - let mut incentives: BTreeMap = BTreeMap::new(); + let pending_alpha = AlphaBalance::ZERO; // None to valis + let owner_cut = AlphaBalance::ZERO; + let mut incentives: BTreeMap = BTreeMap::new(); // Give incentive to hotkeys incentives.insert(other_hk_1, 10_000_000.into()); @@ -1991,11 +1995,11 @@ fn test_burn_key_sorting() { #[test] fn test_calculate_dividend_distribution_totals() { new_test_ext(1).execute_with(|| { - let mut stake_map: BTreeMap = BTreeMap::new(); + let mut stake_map: BTreeMap = BTreeMap::new(); let mut dividends: BTreeMap = BTreeMap::new(); - let pending_validator_alpha = AlphaCurrency::from(183_123_567_452); - let pending_root_alpha = AlphaCurrency::from(837_120_949_872); + let pending_validator_alpha = AlphaBalance::from(183_123_567_452_u64); + let pending_root_alpha = AlphaBalance::from(837_120_949_872_u64); let tao_weight: U96F32 = U96F32::from_num(0.18); // 18% let hotkeys = [U256::from(0), U256::from(1)]; @@ -2035,11 +2039,11 @@ fn test_calculate_dividend_distribution_totals() { #[test] fn test_calculate_dividend_distribution_total_only_tao() { new_test_ext(1).execute_with(|| { - let mut stake_map: BTreeMap = BTreeMap::new(); + let mut stake_map: BTreeMap = BTreeMap::new(); let mut dividends: BTreeMap = BTreeMap::new(); - let pending_validator_alpha = AlphaCurrency::ZERO; - let pending_root_alpha = AlphaCurrency::from(837_120_949_872); + let pending_validator_alpha = AlphaBalance::ZERO; + let pending_root_alpha = AlphaBalance::from(837_120_949_872_u64); let tao_weight: U96F32 = U96F32::from_num(0.18); // 18% let hotkeys = [U256::from(0), U256::from(1)]; @@ -2079,11 +2083,11 @@ fn test_calculate_dividend_distribution_total_only_tao() { #[test] fn test_calculate_dividend_distribution_total_no_tao_weight() { new_test_ext(1).execute_with(|| { - let mut stake_map: BTreeMap = BTreeMap::new(); + let mut stake_map: BTreeMap = BTreeMap::new(); let mut dividends: BTreeMap = BTreeMap::new(); - let pending_validator_alpha = AlphaCurrency::from(183_123_567_452); - let pending_tao = TaoCurrency::ZERO; // If tao weight is 0, then only alpha dividends should be input. + let pending_validator_alpha = AlphaBalance::from(183_123_567_452_u64); + let pending_tao = TaoBalance::ZERO; // If tao weight is 0, then only alpha dividends should be input. let tao_weight: U96F32 = U96F32::from_num(0.0); // 0% let hotkeys = [U256::from(0), U256::from(1)]; @@ -2097,7 +2101,7 @@ fn test_calculate_dividend_distribution_total_no_tao_weight() { let (alpha_dividends, tao_dividends) = SubtensorModule::calculate_dividend_distribution( pending_validator_alpha, // pending_tao, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, tao_weight, stake_map, dividends, @@ -2123,11 +2127,11 @@ fn test_calculate_dividend_distribution_total_no_tao_weight() { #[test] fn test_calculate_dividend_distribution_total_only_alpha() { new_test_ext(1).execute_with(|| { - let mut stake_map: BTreeMap = BTreeMap::new(); + let mut stake_map: BTreeMap = BTreeMap::new(); let mut dividends: BTreeMap = BTreeMap::new(); - let pending_validator_alpha = AlphaCurrency::from(183_123_567_452); - let pending_tao = TaoCurrency::ZERO; + let pending_validator_alpha = AlphaBalance::from(183_123_567_452_u64); + let pending_tao = TaoBalance::ZERO; let tao_weight: U96F32 = U96F32::from_num(0.18); // 18% let hotkeys = [U256::from(0), U256::from(1)]; @@ -2141,7 +2145,7 @@ fn test_calculate_dividend_distribution_total_only_alpha() { let (alpha_dividends, tao_dividends) = SubtensorModule::calculate_dividend_distribution( pending_validator_alpha, // pending_tao, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, tao_weight, stake_map, dividends, @@ -2183,9 +2187,9 @@ fn test_calculate_dividend_and_incentive_distribution() { 1.into(), ); - let pending_alpha = AlphaCurrency::from(123_456_789); + let pending_alpha = AlphaBalance::from(123_456_789); let pending_validator_alpha = pending_alpha / 2.into(); // Pay half to validators. - let pending_tao = TaoCurrency::ZERO; + let pending_tao = TaoBalance::ZERO; let pending_swapped = 0; // Only alpha output. let tao_weight: U96F32 = U96F32::from_num(0.0); // 0% @@ -2196,7 +2200,7 @@ fn test_calculate_dividend_and_incentive_distribution() { SubtensorModule::calculate_dividend_and_incentive_distribution( netuid, // pending_tao, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, pending_validator_alpha, hotkey_emission, tao_weight, @@ -2232,9 +2236,9 @@ fn test_calculate_dividend_and_incentive_distribution_all_to_validators() { 1.into(), ); - let pending_alpha = AlphaCurrency::from(123_456_789); + let pending_alpha = AlphaBalance::from(123_456_789); let pending_validator_alpha = pending_alpha; // Pay all to validators. - let pending_tao = TaoCurrency::ZERO; + let pending_tao = TaoBalance::ZERO; let tao_weight: U96F32 = U96F32::from_num(0.0); // 0% // Hotkey, Incentive, Dividend @@ -2244,7 +2248,7 @@ fn test_calculate_dividend_and_incentive_distribution_all_to_validators() { SubtensorModule::calculate_dividend_and_incentive_distribution( netuid, // pending_tao, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, pending_validator_alpha, hotkey_emission, tao_weight, @@ -2254,7 +2258,7 @@ fn test_calculate_dividend_and_incentive_distribution_all_to_validators() { let dividends_total = alpha_dividends.values().sum::().to_num::(); assert_eq!( - AlphaCurrency::from(dividends_total + incentives_total), + AlphaBalance::from(dividends_total + incentives_total), pending_alpha ); }); @@ -2279,8 +2283,8 @@ fn test_calculate_dividends_and_incentives() { 1.into(), ); - let divdends = AlphaCurrency::from(123_456_789); - let incentive = AlphaCurrency::from(683_051_923); + let divdends = AlphaBalance::from(123_456_789); + let incentive = AlphaBalance::from(683_051_923); let total_emission = divdends + incentive; // Hotkey, Incentive, Dividend @@ -2292,9 +2296,9 @@ fn test_calculate_dividends_and_incentives() { let incentives_total = incentives .values() .copied() - .fold(AlphaCurrency::ZERO, |acc, x| acc + x); + .fold(AlphaBalance::ZERO, |acc, x| acc + x); let dividends_total = - AlphaCurrency::from(dividends.values().sum::().to_num::()); + AlphaBalance::from(dividends.values().sum::().to_num::()); assert_eq!(dividends_total + incentives_total, total_emission); }); @@ -2319,8 +2323,8 @@ fn test_calculate_dividends_and_incentives_only_validators() { 1.into(), ); - let divdends = AlphaCurrency::from(123_456_789); - let incentive = AlphaCurrency::ZERO; + let divdends = AlphaBalance::from(123_456_789); + let incentive = AlphaBalance::ZERO; // Hotkey, Incentive, Dividend let hotkey_emission = vec![(hotkey, incentive, divdends)]; @@ -2331,12 +2335,12 @@ fn test_calculate_dividends_and_incentives_only_validators() { let incentives_total = incentives .values() .copied() - .fold(AlphaCurrency::ZERO, |acc, x| acc + x); + .fold(AlphaBalance::ZERO, |acc, x| acc + x); let dividends_total = - AlphaCurrency::from(dividends.values().sum::().to_num::()); + AlphaBalance::from(dividends.values().sum::().to_num::()); assert_eq!(dividends_total, divdends); - assert_eq!(incentives_total, AlphaCurrency::ZERO); + assert_eq!(incentives_total, AlphaBalance::ZERO); }); } @@ -2359,8 +2363,8 @@ fn test_calculate_dividends_and_incentives_only_miners() { 1.into(), ); - let divdends = AlphaCurrency::ZERO; - let incentive = AlphaCurrency::from(123_456_789); + let divdends = AlphaBalance::ZERO; + let incentive = AlphaBalance::from(123_456_789); // Hotkey, Incentive, Dividend let hotkey_emission = vec![(hotkey, incentive, divdends)]; @@ -2371,9 +2375,9 @@ fn test_calculate_dividends_and_incentives_only_miners() { let incentives_total = incentives .values() .copied() - .fold(AlphaCurrency::ZERO, |acc, x| acc + x); + .fold(AlphaBalance::ZERO, |acc, x| acc + x); let dividends_total = - AlphaCurrency::from(dividends.values().sum::().to_num::()); + AlphaBalance::from(dividends.values().sum::().to_num::()); assert_eq!(incentives_total, incentive); assert_eq!(dividends_total, divdends); @@ -2404,14 +2408,14 @@ fn test_distribute_emission_no_miners_all_drained() { SubtensorModule::set_tao_weight(0); // Set the emission to be 1 million. - let emission = AlphaCurrency::from(1_000_000); + let emission = AlphaBalance::from(1_000_000); // Run drain pending without any miners. SubtensorModule::distribute_emission( netuid, emission.saturating_div(2.into()).into(), emission.saturating_div(2.into()).into(), - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, ); // Get the new stake of the hotkey. @@ -2461,7 +2465,7 @@ fn test_distribute_emission_zero_emission() { run_to_block_no_epoch(netuid, 50); // Run epoch for initial setup. - SubtensorModule::epoch(netuid, AlphaCurrency::ZERO); + SubtensorModule::epoch(netuid, AlphaBalance::ZERO); // Set weights on miner assert_ok!(SubtensorModule::set_weights( @@ -2481,10 +2485,10 @@ fn test_distribute_emission_zero_emission() { // Set the emission to be ZERO. SubtensorModule::distribute_emission( netuid, - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, ); // Get the new stake of the hotkey. @@ -2553,7 +2557,7 @@ fn test_run_coinbase_not_started() { run_to_block_no_epoch(netuid, 30); // Run epoch for initial setup. - SubtensorModule::epoch(netuid, AlphaCurrency::ZERO); + SubtensorModule::epoch(netuid, AlphaBalance::ZERO); // Set weights on miner assert_ok!(SubtensorModule::set_weights( @@ -2644,7 +2648,7 @@ fn test_run_coinbase_not_started_start_after() { run_to_block_no_epoch(netuid, 30); // Run epoch for initial setup. - SubtensorModule::epoch(netuid, AlphaCurrency::ZERO); + SubtensorModule::epoch(netuid, AlphaBalance::ZERO); // Set weights on miner assert_ok!(SubtensorModule::set_weights( @@ -2713,8 +2717,8 @@ fn test_coinbase_v3_liquidity_update() { // Force the swap to initialize SubtensorModule::swap_tao_for_alpha( netuid, - TaoCurrency::ZERO, - 1_000_000_000_000.into(), + TaoBalance::ZERO, + 1_000_000_000_000_u64.into(), false, ) .unwrap(); @@ -2756,7 +2760,7 @@ fn test_drain_alpha_childkey_parentkey_with_burn() { let parent = U256::from(1); let child = U256::from(2); let coldkey = U256::from(3); - let stake_before = AlphaCurrency::from(1_000_000_000); + let stake_before = AlphaBalance::from(1_000_000_000); register_ok_neuron(netuid, child, coldkey, 0); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &parent, @@ -2773,13 +2777,13 @@ fn test_drain_alpha_childkey_parentkey_with_burn() { let parent_stake_before = SubtensorModule::get_stake_for_hotkey_on_subnet(&parent, netuid); let child_stake_before = SubtensorModule::get_stake_for_hotkey_on_subnet(&child, netuid); - let pending_alpha = AlphaCurrency::from(1_000_000_000); + let pending_alpha = AlphaBalance::from(1_000_000_000); SubtensorModule::distribute_emission( netuid, pending_alpha.saturating_div(2.into()).into(), pending_alpha.saturating_div(2.into()).into(), - AlphaCurrency::ZERO, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, + AlphaBalance::ZERO, ); let parent_stake_after = SubtensorModule::get_stake_for_hotkey_on_subnet(&parent, netuid); let child_stake_after = SubtensorModule::get_stake_for_hotkey_on_subnet(&child, netuid); @@ -2852,13 +2856,13 @@ fn test_incentive_is_autostaked_to_owner_destination() { ); // Distribute an incentive to the miner hotkey - let mut incentives: BTreeMap = BTreeMap::new(); - let incentive: AlphaCurrency = 10_000_000u64.into(); + let mut incentives: BTreeMap = BTreeMap::new(); + let incentive: AlphaBalance = 10_000_000u64.into(); incentives.insert(miner_hk, incentive); SubtensorModule::distribute_dividends_and_incentives( netuid, - AlphaCurrency::ZERO, // owner_cut + AlphaBalance::ZERO, // owner_cut incentives, BTreeMap::new(), // alpha_dividends BTreeMap::new(), // tao_dividends @@ -2898,13 +2902,13 @@ fn test_incentive_goes_to_hotkey_when_no_autostake_destination() { ); // Distribute an incentive to the miner hotkey - let mut incentives: BTreeMap = BTreeMap::new(); - let incentive: AlphaCurrency = 5_000_000u64.into(); + let mut incentives: BTreeMap = BTreeMap::new(); + let incentive: AlphaBalance = 5_000_000u64.into(); incentives.insert(miner_hk, incentive); SubtensorModule::distribute_dividends_and_incentives( netuid, - AlphaCurrency::ZERO, // owner_cut + AlphaBalance::ZERO, // owner_cut incentives, BTreeMap::new(), // alpha_dividends BTreeMap::new(), // tao_dividends @@ -2929,10 +2933,10 @@ fn test_zero_shares_zero_emission() { let emission: u64 = 1_000_000; // Setup prices 1 and 1 let initial: u64 = 1_000_000; - SubnetTAO::::insert(netuid1, TaoCurrency::from(initial)); - SubnetAlphaIn::::insert(netuid1, AlphaCurrency::from(initial)); - SubnetTAO::::insert(netuid2, TaoCurrency::from(initial)); - SubnetAlphaIn::::insert(netuid2, AlphaCurrency::from(initial)); + SubnetTAO::::insert(netuid1, TaoBalance::from(initial)); + SubnetAlphaIn::::insert(netuid1, AlphaBalance::from(initial)); + SubnetTAO::::insert(netuid2, TaoBalance::from(initial)); + SubnetAlphaIn::::insert(netuid2, AlphaBalance::from(initial)); // Set subnet prices so that both are // - cut off by lower limit for tao flow method // - zeroed out for price ema method @@ -2970,23 +2974,23 @@ fn test_mining_emission_distribution_with_no_root_sell() { SubnetMechanism::::insert(netuid, 1); // Set mechanism to 1 // Setup large LPs to prevent slippage - SubnetTAO::::insert(netuid, TaoCurrency::from(1_000_000_000_000_000)); - SubnetAlphaIn::::insert(netuid, AlphaCurrency::from(1_000_000_000_000_000)); + SubnetTAO::::insert(netuid, TaoBalance::from(1_000_000_000_000_000_u64)); + SubnetAlphaIn::::insert(netuid, AlphaBalance::from(1_000_000_000_000_000_u64)); register_ok_neuron(netuid, validator_hotkey, validator_coldkey, 0); register_ok_neuron(netuid, validator_miner_hotkey, validator_miner_coldkey, 1); register_ok_neuron(netuid, miner_hotkey, miner_coldkey, 2); SubtensorModule::add_balance_to_coldkey_account( &validator_coldkey, - stake + ExistentialDeposit::get(), + TaoBalance::from(stake) + ExistentialDeposit::get(), ); SubtensorModule::add_balance_to_coldkey_account( &validator_miner_coldkey, - stake + ExistentialDeposit::get(), + TaoBalance::from(stake) + ExistentialDeposit::get(), ); SubtensorModule::add_balance_to_coldkey_account( &miner_coldkey, - stake + ExistentialDeposit::get(), + TaoBalance::from(stake) + ExistentialDeposit::get(), ); SubtensorModule::set_weights_set_rate_limit(netuid, 0); step_block(subnet_tempo); @@ -3039,7 +3043,7 @@ fn test_mining_emission_distribution_with_no_root_sell() { // Make root sell NOT happen // set price very low, e.g. a lot of alpha in - //SubnetAlphaIn::::insert(netuid, AlphaCurrency::from(1_000_000_000_000_000)); + //SubnetAlphaIn::::insert(netuid, AlphaBalance::from(1_000_000_000_000_000)); pallet_subtensor_swap::AlphaSqrtPrice::::insert( netuid, U64F64::saturating_from_num(0.01), @@ -3070,7 +3074,7 @@ fn test_mining_emission_distribution_with_no_root_sell() { // Check root divs are zero assert_eq!( new_root_alpha_divs, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, "Root alpha divs should be zero" ); let miner_stake_before_epoch = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( @@ -3097,7 +3101,7 @@ fn test_mining_emission_distribution_with_no_root_sell() { let miner_uid = Uids::::get(netuid, miner_hotkey).unwrap_or(0); log::info!("Miner uid: {miner_uid:?}"); - let miner_incentive: AlphaCurrency = { + let miner_incentive: AlphaBalance = { let miner_incentive = Incentive::::get(NetUidStorageIndex::from(netuid)) .get(miner_uid as usize) .copied(); @@ -3165,23 +3169,23 @@ fn test_mining_emission_distribution_with_root_sell() { FirstEmissionBlockNumber::::insert(netuid, 0); // Setup large LPs to prevent slippage - SubnetTAO::::insert(netuid, TaoCurrency::from(1_000_000_000_000_000)); - SubnetAlphaIn::::insert(netuid, AlphaCurrency::from(1_000_000_000_000_000)); + SubnetTAO::::insert(netuid, TaoBalance::from(1_000_000_000_000_000_u64)); + SubnetAlphaIn::::insert(netuid, AlphaBalance::from(1_000_000_000_000_000_u64)); register_ok_neuron(netuid, validator_hotkey, validator_coldkey, 0); register_ok_neuron(netuid, validator_miner_hotkey, validator_miner_coldkey, 1); register_ok_neuron(netuid, miner_hotkey, miner_coldkey, 2); SubtensorModule::add_balance_to_coldkey_account( &validator_coldkey, - stake + ExistentialDeposit::get(), + TaoBalance::from(stake) + ExistentialDeposit::get(), ); SubtensorModule::add_balance_to_coldkey_account( &validator_miner_coldkey, - stake + ExistentialDeposit::get(), + TaoBalance::from(stake) + ExistentialDeposit::get(), ); SubtensorModule::add_balance_to_coldkey_account( &miner_coldkey, - stake + ExistentialDeposit::get(), + TaoBalance::from(stake) + ExistentialDeposit::get(), ); SubtensorModule::set_weights_set_rate_limit(netuid, 0); step_block(subnet_tempo); @@ -3266,7 +3270,7 @@ fn test_mining_emission_distribution_with_root_sell() { "Root alpha divs should be changing" ); assert!( - new_root_alpha_divs > AlphaCurrency::ZERO, + new_root_alpha_divs > AlphaBalance::ZERO, "Root alpha divs should be greater than 0" ); @@ -3274,7 +3278,7 @@ fn test_mining_emission_distribution_with_root_sell() { step_block(subnet_tempo - 1); let miner_uid = Uids::::get(netuid, miner_hotkey).unwrap_or(0); - let miner_incentive: AlphaCurrency = { + let miner_incentive: AlphaBalance = { let miner_incentive = Incentive::::get(NetUidStorageIndex::from(netuid)) .get(miner_uid as usize) .copied(); @@ -3360,8 +3364,8 @@ fn test_coinbase_subnet_terms_with_alpha_in_gt_alpha_emission() { let netuid0 = add_dynamic_network(&U256::from(1), &U256::from(2)); mock::setup_reserves( netuid0, - TaoCurrency::from(1_000_000_000_000_000), - AlphaCurrency::from(1_000_000_000_000_000), + TaoBalance::from(1_000_000_000_000_000_u64), + AlphaBalance::from(1_000_000_000_000_000_u64), ); // Initialize swap v3 Swap::maybe_initialize_v3(netuid0); @@ -3436,8 +3440,8 @@ fn test_coinbase_subnet_terms_with_alpha_in_lte_alpha_emission() { let netuid0 = add_dynamic_network(&U256::from(1), &U256::from(2)); mock::setup_reserves( netuid0, - TaoCurrency::from(1_000_000_000_000_000), - AlphaCurrency::from(1_000_000_000_000_000), + TaoBalance::from(1_000_000_000_000_000_u64), + AlphaBalance::from(1_000_000_000_000_000_u64), ); // Initialize swap v3 Swap::maybe_initialize_v3(netuid0); @@ -3499,8 +3503,8 @@ fn test_coinbase_inject_and_maybe_swap_does_not_skew_reserves() { let netuid0 = add_dynamic_network(&U256::from(1), &U256::from(2)); mock::setup_reserves( netuid0, - TaoCurrency::from(1_000_000_000_000_000), - AlphaCurrency::from(1_000_000_000_000_000), + TaoBalance::from(1_000_000_000_000_000_u64), + AlphaBalance::from(1_000_000_000_000_000_u64), ); // Initialize swap v3 Swap::maybe_initialize_v3(netuid0); @@ -3585,10 +3589,10 @@ fn test_coinbase_drain_pending_gets_counters_and_resets_them() { let block_number = 98; assert!(SubtensorModule::should_run_epoch(netuid0, block_number)); - let pending_server_em = AlphaCurrency::from(123434534); - let pending_validator_em = AlphaCurrency::from(111111); - let pending_root = AlphaCurrency::from(12222222); - let pending_owner_cut = AlphaCurrency::from(12345678); + let pending_server_em = AlphaBalance::from(123434534); + let pending_validator_em = AlphaBalance::from(111111); + let pending_root = AlphaBalance::from(12222222); + let pending_owner_cut = AlphaBalance::from(12345678); PendingServerEmission::::insert(netuid0, pending_server_em); PendingValidatorEmission::::insert(netuid0, pending_validator_em); @@ -3610,17 +3614,17 @@ fn test_coinbase_drain_pending_gets_counters_and_resets_them() { // Check that the pending emissions are reset assert_eq!( PendingServerEmission::::get(netuid0), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); assert_eq!( PendingValidatorEmission::::get(netuid0), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); assert_eq!( PendingRootAlphaDivs::::get(netuid0), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); - assert_eq!(PendingOwnerCut::::get(netuid0), AlphaCurrency::ZERO); + assert_eq!(PendingOwnerCut::::get(netuid0), AlphaBalance::ZERO); }); } @@ -3633,8 +3637,8 @@ fn test_coinbase_emit_to_subnets_with_no_root_sell() { SubnetOwnerCut::::set(u16::MAX / 10); mock::setup_reserves( netuid0, - TaoCurrency::from(1_000_000_000_000_000), - AlphaCurrency::from(1_000_000_000_000_000), + TaoBalance::from(1_000_000_000_000_000_u64), + AlphaBalance::from(1_000_000_000_000_000_u64), ); // Initialize swap v3 Swap::maybe_initialize_v3(netuid0); @@ -3675,7 +3679,7 @@ fn test_coinbase_emit_to_subnets_with_no_root_sell() { .checked_div(tao_weight.saturating_add(alpha_issuance)) .unwrap_or(U96F32::min_value()); // Expect root alpha divs to be root prop * alpha emission - let expected_root_alpha_divs: AlphaCurrency = AlphaCurrency::from( + let expected_root_alpha_divs: AlphaBalance = AlphaBalance::from( root_prop .saturating_mul(alpha_emission) .saturating_to_num::(), @@ -3691,7 +3695,7 @@ fn test_coinbase_emit_to_subnets_with_no_root_sell() { // NO root sell, so no root alpha divs assert_eq!( PendingRootAlphaDivs::::get(netuid0), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); // Should be alpha_emission minus the owner cut, assert_abs_diff_eq!( @@ -3724,8 +3728,8 @@ fn test_coinbase_emit_to_subnets_with_root_sell() { SubnetOwnerCut::::set(u16::MAX / 10); mock::setup_reserves( netuid0, - TaoCurrency::from(1_000_000_000_000_000), - AlphaCurrency::from(1_000_000_000_000_000), + TaoBalance::from(1_000_000_000_000_000_u64), + AlphaBalance::from(1_000_000_000_000_000_u64), ); // Initialize swap v3 Swap::maybe_initialize_v3(netuid0); @@ -3766,7 +3770,7 @@ fn test_coinbase_emit_to_subnets_with_root_sell() { .checked_div(tao_weight.saturating_add(alpha_issuance)) .unwrap_or(U96F32::min_value()); // Expect root alpha divs to be root prop * alpha emission - let expected_root_alpha_divs: AlphaCurrency = AlphaCurrency::from( + let expected_root_alpha_divs: AlphaBalance = AlphaBalance::from( root_prop .saturating_mul(alpha_emission) .saturating_to_num::(), @@ -3833,7 +3837,7 @@ fn test_pending_emission_start_call_not_done() { register_ok_neuron(netuid, validator_hotkey, validator_coldkey, 0); SubtensorModule::add_balance_to_coldkey_account( &validator_coldkey, - stake + ExistentialDeposit::get(), + TaoBalance::from(stake) + ExistentialDeposit::get(), ); SubtensorModule::set_weights_set_rate_limit(netuid, 0); step_block(subnet_tempo); @@ -3877,15 +3881,15 @@ fn test_pending_emission_start_call_not_done() { // Verify that all pending emissions are zero assert_eq!( PendingServerEmission::::get(netuid), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); assert_eq!( PendingValidatorEmission::::get(netuid), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); assert_eq!( PendingRootAlphaDivs::::get(netuid), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); }); } @@ -3898,11 +3902,11 @@ fn test_root_prop_filled_on_block_step() { let netuid1 = add_dynamic_network(&hotkey, &coldkey); let netuid2 = add_dynamic_network(&hotkey, &coldkey); - SubnetTAO::::insert(NetUid::ROOT, TaoCurrency::from(1_000_000_000_000u64)); + SubnetTAO::::insert(NetUid::ROOT, TaoBalance::from(1_000_000_000_000u64)); SubtensorModule::set_tao_weight(u64::MAX); // Set TAO weight to 1.0 - let tao_reserve = TaoCurrency::from(50_000_000_000); - let alpha_in = AlphaCurrency::from(100_000_000_000); + let tao_reserve = TaoBalance::from(50_000_000_000_u64); + let alpha_in = AlphaBalance::from(100_000_000_000_u64); SubnetTAO::::insert(netuid1, tao_reserve); SubnetAlphaIn::::insert(netuid1, alpha_in); SubnetTAO::::insert(netuid2, tao_reserve); @@ -3926,13 +3930,13 @@ fn test_root_proportion() { let netuid = add_dynamic_network(&hotkey, &coldkey); let root_tao_reserve = 1_000_000_000_000u64; - SubnetTAO::::insert(NetUid::ROOT, TaoCurrency::from(root_tao_reserve)); + SubnetTAO::::insert(NetUid::ROOT, TaoBalance::from(root_tao_reserve)); let tao_weight = 3_320_413_933_267_719_290u64; SubtensorModule::set_tao_weight(tao_weight); let alpha_in = 100_000_000_000u64; - SubnetAlphaIn::::insert(netuid, AlphaCurrency::from(alpha_in)); + SubnetAlphaIn::::insert(netuid, AlphaBalance::from(alpha_in)); let actual_root_proportion = SubtensorModule::root_proportion(netuid); let expected_root_prop = { @@ -3959,7 +3963,7 @@ fn test_get_subnet_terms_alpha_emissions_cap() { let netuid = add_dynamic_network(&owner_hotkey, &owner_coldkey); let tao_block_emission: U96F32 = U96F32::saturating_from_num( SubtensorModule::get_block_emission() - .unwrap_or(TaoCurrency::ZERO) + .unwrap_or(TaoBalance::ZERO) .to_u64(), ); diff --git a/pallets/subtensor/src/tests/consensus.rs b/pallets/subtensor/src/tests/consensus.rs index 454f41e2cf..4a85f652a8 100644 --- a/pallets/subtensor/src/tests/consensus.rs +++ b/pallets/subtensor/src/tests/consensus.rs @@ -9,7 +9,7 @@ use super::mock::*; use crate::*; use frame_support::assert_ok; -use rand::{Rng, SeedableRng, distributions::Uniform, rngs::StdRng, seq::SliceRandom, thread_rng}; +use rand::{RngExt, SeedableRng, distr::Uniform, rngs::StdRng, seq::SliceRandom}; use sp_core::U256; use std::time::Instant; use substrate_fixed::transcendental::{PI, cos, ln, sqrt}; @@ -111,7 +111,7 @@ fn distribute_nodes( } else if interleave == 2 { // random interleaving let mut permuted_uids: Vec = (0..network_n as u16).collect(); - permuted_uids.shuffle(&mut thread_rng()); + permuted_uids.shuffle(&mut rand::rng()); validators = permuted_uids[0..validators_n].into(); servers = permuted_uids[validators_n..network_n].into(); } @@ -185,7 +185,7 @@ fn init_run_epochs( }; // let stake: u64 = 1; // alternative test: all nodes receive stake, should be same outcome, except stake - SubtensorModule::add_balance_to_coldkey_account(&(U256::from(key)), stake); + SubtensorModule::add_balance_to_coldkey_account(&(U256::from(key)), stake.into()); SubtensorModule::append_neuron(netuid, &(U256::from(key)), 0); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &U256::from(key), @@ -207,7 +207,7 @@ fn init_run_epochs( // === Set weights let mut rng = StdRng::seed_from_u64(random_seed); // constant seed so weights over multiple runs are equal - let range = Uniform::new(0, u16::MAX); + let range = Uniform::new(0, u16::MAX).unwrap(); let mut weights: Vec = vec![u16::MAX / n; servers.len()]; for uid in validators { if random_weights { @@ -306,7 +306,7 @@ fn split_graph( let stddev: I32F32 = I32F32::from_num(0.3); let total_stake: I64F64 = I64F64::from_num(21_000_000_000_000_000_u64); let mut rng = StdRng::seed_from_u64(0); // constant seed so weights over multiple runs are equal - let dist = Uniform::new(0, u16::MAX); + let dist = Uniform::new(0, u16::MAX).unwrap(); let mut stake: Vec = vec![0; network_n]; let mut stake_fixed: Vec = vec![zero; network_n]; diff --git a/pallets/subtensor/src/tests/delegate_info.rs b/pallets/subtensor/src/tests/delegate_info.rs index 0553a88fe5..8c04c9d136 100644 --- a/pallets/subtensor/src/tests/delegate_info.rs +++ b/pallets/subtensor/src/tests/delegate_info.rs @@ -119,7 +119,10 @@ fn test_get_delegated() { let Some(delegate) = delegate else { continue; }; - SubtensorModule::add_balance_to_coldkey_account(delegatee, *amount + 500_000); + SubtensorModule::add_balance_to_coldkey_account( + delegatee, + (*amount + 500_000).into(), + ); assert_ok!(SubtensorModule::add_stake( RuntimeOrigin::signed(*delegatee), *delegate, diff --git a/pallets/subtensor/src/tests/epoch.rs b/pallets/subtensor/src/tests/epoch.rs index 32f754f78d..3775efbea0 100644 --- a/pallets/subtensor/src/tests/epoch.rs +++ b/pallets/subtensor/src/tests/epoch.rs @@ -9,10 +9,10 @@ use std::time::Instant; use approx::assert_abs_diff_eq; use frame_support::{assert_err, assert_ok}; -use rand::{Rng, SeedableRng, distributions::Uniform, rngs::StdRng, seq::SliceRandom, thread_rng}; +use rand::{RngExt, SeedableRng, distr::Uniform, rngs::StdRng, seq::SliceRandom}; use sp_core::{Get, U256}; use substrate_fixed::types::I32F32; -use subtensor_runtime_common::{AlphaCurrency, NetUidStorageIndex, TaoCurrency}; +use subtensor_runtime_common::{AlphaBalance, NetUidStorageIndex, TaoBalance}; use subtensor_swap_interface::SwapHandler; use super::mock::*; @@ -104,7 +104,7 @@ fn distribute_nodes( } else if interleave == 2 { // random interleaving let mut permuted_uids: Vec = (0..network_n as u16).collect(); - permuted_uids.shuffle(&mut thread_rng()); + permuted_uids.shuffle(&mut rand::rng()); validators = permuted_uids[0..validators_n].into(); servers = permuted_uids[validators_n..network_n].into(); } @@ -178,7 +178,7 @@ fn init_run_epochs( }; // let stake: u64 = 1; // alternative test: all nodes receive stake, should be same outcome, except stake - SubtensorModule::add_balance_to_coldkey_account(&(U256::from(key)), stake); + SubtensorModule::add_balance_to_coldkey_account(&(U256::from(key)), stake.into()); SubtensorModule::append_neuron(netuid, &(U256::from(key)), 0); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &U256::from(key), @@ -200,7 +200,7 @@ fn init_run_epochs( // === Set weights let mut rng = StdRng::seed_from_u64(random_seed); // constant seed so weights over multiple runs are equal - let range = Uniform::new(0, u16::MAX); + let range = Uniform::new(0, u16::MAX).unwrap(); let mut weights: Vec = vec![u16::MAX / n; servers.len()]; for uid in validators { if random_weights { @@ -565,7 +565,7 @@ fn test_1_graph() { SubtensorModule::set_max_allowed_uids(netuid, 1); SubtensorModule::add_balance_to_coldkey_account( &coldkey, - stake_amount + ExistentialDeposit::get(), + TaoBalance::from(stake_amount) + ExistentialDeposit::get(), ); register_ok_neuron(netuid, hotkey, coldkey, 1); SubtensorModule::set_weights_set_rate_limit(netuid, 0); @@ -656,7 +656,7 @@ fn test_10_graph() { for i in 0..n { assert_eq!( SubtensorModule::get_total_stake_for_hotkey(&(U256::from(i))), - TaoCurrency::from(1) + TaoBalance::from(1) ); assert_eq!(SubtensorModule::get_rank_for_uid(netuid, i as u16), 0); assert_eq!(SubtensorModule::get_trust_for_uid(netuid, i as u16), 0); @@ -734,7 +734,7 @@ fn test_512_graph() { for uid in servers { assert_eq!( SubtensorModule::get_total_stake_for_hotkey(&(U256::from(uid))), - TaoCurrency::ZERO + TaoBalance::ZERO ); assert_eq!(SubtensorModule::get_consensus_for_uid(netuid, uid), 146); assert_eq!( @@ -778,7 +778,7 @@ fn test_512_graph_random_weights() { Vec, Vec, Vec, - Vec, + Vec, Vec, Vec, ) = (vec![], vec![], vec![], vec![], vec![], vec![]); @@ -1024,7 +1024,7 @@ fn test_bonds() { // === Register [validator1, validator2, validator3, validator4, server1, server2, server3, server4] for key in 0..n as u64 { - SubtensorModule::add_balance_to_coldkey_account( &U256::from(key), max_stake ); + SubtensorModule::add_balance_to_coldkey_account( &U256::from(key), max_stake.into()); let (nonce, work): (u64, Vec) = SubtensorModule::create_work_for_block_number( netuid, block_number, key * 1_000_000, &U256::from(key)); assert_ok!(SubtensorModule::register(<::RuntimeOrigin>::signed(U256::from(key)), netuid, block_number, nonce, work, U256::from(key), U256::from(key))); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &U256::from(key), &U256::from(key), netuid, stakes[key as usize].into() ); @@ -1315,7 +1315,7 @@ fn test_set_alpha_disabled() { // Enable Liquid Alpha and setup SubtensorModule::set_liquid_alpha_enabled(netuid, true); migrations::migrate_create_root_network::migrate_create_root_network::(); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, 1_000_000_000_000_000); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, 1_000_000_000_000_000_u64.into()); assert_ok!(SubtensorModule::root_register(signer.clone(), hotkey,)); let fee = ::SwapInterface::approx_fee_amount( netuid.into(), @@ -1325,7 +1325,7 @@ fn test_set_alpha_disabled() { signer.clone(), hotkey, netuid, - TaoCurrency::from(5) * DefaultMinStake::::get() + fee + TaoBalance::from(5) * DefaultMinStake::::get() + fee )); // Only owner can set alpha values assert_ok!(SubtensorModule::register_network(signer.clone(), hotkey)); @@ -1367,7 +1367,7 @@ fn test_active_stake() { // === Register [validator1, validator2, server1, server2] for key in 0..n as u64 { - SubtensorModule::add_balance_to_coldkey_account(&U256::from(key), stake); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(key), stake.into()); let (nonce, work): (u64, Vec) = SubtensorModule::create_work_for_block_number( netuid, block_number, @@ -1585,7 +1585,7 @@ fn test_outdated_weights() { // === Register [validator1, validator2, server1, server2] for key in 0..n as u64 { - SubtensorModule::add_balance_to_coldkey_account(&U256::from(key), stake); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(key), stake.into()); let (nonce, work): (u64, Vec) = SubtensorModule::create_work_for_block_number( netuid, block_number, @@ -1789,7 +1789,7 @@ fn test_zero_weights() { )); } for validator in 0..(n / 2) as u64 { - SubtensorModule::add_balance_to_coldkey_account(&U256::from(validator), stake); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(validator), stake.into()); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &U256::from(validator), &U256::from(validator), @@ -1977,7 +1977,7 @@ fn test_deregistered_miner_bonds() { // === Register [validator1, validator2, server1, server2] let block_number = System::block_number(); for key in 0..n as u64 { - SubtensorModule::add_balance_to_coldkey_account(&U256::from(key), stake); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(key), stake.into()); let (nonce, work): (u64, Vec) = SubtensorModule::create_work_for_block_number( netuid, block_number, @@ -2172,7 +2172,7 @@ fn test_validator_permits() { for key in 0..network_n as u64 { SubtensorModule::add_balance_to_coldkey_account( &U256::from(key), - stake[key as usize], + stake[key as usize].into(), ); let (nonce, work): (u64, Vec) = SubtensorModule::create_work_for_block_number( @@ -2223,7 +2223,7 @@ fn test_validator_permits() { for server in &servers { SubtensorModule::add_balance_to_coldkey_account( &(U256::from(*server as u64)), - 2 * network_n as u64, + (2 * network_n as u64).into(), ); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &(U256::from(*server as u64)), @@ -2271,7 +2271,7 @@ fn test_get_set_alpha() { // Enable Liquid Alpha and setup SubtensorModule::set_liquid_alpha_enabled(netuid, true); migrations::migrate_create_root_network::migrate_create_root_network::(); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, 1_000_000_000_000_000); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, 1_000_000_000_000_000_u64.into()); assert_ok!(SubtensorModule::root_register(signer.clone(), hotkey,)); // Should fail as signer does not own the subnet @@ -2465,8 +2465,8 @@ fn test_can_set_self_weight_as_subnet_owner() { let other_hotkey: U256 = U256::from(2); - let stake = 5_000_000_000_000; // 5k TAO - let to_emit: u64 = 1_000_000_000; // 1 TAO + let stake = 5_000_000_000_000_u64; // 5k TAO + let to_emit: u64 = 1_000_000_000_u64; // 1 TAO // Create subnet let netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); @@ -2538,19 +2538,19 @@ fn test_epoch_outputs_single_staker_registered_no_weights() { 1.into(), ); - let pending_alpha = AlphaCurrency::from(1_000_000_000); + let pending_alpha = AlphaBalance::from(1_000_000_000); let hotkey_emission = SubtensorModule::epoch(netuid, pending_alpha); let sum_incentives = hotkey_emission .iter() .map(|(_, incentive, _)| incentive) .copied() - .fold(AlphaCurrency::ZERO, |acc, x| acc + x); - let sum_dividends: AlphaCurrency = hotkey_emission + .fold(AlphaBalance::ZERO, |acc, x| acc + x); + let sum_dividends: AlphaBalance = hotkey_emission .iter() .map(|(_, _, dividend)| dividend) .copied() - .fold(AlphaCurrency::ZERO, |acc, x| acc + x); + .fold(AlphaBalance::ZERO, |acc, x| acc + x); assert_abs_diff_eq!( sum_incentives.saturating_add(sum_dividends), @@ -2696,7 +2696,7 @@ fn setup_yuma_3_scenario(netuid: NetUid, n: u16, sparse: bool, max_stake: u64, s // === Register for key in 0..n as u64 { - SubtensorModule::add_balance_to_coldkey_account(&U256::from(key), max_stake); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(key), max_stake.into()); let (nonce, work): (u64, Vec) = SubtensorModule::create_work_for_block_number( netuid, block_number, @@ -3833,7 +3833,7 @@ fn test_last_update_size_mismatch() { SubtensorModule::set_max_allowed_uids(netuid, 1); SubtensorModule::add_balance_to_coldkey_account( &coldkey, - stake_amount + ExistentialDeposit::get(), + TaoBalance::from(stake_amount) + ExistentialDeposit::get(), ); register_ok_neuron(netuid, hotkey, coldkey, 1); SubtensorModule::set_weights_set_rate_limit(netuid, 0); diff --git a/pallets/subtensor/src/tests/epoch_logs.rs b/pallets/subtensor/src/tests/epoch_logs.rs index 38e3a1b734..265add2802 100644 --- a/pallets/subtensor/src/tests/epoch_logs.rs +++ b/pallets/subtensor/src/tests/epoch_logs.rs @@ -13,7 +13,7 @@ use frame_support::assert_ok; use sp_core::U256; use std::io::{Result as IoResult, Write}; use std::sync::{Arc, Mutex}; -use subtensor_runtime_common::{AlphaCurrency, MechId}; +use subtensor_runtime_common::{AlphaBalance, MechId}; use tracing_subscriber::{EnvFilter, layer::SubscriberExt}; const NETUID: u16 = 1; @@ -82,7 +82,7 @@ fn setup_epoch(neurons: Vec, mechanism_count: u8) { &hotkey, &U256::from(COLDKEY), netuid, - AlphaCurrency::from(neuron.alpha_stake), + AlphaBalance::from(neuron.alpha_stake), ); }); @@ -176,7 +176,7 @@ fn test_simple() { setup_epoch(neurons.to_vec(), 1); // Run epoch, watch logs - let emission = AlphaCurrency::from(1_000_000_000); + let emission = AlphaBalance::from(1_000_000_000); SubtensorModule::epoch_mechanism(NetUid::from(NETUID), MechId::from(0), emission); }); @@ -195,7 +195,7 @@ fn test_simple() { assert!(has("Normalized Validator Emission: [0.5, 0.5]")); assert!(has("Normalized Combined Emission: [0.5, 0.5]")); assert!(has( - "Combined Emission: [AlphaCurrency(500000000), AlphaCurrency(500000000)]" + "Combined Emission: [AlphaBalance(500000000), AlphaBalance(500000000)]" )); assert!(!has("math error:")); }); @@ -215,7 +215,7 @@ fn test_bad_permit_vector() { ValidatorPermit::::insert(NetUid::from(NETUID), vec![true]); // Run epoch, watch logs - let emission = AlphaCurrency::from(1_000_000_000); + let emission = AlphaBalance::from(1_000_000_000); SubtensorModule::epoch_mechanism(NetUid::from(NETUID), MechId::from(0), emission); }); @@ -225,7 +225,7 @@ fn test_bad_permit_vector() { "math error: inplace_mask_vector input lengths are not equal" )); assert!(has( - "Validator Emission: [AlphaCurrency(1000000000), AlphaCurrency(0)]" + "Validator Emission: [AlphaBalance(1000000000), AlphaBalance(0)]" )); }); } @@ -243,7 +243,7 @@ fn test_inactive_mask_zeroes_active_stake() { ]; setup_epoch(neurons.to_vec(), 1); - let emission = AlphaCurrency::from(1_000_000_000); + let emission = AlphaBalance::from(1_000_000_000); SubtensorModule::epoch_mechanism(NetUid::from(NETUID), MechId::from(0), emission); }); @@ -271,7 +271,7 @@ fn test_validator_permit_masks_active_stake() { let netuid = NetUid::from(NETUID); ValidatorPermit::::insert(netuid, vec![true, false]); - let emission = AlphaCurrency::from(1_000_000_000); + let emission = AlphaBalance::from(1_000_000_000); SubtensorModule::epoch_mechanism(netuid, MechId::from(0), emission); }); @@ -296,7 +296,7 @@ fn yuma_emergency_mode() { setup_epoch(neurons.to_vec(), 1); // No weights needed; keep defaults empty to make ranks/dividends zero. - let emission = AlphaCurrency::from(1_000_000_000); + let emission = AlphaBalance::from(1_000_000_000); SubtensorModule::epoch_mechanism(NetUid::from(NETUID), MechId::from(0), emission); }); @@ -319,7 +319,7 @@ fn epoch_uses_active_stake_when_nonzero_active() { ]; setup_epoch(neurons.to_vec(), 1); - let emission = AlphaCurrency::from(1_000_000_000); + let emission = AlphaBalance::from(1_000_000_000); SubtensorModule::epoch_mechanism(NetUid::from(NETUID), MechId::from(0), emission); }); @@ -347,7 +347,7 @@ fn epoch_topk_validator_permits() { let netuid = NetUid::from(NETUID); MaxAllowedValidators::::insert(netuid, 1u16); - let emission = AlphaCurrency::from(1_000_000_000); + let emission = AlphaBalance::from(1_000_000_000); SubtensorModule::epoch_mechanism(netuid, MechId::from(0), emission); }); @@ -375,7 +375,7 @@ fn epoch_yuma3_bonds_pipeline() { let netuid = NetUid::from(NETUID); Yuma3On::::insert(netuid, true); - let emission = AlphaCurrency::from(1_000_000_000); + let emission = AlphaBalance::from(1_000_000_000); SubtensorModule::epoch_mechanism(netuid, MechId::from(0), emission); }); @@ -402,7 +402,7 @@ fn epoch_original_yuma_bonds_pipeline() { let netuid = NetUid::from(NETUID); Yuma3On::::insert(netuid, false); - let emission = AlphaCurrency::from(1_000_000_000); + let emission = AlphaBalance::from(1_000_000_000); SubtensorModule::epoch_mechanism(netuid, MechId::from(0), emission); }); @@ -442,7 +442,7 @@ fn test_validators_weight_two_distinct_servers() { vec![3, 4], ); - let emission = AlphaCurrency::from(1_000_000_000); + let emission = AlphaBalance::from(1_000_000_000); SubtensorModule::epoch_mechanism(netuid, MechId::from(0), emission); }); @@ -491,7 +491,7 @@ fn test_validator_splits_weight_across_two_servers() { vec![3, 4], ); - let emission = AlphaCurrency::from(1_000_000_000); + let emission = AlphaBalance::from(1_000_000_000); SubtensorModule::epoch_mechanism(netuid, MechId::from(0), emission); }); @@ -533,7 +533,7 @@ fn epoch_mechanism_reads_weights_per_mechanism() { ], ); let logs_m0 = with_log_capture("trace", || { - SubtensorModule::epoch_mechanism(netuid, MechId::from(0), AlphaCurrency::from(1_000)); + SubtensorModule::epoch_mechanism(netuid, MechId::from(0), AlphaBalance::from(1_000)); }); // Mech 1: flipped routing: V0,V2 -> server 4 ; V1 -> server 3 @@ -547,7 +547,7 @@ fn epoch_mechanism_reads_weights_per_mechanism() { ], ); let logs_m1 = with_log_capture("trace", || { - SubtensorModule::epoch_mechanism(netuid, MechId::from(1), AlphaCurrency::from(1_000)); + SubtensorModule::epoch_mechanism(netuid, MechId::from(1), AlphaBalance::from(1_000)); }); // Both should run the full pipeline… @@ -609,13 +609,13 @@ fn epoch_mechanism_three_mechanisms_separate_state() { ); let l0 = with_log_capture("trace", || { - SubtensorModule::epoch_mechanism(netuid, MechId::from(0), AlphaCurrency::from(1_000)); + SubtensorModule::epoch_mechanism(netuid, MechId::from(0), AlphaBalance::from(1_000)); }); let l1 = with_log_capture("trace", || { - SubtensorModule::epoch_mechanism(netuid, MechId::from(1), AlphaCurrency::from(1_000)); + SubtensorModule::epoch_mechanism(netuid, MechId::from(1), AlphaBalance::from(1_000)); }); let l2 = with_log_capture("trace", || { - SubtensorModule::epoch_mechanism(netuid, MechId::from(2), AlphaCurrency::from(1_000)); + SubtensorModule::epoch_mechanism(netuid, MechId::from(2), AlphaBalance::from(1_000)); }); // Check major epoch indicators diff --git a/pallets/subtensor/src/tests/evm.rs b/pallets/subtensor/src/tests/evm.rs index 6d668d738d..ae0acde27a 100644 --- a/pallets/subtensor/src/tests/evm.rs +++ b/pallets/subtensor/src/tests/evm.rs @@ -9,6 +9,7 @@ use super::mock::*; use crate::*; use frame_support::testing_prelude::*; use sp_core::{H160, Pair, U256, blake2_256, ecdsa, keccak_256}; +use std::convert::AsRef; fn public_to_evm_key(pubkey: &ecdsa::Public) -> H160 { use libsecp256k1::PublicKey; @@ -103,7 +104,11 @@ fn test_associate_evm_key_different_block_number_success() { let hashed_block_number = keccak_256(block_number.encode().as_ref()); let hotkey_bytes = hotkey.encode(); - let message = [hotkey_bytes.as_ref(), hashed_block_number.as_ref()].concat(); + let message = [ + hotkey_bytes.as_ref(), + <[u8; 32] as AsRef<[u8]>>::as_ref(&hashed_block_number), + ] + .concat(); let signature = sign_evm_message(&pair, message); assert_ok!(SubtensorModule::associate_evm_key( @@ -145,7 +150,11 @@ fn test_associate_evm_key_coldkey_does_not_own_hotkey() { let hashed_block_number = keccak_256(block_number.encode().as_ref()); let hotkey_bytes = hotkey.encode(); - let message = [hotkey_bytes.as_ref(), hashed_block_number.as_ref()].concat(); + let message = [ + hotkey_bytes.as_ref(), + <[u8; 32] as AsRef<[u8]>>::as_ref(&hashed_block_number), + ] + .concat(); let signature = sign_evm_message(&pair, message); assert_err!( @@ -182,7 +191,11 @@ fn test_associate_evm_key_hotkey_not_registered_in_subnet() { let hashed_block_number = keccak_256(block_number.encode().as_ref()); let hotkey_bytes = hotkey.encode(); - let message = [hotkey_bytes.as_ref(), hashed_block_number.as_ref()].concat(); + let message = [ + hotkey_bytes.as_ref(), + <[u8; 32] as AsRef<[u8]>>::as_ref(&hashed_block_number), + ] + .concat(); let signature = sign_evm_message(&pair, message); assert_err!( @@ -222,7 +235,11 @@ fn test_associate_evm_key_using_wrong_hash_function() { let hashed_block_number = keccak_256(block_number.encode().as_ref()); let hotkey_bytes = hotkey.encode(); - let message = [hotkey_bytes.as_ref(), hashed_block_number.as_ref()].concat(); + let message = [ + hotkey_bytes.as_ref(), + <[u8; 32] as AsRef<[u8]>>::as_ref(&hashed_block_number), + ] + .concat(); let hashed_message = blake2_256(message.as_ref()); let signature = pair.sign_prehashed(&hashed_message); @@ -262,7 +279,11 @@ fn test_associate_evm_key_rate_limit_exceeded() { let hashed_block_number = keccak_256(block_number.encode().as_ref()); let hotkey_bytes = hotkey.encode(); - let message = [hotkey_bytes.as_ref(), hashed_block_number.as_ref()].concat(); + let message = [ + hotkey_bytes.as_ref(), + <[u8; 32] as AsRef<[u8]>>::as_ref(&hashed_block_number), + ] + .concat(); let signature = sign_evm_message(&pair, message); // First association should succeed @@ -278,7 +299,11 @@ fn test_associate_evm_key_rate_limit_exceeded() { let block_number = frame_system::Pallet::::block_number(); let hashed_block_number = keccak_256(block_number.encode().as_ref()); let hotkey_bytes = hotkey.encode(); - let message = [hotkey_bytes.as_ref(), hashed_block_number.as_ref()].concat(); + let message = [ + hotkey_bytes.as_ref(), + <[u8; 32] as AsRef<[u8]>>::as_ref(&hashed_block_number), + ] + .concat(); let signature = sign_evm_message(&pair, message); // Second association should fail due to rate limit @@ -297,7 +322,11 @@ fn test_associate_evm_key_rate_limit_exceeded() { let block_number = frame_system::Pallet::::block_number(); let hashed_block_number = keccak_256(block_number.encode().as_ref()); let hotkey_bytes = hotkey.encode(); - let message = [hotkey_bytes.as_ref(), hashed_block_number.as_ref()].concat(); + let message = [ + hotkey_bytes.as_ref(), + <[u8; 32] as AsRef<[u8]>>::as_ref(&hashed_block_number), + ] + .concat(); let signature = sign_evm_message(&pair, message); assert_ok!(SubtensorModule::associate_evm_key( @@ -329,7 +358,11 @@ fn test_associate_evm_key_uid_not_found() { let hashed_block_number = keccak_256(block_number.encode().as_ref()); let hotkey_bytes = hotkey.encode(); - let message = [hotkey_bytes.as_ref(), hashed_block_number.as_ref()].concat(); + let message = [ + hotkey_bytes.as_ref(), + <[u8; 32] as AsRef<[u8]>>::as_ref(&hashed_block_number), + ] + .concat(); let signature = sign_evm_message(&pair, message); assert_noop!( diff --git a/pallets/subtensor/src/tests/leasing.rs b/pallets/subtensor/src/tests/leasing.rs index 9f8bf4d6bf..0c6ae629c3 100644 --- a/pallets/subtensor/src/tests/leasing.rs +++ b/pallets/subtensor/src/tests/leasing.rs @@ -9,7 +9,7 @@ use frame_support::{StorageDoubleMap, assert_err, assert_ok}; use sp_core::U256; use sp_runtime::Percent; use substrate_fixed::types::U64F64; -use subtensor_runtime_common::AlphaCurrency; +use subtensor_runtime_common::AlphaBalance; #[test] fn test_register_leased_network_works() { @@ -69,7 +69,7 @@ fn test_register_leased_network_works() { assert_eq!(SubtensorModule::get_hotkey_take(&lease.hotkey), 0); // Ensure each contributor and beneficiary has been refunded their share of the leftover cap - let leftover_cap = cap.saturating_sub(lease.cost); + let leftover_cap = cap.saturating_sub(lease.cost.into()); let expected_contributor1_refund = U64F64::from(leftover_cap) .saturating_mul(contributor1_share) @@ -77,7 +77,7 @@ fn test_register_leased_network_works() { .to_num::(); assert_eq!( SubtensorModule::get_coldkey_balance(&contributions[0].0), - expected_contributor1_refund + expected_contributor1_refund.into() ); let expected_contributor2_refund = U64F64::from(leftover_cap) @@ -86,11 +86,11 @@ fn test_register_leased_network_works() { .to_num::(); assert_eq!( SubtensorModule::get_coldkey_balance(&contributions[1].0), - expected_contributor2_refund + expected_contributor2_refund.into() ); assert_eq!( SubtensorModule::get_coldkey_balance(&beneficiary), - leftover_cap - (expected_contributor1_refund + expected_contributor2_refund) + (leftover_cap - (expected_contributor1_refund + expected_contributor2_refund)).into() ); // Ensure the event is emitted @@ -511,32 +511,32 @@ fn test_distribute_lease_network_dividends_multiple_contributors_works() { &contributions[0].0, lease.netuid, ); - assert_eq!(contributor1_alpha_before, AlphaCurrency::ZERO); + assert_eq!(contributor1_alpha_before, AlphaBalance::ZERO); let contributor2_alpha_before = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( &lease.hotkey, &contributions[1].0, lease.netuid, ); - assert_eq!(contributor2_alpha_before, AlphaCurrency::ZERO); + assert_eq!(contributor2_alpha_before, AlphaBalance::ZERO); let beneficiary_alpha_before = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( &lease.hotkey, &beneficiary, lease.netuid, ); - assert_eq!(beneficiary_alpha_before, AlphaCurrency::ZERO); + assert_eq!(beneficiary_alpha_before, AlphaBalance::ZERO); // Setup some previously accumulated dividends - let accumulated_dividends = AlphaCurrency::from(10_000_000_000); + let accumulated_dividends = AlphaBalance::from(10_000_000_000_u64); AccumulatedLeaseDividends::::insert(lease_id, accumulated_dividends); // Distribute the dividends - let owner_cut_alpha = AlphaCurrency::from(5_000_000_000); + let owner_cut_alpha = AlphaBalance::from(5_000_000_000_u64); SubtensorModule::distribute_leased_network_dividends(lease_id, owner_cut_alpha); // Ensure the dividends were distributed correctly relative to their shares let distributed_alpha = accumulated_dividends + emissions_share.mul_ceil(owner_cut_alpha.to_u64()).into(); - assert_ne!(distributed_alpha, AlphaCurrency::ZERO); + assert_ne!(distributed_alpha, AlphaBalance::ZERO); let contributor1_alpha_delta = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( &lease.hotkey, @@ -544,7 +544,7 @@ fn test_distribute_lease_network_dividends_multiple_contributors_works() { lease.netuid, ) .saturating_sub(contributor1_alpha_before); - assert_ne!(contributor1_alpha_delta, AlphaCurrency::ZERO); + assert_ne!(contributor1_alpha_delta, AlphaBalance::ZERO); let contributor2_alpha_delta = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( &lease.hotkey, @@ -552,7 +552,7 @@ fn test_distribute_lease_network_dividends_multiple_contributors_works() { lease.netuid, ) .saturating_sub(contributor2_alpha_before); - assert_ne!(contributor2_alpha_delta, AlphaCurrency::ZERO); + assert_ne!(contributor2_alpha_delta, AlphaBalance::ZERO); let beneficiary_alpha_delta = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( &lease.hotkey, @@ -560,7 +560,7 @@ fn test_distribute_lease_network_dividends_multiple_contributors_works() { lease.netuid, ) .saturating_sub(beneficiary_alpha_before); - assert_ne!(beneficiary_alpha_delta, AlphaCurrency::ZERO); + assert_ne!(beneficiary_alpha_delta, AlphaBalance::ZERO); // What has been distributed should be equal to the sum of all contributors received alpha assert_eq!( @@ -614,7 +614,7 @@ fn test_distribute_lease_network_dividends_multiple_contributors_works() { // Ensure nothing was accumulated for later distribution assert_eq!( AccumulatedLeaseDividends::::get(lease_id), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); }); } @@ -650,20 +650,20 @@ fn test_distribute_lease_network_dividends_only_beneficiary_works() { &beneficiary, lease.netuid, ); - assert_eq!(beneficiary_alpha_before, AlphaCurrency::ZERO); + assert_eq!(beneficiary_alpha_before, AlphaBalance::ZERO); // Setup some previously accumulated dividends - let accumulated_dividends = AlphaCurrency::from(10_000_000_000); + let accumulated_dividends = AlphaBalance::from(10_000_000_000_u64); AccumulatedLeaseDividends::::insert(lease_id, accumulated_dividends); // Distribute the dividends - let owner_cut_alpha = AlphaCurrency::from(5_000_000_000); + let owner_cut_alpha = AlphaBalance::from(5_000_000_000_u64); SubtensorModule::distribute_leased_network_dividends(lease_id, owner_cut_alpha); // Ensure the dividends were distributed correctly relative to their shares let distributed_alpha = accumulated_dividends + emissions_share.mul_ceil(owner_cut_alpha.to_u64()).into(); - assert_ne!(distributed_alpha, AlphaCurrency::ZERO); + assert_ne!(distributed_alpha, AlphaBalance::ZERO); let beneficiary_alpha_delta = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( &lease.hotkey, &beneficiary, @@ -682,7 +682,7 @@ fn test_distribute_lease_network_dividends_only_beneficiary_works() { // Ensure nothing was accumulated for later distribution assert_eq!( AccumulatedLeaseDividends::::get(lease_id), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); }); } @@ -721,26 +721,26 @@ fn test_distribute_lease_network_dividends_accumulates_if_not_the_correct_block( &contributions[0].0, lease.netuid, ); - assert_eq!(contributor1_alpha_before, AlphaCurrency::ZERO); + assert_eq!(contributor1_alpha_before, AlphaBalance::ZERO); let contributor2_alpha_before = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( &lease.hotkey, &contributions[1].0, lease.netuid, ); - assert_eq!(contributor2_alpha_before, AlphaCurrency::ZERO); + assert_eq!(contributor2_alpha_before, AlphaBalance::ZERO); let beneficiary_alpha_before = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( &lease.hotkey, &beneficiary, lease.netuid, ); - assert_eq!(beneficiary_alpha_before, AlphaCurrency::ZERO); + assert_eq!(beneficiary_alpha_before, AlphaBalance::ZERO); // Setup some previously accumulated dividends - let accumulated_dividends = AlphaCurrency::from(10_000_000_000); + let accumulated_dividends = AlphaBalance::from(10_000_000_000_u64); AccumulatedLeaseDividends::::insert(lease_id, accumulated_dividends); // Distribute the dividends - let owner_cut_alpha = AlphaCurrency::from(5_000_000_000); + let owner_cut_alpha = AlphaBalance::from(5_000_000_000_u64); SubtensorModule::distribute_leased_network_dividends(lease_id, owner_cut_alpha); // Ensure the dividends were not distributed @@ -782,7 +782,7 @@ fn test_distribute_lease_network_dividends_accumulates_if_not_the_correct_block( fn test_distribute_lease_network_dividends_does_nothing_if_lease_does_not_exist() { new_test_ext(1).execute_with(|| { let lease_id = 0; - let owner_cut_alpha = AlphaCurrency::from(5_000_000); + let owner_cut_alpha = AlphaBalance::from(5_000_000); SubtensorModule::distribute_leased_network_dividends(lease_id, owner_cut_alpha); }); } @@ -821,26 +821,26 @@ fn test_distribute_lease_network_dividends_does_nothing_if_lease_has_ended() { &contributions[0].0, lease.netuid, ); - assert_eq!(contributor1_alpha_before, AlphaCurrency::ZERO); + assert_eq!(contributor1_alpha_before, AlphaBalance::ZERO); let contributor2_alpha_before = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( &lease.hotkey, &contributions[1].0, lease.netuid, ); - assert_eq!(contributor2_alpha_before, AlphaCurrency::ZERO); + assert_eq!(contributor2_alpha_before, AlphaBalance::ZERO); let beneficiary_alpha_before = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( &lease.hotkey, &beneficiary, lease.netuid, ); - assert_eq!(beneficiary_alpha_before, AlphaCurrency::ZERO); + assert_eq!(beneficiary_alpha_before, AlphaBalance::ZERO); // No dividends are present, lease is new let accumulated_dividends_before = AccumulatedLeaseDividends::::get(lease_id); - assert_eq!(accumulated_dividends_before, AlphaCurrency::ZERO); + assert_eq!(accumulated_dividends_before, AlphaBalance::ZERO); // Try to distribute the dividends - let owner_cut_alpha = AlphaCurrency::from(5_000_000_000); + let owner_cut_alpha = AlphaBalance::from(5_000_000_000_u64); SubtensorModule::distribute_leased_network_dividends(lease_id, owner_cut_alpha); // Ensure the dividends were not distributed @@ -907,22 +907,22 @@ fn test_distribute_lease_network_dividends_accumulates_if_amount_is_too_low() { &contributions[0].0, lease.netuid, ); - assert_eq!(contributor1_alpha_before, AlphaCurrency::ZERO); + assert_eq!(contributor1_alpha_before, AlphaBalance::ZERO); let contributor2_alpha_before = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( &lease.hotkey, &contributions[1].0, lease.netuid, ); - assert_eq!(contributor2_alpha_before, AlphaCurrency::ZERO); + assert_eq!(contributor2_alpha_before, AlphaBalance::ZERO); let beneficiary_alpha_before = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( &lease.hotkey, &beneficiary, lease.netuid, ); - assert_eq!(beneficiary_alpha_before, AlphaCurrency::ZERO); + assert_eq!(beneficiary_alpha_before, AlphaBalance::ZERO); // Try to distribute the dividends - let owner_cut_alpha = AlphaCurrency::from(5_000); + let owner_cut_alpha = AlphaBalance::from(5_000); SubtensorModule::distribute_leased_network_dividends(lease_id, owner_cut_alpha); // Ensure the dividends were not distributed @@ -988,22 +988,22 @@ fn test_distribute_lease_network_dividends_accumulates_if_insufficient_liquidity &contributions[0].0, lease.netuid, ); - assert_eq!(contributor1_alpha_before, AlphaCurrency::ZERO); + assert_eq!(contributor1_alpha_before, AlphaBalance::ZERO); let contributor2_alpha_before = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( &lease.hotkey, &contributions[1].0, lease.netuid, ); - assert_eq!(contributor2_alpha_before, AlphaCurrency::ZERO); + assert_eq!(contributor2_alpha_before, AlphaBalance::ZERO); let beneficiary_alpha_before = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( &lease.hotkey, &beneficiary, lease.netuid, ); - assert_eq!(beneficiary_alpha_before, AlphaCurrency::ZERO); + assert_eq!(beneficiary_alpha_before, AlphaBalance::ZERO); // Try to distribute the dividends - let owner_cut_alpha = AlphaCurrency::from(5_000_000); + let owner_cut_alpha = AlphaBalance::from(5_000_000); SubtensorModule::distribute_leased_network_dividends(lease_id, owner_cut_alpha); // Ensure the dividends were not distributed @@ -1047,13 +1047,15 @@ fn setup_crowdloan( contributions: &[(U256, u64)], ) { let funds_account = U256::from(42424242 + id); + let deposit = TaoBalance::from(deposit); + let cap = TaoBalance::from(cap); pallet_crowdloan::Crowdloans::::insert( id, pallet_crowdloan::CrowdloanInfo { creator: beneficiary, deposit, - min_contribution: 0, + min_contribution: TaoBalance::ZERO, end: 0, cap, raised: cap, @@ -1068,6 +1070,7 @@ fn setup_crowdloan( // Simulate contributions pallet_crowdloan::Contributions::::insert(id, beneficiary, deposit); for (contributor, amount) in contributions { + let amount = TaoBalance::from(*amount); pallet_crowdloan::Contributions::::insert(id, contributor, amount); } @@ -1096,7 +1099,7 @@ fn setup_leased_network( SubtokenEnabled::::insert(netuid, true); if let Some(tao_to_stake) = tao_to_stake { - SubtensorModule::add_balance_to_coldkey_account(&lease.coldkey, tao_to_stake); + SubtensorModule::add_balance_to_coldkey_account(&lease.coldkey, tao_to_stake.into()); assert_ok!(SubtensorModule::add_stake( RuntimeOrigin::signed(lease.coldkey), lease.hotkey, diff --git a/pallets/subtensor/src/tests/math.rs b/pallets/subtensor/src/tests/math.rs index 6c6636ca68..6591d975b0 100644 --- a/pallets/subtensor/src/tests/math.rs +++ b/pallets/subtensor/src/tests/math.rs @@ -6,7 +6,7 @@ use substrate_fixed::types::{I32F32, I64F64}; use crate::epoch::math::*; -use rand::{Rng, seq::SliceRandom, thread_rng}; +use rand::{RngExt, seq::SliceRandom}; use substrate_fixed::{ transcendental::exp, types::{I96F32, I110F18}, @@ -1437,7 +1437,7 @@ fn test_math_col_clip_sparse() { #[test] fn test_math_weighted_median() { - let mut rng = thread_rng(); + let mut rng = rand::rng(); let zero: I32F32 = fixed(0.); let one: I32F32 = fixed(1.); for _ in 0..100 { @@ -1631,11 +1631,11 @@ fn test_math_weighted_median() { let mut last_score: I32F32 = zero; for i in 0..n { if allow_equal { - match rng.gen_range(0..2) { + match rng.random_range(0..2) { 1 => stake.push(one), _ => stake.push(zero), } - if rng.gen_range(0..2) == 1 { + if rng.random_range(0..2) == 1 { last_score += one } score.push(last_score); @@ -1681,7 +1681,7 @@ fn test_math_weighted_median() { assert!(medians.contains(&result)); for _ in 0..10 { let mut permuted_uids: Vec = (0..n).collect(); - permuted_uids.shuffle(&mut thread_rng()); + permuted_uids.shuffle(&mut rng); stake = permuted_uids.iter().map(|&i| stake[i]).collect(); score = permuted_uids.iter().map(|&i| score[i]).collect(); let result: I32F32 = diff --git a/pallets/subtensor/src/tests/mechanism.rs b/pallets/subtensor/src/tests/mechanism.rs index 7f0ead8918..6cf37fbcc1 100644 --- a/pallets/subtensor/src/tests/mechanism.rs +++ b/pallets/subtensor/src/tests/mechanism.rs @@ -393,8 +393,8 @@ fn split_emissions_even_division() { new_test_ext(1).execute_with(|| { let netuid = NetUid::from(5u16); MechanismCountCurrent::::insert(netuid, MechId::from(5u8)); // 5 sub-subnets - let out = SubtensorModule::split_emissions(netuid, AlphaCurrency::from(25u64)); - assert_eq!(out, vec![AlphaCurrency::from(5u64); 5]); + let out = SubtensorModule::split_emissions(netuid, AlphaBalance::from(25u64)); + assert_eq!(out, vec![AlphaBalance::from(5u64); 5]); }); } @@ -403,14 +403,14 @@ fn split_emissions_rounding_to_first() { new_test_ext(1).execute_with(|| { let netuid = NetUid::from(6u16); MechanismCountCurrent::::insert(netuid, MechId::from(4u8)); // 4 sub-subnets - let out = SubtensorModule::split_emissions(netuid, AlphaCurrency::from(10u64)); // 10 / 4 = 2, rem=2 + let out = SubtensorModule::split_emissions(netuid, AlphaBalance::from(10u64)); // 10 / 4 = 2, rem=2 assert_eq!( out, vec![ - AlphaCurrency::from(4u64), // 2 + remainder(2) - AlphaCurrency::from(2u64), - AlphaCurrency::from(2u64), - AlphaCurrency::from(2u64), + AlphaBalance::from(4u64), // 2 + remainder(2) + AlphaBalance::from(2u64), + AlphaBalance::from(2u64), + AlphaBalance::from(2u64), ] ); }); @@ -422,15 +422,15 @@ fn split_emissions_fibbonacci() { let netuid = NetUid::from(5u16); MechanismCountCurrent::::insert(netuid, MechId::from(5u8)); // 5 sub-subnets MechanismEmissionSplit::::insert(netuid, vec![3450, 6899, 10348, 17247, 27594]); - let out = SubtensorModule::split_emissions(netuid, AlphaCurrency::from(19u64)); + let out = SubtensorModule::split_emissions(netuid, AlphaBalance::from(19u64)); assert_eq!( out, vec![ - AlphaCurrency::from(1u64), - AlphaCurrency::from(2u64), - AlphaCurrency::from(3u64), - AlphaCurrency::from(5u64), - AlphaCurrency::from(8u64), + AlphaBalance::from(1u64), + AlphaBalance::from(2u64), + AlphaBalance::from(3u64), + AlphaBalance::from(5u64), + AlphaBalance::from(8u64), ] ); }); @@ -461,7 +461,7 @@ pub fn mock_epoch_state(netuid: NetUid, ck0: U256, hk0: U256, ck1: U256, hk1: U2 BlockAtRegistration::::insert(netuid, 1, 1u64); // Add stake - let stake_amount = AlphaCurrency::from(1_000_000_000); // 1 Alpha + let stake_amount = AlphaBalance::from(1_000_000_000); // 1 Alpha SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &hk0, &ck0, @@ -511,7 +511,7 @@ fn epoch_with_mechanisms_produces_per_mechanism_incentive() { let hk0 = U256::from(2); let ck1 = U256::from(3); let hk1 = U256::from(4); - let emission = AlphaCurrency::from(1_000_000_000); + let emission = AlphaBalance::from(1_000_000_000); mock_epoch_state(netuid, ck0, hk0, ck1, hk1); SubtensorModule::epoch_with_mechanisms(netuid, emission); @@ -536,7 +536,7 @@ fn epoch_with_mechanisms_updates_bonds() { let hk0 = U256::from(2); let ck1 = U256::from(3); let hk1 = U256::from(4); - let emission = AlphaCurrency::from(1_000_000_000); + let emission = AlphaBalance::from(1_000_000_000); mock_epoch_state(netuid, ck0, hk0, ck1, hk1); @@ -572,7 +572,7 @@ fn epoch_with_mechanisms_incentives_proportional_to_weights() { let ck1 = U256::from(3); let hk1 = U256::from(4); let hk2 = U256::from(6); - let emission = AlphaCurrency::from(1_000_000_000); + let emission = AlphaBalance::from(1_000_000_000); mock_epoch_state(netuid, ck0, hk0, ck1, hk1); mock_3_neurons(netuid, hk2); @@ -627,7 +627,7 @@ fn epoch_with_mechanisms_persists_and_aggregates_all_terms() { let ck1 = U256::from(3); let hk1 = U256::from(4); let hk2 = U256::from(6); - let emission = AlphaCurrency::from(1_000_000_000u64); + let emission = AlphaBalance::from(1_000_000_000u64); // Healthy minimal state and 3rd neuron mock_epoch_state(netuid, ck0, hk0, ck1, hk1); @@ -801,7 +801,7 @@ fn epoch_with_mechanisms_no_weight_no_incentive() { let ck1 = U256::from(3); let hk1 = U256::from(4); let hk2 = U256::from(5); // No weight miner - let emission = AlphaCurrency::from(1_000_000_000); + let emission = AlphaBalance::from(1_000_000_000); mock_epoch_state(netuid, ck0, hk0, ck1, hk1); mock_3_neurons(netuid, hk2); @@ -841,9 +841,9 @@ fn neuron_dereg_cleans_weights_across_subids() { Emission::::insert( netuid, vec![ - AlphaCurrency::from(1u64), - AlphaCurrency::from(9u64), - AlphaCurrency::from(3u64), + AlphaBalance::from(1u64), + AlphaBalance::from(9u64), + AlphaBalance::from(3u64), ], ); Consensus::::insert(netuid, vec![21u16, 88u16, 44u16]); @@ -907,7 +907,7 @@ fn clear_neuron_handles_absent_rows_gracefully() { MechanismCountCurrent::::insert(netuid, MechId::from(1u8)); // single sub-subnet // Minimal vectors with non-zero at index 0 (we will clear UID=0) - Emission::::insert(netuid, vec![AlphaCurrency::from(5u64)]); + Emission::::insert(netuid, vec![AlphaBalance::from(5u64)]); Consensus::::insert(netuid, vec![6u16]); Dividends::::insert(netuid, vec![7u16]); @@ -918,7 +918,7 @@ fn clear_neuron_handles_absent_rows_gracefully() { // Emission/Consensus/Dividends zeroed at index 0 assert_eq!( Emission::::get(netuid), - vec![AlphaCurrency::from(0u64)] + vec![AlphaBalance::from(0u64)] ); assert_eq!(Consensus::::get(netuid), vec![0u16]); @@ -951,7 +951,7 @@ fn test_set_mechanism_weights_happy_path_sets_row_under_subid() { // Make caller a permitted validator with stake SubtensorModule::set_stake_threshold(0); SubtensorModule::set_validator_permit_for_uid(netuid, uid1, true); - SubtensorModule::add_balance_to_coldkey_account(&ck1, 1); + SubtensorModule::add_balance_to_coldkey_account(&ck1, 1.into()); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &hk1, &ck1, @@ -1008,7 +1008,7 @@ fn test_set_mechanism_weights_above_mechanism_count_fails() { // Make caller a permitted validator with stake SubtensorModule::set_stake_threshold(0); SubtensorModule::set_validator_permit_for_uid(netuid, uid1, true); - SubtensorModule::add_balance_to_coldkey_account(&ck1, 1); + SubtensorModule::add_balance_to_coldkey_account(&ck1, 1.into()); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &hk1, &ck1, @@ -1066,7 +1066,7 @@ fn test_commit_reveal_mechanism_weights_ok() { SubtensorModule::set_weights_set_rate_limit(netuid, 5); SubtensorModule::set_validator_permit_for_uid(netuid, uid1, true); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); - SubtensorModule::add_balance_to_coldkey_account(&ck1, 1); + SubtensorModule::add_balance_to_coldkey_account(&ck1, 1.into()); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &hk1, &ck1, @@ -1150,7 +1150,7 @@ fn test_commit_reveal_above_mechanism_count_fails() { SubtensorModule::set_weights_set_rate_limit(netuid, 5); SubtensorModule::set_validator_permit_for_uid(netuid, uid1, true); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); - SubtensorModule::add_balance_to_coldkey_account(&ck1, 1); + SubtensorModule::add_balance_to_coldkey_account(&ck1, 1.into()); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &hk1, &ck1, @@ -1237,8 +1237,8 @@ fn test_reveal_crv3_commits_sub_success() { SubtensorModule::set_validator_permit_for_uid(netuid, uid1, true); SubtensorModule::set_validator_permit_for_uid(netuid, uid2, true); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(3), 1); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(4), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(3), 1.into()); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(4), 1.into()); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet(&hotkey1, &U256::from(3), netuid, 1.into()); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet(&hotkey2, &U256::from(4), netuid, 1.into()); @@ -1342,7 +1342,7 @@ fn test_crv3_above_mechanism_count_fails() { let uid2 = SubtensorModule::get_uid_for_net_and_hotkey(netuid, &hotkey2).expect("uid2"); SubtensorModule::set_validator_permit_for_uid(netuid, uid1, true); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(3), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(3), 1.into()); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet(&hotkey1, &U256::from(3), netuid, 1.into()); let version_key = SubtensorModule::get_weights_version_key(netuid); @@ -1412,7 +1412,7 @@ fn test_do_commit_crv3_mechanism_weights_committing_too_fast() { // make validator with stake SubtensorModule::set_stake_threshold(0); SubtensorModule::set_validator_permit_for_uid(netuid, uid, true); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(2), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(2), 1.into()); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &hotkey, &U256::from(2), @@ -1523,29 +1523,29 @@ fn epoch_mechanism_emergency_mode_distributes_by_stake() { // (leave Weights/Bonds empty for all rows on this sub-subnet) // stake proportions: uid0:uid1:uid2 = 10:30:60 - SubtensorModule::add_balance_to_coldkey_account(&ck0, 10); - SubtensorModule::add_balance_to_coldkey_account(&ck1, 30); - SubtensorModule::add_balance_to_coldkey_account(&ck2, 60); + SubtensorModule::add_balance_to_coldkey_account(&ck0, 10.into()); + SubtensorModule::add_balance_to_coldkey_account(&ck1, 30.into()); + SubtensorModule::add_balance_to_coldkey_account(&ck2, 60.into()); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &hk0, &ck0, netuid, - AlphaCurrency::from(10), + AlphaBalance::from(10), ); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &hk1, &ck1, netuid, - AlphaCurrency::from(30), + AlphaBalance::from(30), ); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &hk2, &ck2, netuid, - AlphaCurrency::from(60), + AlphaBalance::from(60), ); - let emission = AlphaCurrency::from(1_000_000u64); + let emission = AlphaBalance::from(1_000_000u64); // --- act: run epoch on this sub-subnet only --- let out = SubtensorModule::epoch_mechanism(netuid, mecid, emission); diff --git a/pallets/subtensor/src/tests/migration.rs b/pallets/subtensor/src/tests/migration.rs index beec7a3cba..f4d0347686 100644 --- a/pallets/subtensor/src/tests/migration.rs +++ b/pallets/subtensor/src/tests/migration.rs @@ -28,7 +28,7 @@ use sp_io::hashing::twox_128; 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}; +use subtensor_runtime_common::{NetUidStorageIndex, TaoBalance}; #[allow(clippy::arithmetic_side_effects)] fn close(value: u64, target: u64, eps: u64) { @@ -43,9 +43,9 @@ fn test_initialise_ti() { use frame_support::traits::OnRuntimeUpgrade; new_test_ext(1).execute_with(|| { - pallet_balances::TotalIssuance::::put(1000); - crate::SubnetTAO::::insert(NetUid::from(1), TaoCurrency::from(100)); - crate::SubnetTAO::::insert(NetUid::from(2), TaoCurrency::from(5)); + pallet_balances::TotalIssuance::::put(TaoBalance::from(1000)); + crate::SubnetTAO::::insert(NetUid::from(1), TaoBalance::from(100)); + crate::SubnetTAO::::insert(NetUid::from(2), TaoBalance::from(5)); // Ensure values are NOT initialized prior to running migration assert!(crate::TotalIssuance::::get().is_zero()); @@ -54,9 +54,9 @@ fn test_initialise_ti() { crate::migrations::migrate_init_total_issuance::initialise_total_issuance::Migration::::on_runtime_upgrade(); // Ensure values were initialized correctly - assert_eq!(crate::TotalStake::::get(), TaoCurrency::from(105)); + assert_eq!(crate::TotalStake::::get(), TaoBalance::from(105)); assert_eq!( - crate::TotalIssuance::::get(), TaoCurrency::from(105 + 1000) + crate::TotalIssuance::::get(), TaoBalance::from(105 + 1000) ); }); } @@ -482,11 +482,11 @@ fn test_migrate_remove_zero_total_hotkey_alpha() { let hotkey_nonzero = U256::from(101u64); // Insert one zero-alpha entry and one non-zero entry - TotalHotkeyAlpha::::insert(hotkey_zero, netuid, AlphaCurrency::ZERO); - TotalHotkeyAlpha::::insert(hotkey_nonzero, netuid, AlphaCurrency::from(123)); + TotalHotkeyAlpha::::insert(hotkey_zero, netuid, AlphaBalance::ZERO); + TotalHotkeyAlpha::::insert(hotkey_nonzero, netuid, AlphaBalance::from(123)); - assert_eq!(TotalHotkeyAlpha::::get(hotkey_zero, netuid), AlphaCurrency::ZERO); - assert_eq!(TotalHotkeyAlpha::::get(hotkey_nonzero, netuid), AlphaCurrency::from(123)); + assert_eq!(TotalHotkeyAlpha::::get(hotkey_zero, netuid), AlphaBalance::ZERO); + assert_eq!(TotalHotkeyAlpha::::get(hotkey_nonzero, netuid), AlphaBalance::from(123)); assert!( !HasMigrationRun::::get(MIGRATION_NAME.as_bytes().to_vec()), @@ -505,7 +505,7 @@ fn test_migrate_remove_zero_total_hotkey_alpha() { "Zero-alpha entry should have been removed." ); - assert_eq!(TotalHotkeyAlpha::::get(hotkey_nonzero, netuid), AlphaCurrency::from(123)); + assert_eq!(TotalHotkeyAlpha::::get(hotkey_nonzero, netuid), AlphaBalance::from(123)); assert!( !weight.is_zero(), @@ -1178,7 +1178,7 @@ fn test_migrate_fix_root_subnet_tao() { new_test_ext(1).execute_with(|| { const MIGRATION_NAME: &str = "migrate_fix_root_subnet_tao"; - let mut expected_total_stake = 0; + let mut expected_total_stake = 0_u64; // Seed some hotkeys with some fake stake. for i in 0..100_000 { Owner::::insert(U256::from(U256::from(i)), U256::from(i + 1_000_000)); @@ -1186,12 +1186,12 @@ fn test_migrate_fix_root_subnet_tao() { TotalHotkeyAlpha::::insert( U256::from(U256::from(i)), NetUid::ROOT, - AlphaCurrency::from(stake), + AlphaBalance::from(stake), ); expected_total_stake += stake; } - assert_eq!(SubnetTAO::::get(NetUid::ROOT), TaoCurrency::ZERO); + assert_eq!(SubnetTAO::::get(NetUid::ROOT), TaoBalance::ZERO); assert!( !HasMigrationRun::::get(MIGRATION_NAME.as_bytes().to_vec()), "Migration should not have run yet" @@ -1221,12 +1221,12 @@ fn test_migrate_fix_root_tao_and_alpha_in() { const MIGRATION_NAME: &str = "migrate_fix_root_tao_and_alpha_in"; // Set counters initially - let initial_value = 1_000_000_000_000; - SubnetTAO::::insert(NetUid::ROOT, TaoCurrency::from(initial_value)); - SubnetAlphaIn::::insert(NetUid::ROOT, AlphaCurrency::from(initial_value)); - SubnetAlphaOut::::insert(NetUid::ROOT, AlphaCurrency::from(initial_value)); + let initial_value = 1_000_000_000_000_u64; + SubnetTAO::::insert(NetUid::ROOT, TaoBalance::from(initial_value)); + SubnetAlphaIn::::insert(NetUid::ROOT, AlphaBalance::from(initial_value)); + SubnetAlphaOut::::insert(NetUid::ROOT, AlphaBalance::from(initial_value)); SubnetVolume::::insert(NetUid::ROOT, initial_value as u128); - TotalStake::::set(TaoCurrency::from(initial_value)); + TotalStake::::set(TaoBalance::from(initial_value)); assert!( !HasMigrationRun::::get(MIGRATION_NAME.as_bytes().to_vec()), @@ -2564,15 +2564,15 @@ fn do_setup_unactive_sn() -> (Vec, Vec) { .collect(); let initial_tao = Pallet::::get_network_min_lock(); - let initial_alpha: AlphaCurrency = initial_tao.to_u64().into(); + let initial_alpha: AlphaBalance = initial_tao.to_u64().into(); const EXTRA_POOL_TAO: u64 = 123_123_u64; const EXTRA_POOL_ALPHA: u64 = 123_123_u64; // Add stake to the subnet pools for netuid in &netuids { - let extra_for_pool = TaoCurrency::from(EXTRA_POOL_TAO); - let stake_in_pool = TaoCurrency::from( + let extra_for_pool = TaoBalance::from(EXTRA_POOL_TAO); + let stake_in_pool = TaoBalance::from( u64::from(initial_tao) .checked_add(EXTRA_POOL_TAO) .expect("initial_tao + extra_for_pool overflow"), @@ -2591,13 +2591,13 @@ fn do_setup_unactive_sn() -> (Vec, Vec) { *total_issuance = updated_total.into(); }); - let subnet_alpha_in = AlphaCurrency::from( + let subnet_alpha_in = AlphaBalance::from( u64::from(initial_alpha) .checked_add(EXTRA_POOL_ALPHA) .expect("initial alpha + extra alpha overflow"), ); SubnetAlphaIn::::insert(netuid, subnet_alpha_in); - SubnetAlphaOut::::insert(netuid, AlphaCurrency::from(EXTRA_POOL_ALPHA)); + SubnetAlphaOut::::insert(netuid, AlphaBalance::from(EXTRA_POOL_ALPHA)); SubnetVolume::::insert(netuid, 123123_u128); // Try registering on the subnet to simulate a real network @@ -2628,7 +2628,7 @@ fn do_setup_unactive_sn() -> (Vec, Vec) { SubtokenEnabled::::insert(netuid, true); } - let alpha_amt = AlphaCurrency::from(123123_u64); + let alpha_amt = AlphaBalance::from(123123_u64); // Create some Stake entries for netuid in &netuids { for hotkey in 0..10 { @@ -2648,16 +2648,16 @@ fn do_setup_unactive_sn() -> (Vec, Vec) { } } // Add some pending emissions - let alpha_em_amt = AlphaCurrency::from(355555_u64); + let alpha_em_amt = AlphaBalance::from(355555_u64); for netuid in &netuids { PendingServerEmission::::insert(netuid, alpha_em_amt); PendingValidatorEmission::::insert(netuid, alpha_em_amt); PendingRootAlphaDivs::::insert(netuid, alpha_em_amt); PendingOwnerCut::::insert(netuid, alpha_em_amt); - SubnetTaoInEmission::::insert(netuid, TaoCurrency::from(12345678_u64)); - SubnetAlphaInEmission::::insert(netuid, AlphaCurrency::from(12345678_u64)); - SubnetAlphaOutEmission::::insert(netuid, AlphaCurrency::from(12345678_u64)); + SubnetTaoInEmission::::insert(netuid, TaoBalance::from(12345678_u64)); + SubnetAlphaInEmission::::insert(netuid, AlphaBalance::from(12345678_u64)); + SubnetAlphaOutEmission::::insert(netuid, AlphaBalance::from(12345678_u64)); } (active_netuids, inactive_netuids) @@ -2669,7 +2669,7 @@ fn test_migrate_reset_unactive_sn_get_unactive_netuids() { let (active_netuids, inactive_netuids) = do_setup_unactive_sn(); let initial_tao = Pallet::::get_network_min_lock(); - let initial_alpha: AlphaCurrency = initial_tao.to_u64().into(); + let initial_alpha: AlphaBalance = initial_tao.to_u64().into(); let (unactive_netuids, w) = crate::migrations::migrate_reset_unactive_sn::get_unactive_sn_netuids::( @@ -2696,7 +2696,7 @@ fn test_migrate_reset_unactive_sn() { let (active_netuids, inactive_netuids) = do_setup_unactive_sn(); let initial_tao = Pallet::::get_network_min_lock(); - let initial_alpha: AlphaCurrency = initial_tao.to_u64().into(); + let initial_alpha: AlphaBalance = initial_tao.to_u64().into(); // Run the migration let w = crate::migrations::migrate_reset_unactive_sn::migrate_reset_unactive_sn::(); @@ -2706,21 +2706,21 @@ fn test_migrate_reset_unactive_sn() { for netuid in &inactive_netuids { let actual_tao_lock_amount = SubnetLocked::::get(*netuid); let actual_tao_lock_amount_less_pool_tao = if (actual_tao_lock_amount < initial_tao) { - TaoCurrency::ZERO + TaoBalance::ZERO } else { actual_tao_lock_amount - initial_tao }; assert_eq!( PendingServerEmission::::get(netuid), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); assert_eq!( PendingValidatorEmission::::get(netuid), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); assert_eq!( PendingRootAlphaDivs::::get(netuid), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); assert_eq!( // not modified @@ -2730,25 +2730,25 @@ fn test_migrate_reset_unactive_sn() { assert!(pallet_subtensor_swap::AlphaSqrtPrice::::contains_key( *netuid )); - assert_eq!(PendingOwnerCut::::get(netuid), AlphaCurrency::ZERO); + assert_eq!(PendingOwnerCut::::get(netuid), AlphaBalance::ZERO); assert_ne!(SubnetTAO::::get(netuid), initial_tao); assert_ne!(SubnetAlphaIn::::get(netuid), initial_alpha); - assert_ne!(SubnetAlphaOut::::get(netuid), AlphaCurrency::ZERO); - assert_eq!(SubnetTaoInEmission::::get(netuid), TaoCurrency::ZERO); + assert_ne!(SubnetAlphaOut::::get(netuid), AlphaBalance::ZERO); + assert_eq!(SubnetTaoInEmission::::get(netuid), TaoBalance::ZERO); assert_eq!( SubnetAlphaInEmission::::get(netuid), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); assert_eq!( SubnetAlphaOutEmission::::get(netuid), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); assert_ne!(SubnetVolume::::get(netuid), 0u128); for hotkey in 0..10 { let hk = U256::from(hotkey); assert_ne!( TotalHotkeyAlpha::::get(hk, netuid), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); assert_ne!( TotalHotkeyShares::::get(hk, netuid), @@ -2756,7 +2756,7 @@ fn test_migrate_reset_unactive_sn() { ); assert_ne!( TotalHotkeyAlphaLastEpoch::::get(hk, netuid), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); assert_ne!(RootClaimable::::get(hk).get(netuid), None); for coldkey in 0..10 { @@ -2767,7 +2767,7 @@ fn test_migrate_reset_unactive_sn() { } // Don't touch SubnetLocked - assert_ne!(SubnetLocked::::get(netuid), TaoCurrency::ZERO); + assert_ne!(SubnetLocked::::get(netuid), TaoBalance::ZERO); } // !!! Make sure the active subnets were not reset @@ -2776,43 +2776,43 @@ fn test_migrate_reset_unactive_sn() { let actual_tao_lock_amount_less_pool_tao = actual_tao_lock_amount - initial_tao; assert_ne!( PendingServerEmission::::get(netuid), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); assert_ne!( PendingValidatorEmission::::get(netuid), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); assert_ne!( PendingRootAlphaDivs::::get(netuid), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); assert_eq!( // not modified RAORecycledForRegistration::::get(netuid), actual_tao_lock_amount_less_pool_tao ); - assert_ne!(SubnetTaoInEmission::::get(netuid), TaoCurrency::ZERO); + assert_ne!(SubnetTaoInEmission::::get(netuid), TaoBalance::ZERO); assert_ne!( SubnetAlphaInEmission::::get(netuid), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); assert_ne!( SubnetAlphaOutEmission::::get(netuid), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); assert!(pallet_subtensor_swap::AlphaSqrtPrice::::contains_key( *netuid )); - assert_ne!(PendingOwnerCut::::get(netuid), AlphaCurrency::ZERO); + assert_ne!(PendingOwnerCut::::get(netuid), AlphaBalance::ZERO); assert_ne!(SubnetTAO::::get(netuid), initial_tao); assert_ne!(SubnetAlphaIn::::get(netuid), initial_alpha); - assert_ne!(SubnetAlphaOut::::get(netuid), AlphaCurrency::ZERO); + assert_ne!(SubnetAlphaOut::::get(netuid), AlphaBalance::ZERO); assert_ne!(SubnetVolume::::get(netuid), 0u128); for hotkey in 0..10 { let hk = U256::from(hotkey); assert_ne!( TotalHotkeyAlpha::::get(hk, netuid), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); assert_ne!( TotalHotkeyShares::::get(hk, netuid), @@ -2820,7 +2820,7 @@ fn test_migrate_reset_unactive_sn() { ); assert_ne!( TotalHotkeyAlphaLastEpoch::::get(hk, netuid), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); assert!(RootClaimable::::get(hk).contains_key(netuid)); for coldkey in 0..10 { @@ -2830,7 +2830,7 @@ fn test_migrate_reset_unactive_sn() { } } // Don't touch SubnetLocked - assert_ne!(SubnetLocked::::get(netuid), TaoCurrency::ZERO); + assert_ne!(SubnetLocked::::get(netuid), TaoBalance::ZERO); } }); } @@ -2867,7 +2867,7 @@ fn test_migrate_reset_unactive_sn_idempotence() { for netuid in &netuids { assert_eq!( SubnetTAO::::get(netuid), - *subnet_tao_before.get(netuid).unwrap_or(&TaoCurrency::ZERO) + *subnet_tao_before.get(netuid).unwrap_or(&TaoBalance::ZERO) ); } assert_eq!(TotalStake::::get(), total_stake_before); diff --git a/pallets/subtensor/src/tests/mock.rs b/pallets/subtensor/src/tests/mock.rs index 7af9420ba3..deb4cd7fc5 100644 --- a/pallets/subtensor/src/tests/mock.rs +++ b/pallets/subtensor/src/tests/mock.rs @@ -20,16 +20,15 @@ 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::{BadOrigin, BlakeTwo256, IdentityLookup}, + traits::{BlakeTwo256, IdentityLookup}, }; use sp_std::{cell::RefCell, cmp::Ordering, sync::OnceLock}; use sp_tracing::tracing_subscriber; -use subtensor_runtime_common::{AuthorshipInfo, NetUid, TaoCurrency}; +use subtensor_runtime_common::{AuthorshipInfo, NetUid, TaoBalance}; use subtensor_swap_interface::{Order, SwapHandler}; use tracing_subscriber::{EnvFilter, layer::SubscriberExt, util::SubscriberInitExt}; type Block = frame_system::mocking::MockBlock; @@ -40,17 +39,15 @@ frame_support::construct_runtime!( { 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, + Shield: pallet_shield = 3, + SubtensorModule: crate = 4, + Utility: pallet_utility = 5, + Scheduler: pallet_scheduler = 6, + Preimage: pallet_preimage = 7, + Drand: pallet_drand = 8, + Swap: pallet_subtensor_swap = 9, + Crowdloan: pallet_crowdloan = 10, + Proxy: pallet_subtensor_proxy = 11, } ); @@ -77,7 +74,7 @@ pub type Address = AccountId; // Balance of an account. #[allow(dead_code)] -pub type Balance = u64; +pub type Balance = TaoBalance; // An index to a block. #[allow(dead_code)] @@ -99,6 +96,11 @@ impl pallet_balances::Config for Test { type MaxFreezes = (); } +impl pallet_shield::Config for Test { + type AuthorityId = sp_core::sr25519::Public; + type FindAuthors = (); +} + pub struct NoNestingCallFilter; impl Contains for NoNestingCallFilter { @@ -137,7 +139,7 @@ impl system::Config for Test { type BlockHashCount = BlockHashCount; type Version = (); type PalletInfo = PalletInfo; - type AccountData = pallet_balances::AccountData; + type AccountData = pallet_balances::AccountData; type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); @@ -171,8 +173,8 @@ parameter_types! { Weight::from_parts(2_000_000_000_000, u64::MAX), Perbill::from_percent(75), ); - pub const ExistentialDeposit: Balance = 1; - pub const TransactionByteFee: Balance = 100; + pub const ExistentialDeposit: Balance = TaoBalance::new(1); + pub const TransactionByteFee: Balance = TaoBalance::new(100); pub const SDebug:u64 = 1; pub const InitialRho: u16 = 30; pub const InitialAlphaSigmoidSteepness: i16 = 1000; @@ -200,8 +202,8 @@ parameter_types! { pub const InitialBurn: u64 = 0; pub const InitialMinBurn: u64 = 500_000; pub const InitialMaxBurn: u64 = 1_000_000_000; - pub const MinBurnUpperBound: TaoCurrency = TaoCurrency::new(1_000_000_000); // 1 TAO - pub const MaxBurnLowerBound: TaoCurrency = TaoCurrency::new(100_000_000); // 0.1 TAO + pub const MinBurnUpperBound: TaoBalance = TaoBalance::new(1_000_000_000); // 1 TAO + pub const MaxBurnLowerBound: TaoBalance = TaoBalance::new(100_000_000); // 0.1 TAO pub const InitialValidatorPruneLen: u64 = 0; pub const InitialScalingLawPower: u16 = 50; pub const InitialMaxAllowedValidators: u16 = 100; @@ -380,8 +382,8 @@ impl pallet_utility::Config for Test { parameter_types! { pub const PreimageMaxSize: u32 = 4096 * 1024; - pub const PreimageBaseDeposit: Balance = 1; - pub const PreimageByteDeposit: Balance = 1; + pub const PreimageBaseDeposit: Balance = TaoBalance::new(1); + pub const PreimageByteDeposit: Balance = TaoBalance::new(1); } impl pallet_preimage::Config for Test { @@ -444,17 +446,17 @@ impl pallet_crowdloan::Config for Test { // Proxy Pallet config parameter_types! { // Set as 1 for testing purposes - pub const ProxyDepositBase: Balance = 1; + pub const ProxyDepositBase: Balance = TaoBalance::new(1); // Set as 1 for testing purposes - pub const ProxyDepositFactor: Balance = 1; + pub const ProxyDepositFactor: Balance = TaoBalance::new(1); // Set as 20 for testing purposes pub const MaxProxies: u32 = 20; // max num proxies per acct // Set as 15 for testing purposes pub const MaxPending: u32 = 15; // max blocks pending ~15min // Set as 1 for testing purposes - pub const AnnouncementDepositBase: Balance = 1; + pub const AnnouncementDepositBase: Balance = TaoBalance::new(1); // Set as 1 for testing purposes - pub const AnnouncementDepositFactor: Balance = 1; + pub const AnnouncementDepositFactor: Balance = TaoBalance::new(1); } impl pallet_proxy::Config for Test { @@ -567,41 +569,6 @@ 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() { @@ -652,8 +619,8 @@ pub fn test_ext_with_balances(balances: Vec<(U256, u128)>) -> sp_io::TestExterna pallet_balances::GenesisConfig:: { balances: balances .iter() - .map(|(a, b)| (*a, *b as u64)) - .collect::>(), + .map(|(a, b)| (*a, TaoBalance::from(*b as u64))) + .collect::>(), dev_accounts: None, } .assimilate_storage(&mut t) @@ -863,7 +830,7 @@ pub fn add_network_disable_commit_reveal(netuid: NetUid, tempo: u16, _modality: // Helper function to set up a neuron with stake #[allow(dead_code)] -pub fn setup_neuron_with_stake(netuid: NetUid, hotkey: U256, coldkey: U256, stake: TaoCurrency) { +pub fn setup_neuron_with_stake(netuid: NetUid, hotkey: U256, coldkey: U256, stake: TaoBalance) { register_ok_neuron(netuid, hotkey, coldkey, stake.into()); increase_stake_on_coldkey_hotkey_account(&coldkey, &hotkey, stake, netuid); } @@ -933,7 +900,7 @@ pub fn step_rate_limit(transaction_type: &TransactionType, netuid: NetUid) { pub fn increase_stake_on_coldkey_hotkey_account( coldkey: &U256, hotkey: &U256, - tao_staked: TaoCurrency, + tao_staked: TaoBalance, netuid: NetUid, ) { SubtensorModule::stake_into_subnet( @@ -954,7 +921,7 @@ pub fn increase_stake_on_coldkey_hotkey_account( /// * `hotkey` - The hotkey account ID. /// * `increment` - The amount to be incremented. #[allow(dead_code)] -pub fn increase_stake_on_hotkey_account(hotkey: &U256, increment: TaoCurrency, netuid: NetUid) { +pub fn increase_stake_on_hotkey_account(hotkey: &U256, increment: TaoBalance, netuid: NetUid) { increase_stake_on_coldkey_hotkey_account( &SubtensorModule::get_owning_coldkey_for_hotkey(hotkey), hotkey, @@ -967,12 +934,12 @@ pub(crate) fn remove_stake_rate_limit_for_tests(hotkey: &U256, coldkey: &U256, n StakingOperationRateLimiter::::remove((hotkey, coldkey, netuid)); } -pub(crate) fn setup_reserves(netuid: NetUid, tao: TaoCurrency, alpha: AlphaCurrency) { +pub(crate) fn setup_reserves(netuid: NetUid, tao: TaoBalance, alpha: AlphaBalance) { SubnetTAO::::set(netuid, tao); SubnetAlphaIn::::set(netuid, alpha); } -pub(crate) fn swap_tao_to_alpha(netuid: NetUid, tao: TaoCurrency) -> (AlphaCurrency, u64) { +pub(crate) fn swap_tao_to_alpha(netuid: NetUid, tao: TaoBalance) -> (AlphaBalance, u64) { if netuid.is_root() { return (tao.to_u64().into(), 0); } @@ -991,23 +958,23 @@ pub(crate) fn swap_tao_to_alpha(netuid: NetUid, tao: TaoCurrency) -> (AlphaCurre let result = result.unwrap(); // we don't want to have silent 0 comparisons in tests - assert!(result.amount_paid_out > AlphaCurrency::ZERO); + assert!(result.amount_paid_out > AlphaBalance::ZERO); (result.amount_paid_out, result.fee_paid.into()) } pub(crate) fn swap_alpha_to_tao_ext( netuid: NetUid, - alpha: AlphaCurrency, + alpha: AlphaBalance, drop_fees: bool, -) -> (TaoCurrency, u64) { +) -> (TaoBalance, u64) { if netuid.is_root() { return (alpha.to_u64().into(), 0); } println!( "::SwapInterface::min_price() = {:?}", - ::SwapInterface::min_price::() + ::SwapInterface::min_price::() ); let order = GetTaoForAlpha::::with_amount(alpha); @@ -1029,7 +996,7 @@ pub(crate) fn swap_alpha_to_tao_ext( (result.amount_paid_out, result.fee_paid.into()) } -pub(crate) fn swap_alpha_to_tao(netuid: NetUid, alpha: AlphaCurrency) -> (TaoCurrency, u64) { +pub(crate) fn swap_alpha_to_tao(netuid: NetUid, alpha: AlphaBalance) -> (TaoBalance, u64) { swap_alpha_to_tao_ext(netuid, alpha, false) } diff --git a/pallets/subtensor/src/tests/move_stake.rs b/pallets/subtensor/src/tests/move_stake.rs index 57be08e2df..294dc79661 100644 --- a/pallets/subtensor/src/tests/move_stake.rs +++ b/pallets/subtensor/src/tests/move_stake.rs @@ -4,7 +4,7 @@ use approx::assert_abs_diff_eq; use frame_support::{assert_err, assert_noop, assert_ok}; use sp_core::{Get, U256}; use substrate_fixed::types::{U64F64, U96F32}; -use subtensor_runtime_common::TaoCurrency; +use subtensor_runtime_common::TaoBalance; use subtensor_swap_interface::SwapHandler; use super::mock; @@ -62,7 +62,7 @@ fn test_do_move_success() { &coldkey, netuid ), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); assert_abs_diff_eq!( SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( @@ -138,7 +138,7 @@ fn test_do_move_different_subnets() { &coldkey, origin_netuid ), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); let fee = ::SwapInterface::approx_fee_amount(destination_netuid.into(), alpha); @@ -247,7 +247,7 @@ fn test_do_move_nonexistent_origin_hotkey() { &coldkey, netuid ), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); assert_eq!( SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( @@ -255,7 +255,7 @@ fn test_do_move_nonexistent_origin_hotkey() { &coldkey, netuid ), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); }); } @@ -318,7 +318,7 @@ fn test_do_move_nonexistent_destination_hotkey() { &coldkey, netuid ), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); }); } @@ -359,7 +359,7 @@ fn test_do_move_partial_stake() { ); // Move partial stake - let alpha_moved = AlphaCurrency::from(alpha.to_u64() * portion_moved / 10); + let alpha_moved = AlphaBalance::from(alpha.to_u64() * portion_moved / 10); SubtensorModule::create_account_if_non_existent(&coldkey, &origin_hotkey); SubtensorModule::create_account_if_non_existent(&coldkey, &destination_hotkey); assert_ok!(SubtensorModule::do_move_stake( @@ -461,7 +461,7 @@ fn test_do_move_multiple_times() { ); assert_eq!( SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(&hotkey2, &coldkey, netuid), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); }); } @@ -530,7 +530,7 @@ fn test_do_move_wrong_origin() { &coldkey, netuid ), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); }); } @@ -700,7 +700,7 @@ fn test_do_move_storage_updates() { &coldkey, origin_netuid ), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); assert_abs_diff_eq!( @@ -762,7 +762,7 @@ fn test_move_full_amount_same_netuid() { &coldkey, netuid ), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); assert_eq!( SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( @@ -830,7 +830,7 @@ fn test_do_move_max_values() { &coldkey, netuid ), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); assert_eq!( SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( @@ -861,7 +861,7 @@ fn test_moving_too_little_unstakes() { SubtensorModule::add_balance_to_coldkey_account( &coldkey_account_id, - amount.to_u64() + fee * 2, + amount + (fee * 2).into(), ); assert_ok!(SubtensorModule::add_stake( @@ -937,7 +937,7 @@ fn test_do_transfer_success() { &origin_coldkey, netuid ), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); assert_abs_diff_eq!( SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( @@ -1052,7 +1052,10 @@ fn test_do_transfer_wrong_origin() { let fee: u64 = 0; // FIXME: DefaultStakingFee is deprecated SubtensorModule::create_account_if_non_existent(&origin_coldkey, &hotkey); - SubtensorModule::add_balance_to_coldkey_account(&origin_coldkey, stake_amount + fee); + SubtensorModule::add_balance_to_coldkey_account( + &origin_coldkey, + (stake_amount + fee).into(), + ); SubtensorModule::stake_into_subnet( &hotkey, &origin_coldkey, @@ -1136,7 +1139,7 @@ fn test_do_transfer_different_subnets() { SubtensorModule::create_account_if_non_existent(&destination_coldkey, &hotkey); // 4. Deposit free balance so transaction fees do not reduce staked funds. - SubtensorModule::add_balance_to_coldkey_account(&origin_coldkey, 1_000_000_000); + SubtensorModule::add_balance_to_coldkey_account(&origin_coldkey, 1_000_000_000.into()); // 5. Stake into the origin subnet. SubtensorModule::stake_into_subnet( @@ -1176,7 +1179,7 @@ fn test_do_transfer_different_subnets() { &origin_coldkey, origin_netuid ), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); // 8. Verify stake ended up in destination subnet for destination coldkey. @@ -1237,7 +1240,7 @@ fn test_do_swap_success() { &coldkey, origin_netuid ), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); let alpha_after = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( @@ -1551,7 +1554,7 @@ fn test_do_swap_storage_updates() { &coldkey, origin_netuid ), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); assert_abs_diff_eq!( @@ -1590,7 +1593,7 @@ fn test_do_swap_multiple_times() { ) .unwrap(); - let mut expected_alpha = AlphaCurrency::ZERO; + let mut expected_alpha = AlphaBalance::ZERO; for _ in 0..3 { let alpha1 = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( &hotkey, &coldkey, netuid1, @@ -1630,7 +1633,7 @@ fn test_do_swap_multiple_times() { ); assert_eq!( SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(&hotkey, &coldkey, netuid2), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); }); } @@ -1688,10 +1691,10 @@ fn test_move_stake_specific_stake_into_subnet_fail() { let existing_shares: U64F64 = U64F64::from_num(161_986_254).saturating_div(U64F64::from_num(u64::MAX)); - let existing_stake = AlphaCurrency::from(36_711_495_953); + let existing_stake = AlphaBalance::from(36_711_495_953_u64); - let tao_in = TaoCurrency::from(2_409_892_148_947); - let alpha_in = AlphaCurrency::from(15_358_708_513_716); + let tao_in = TaoBalance::from(2_409_892_148_947_u64); + let alpha_in = AlphaBalance::from(15_358_708_513_716_u64); let tao_staked = 200_000_000; @@ -1708,7 +1711,7 @@ fn test_move_stake_specific_stake_into_subnet_fail() { // Check we have zero staked assert_eq!( SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), - TaoCurrency::ZERO + TaoBalance::ZERO ); // Set a hotkey pool for the hotkey on destination subnet @@ -1729,7 +1732,7 @@ fn test_move_stake_specific_stake_into_subnet_fail() { // Give TAO balance to coldkey SubtensorModule::add_balance_to_coldkey_account( &coldkey_account_id, - tao_staked + 1_000_000_000, + (tao_staked + 1_000_000_000).into(), ); // Setup Subnet pool for origin netuid @@ -1769,7 +1772,7 @@ fn test_move_stake_specific_stake_into_subnet_fail() { &coldkey_account_id, origin_netuid ), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); assert_abs_diff_eq!( diff --git a/pallets/subtensor/src/tests/networks.rs b/pallets/subtensor/src/tests/networks.rs index aa45fb441a..f6a50cf4ff 100644 --- a/pallets/subtensor/src/tests/networks.rs +++ b/pallets/subtensor/src/tests/networks.rs @@ -8,7 +8,7 @@ use frame_system::Config; use sp_core::U256; use sp_std::collections::{btree_map::BTreeMap, vec_deque::VecDeque}; use substrate_fixed::types::{I96F32, U64F64, U96F32}; -use subtensor_runtime_common::{MechId, NetUidStorageIndex, TaoCurrency}; +use subtensor_runtime_common::{MechId, NetUidStorageIndex, TaoBalance}; use subtensor_swap_interface::{Order, SwapHandler}; #[test] @@ -52,9 +52,9 @@ fn dissolve_no_stakers_no_alpha_no_emission() { let hot = U256::from(2); let net = add_dynamic_network(&hot, &cold); - SubtensorModule::set_subnet_locked_balance(net, TaoCurrency::from(0)); - SubnetTAO::::insert(net, TaoCurrency::from(0)); - Emission::::insert(net, Vec::::new()); + SubtensorModule::set_subnet_locked_balance(net, TaoBalance::from(0)); + SubnetTAO::::insert(net, TaoBalance::from(0)); + Emission::::insert(net, Vec::::new()); let before = SubtensorModule::get_coldkey_balance(&cold); assert_ok!(SubtensorModule::do_dissolve_network(net)); @@ -77,16 +77,16 @@ fn dissolve_refunds_full_lock_cost_when_no_emission() { let reg_at = NetworkRegisteredAt::::get(net); NetworkRegistrationStartBlock::::put(reg_at.saturating_add(1)); - let lock: TaoCurrency = TaoCurrency::from(1_000_000); + let lock: TaoBalance = TaoBalance::from(1_000_000); SubtensorModule::set_subnet_locked_balance(net, lock); - SubnetTAO::::insert(net, TaoCurrency::from(0)); - Emission::::insert(net, Vec::::new()); + SubnetTAO::::insert(net, TaoBalance::from(0)); + Emission::::insert(net, Vec::::new()); let before = SubtensorModule::get_coldkey_balance(&cold); assert_ok!(SubtensorModule::do_dissolve_network(net)); let after = SubtensorModule::get_coldkey_balance(&cold); - assert_eq!(TaoCurrency::from(after), TaoCurrency::from(before) + lock); + assert_eq!(TaoBalance::from(after), TaoBalance::from(before) + lock); }); } @@ -104,9 +104,9 @@ fn dissolve_single_alpha_out_staker_gets_all_tao() { // Entire TAO pot should be paid to staker's cold-key let pot: u64 = 99_999; - SubnetTAO::::insert(net, TaoCurrency::from(pot)); + SubnetTAO::::insert(net, TaoBalance::from(pot)); SubtensorModule::set_subnet_locked_balance(net, 0.into()); - TotalHotkeyAlpha::::insert(s_hot, net, AlphaCurrency::from(5_000u64)); + TotalHotkeyAlpha::::insert(s_hot, net, AlphaBalance::from(5_000u64)); // Cold-key balance before let before = SubtensorModule::get_coldkey_balance(&s_cold); @@ -116,7 +116,7 @@ fn dissolve_single_alpha_out_staker_gets_all_tao() { // Cold-key received full pot let after = SubtensorModule::get_coldkey_balance(&s_cold); - assert_eq!(after, before + pot); + assert_eq!(after, before + pot.into()); // No α entries left for dissolved subnet assert!(Alpha::::iter().all(|((_h, _c, n), _)| n != net)); @@ -143,11 +143,11 @@ fn dissolve_two_stakers_pro_rata_distribution() { Alpha::::insert((s1_hot, s1_cold, net), U64F64::from_num(a1)); Alpha::::insert((s2_hot, s2_cold, net), U64F64::from_num(a2)); - TotalHotkeyAlpha::::insert(s1_hot, net, AlphaCurrency::from(a1 as u64)); - TotalHotkeyAlpha::::insert(s2_hot, net, AlphaCurrency::from(a2 as u64)); + TotalHotkeyAlpha::::insert(s1_hot, net, AlphaBalance::from(a1 as u64)); + TotalHotkeyAlpha::::insert(s2_hot, net, AlphaBalance::from(a2 as u64)); let pot: u64 = 10_000; - SubnetTAO::::insert(net, TaoCurrency::from(pot)); + SubnetTAO::::insert(net, TaoBalance::from(pot)); SubtensorModule::set_subnet_locked_balance(net, 5_000.into()); // owner refund path present; emission = 0 // Cold-key balances before @@ -188,17 +188,17 @@ fn dissolve_two_stakers_pro_rata_distribution() { // Cold-keys received their τ shares assert_eq!( SubtensorModule::get_coldkey_balance(&s1_cold), - s1_before + expected1 + s1_before + expected1.into() ); assert_eq!( SubtensorModule::get_coldkey_balance(&s2_cold), - s2_before + expected2 + s2_before + expected2.into() ); // Owner refunded lock (no emission) assert_eq!( SubtensorModule::get_coldkey_balance(&oc), - owner_before + 5_000 + owner_before + 5_000.into() ); // α entries for dissolved subnet gone @@ -224,12 +224,12 @@ fn dissolve_owner_cut_refund_logic() { &sh, &sc, net, - AlphaCurrency::from(800u64), + AlphaBalance::from(800u64), ); - SubnetTAO::::insert(net, TaoCurrency::from(1_000)); + SubnetTAO::::insert(net, TaoBalance::from(1_000)); // Lock & emissions: total emitted α = 800. - let lock: TaoCurrency = TaoCurrency::from(2_000); + let lock: TaoBalance = TaoBalance::from(2_000); SubtensorModule::set_subnet_locked_balance(net, lock); // ensure there was some Alpha issued assert!(SubtensorModule::get_alpha_issuance(net).to_u64() > 0); @@ -256,7 +256,7 @@ fn dissolve_owner_cut_refund_logic() { .into() }; - let expected_refund: TaoCurrency = lock.saturating_sub(owner_emission_tao); + let expected_refund: TaoBalance = lock.saturating_sub(owner_emission_tao); let before = SubtensorModule::get_coldkey_balance(&oc); assert_ok!(SubtensorModule::do_dissolve_network(net)); @@ -264,8 +264,8 @@ fn dissolve_owner_cut_refund_logic() { assert!(after > before); // some refund is expected assert_eq!( - TaoCurrency::from(after), - TaoCurrency::from(before) + expected_refund + TaoBalance::from(after), + TaoBalance::from(before) + expected_refund ); }); } @@ -277,9 +277,9 @@ fn dissolve_zero_refund_when_emission_exceeds_lock() { let oh = U256::from(2_000); let net = add_dynamic_network(&oh, &oc); - SubtensorModule::set_subnet_locked_balance(net, TaoCurrency::from(1_000)); + SubtensorModule::set_subnet_locked_balance(net, TaoBalance::from(1_000)); SubnetOwnerCut::::put(u16::MAX); // 100 % - Emission::::insert(net, vec![AlphaCurrency::from(2_000)]); + Emission::::insert(net, vec![AlphaBalance::from(2_000)]); let before = SubtensorModule::get_coldkey_balance(&oc); assert_ok!(SubtensorModule::do_dissolve_network(net)); @@ -320,7 +320,7 @@ fn dissolve_clears_all_per_subnet_storages() { Rank::::insert(net, vec![1u16]); Trust::::insert(net, vec![1u16]); Active::::insert(net, vec![true]); - Emission::::insert(net, vec![AlphaCurrency::from(1)]); + Emission::::insert(net, vec![AlphaBalance::from(1)]); Incentive::::insert(NetUidStorageIndex::from(net), vec![1u16]); Consensus::::insert(net, vec![1u16]); Dividends::::insert(net, vec![1u16]); @@ -344,15 +344,15 @@ fn dissolve_clears_all_per_subnet_storages() { BurnRegistrationsThisInterval::::insert(net, 1u16); // Pool / AMM counters - SubnetTAO::::insert(net, TaoCurrency::from(1)); - SubnetAlphaInEmission::::insert(net, AlphaCurrency::from(1)); - SubnetAlphaOutEmission::::insert(net, AlphaCurrency::from(1)); - SubnetTaoInEmission::::insert(net, TaoCurrency::from(1)); + SubnetTAO::::insert(net, TaoBalance::from(1)); + SubnetAlphaInEmission::::insert(net, AlphaBalance::from(1)); + SubnetAlphaOutEmission::::insert(net, AlphaBalance::from(1)); + SubnetTaoInEmission::::insert(net, TaoBalance::from(1)); SubnetVolume::::insert(net, 1u128); // Items now REMOVED (not zeroed) by dissolution - SubnetAlphaIn::::insert(net, AlphaCurrency::from(2)); - SubnetAlphaOut::::insert(net, AlphaCurrency::from(3)); + SubnetAlphaIn::::insert(net, AlphaBalance::from(2)); + SubnetAlphaOut::::insert(net, AlphaBalance::from(3)); // Prefix / double-map collections Keys::::insert(net, 0u16, owner_hot); @@ -365,8 +365,8 @@ fn dissolve_clears_all_per_subnet_storages() { // Token / price / provided reserves TokenSymbol::::insert(net, b"XX".to_vec()); SubnetMovingPrice::::insert(net, substrate_fixed::types::I96F32::from_num(1)); - SubnetTaoProvided::::insert(net, TaoCurrency::from(1)); - SubnetAlphaInProvided::::insert(net, AlphaCurrency::from(1)); + SubnetTaoProvided::::insert(net, TaoBalance::from(1)); + SubnetAlphaInProvided::::insert(net, AlphaBalance::from(1)); // TAO Flow SubnetTaoFlow::::insert(net, 0i64); @@ -374,7 +374,7 @@ fn dissolve_clears_all_per_subnet_storages() { // Subnet locks TransferToggle::::insert(net, true); - SubnetLocked::::insert(net, TaoCurrency::from(1)); + SubnetLocked::::insert(net, TaoBalance::from(1)); LargestLocked::::insert(net, 1u64); // Subnet parameters & pending counters @@ -382,10 +382,10 @@ fn dissolve_clears_all_per_subnet_storages() { SubnetMechanism::::insert(net, 1u16); NetworkRegistrationAllowed::::insert(net, true); NetworkPowRegistrationAllowed::::insert(net, true); - PendingServerEmission::::insert(net, AlphaCurrency::from(1)); - PendingValidatorEmission::::insert(net, AlphaCurrency::from(1)); - PendingRootAlphaDivs::::insert(net, AlphaCurrency::from(1)); - PendingOwnerCut::::insert(net, AlphaCurrency::from(1)); + PendingServerEmission::::insert(net, AlphaBalance::from(1)); + PendingValidatorEmission::::insert(net, AlphaBalance::from(1)); + PendingRootAlphaDivs::::insert(net, AlphaBalance::from(1)); + PendingOwnerCut::::insert(net, AlphaBalance::from(1)); BlocksSinceLastStep::::insert(net, 1u64); LastMechansimStepBlock::::insert(net, 1u64); ServingRateLimit::::insert(net, 1u64); @@ -407,14 +407,14 @@ fn dissolve_clears_all_per_subnet_storages() { CommitRevealWeightsEnabled::::insert(net, true); // Burn/difficulty/adjustment - Burn::::insert(net, TaoCurrency::from(1)); - MinBurn::::insert(net, TaoCurrency::from(1)); - MaxBurn::::insert(net, TaoCurrency::from(2)); + Burn::::insert(net, TaoBalance::from(1)); + MinBurn::::insert(net, TaoBalance::from(1)); + MaxBurn::::insert(net, TaoBalance::from(2)); MinDifficulty::::insert(net, 1u64); MaxDifficulty::::insert(net, 2u64); RegistrationsThisBlock::::insert(net, 1u16); EMAPriceHalvingBlocks::::insert(net, 1u64); - RAORecycledForRegistration::::insert(net, TaoCurrency::from(1)); + RAORecycledForRegistration::::insert(net, TaoBalance::from(1)); // Feature toggles LiquidAlphaOn::::insert(net, true); @@ -431,7 +431,7 @@ fn dissolve_clears_all_per_subnet_storages() { BlockAtRegistration::::insert(net, 0u16, 1u64); // Per‑subnet dividends - AlphaDividendsPerSubnet::::insert(net, owner_hot, AlphaCurrency::from(1)); + AlphaDividendsPerSubnet::::insert(net, owner_hot, AlphaBalance::from(1)); // Parent/child topology + takes ChildkeyTake::::insert(owner_hot, net, 1u16); @@ -636,10 +636,10 @@ fn dissolve_alpha_out_but_zero_tao_no_rewards() { let sc = U256::from(24); Alpha::::insert((sh, sc, net), U64F64::from_num(1_000u64)); - SubnetTAO::::insert(net, TaoCurrency::from(0)); // zero TAO - SubtensorModule::set_subnet_locked_balance(net, TaoCurrency::from(0)); - Emission::::insert(net, Vec::::new()); - TotalHotkeyAlpha::::insert(sh, net, AlphaCurrency::from(1_000u64)); + SubnetTAO::::insert(net, TaoBalance::from(0)); // zero TAO + SubtensorModule::set_subnet_locked_balance(net, TaoBalance::from(0)); + Emission::::insert(net, Vec::::new()); + TotalHotkeyAlpha::::insert(sh, net, AlphaBalance::from(1_000u64)); let before = SubtensorModule::get_coldkey_balance(&sc); assert_ok!(SubtensorModule::do_dissolve_network(net)); @@ -682,11 +682,11 @@ fn dissolve_rounding_remainder_distribution() { Alpha::::insert((s1h, s1c, net), U64F64::from_num(3u128)); Alpha::::insert((s2h, s2c, net), U64F64::from_num(2u128)); - SubnetTAO::::insert(net, TaoCurrency::from(1)); // TAO pot = 1 - SubtensorModule::set_subnet_locked_balance(net, TaoCurrency::from(0)); + SubnetTAO::::insert(net, TaoBalance::from(1)); // TAO pot = 1 + SubtensorModule::set_subnet_locked_balance(net, TaoBalance::from(0)); - TotalHotkeyAlpha::::insert(s1h, net, AlphaCurrency::from(3u64)); - TotalHotkeyAlpha::::insert(s2h, net, AlphaCurrency::from(2u64)); + TotalHotkeyAlpha::::insert(s1h, net, AlphaBalance::from(3u64)); + TotalHotkeyAlpha::::insert(s2h, net, AlphaBalance::from(2u64)); // Cold-key balances before let c1_before = SubtensorModule::get_coldkey_balance(&s1c); @@ -699,7 +699,7 @@ fn dissolve_rounding_remainder_distribution() { let c1_after = SubtensorModule::get_coldkey_balance(&s1c); let c2_after = SubtensorModule::get_coldkey_balance(&s2c); - assert_eq!(c1_after, c1_before + 1); + assert_eq!(c1_after, c1_before + 1.into()); assert_eq!(c2_after, c2_before); // α records for subnet gone; TAO key gone @@ -731,8 +731,8 @@ fn destroy_alpha_out_multiple_stakers_pro_rata() { let s1: u64 = 3u64 * min_total_u64; let s2: u64 = 7u64 * min_total_u64; - SubtensorModule::add_balance_to_coldkey_account(&c1, s1 + 50_000); - SubtensorModule::add_balance_to_coldkey_account(&c2, s2 + 50_000); + SubtensorModule::add_balance_to_coldkey_account(&c1, (s1 + 50_000).into()); + SubtensorModule::add_balance_to_coldkey_account(&c2, (s2 + 50_000).into()); assert_ok!(SubtensorModule::do_add_stake( RuntimeOrigin::signed(c1), @@ -754,8 +754,8 @@ fn destroy_alpha_out_multiple_stakers_pro_rata() { // 5. TAO pot & lock let tao_pot: u64 = 10_000; - SubnetTAO::::insert(netuid, TaoCurrency::from(tao_pot)); - SubtensorModule::set_subnet_locked_balance(netuid, TaoCurrency::from(5_000)); + SubnetTAO::::insert(netuid, TaoBalance::from(tao_pot)); + SubtensorModule::set_subnet_locked_balance(netuid, TaoBalance::from(5_000)); // 6. Balances before let c1_before = SubtensorModule::get_coldkey_balance(&c1); @@ -785,17 +785,17 @@ fn destroy_alpha_out_multiple_stakers_pro_rata() { // 9. Cold-key balances must have increased accordingly assert_eq!( SubtensorModule::get_coldkey_balance(&c1), - c1_before + s1_share + c1_before + s1_share.into() ); assert_eq!( SubtensorModule::get_coldkey_balance(&c2), - c2_before + s2_share + c2_before + s2_share.into() ); // 10. Owner refund (5 000 τ) to cold-key (no emission) assert_eq!( SubtensorModule::get_coldkey_balance(&owner_cold), - owner_before + 5_000 + owner_before + 5_000.into() ); // 11. α entries cleared for the subnet @@ -842,7 +842,7 @@ fn destroy_alpha_out_many_stakers_complex_distribution() { stake[i] = (i as u64 + 1u64) * min_amount_u64; // multiples of min_amount register_ok_neuron(netuid, hot[i], cold[i], 0); - SubtensorModule::add_balance_to_coldkey_account(&cold[i], stake[i] + 100_000); + SubtensorModule::add_balance_to_coldkey_account(&cold[i], (stake[i] + 100_000).into()); assert_ok!(SubtensorModule::do_add_stake( RuntimeOrigin::signed(cold[i]), @@ -863,8 +863,8 @@ fn destroy_alpha_out_many_stakers_complex_distribution() { // ── 3) TAO pot & subnet lock ──────────────────────────────────────── let tao_pot: u64 = 123_456; let lock: u64 = 30_000; - SubnetTAO::::insert(netuid, TaoCurrency::from(tao_pot)); - SubtensorModule::set_subnet_locked_balance(netuid, TaoCurrency::from(lock)); + SubnetTAO::::insert(netuid, TaoBalance::from(tao_pot)); + SubtensorModule::set_subnet_locked_balance(netuid, TaoBalance::from(lock)); // ensure there was some Alpha issued assert!(SubtensorModule::get_alpha_issuance(netuid).to_u64() > 0); @@ -873,7 +873,7 @@ fn destroy_alpha_out_many_stakers_complex_distribution() { SubnetOwnerCut::::put(32_768u16); // ~ 0.5 in fixed-point // ── 4) balances before ────────────────────────────────────────────── - let mut bal_before = [0u64; N]; + let mut bal_before = [TaoBalance::new(0); N]; for i in 0..N { bal_before[i] = SubtensorModule::get_coldkey_balance(&cold[i]); } @@ -925,7 +925,7 @@ fn destroy_alpha_out_many_stakers_complex_distribution() { // cold-key balances increased by expected τ share assert_eq!( SubtensorModule::get_coldkey_balance(&cold[i]), - bal_before[i] + share[i], + bal_before[i] + share[i].into(), "staker {i} cold-key balance changed unexpectedly" ); } @@ -933,7 +933,7 @@ fn destroy_alpha_out_many_stakers_complex_distribution() { // owner refund assert_eq!( SubtensorModule::get_coldkey_balance(&owner_cold), - owner_before + expected_refund + owner_before + expected_refund.into() ); // α cleared for dissolved subnet & related counters reset @@ -961,7 +961,7 @@ fn destroy_alpha_out_refund_gating_by_registration_block() { // Lock and (nonzero) emissions let lock_u64: u64 = 50_000; - SubtensorModule::set_subnet_locked_balance(netuid, TaoCurrency::from(lock_u64)); + SubtensorModule::set_subnet_locked_balance(netuid, TaoBalance::from(lock_u64)); // Owner cut ≈ 50% SubnetOwnerCut::::put(32_768u16); @@ -972,7 +972,7 @@ fn destroy_alpha_out_refund_gating_by_registration_block() { &other_hot, &other_cold, netuid, - AlphaCurrency::from(30u64), // not nearly enough to cover the lock + AlphaBalance::from(30u64), // not nearly enough to cover the lock ); // ensure there was some Alpha issued @@ -1005,12 +1005,12 @@ fn destroy_alpha_out_refund_gating_by_registration_block() { // Owner received their refund… let owner_after = SubtensorModule::get_coldkey_balance(&owner_cold); - assert_eq!(owner_after, owner_before + expected_refund); + assert_eq!(owner_after, owner_before + expected_refund.into()); // …and the lock is always cleared to zero by destroy_alpha_in_out_stakes. assert_eq!( SubtensorModule::get_subnet_locked_balance(netuid), - TaoCurrency::from(0u64) + TaoBalance::from(0u64) ); }); @@ -1029,7 +1029,7 @@ fn destroy_alpha_out_refund_gating_by_registration_block() { // Lock and emissions present (should be ignored for refund) let lock_u64: u64 = 42_000; - SubtensorModule::set_subnet_locked_balance(netuid, TaoCurrency::from(lock_u64)); + SubtensorModule::set_subnet_locked_balance(netuid, TaoBalance::from(lock_u64)); // give some stake to other key let other_cold = U256::from(1_234); let other_hot = U256::from(2_345); @@ -1037,7 +1037,7 @@ fn destroy_alpha_out_refund_gating_by_registration_block() { &other_hot, &other_cold, netuid, - AlphaCurrency::from(300u64), // not nearly enough to cover the lock + AlphaBalance::from(300u64), // not nearly enough to cover the lock ); // ensure there was some Alpha issued assert!(SubtensorModule::get_alpha_issuance(netuid).to_u64() > 0); @@ -1056,7 +1056,7 @@ fn destroy_alpha_out_refund_gating_by_registration_block() { // Lock is still cleared to zero by the routine assert_eq!( SubtensorModule::get_subnet_locked_balance(netuid), - TaoCurrency::from(0u64) + TaoBalance::from(0u64) ); }); @@ -1074,8 +1074,8 @@ fn destroy_alpha_out_refund_gating_by_registration_block() { NetworkRegistrationStartBlock::::put(reg_at.saturating_add(1)); // lock = 0; emissions present (must not matter) - SubtensorModule::set_subnet_locked_balance(netuid, TaoCurrency::from(0u64)); - SubnetAlphaOut::::insert(netuid, AlphaCurrency::from(10_000)); + SubtensorModule::set_subnet_locked_balance(netuid, TaoBalance::from(0u64)); + SubnetAlphaOut::::insert(netuid, AlphaBalance::from(10_000)); // ensure there was some Alpha issued assert!(SubtensorModule::get_alpha_issuance(netuid).to_u64() > 0); SubnetOwnerCut::::put(32_768u16); // ~50% @@ -1088,7 +1088,7 @@ fn destroy_alpha_out_refund_gating_by_registration_block() { assert_eq!(owner_after, owner_before); assert_eq!( SubtensorModule::get_subnet_locked_balance(netuid), - TaoCurrency::from(0u64) + TaoBalance::from(0u64) ); }); } @@ -1108,7 +1108,7 @@ fn prune_none_when_all_networks_immune() { let _n2 = add_dynamic_network(&U256::from(4), &U256::from(3)); // emissions don’t matter while immune - Emission::::insert(n1, vec![AlphaCurrency::from(10)]); + Emission::::insert(n1, vec![AlphaBalance::from(10)]); assert_eq!(SubtensorModule::get_network_to_prune(), None); }); @@ -1379,13 +1379,16 @@ fn register_network_prunes_and_recycles_netuid() { let imm = SubtensorModule::get_network_immunity_period(); System::set_block_number(imm + 100); - Emission::::insert(n1, vec![AlphaCurrency::from(1)]); - Emission::::insert(n2, vec![AlphaCurrency::from(1_000)]); + Emission::::insert(n1, vec![AlphaBalance::from(1)]); + Emission::::insert(n2, vec![AlphaBalance::from(1_000)]); let new_cold = U256::from(30); let new_hot = U256::from(31); let needed: u64 = SubtensorModule::get_network_lock_cost().into(); - SubtensorModule::add_balance_to_coldkey_account(&new_cold, needed.saturating_mul(10)); + SubtensorModule::add_balance_to_coldkey_account( + &new_cold, + needed.saturating_mul(10).into(), + ); assert_ok!(SubtensorModule::do_register_network( RuntimeOrigin::signed(new_cold), @@ -1412,7 +1415,7 @@ fn register_network_fails_before_prune_keeps_existing() { let imm = SubtensorModule::get_network_immunity_period(); System::set_block_number(imm + 50); - Emission::::insert(net, vec![AlphaCurrency::from(10)]); + Emission::::insert(net, vec![AlphaBalance::from(10)]); let caller_cold = U256::from(50); let caller_hot = U256::from(51); @@ -1711,12 +1714,12 @@ fn test_migrate_network_immunity_period() { #[test] fn test_register_subnet_low_lock_cost() { new_test_ext(1).execute_with(|| { - NetworkMinLockCost::::set(TaoCurrency::from(1_000)); - NetworkLastLockCost::::set(TaoCurrency::from(1_000)); + NetworkMinLockCost::::set(TaoBalance::from(1_000)); + NetworkLastLockCost::::set(TaoBalance::from(1_000)); // Make sure lock cost is lower than 100 TAO let lock_cost = SubtensorModule::get_network_lock_cost(); - assert!(lock_cost < 100_000_000_000.into()); + assert!(lock_cost < 100_000_000_000_u64.into()); let subnet_owner_coldkey = U256::from(1); let subnet_owner_hotkey = U256::from(2); @@ -1736,13 +1739,13 @@ fn test_register_subnet_low_lock_cost() { #[test] fn test_register_subnet_high_lock_cost() { new_test_ext(1).execute_with(|| { - let lock_cost = TaoCurrency::from(1_000_000_000_000); + let lock_cost = TaoBalance::from(1_000_000_000_000_u64); NetworkMinLockCost::::set(lock_cost); NetworkLastLockCost::::set(lock_cost); // Make sure lock cost is higher than 100 TAO let lock_cost = SubtensorModule::get_network_lock_cost(); - assert!(lock_cost >= 1_000_000_000_000.into()); + assert!(lock_cost >= 1_000_000_000_000_u64.into()); let subnet_owner_coldkey = U256::from(1); let subnet_owner_hotkey = U256::from(2); @@ -1812,27 +1815,6 @@ fn massive_dissolve_refund_and_reregistration_flow_is_lossless_and_cleans_state( &cold_lps[1..5], // net3: B,C,D,E ]; - // Multiple bands/sizes → many positions per cold across nets, using mixed hotkeys. - // let bands: [i32; 3] = [5, 13, 30]; - // let liqs: [u64; 3] = [400_000, 700_000, 1_100_000]; - - // TODO: Revise when user liquidity is available - // Helper: add a V3 position via a (hot, cold) pair. - // let add_pos = |net: NetUid, hot: U256, cold: U256, band: i32, liq: u64| { - // let ct = pallet_subtensor_swap::CurrentTick::::get(net); - // let lo = ct.saturating_sub(band); - // let hi = ct.saturating_add(band); - // pallet_subtensor_swap::EnabledUserLiquidity::::insert(net, true); - // assert_ok!(pallet_subtensor_swap::Pallet::::add_liquidity( - // RuntimeOrigin::signed(cold), - // hot, - // net, - // lo, - // hi, - // liq - // )); - // }; - // ──────────────────────────────────────────────────────────────────── // 1) Create many subnets, enable V3, fix price at tick=0 (sqrt≈1) // ──────────────────────────────────────────────────────────────────── @@ -1843,8 +1825,8 @@ fn massive_dissolve_refund_and_reregistration_flow_is_lossless_and_cleans_state( let net = add_dynamic_network(&owner_hot, &owner_cold); SubtensorModule::set_max_registrations_per_block(net, 1_000u16); SubtensorModule::set_target_registrations_per_interval(net, 1_000u16); - Emission::::insert(net, Vec::::new()); - SubtensorModule::set_subnet_locked_balance(net, TaoCurrency::from(0)); + Emission::::insert(net, Vec::::new()); + SubtensorModule::set_subnet_locked_balance(net, TaoBalance::from(0)); assert_ok!( pallet_subtensor_swap::Pallet::::toggle_user_liquidity( @@ -1884,11 +1866,11 @@ fn massive_dissolve_refund_and_reregistration_flow_is_lossless_and_cleans_state( // 3) LPs per net: register each (hot, cold), massive τ prefund, and stake // ──────────────────────────────────────────────────────────────────── for &cold in cold_lps.iter() { - SubtensorModule::add_balance_to_coldkey_account(&cold, u64::MAX); + SubtensorModule::add_balance_to_coldkey_account(&cold, u64::MAX.into()); } // τ balances before LP adds (after staking): - let mut tao_before: BTreeMap = BTreeMap::new(); + let mut tao_before: BTreeMap = BTreeMap::new(); // Ordered α snapshot per net at **pair granularity** (pre‑LP): let mut alpha_pairs_per_net: BTreeMap> = BTreeMap::new(); @@ -1936,7 +1918,7 @@ fn massive_dissolve_refund_and_reregistration_flow_is_lossless_and_cleans_state( // Record τ balances now (post‑stake, pre‑LP). for &cold in cold_lps.iter() { - tao_before.insert(cold, SubtensorModule::get_coldkey_balance(&cold)); + tao_before.insert(cold, SubtensorModule::get_coldkey_balance(&cold).into()); } // Capture **pair‑level** α snapshot per net (pre‑LP). @@ -1953,26 +1935,8 @@ fn massive_dissolve_refund_and_reregistration_flow_is_lossless_and_cleans_state( } } - // ──────────────────────────────────────────────────────────────────── - // 4) Add many V3 positions per cold across nets, alternating hotkeys - // ──────────────────────────────────────────────────────────────────── - // TODO: Revise when user liquidity is available - // for (ni, &net) in nets.iter().enumerate() { - // let participants = lp_sets_per_net[ni]; - // for (pi, &cold) in participants.iter().enumerate() { - // let [hot1, hot2] = cold_to_hots[&cold]; - // let hots = [hot1, hot2]; - // for k in 0..3 { - // let band = bands[(pi + k) % bands.len()]; - // let liq = liqs[(ni + k) % liqs.len()]; - // let hot = hots[k % hots.len()]; - // add_pos(net, hot, cold, band, liq); - // } - // } - // } - // Snapshot τ balances AFTER LP adds (to measure actual principal debit). - let mut tao_after_adds: BTreeMap = BTreeMap::new(); + let mut tao_after_adds: BTreeMap = BTreeMap::new(); for &cold in cold_lps.iter() { tao_after_adds.insert(cold, SubtensorModule::get_coldkey_balance(&cold)); } @@ -2017,7 +1981,7 @@ fn massive_dissolve_refund_and_reregistration_flow_is_lossless_and_cleans_state( // 6) Seed τ pots and dissolve *all* networks (liquidates LPs + refunds) // ──────────────────────────────────────────────────────────────────── for (ni, &net) in nets.iter().enumerate() { - SubnetTAO::::insert(net, TaoCurrency::from(pots[ni])); + SubnetTAO::::insert(net, TaoBalance::from(pots[ni])); } for &net in nets.iter() { assert_ok!(SubtensorModule::do_dissolve_network(net)); @@ -2033,7 +1997,7 @@ fn massive_dissolve_refund_and_reregistration_flow_is_lossless_and_cleans_state( for &cold in cold_lps.iter() { let before = tao_before[&cold]; let after = SubtensorModule::get_coldkey_balance(&cold); - actual_pot_cold.insert(cold, after.saturating_sub(before)); + actual_pot_cold.insert(cold, after.saturating_sub(before.into()).into()); } // (a) Sum of actual pot credits equals total pots. @@ -2075,10 +2039,10 @@ fn massive_dissolve_refund_and_reregistration_flow_is_lossless_and_cleans_state( let mid = tao_after_adds[&cold]; let after = SubtensorModule::get_coldkey_balance(&cold); let principal_actual = before.saturating_sub(mid); - let actual_pot = after.saturating_sub(before); + let actual_pot = after.saturating_sub(before.into()); assert_eq!( - after.saturating_sub(mid), - principal_actual.saturating_add(actual_pot), + after.saturating_sub(mid.into()), + principal_actual.saturating_add(actual_pot.into()).into(), "cold {cold:?} τ balance incorrect vs 'after_adds'" ); } @@ -2144,8 +2108,8 @@ fn massive_dissolve_refund_and_reregistration_flow_is_lossless_and_cleans_state( let net_new = add_dynamic_network(&new_owner_hot, &new_owner_cold); SubtensorModule::set_max_registrations_per_block(net_new, 1_000u16); SubtensorModule::set_target_registrations_per_interval(net_new, 1_000u16); - Emission::::insert(net_new, Vec::::new()); - SubtensorModule::set_subnet_locked_balance(net_new, TaoCurrency::from(0)); + Emission::::insert(net_new, Vec::::new()); + SubtensorModule::set_subnet_locked_balance(net_new, TaoBalance::from(0)); assert_ok!( pallet_subtensor_swap::Pallet::::toggle_user_liquidity( @@ -2203,7 +2167,7 @@ fn massive_dissolve_refund_and_reregistration_flow_is_lossless_and_cleans_state( // τ decreased by exactly the amount we sent. assert_eq!( after_tao, - before_tao.saturating_sub(min_amount_required), + before_tao.saturating_sub(min_amount_required.into()), "τ did not decrease by the min required restake amount for cold {cold:?}" ); @@ -2213,17 +2177,6 @@ fn massive_dissolve_refund_and_reregistration_flow_is_lossless_and_cleans_state( "α minted mismatch for cold {cold:?} (hot {hot1:?}) on new net (αΔ {a_delta}, expected {expected_alpha_out})" ); } - - // Ensure V3 still functional on new net: add a small position for the first cold using its hot1 - // TODO: Revise when user liquidity is available - // let who_cold = cold_lps[0]; - // let [who_hot, _] = cold_to_hots[&who_cold]; - // add_pos(net_new, who_hot, who_cold, 8, 123_456); - // assert!( - // pallet_subtensor_swap::Positions::::iter() - // .any(|((n, owner, _pid), _)| n == net_new && owner == who_cold), - // "new position not recorded on the re-registered net" - // ); }); } diff --git a/pallets/subtensor/src/tests/recycle_alpha.rs b/pallets/subtensor/src/tests/recycle_alpha.rs index 5cf589de97..9ae3975744 100644 --- a/pallets/subtensor/src/tests/recycle_alpha.rs +++ b/pallets/subtensor/src/tests/recycle_alpha.rs @@ -5,7 +5,7 @@ use approx::assert_abs_diff_eq; use frame_support::{assert_noop, assert_ok, traits::Currency}; use sp_core::U256; use substrate_fixed::types::{U64F64, U96F32}; -use subtensor_runtime_common::{AlphaCurrency, Currency as CurrencyT}; +use subtensor_runtime_common::{AlphaBalance, Token}; use subtensor_swap_interface::SwapHandler; #[test] @@ -19,7 +19,7 @@ fn test_recycle_success() { let netuid = add_dynamic_network(&owner_hotkey, &owner_coldkey); let initial_balance = 1_000_000_000; - Balances::make_free_balance_be(&coldkey, initial_balance); + Balances::make_free_balance_be(&coldkey, initial_balance.into()); // associate coldkey and hotkey SubtensorModule::create_account_if_non_existent(&coldkey, &hotkey); @@ -36,7 +36,7 @@ fn test_recycle_success() { let initial_net_alpha = SubnetAlphaOut::::get(netuid); // amount to recycle - let recycle_amount = AlphaCurrency::from(stake / 2); + let recycle_amount = AlphaBalance::from(stake / 2); // recycle assert_ok!(SubtensorModule::recycle_alpha( @@ -75,7 +75,7 @@ fn test_recycle_two_stakers() { let netuid = add_dynamic_network(&owner_hotkey, &owner_coldkey); let initial_balance = 1_000_000_000; - Balances::make_free_balance_be(&coldkey, initial_balance); + Balances::make_free_balance_be(&coldkey, initial_balance.into()); // associate coldkey and hotkey SubtensorModule::create_account_if_non_existent(&coldkey, &hotkey); @@ -96,7 +96,7 @@ fn test_recycle_two_stakers() { let initial_net_alpha = SubnetAlphaOut::::get(netuid); // amount to recycle - let recycle_amount = AlphaCurrency::from(stake / 2); + let recycle_amount = AlphaBalance::from(stake / 2); // recycle assert_ok!(SubtensorModule::recycle_alpha( @@ -145,7 +145,7 @@ fn test_recycle_staker_is_nominator() { let netuid = add_dynamic_network(&owner_hotkey, &owner_coldkey); let initial_balance = 1_000_000_000; - Balances::make_free_balance_be(&coldkey, initial_balance); + Balances::make_free_balance_be(&coldkey, initial_balance.into()); // associate coldkey and hotkey SubtensorModule::create_account_if_non_existent(&coldkey, &hotkey); @@ -172,7 +172,7 @@ fn test_recycle_staker_is_nominator() { let initial_net_alpha = SubnetAlphaOut::::get(netuid); // amount to recycle - let recycle_amount = AlphaCurrency::from(stake / 2); + let recycle_amount = AlphaBalance::from(stake / 2); // recycle from nominator coldkey assert_ok!(SubtensorModule::recycle_alpha( @@ -218,7 +218,7 @@ fn test_burn_success() { let netuid = add_dynamic_network(&owner_hotkey, &owner_coldkey); let initial_balance = 1_000_000_000; - Balances::make_free_balance_be(&coldkey, initial_balance); + Balances::make_free_balance_be(&coldkey, initial_balance.into()); // associate coldkey and hotkey SubtensorModule::create_account_if_non_existent(&coldkey, &hotkey); @@ -274,7 +274,7 @@ fn test_burn_staker_is_nominator() { let netuid = add_dynamic_network(&owner_hotkey, &owner_coldkey); let initial_balance = 1_000_000_000; - Balances::make_free_balance_be(&coldkey, initial_balance); + Balances::make_free_balance_be(&coldkey, initial_balance.into()); // associate coldkey and hotkey SubtensorModule::create_account_if_non_existent(&coldkey, &hotkey); @@ -296,7 +296,7 @@ fn test_burn_staker_is_nominator() { let initial_net_alpha = SubnetAlphaOut::::get(netuid); // amount to recycle - let burn_amount = AlphaCurrency::from(stake / 2); + let burn_amount = AlphaBalance::from(stake / 2); // burn from nominator coldkey assert_ok!(SubtensorModule::burn_alpha( @@ -344,7 +344,7 @@ fn test_burn_two_stakers() { let netuid = add_dynamic_network(&owner_hotkey, &owner_coldkey); let initial_balance = 1_000_000_000; - Balances::make_free_balance_be(&coldkey, initial_balance); + Balances::make_free_balance_be(&coldkey, initial_balance.into()); // associate coldkey and hotkey SubtensorModule::create_account_if_non_existent(&coldkey, &hotkey); @@ -365,7 +365,7 @@ fn test_burn_two_stakers() { let initial_net_alpha = SubnetAlphaOut::::get(netuid); // amount to recycle - let burn_amount = AlphaCurrency::from(stake / 2); + let burn_amount = AlphaBalance::from(stake / 2); // burn from coldkey assert_ok!(SubtensorModule::burn_alpha( @@ -416,7 +416,7 @@ fn test_recycle_errors() { migrations::migrate_create_root_network::migrate_create_root_network::(); let initial_balance = 1_000_000_000; - Balances::make_free_balance_be(&coldkey, initial_balance); + Balances::make_free_balance_be(&coldkey, initial_balance.into()); SubtensorModule::create_account_if_non_existent(&coldkey, &hotkey); register_ok_neuron(netuid, hotkey, coldkey, 0); @@ -488,7 +488,7 @@ fn test_burn_errors() { migrations::migrate_create_root_network::migrate_create_root_network::(); let initial_balance = 1_000_000_000; - Balances::make_free_balance_be(&coldkey, initial_balance); + Balances::make_free_balance_be(&coldkey, initial_balance.into()); SubtensorModule::create_account_if_non_existent(&coldkey, &hotkey); register_ok_neuron(netuid, hotkey, coldkey, 0); @@ -553,7 +553,7 @@ fn test_recycle_precision_loss() { let netuid = add_dynamic_network(&hotkey, &coldkey); - Balances::make_free_balance_be(&coldkey, 1_000_000_000); + Balances::make_free_balance_be(&coldkey, 1_000_000_000.into()); // sanity check assert!(SubtensorModule::if_subnet_exist(netuid)); @@ -562,7 +562,7 @@ fn test_recycle_precision_loss() { increase_stake_on_coldkey_hotkey_account(&coldkey, &hotkey, stake.into(), netuid); // amount to recycle - let recycle_amount = AlphaCurrency::from(stake / 2); + let recycle_amount = AlphaBalance::from(stake / 2); // Modify the alpha pool denominator so it's low-precision let denominator = U64F64::from_num(0.00000001); @@ -590,7 +590,7 @@ fn test_burn_precision_loss() { let netuid = add_dynamic_network(&hotkey, &coldkey); - Balances::make_free_balance_be(&coldkey, 1_000_000_000); + Balances::make_free_balance_be(&coldkey, 1_000_000_000.into()); // sanity check assert!(SubtensorModule::if_subnet_exist(netuid)); @@ -599,7 +599,7 @@ fn test_burn_precision_loss() { increase_stake_on_coldkey_hotkey_account(&coldkey, &hotkey, stake.into(), netuid); // amount to recycle - let burn_amount = AlphaCurrency::from(stake / 2); + let burn_amount = AlphaBalance::from(stake / 2); // Modify the alpha pool denominator so it's low-precision let denominator = U64F64::from_num(0.00000001); @@ -634,12 +634,12 @@ fn test_add_stake_burn_success() { (amount * 10_000_000).into(), ); - SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount.into()); // Check we have zero staked before transfer assert_eq!( SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), - TaoCurrency::ZERO + TaoBalance::ZERO ); // Execute add_stake_burn - this stakes TAO to get Alpha, then burns the Alpha @@ -654,14 +654,14 @@ fn test_add_stake_burn_success() { // 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 + TaoBalance::ZERO ); // We spent TAO assert_abs_diff_eq!( SubtensorModule::get_coldkey_balance(&coldkey_account_id), - 0u64, - epsilon = 1u64 + 0u64.into(), + epsilon = 1u64.into() ); // Verify AlphaBurned event was emitted @@ -693,8 +693,8 @@ fn test_add_stake_burn_with_limit_success() { 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 + let tao_reserve = TaoBalance::from(1_000_000_000_000_u64); // 1000 TAO + let alpha_in = AlphaBalance::from(1_000_000_000_000_u64); // 1000 Alpha mock::setup_reserves(netuid, tao_reserve, alpha_in); // Verify current price is 1.0 @@ -703,13 +703,13 @@ fn test_add_stake_burn_with_limit_success() { assert_eq!(current_price, U96F32::from_num(1.0)); // Give coldkey sufficient balance - SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount.into()); 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 + let limit_price = TaoBalance::from(2_000_000_000); // 2.0 TAO per Alpha // Execute add_stake_burn with limit assert_ok!(SubtensorModule::add_stake_burn( @@ -723,7 +723,7 @@ fn test_add_stake_burn_with_limit_success() { // 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 + TaoBalance::ZERO ); // TAO should have been spent @@ -770,7 +770,7 @@ fn test_add_stake_burn_non_owner_fails() { ); // Give non-owner some balance - SubtensorModule::add_balance_to_coldkey_account(&non_owner_coldkey, amount); + SubtensorModule::add_balance_to_coldkey_account(&non_owner_coldkey, amount.into()); // Non-owner trying to call add_stake_burn should fail with BadOrigin assert_noop!( @@ -794,7 +794,7 @@ fn test_add_stake_burn_nonexistent_subnet_fails() { let amount = DefaultMinStake::::get().to_u64() * 10; // Give some balance - SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount.into()); // Try to call add_stake_burn on non-existent subnet let nonexistent_netuid = NetUid::from(999); @@ -852,12 +852,12 @@ fn test_add_stake_burn_rate_limit_exceeded() { 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); + let tao_reserve = TaoBalance::from(1_000_000_000_000_u64); + let alpha_in = AlphaBalance::from(1_000_000_000_000_u64); 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); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, (amount * 10).into()); assert_eq!( SubtensorModule::get_rate_limited_last_block(&RateLimitKey::AddStakeBurn(netuid)), diff --git a/pallets/subtensor/src/tests/registration.rs b/pallets/subtensor/src/tests/registration.rs index 635b996cea..5209204115 100644 --- a/pallets/subtensor/src/tests/registration.rs +++ b/pallets/subtensor/src/tests/registration.rs @@ -9,12 +9,14 @@ use frame_support::{assert_err, assert_noop, assert_ok}; use frame_system::{Config, RawOrigin}; use sp_core::U256; use sp_runtime::traits::{DispatchInfoOf, TransactionExtension, TxBaseImplication}; -use subtensor_runtime_common::{AlphaCurrency, Currency as CurrencyT, NetUid, NetUidStorageIndex}; +use subtensor_runtime_common::{ + AlphaBalance, CustomTransactionError, NetUid, NetUidStorageIndex, Token, +}; use super::mock; use super::mock::*; use crate::extensions::SubtensorTransactionExtension; -use crate::{AxonInfoOf, CustomTransactionError, Error}; +use crate::{AxonInfoOf, Error}; /******************************************** subscribing::subscribe() tests @@ -125,7 +127,7 @@ fn test_registration_ok() { // Check if the balance of this hotkey account for this subnetwork == 0 assert_eq!( SubtensorModule::get_stake_for_uid_and_subnetwork(netuid, neuron_uid), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); }); } @@ -291,12 +293,15 @@ fn test_burned_registration_under_limit() { // Set the burn cost SubtensorModule::set_burn(netuid, burn_cost.into()); - let reserve = 1_000_000_000_000; + let reserve = 1_000_000_000_000_u64; mock::setup_reserves(netuid, reserve.into(), reserve.into()); add_network(netuid, 13, 0); // Add the network // Give it some TAO to the coldkey balance; more than the burn cost - SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, burn_cost + 10_000); + SubtensorModule::add_balance_to_coldkey_account( + &coldkey_account_id, + (burn_cost + 10_000).into(), + ); let target_registrants = 2; let max_registrants = target_registrants * 3; // Maximum is 3 times the target @@ -391,12 +396,15 @@ fn test_burned_registration_rate_allows_burn_adjustment() { // Set the burn cost SubtensorModule::set_burn(netuid, burn_cost.into()); - let reserve = 1_000_000_000_000; + let reserve = 1_000_000_000_000_u64; mock::setup_reserves(netuid, reserve.into(), reserve.into()); add_network(netuid, 13, 0); // Add the network // Give it some TAO to the coldkey balance; more than the burn cost - SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, burn_cost + 10_000); + SubtensorModule::add_balance_to_coldkey_account( + &coldkey_account_id, + (burn_cost + 10_000).into(), + ); let target_registrants = 1; // Target is 1, but we can register more than that, up to some maximum. SubtensorModule::set_target_registrations_per_interval(netuid, target_registrants); @@ -448,11 +456,11 @@ fn test_burned_registration_ok() { SubtensorModule::set_burn(netuid, burn_cost.into()); add_network(netuid, tempo, 0); - let reserve = 1_000_000_000_000; + let reserve = 1_000_000_000_000_u64; mock::setup_reserves(netuid, reserve.into(), reserve.into()); // Give it some $$$ in his coldkey balance - SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, 10000); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, 10000.into()); // Subscribe and check extrinsic output assert_ok!(SubtensorModule::burned_register( <::RuntimeOrigin>::signed(coldkey_account_id), @@ -462,7 +470,7 @@ fn test_burned_registration_ok() { // Check if balance has decreased to pay for the burn. assert_eq!( SubtensorModule::get_coldkey_balance(&coldkey_account_id), - 10000 - burn_cost + (10000 - burn_cost).into() ); // funds drained on reg. // Check if neuron has added to the specified network(netuid) assert_eq!(SubtensorModule::get_subnetwork_n(netuid), 1); @@ -482,7 +490,7 @@ fn test_burned_registration_ok() { // Check if the balance of this hotkey account for this subnetwork == 0 assert_eq!( SubtensorModule::get_stake_for_uid_and_subnetwork(netuid, neuron_uid), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); }); } @@ -499,7 +507,7 @@ fn test_burn_registration_without_neuron_slot() { SubtensorModule::set_burn(netuid, burn_cost.into()); add_network(netuid, tempo, 0); // Give it some $$$ in his coldkey balance - SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, 10000); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, 10000.into()); SubtensorModule::set_max_allowed_uids(netuid, 0); assert_noop!( @@ -527,7 +535,10 @@ fn test_burn_registration_doesnt_write_on_failure() { add_network(netuid, tempo, 0); SubtensorModule::set_burn(netuid, burn_cost.into()); // Give coldkey balance to pay for registration - SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, initial_balance); + SubtensorModule::add_balance_to_coldkey_account( + &coldkey_account_id, + initial_balance.into(), + ); // Set max allowed uids to 0 so registration will fail, but only on last check. SubtensorModule::set_max_allowed_uids(netuid, 0); @@ -544,7 +555,7 @@ fn test_burn_registration_doesnt_write_on_failure() { // Make sure the coldkey balance is unchanged. assert_eq!( SubtensorModule::get_coldkey_balance(&coldkey_account_id), - initial_balance + initial_balance.into() ); // Make sure the neuron is not registered. assert_eq!(SubtensorModule::get_subnetwork_n(netuid), 0); @@ -570,13 +581,16 @@ fn test_burn_adjustment() { target_registrations_per_interval, ); - let reserve = 1_000_000_000_000; + let reserve = 1_000_000_000_000_u64; mock::setup_reserves(netuid, reserve.into(), reserve.into()); // Register key 1. let hotkey_account_id_1 = U256::from(1); let coldkey_account_id_1 = U256::from(1); - SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id_1, init_burn_cost); + SubtensorModule::add_balance_to_coldkey_account( + &coldkey_account_id_1, + init_burn_cost.into(), + ); assert_ok!(SubtensorModule::burned_register( <::RuntimeOrigin>::signed(hotkey_account_id_1), netuid, @@ -586,7 +600,10 @@ fn test_burn_adjustment() { // Register key 2. let hotkey_account_id_2 = U256::from(2); let coldkey_account_id_2 = U256::from(2); - SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id_2, init_burn_cost); + SubtensorModule::add_balance_to_coldkey_account( + &coldkey_account_id_2, + init_burn_cost.into(), + ); assert_ok!(SubtensorModule::burned_register( <::RuntimeOrigin>::signed(hotkey_account_id_2), netuid, @@ -630,13 +647,13 @@ fn test_burn_registration_pruning_scenarios() { SubtensorModule::set_target_registrations_per_interval(netuid, max_allowed_uids); SubtensorModule::set_immunity_period(netuid, immunity_period); - let reserve = 1_000_000_000_000; + let reserve = 1_000_000_000_000_u64; mock::setup_reserves(netuid, reserve.into(), reserve.into()); add_network(netuid, tempo, 0); let mint_balance = burn_cost * max_allowed_uids as u64 + 1_000_000_000; - SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, mint_balance); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, mint_balance.into()); // Register first half of neurons (uids: 0,1,2); all will be immune initially. for i in 0..3 { @@ -1413,7 +1430,7 @@ fn test_registration_get_uid_to_prune_owner_immortality() { // uid0=0, uid1=0, uid2=1 Emission::::insert( netuid, - vec![AlphaCurrency::from(0), 0u64.into(), 1u64.into()], + vec![AlphaBalance::from(0), 0u64.into(), 1u64.into()], ); assert_eq!( @@ -1462,7 +1479,7 @@ fn test_registration_get_uid_to_prune_owner_immortality_all_immune() { // Lowest emission among non-immortal candidates -> uid2 Emission::::insert( netuid, - vec![AlphaCurrency::from(0), 0u64.into(), 1u64.into()], + vec![AlphaBalance::from(0), 0u64.into(), 1u64.into()], ); assert_eq!( @@ -1591,7 +1608,7 @@ fn test_burn_registration_increase_recycled_rao() { let _ = Balances::deposit_creating(&coldkey_account_id, Balance::from(1_000_000_000_000_u64)); - let reserve = 1_000_000_000_000; + let reserve = 1_000_000_000_000_u64; mock::setup_reserves(netuid, reserve.into(), reserve.into()); mock::setup_reserves(netuid2, reserve.into(), reserve.into()); @@ -2135,7 +2152,7 @@ fn test_last_update_correctness() { SubtensorModule::set_burn(netuid, burn_cost.into()); add_network(netuid, tempo, 0); - let reserve = 1_000_000_000_000; + let reserve = 1_000_000_000_000_u64; mock::setup_reserves(netuid, reserve.into(), reserve.into()); // Simulate existing neurons @@ -2146,7 +2163,7 @@ fn test_last_update_correctness() { LastUpdate::::remove(NetUidStorageIndex::from(netuid)); // Give some $$$ to coldkey - SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, 10000); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, 10000.into()); // Subscribe and check extrinsic output assert_ok!(SubtensorModule::burned_register( <::RuntimeOrigin>::signed(coldkey_account_id), diff --git a/pallets/subtensor/src/tests/serving.rs b/pallets/subtensor/src/tests/serving.rs index 552af372e3..2979d4438c 100644 --- a/pallets/subtensor/src/tests/serving.rs +++ b/pallets/subtensor/src/tests/serving.rs @@ -12,6 +12,7 @@ use frame_support::{ use frame_system::{Config, RawOrigin}; use sp_core::U256; use sp_runtime::traits::{DispatchInfoOf, TransactionExtension, TxBaseImplication}; +use subtensor_runtime_common::CustomTransactionError; mod test { use std::net::{Ipv4Addr, Ipv6Addr}; diff --git a/pallets/subtensor/src/tests/staking.rs b/pallets/subtensor/src/tests/staking.rs index 6a293fa11e..0b82fa27eb 100644 --- a/pallets/subtensor/src/tests/staking.rs +++ b/pallets/subtensor/src/tests/staking.rs @@ -11,9 +11,7 @@ use safe_math::FixedExt; use sp_core::{Get, H256, U256}; use substrate_fixed::traits::FromFixed; use substrate_fixed::types::{I96F32, I110F18, U64F64, U96F32}; -use subtensor_runtime_common::{ - AlphaCurrency, Currency as CurrencyT, NetUid, NetUidStorageIndex, TaoCurrency, -}; +use subtensor_runtime_common::{AlphaBalance, NetUid, NetUidStorageIndex, TaoBalance, Token}; use subtensor_swap_interface::{Order, SwapHandler}; use super::mock; @@ -28,7 +26,7 @@ use crate::*; fn test_add_stake_dispatch_info_ok() { new_test_ext(1).execute_with(|| { let hotkey = U256::from(0); - let amount_staked = TaoCurrency::from(5000); + let amount_staked = TaoBalance::from(5000); let netuid = NetUid::from(1); let call = RuntimeCall::SubtensorModule(SubtensorCall::add_stake { hotkey, @@ -58,12 +56,12 @@ fn test_add_stake_ok_no_emission() { ); // Give it some $$$ in his coldkey balance - SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount.into()); // Check we have zero staked before transfer assert_eq!( SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), - TaoCurrency::ZERO + TaoBalance::ZERO ); // Also total stake should be equal to the network initial lock @@ -84,7 +82,7 @@ fn test_add_stake_ok_no_emission() { let (tao_expected, _) = mock::swap_alpha_to_tao(netuid, alpha_staked); let approx_fee = ::SwapInterface::approx_fee_amount( netuid.into(), - TaoCurrency::from(amount), + TaoBalance::from(amount), ); assert_abs_diff_eq!( @@ -101,7 +99,10 @@ fn test_add_stake_ok_no_emission() { ); // Check if balance has decreased - assert_eq!(SubtensorModule::get_coldkey_balance(&coldkey_account_id), 1); + assert_eq!( + SubtensorModule::get_coldkey_balance(&coldkey_account_id), + 1.into() + ); // Check if total stake has increased accordingly. assert_eq!( @@ -162,7 +163,7 @@ fn test_dividends_with_run_to_block() { // Check if the stake is equal to the inital stake + transfer assert_eq!( SubtensorModule::get_total_stake_for_hotkey(&neuron_dest_hotkey_id), - TaoCurrency::ZERO + TaoBalance::ZERO ); }); } @@ -195,7 +196,7 @@ fn test_add_stake_not_registered_key_pair() { let hotkey_account_id = U256::from(54544); let netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); let amount = DefaultMinStake::::get().to_u64() * 10; - SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount.into()); assert_err!( SubtensorModule::add_stake( RuntimeOrigin::signed(coldkey_account_id), @@ -239,7 +240,7 @@ fn test_add_stake_err_not_enough_belance() { let netuid = add_dynamic_network(&hotkey_id, &coldkey_id); // Lets try to stake with 0 balance in cold key account - assert!(SubtensorModule::get_coldkey_balance(&coldkey_id) < stake.to_u64()); + assert!(SubtensorModule::get_coldkey_balance(&coldkey_id) < stake); assert_err!( SubtensorModule::add_stake( RuntimeOrigin::signed(coldkey_id), @@ -264,18 +265,21 @@ fn test_add_stake_total_balance_no_change() { // Give it some $$$ in his coldkey balance let initial_balance = 10000; - SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, initial_balance); + SubtensorModule::add_balance_to_coldkey_account( + &coldkey_account_id, + initial_balance.into(), + ); // Check we have zero staked before transfer let initial_stake = SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id); - assert_eq!(initial_stake, TaoCurrency::ZERO); + assert_eq!(initial_stake, TaoBalance::ZERO); // Check total balance is equal to initial balance let initial_total_balance = Balances::total_balance(&coldkey_account_id); - assert_eq!(initial_total_balance, initial_balance); + assert_eq!(initial_total_balance, initial_balance.into()); // Also total stake should be zero - assert_eq!(SubtensorModule::get_total_stake(), TaoCurrency::ZERO); + assert_eq!(SubtensorModule::get_total_stake(), TaoBalance::ZERO); // Stake to hotkey account, and check if the result is ok assert_ok!(SubtensorModule::add_stake( @@ -291,7 +295,7 @@ fn test_add_stake_total_balance_no_change() { // Check if free balance has decreased let new_free_balance = SubtensorModule::get_coldkey_balance(&coldkey_account_id); - assert_eq!(new_free_balance, 0); + assert_eq!(new_free_balance, 0.into()); // Check if total stake has increased accordingly. assert_eq!(SubtensorModule::get_total_stake(), 10000.into()); @@ -314,22 +318,25 @@ fn test_add_stake_total_issuance_no_change() { // Give it some $$$ in his coldkey balance let initial_balance = 10000; - SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, initial_balance); + SubtensorModule::add_balance_to_coldkey_account( + &coldkey_account_id, + initial_balance.into(), + ); // Check we have zero staked before transfer let initial_stake = SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id); - assert_eq!(initial_stake, TaoCurrency::ZERO); + assert_eq!(initial_stake, TaoBalance::ZERO); // Check total balance is equal to initial balance let initial_total_balance = Balances::total_balance(&coldkey_account_id); - assert_eq!(initial_total_balance, initial_balance); + assert_eq!(initial_total_balance, initial_balance.into()); // Check total issuance is equal to initial balance let initial_total_issuance = Balances::total_issuance(); - assert_eq!(initial_total_issuance, initial_balance); + assert_eq!(initial_total_issuance, initial_balance.into()); // Also total stake should be zero - assert_eq!(SubtensorModule::get_total_stake(), TaoCurrency::ZERO); + assert_eq!(SubtensorModule::get_total_stake(), TaoBalance::ZERO); // Stake to hotkey account, and check if the result is ok assert_ok!(SubtensorModule::add_stake( @@ -345,7 +352,7 @@ fn test_add_stake_total_issuance_no_change() { // Check if free balance has decreased let new_free_balance = SubtensorModule::get_coldkey_balance(&coldkey_account_id); - assert_eq!(new_free_balance, 0); + assert_eq!(new_free_balance, 0.into()); // Check if total stake has increased accordingly. assert_eq!(SubtensorModule::get_total_stake(), 10000.into()); @@ -360,7 +367,7 @@ fn test_add_stake_total_issuance_no_change() { fn test_remove_stake_dispatch_info_ok() { new_test_ext(1).execute_with(|| { let hotkey = U256::from(0); - let amount_unstaked = AlphaCurrency::from(5000); + let amount_unstaked = AlphaBalance::from(5000); let netuid = NetUid::from(1); let call = RuntimeCall::SubtensorModule(SubtensorCall::remove_stake { hotkey, @@ -398,9 +405,12 @@ fn test_remove_stake_ok_no_emission() { ); assert_eq!( SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), - TaoCurrency::ZERO + TaoBalance::ZERO + ); + assert_eq!( + SubtensorModule::get_coldkey_balance(&coldkey_account_id), + 0.into() ); - assert_eq!(SubtensorModule::get_coldkey_balance(&coldkey_account_id), 0); // Give the neuron some stake to remove SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( @@ -431,11 +441,11 @@ fn test_remove_stake_ok_no_emission() { // we do not expect the exact amount due to slippage assert!( SubtensorModule::get_coldkey_balance(&coldkey_account_id) - > amount.to_u64() / 10 * 9 - fee + > (amount.to_u64() / 10 * 9 - fee).into() ); assert_abs_diff_eq!( SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), - TaoCurrency::ZERO, + TaoBalance::ZERO, epsilon = 20000.into() ); assert_abs_diff_eq!( @@ -464,9 +474,12 @@ fn test_remove_stake_amount_too_low() { ); assert_eq!( SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), - TaoCurrency::ZERO + TaoBalance::ZERO + ); + assert_eq!( + SubtensorModule::get_coldkey_balance(&coldkey_account_id), + 0.into() ); - assert_eq!(SubtensorModule::get_coldkey_balance(&coldkey_account_id), 0); // Give the neuron some stake to remove SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( @@ -482,7 +495,7 @@ fn test_remove_stake_amount_too_low() { RuntimeOrigin::signed(coldkey_account_id), hotkey_account_id, netuid, - AlphaCurrency::ZERO + AlphaBalance::ZERO ), Error::::AmountTooLow ); @@ -500,7 +513,7 @@ fn test_remove_stake_below_min_stake() { register_ok_neuron(netuid, hotkey_account_id, coldkey_account_id, 192213123); let min_stake = DefaultMinStake::::get(); - let amount = AlphaCurrency::from(min_stake.to_u64() / 2); + let amount = AlphaBalance::from(min_stake.to_u64() / 2); // Some basic assertions assert_eq!( @@ -509,9 +522,12 @@ fn test_remove_stake_below_min_stake() { ); assert_eq!( SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), - TaoCurrency::ZERO + TaoBalance::ZERO + ); + assert_eq!( + SubtensorModule::get_coldkey_balance(&coldkey_account_id), + 0.into() ); - assert_eq!(SubtensorModule::get_coldkey_balance(&coldkey_account_id), 0); // Give the neuron some stake to remove SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( @@ -565,7 +581,7 @@ fn test_add_stake_partial_below_min_stake_fails() { let amount = min_stake.to_u64() * 2; SubtensorModule::add_balance_to_coldkey_account( &coldkey_account_id, - amount + ExistentialDeposit::get(), + TaoBalance::from(amount) + ExistentialDeposit::get(), ); // Setup reserves so that price is 1.0 and init swap @@ -574,8 +590,8 @@ fn test_add_stake_partial_below_min_stake_fails() { // Force the swap to initialize SubtensorModule::swap_tao_for_alpha( netuid, - TaoCurrency::ZERO, - 1_000_000_000_000.into(), + TaoBalance::ZERO, + 1_000_000_000_000_u64.into(), false, ) .unwrap(); @@ -611,7 +627,7 @@ fn test_add_stake_partial_below_min_stake_fails() { fn test_remove_stake_err_signature() { new_test_ext(1).execute_with(|| { let hotkey_account_id = U256::from(4968585); - let amount = AlphaCurrency::from(10000); // Amount to be removed + let amount = AlphaBalance::from(10000); // Amount to be removed let netuid = NetUid::from(1); assert_err!( @@ -662,7 +678,7 @@ fn test_remove_stake_no_enough_stake() { assert_eq!( SubtensorModule::get_total_stake_for_hotkey(&hotkey_id), - TaoCurrency::ZERO + TaoBalance::ZERO ); assert_err!( @@ -702,11 +718,14 @@ fn test_remove_stake_total_balance_no_change() { ); assert_eq!( SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), - TaoCurrency::ZERO + TaoBalance::ZERO + ); + assert_eq!( + SubtensorModule::get_coldkey_balance(&coldkey_account_id), + 0.into() ); - assert_eq!(SubtensorModule::get_coldkey_balance(&coldkey_account_id), 0); let initial_total_balance = Balances::total_balance(&coldkey_account_id); - assert_eq!(initial_total_balance, 0); + assert_eq!(initial_total_balance, 0.into()); // Give the neuron some stake to remove SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( @@ -734,17 +753,17 @@ fn test_remove_stake_total_balance_no_change() { let fee = ::SwapInterface::approx_fee_amount( netuid.into(), - TaoCurrency::from(amount), + TaoBalance::from(amount), ) .to_u64(); assert_abs_diff_eq!( SubtensorModule::get_coldkey_balance(&coldkey_account_id), - amount - fee, - epsilon = amount / 1000, + (amount - fee).into(), + epsilon = (amount / 1000).into(), ); assert_eq!( SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), - TaoCurrency::ZERO + TaoBalance::ZERO ); assert_abs_diff_eq!( SubtensorModule::get_total_stake(), @@ -754,7 +773,11 @@ fn test_remove_stake_total_balance_no_change() { // Check total balance is equal to the added stake. Even after remove stake (no fee, includes reserved/locked balance) let total_balance = Balances::total_balance(&coldkey_account_id); - assert_abs_diff_eq!(total_balance, amount - fee, epsilon = amount / 1000); + assert_abs_diff_eq!( + total_balance, + (amount - fee).into(), + epsilon = (amount / 1000).into() + ); }); } @@ -769,7 +792,7 @@ fn test_add_stake_insufficient_liquidity() { let netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); SubtensorModule::create_account_if_non_existent(&coldkey, &hotkey); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, amount_staked); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, amount_staked.into()); // Set the liquidity at lowest possible value so that all staking requests fail let reserve = u64::from(mock::SwapMinimumReserve::get()) - 1; @@ -800,7 +823,7 @@ fn test_add_stake_insufficient_liquidity_one_side_ok() { let netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); SubtensorModule::create_account_if_non_existent(&coldkey, &hotkey); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, amount_staked); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, amount_staked.into()); // Set the liquidity at lowest possible value so that all staking requests fail let reserve_alpha = u64::from(mock::SwapMinimumReserve::get()); @@ -829,7 +852,7 @@ fn test_add_stake_insufficient_liquidity_one_side_fail() { let netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); SubtensorModule::create_account_if_non_existent(&coldkey, &hotkey); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, amount_staked); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, amount_staked.into()); // Set the liquidity at lowest possible value so that all staking requests fail let reserve_alpha = u64::from(mock::SwapMinimumReserve::get()) - 1; @@ -860,7 +883,7 @@ fn test_remove_stake_insufficient_liquidity() { let netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); SubtensorModule::create_account_if_non_existent(&coldkey, &hotkey); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, amount_staked); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, amount_staked.into()); // Simulate stake for hotkey let reserve = u64::MAX / 1000; @@ -888,8 +911,8 @@ fn test_remove_stake_insufficient_liquidity() { ); // Mock provided liquidity - remove becomes successful - SubnetTaoProvided::::insert(netuid, TaoCurrency::from(amount_staked + 1)); - SubnetAlphaInProvided::::insert(netuid, AlphaCurrency::from(1)); + SubnetTaoProvided::::insert(netuid, TaoBalance::from(amount_staked + 1)); + SubnetAlphaInProvided::::insert(netuid, AlphaBalance::from(1)); assert_ok!(SubtensorModule::remove_stake( RuntimeOrigin::signed(coldkey), hotkey, @@ -917,7 +940,7 @@ fn test_remove_stake_total_issuance_no_change() { pallet_subtensor_swap::FeeRate::::insert(netuid, 0); // Give it some $$$ in his coldkey balance - SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount.into()); mock::setup_reserves(netuid, (amount * 100).into(), (amount * 100).into()); @@ -928,14 +951,14 @@ fn test_remove_stake_total_issuance_no_change() { ); assert_eq!( SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), - TaoCurrency::ZERO + TaoBalance::ZERO ); assert_eq!( SubtensorModule::get_coldkey_balance(&coldkey_account_id), - amount + amount.into() ); let initial_total_balance = Balances::total_balance(&coldkey_account_id); - assert_eq!(initial_total_balance, amount); + assert_eq!(initial_total_balance, amount.into()); let inital_total_issuance = Balances::total_issuance(); // Stake to hotkey account, and check if the result is ok @@ -971,33 +994,33 @@ fn test_remove_stake_total_issuance_no_change() { assert_abs_diff_eq!( SubtensorModule::get_coldkey_balance(&coldkey_account_id), - amount - total_fee, - epsilon = 50 + (amount - total_fee).into(), + epsilon = 50.into() ); assert_eq!( SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), - TaoCurrency::ZERO + TaoBalance::ZERO ); assert_abs_diff_eq!( SubtensorModule::get_total_stake(), SubtensorModule::get_network_min_lock() + total_fee.into(), - epsilon = TaoCurrency::from(fee) / 1000.into() + 1.into() + epsilon = TaoBalance::from(fee) / 1000.into() + 1.into() ); // Check if total issuance is equal to the added stake, even after remove stake (no fee, // includes reserved/locked balance) assert_abs_diff_eq!( inital_total_issuance, - total_issuance_after_stake + amount, - epsilon = 1, + total_issuance_after_stake + amount.into(), + epsilon = 1.into(), ); // After staking + unstaking the 2 * fee amount stays in SubnetTAO and TotalStake, // so the total issuance should be lower by that amount assert_abs_diff_eq!( inital_total_issuance, - total_issuance_after_unstake + total_fee, - epsilon = inital_total_issuance / 10000, + total_issuance_after_unstake + total_fee.into(), + epsilon = inital_total_issuance / 10000.into(), ); }); } @@ -1027,8 +1050,8 @@ fn test_remove_prev_epoch_stake() { ] .into_iter() .for_each(|(amount_to_stake, alpha_divs, hotkey_alpha)| { - let alpha_divs = AlphaCurrency::from(alpha_divs); - let hotkey_alpha = AlphaCurrency::from(hotkey_alpha); + let alpha_divs = AlphaBalance::from(alpha_divs); + let hotkey_alpha = AlphaBalance::from(hotkey_alpha); let subnet_owner_coldkey = U256::from(1); let subnet_owner_hotkey = U256::from(2); let hotkey_account_id = U256::from(581337); @@ -1038,7 +1061,7 @@ fn test_remove_prev_epoch_stake() { register_ok_neuron(netuid, hotkey_account_id, coldkey_account_id, 192213123); // Give it some $$$ in his coldkey balance - SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount.into()); AlphaDividendsPerSubnet::::insert(netuid, hotkey_account_id, alpha_divs); TotalHotkeyAlphaLastEpoch::::insert(hotkey_account_id, netuid, hotkey_alpha); let balance_before = SubtensorModule::get_coldkey_balance(&coldkey_account_id); @@ -1077,7 +1100,7 @@ fn test_remove_prev_epoch_stake() { let balance_after = SubtensorModule::get_coldkey_balance(&coldkey_account_id); let actual_fee = balance_before - balance_after; - assert_abs_diff_eq!(actual_fee, fee, epsilon = fee / 100); + assert_abs_diff_eq!(actual_fee, fee.into(), epsilon = (fee / 100).into()); }); }); } @@ -1090,23 +1113,23 @@ fn test_staking_sets_div_variables() { let subnet_owner_hotkey = U256::from(2); let hotkey_account_id = U256::from(581337); let coldkey_account_id = U256::from(81337); - let amount = 100_000_000_000; + let amount = 100_000_000_000_u64; let netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); let tempo = 10; Tempo::::insert(netuid, tempo); register_ok_neuron(netuid, hotkey_account_id, coldkey_account_id, 192213123); // Give it some $$$ in his coldkey balance - SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount.into()); // Verify that divident variables are clear in the beginning assert_eq!( AlphaDividendsPerSubnet::::get(netuid, hotkey_account_id), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); assert_eq!( TotalHotkeyAlphaLastEpoch::::get(hotkey_account_id, netuid), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); // Stake to hotkey account, and check if the result is ok @@ -1120,11 +1143,11 @@ fn test_staking_sets_div_variables() { // Verify that divident variables are still clear in the beginning assert_eq!( AlphaDividendsPerSubnet::::get(netuid, hotkey_account_id), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); assert_eq!( TotalHotkeyAlphaLastEpoch::::get(hotkey_account_id, netuid), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); // Wait for 1 epoch @@ -1138,7 +1161,7 @@ fn test_staking_sets_div_variables() { ); assert!( - AlphaDividendsPerSubnet::::get(netuid, hotkey_account_id) > AlphaCurrency::ZERO + AlphaDividendsPerSubnet::::get(netuid, hotkey_account_id) > AlphaBalance::ZERO ); assert_abs_diff_eq!( TotalHotkeyAlphaLastEpoch::::get(hotkey_account_id, netuid), @@ -1158,7 +1181,7 @@ fn test_get_coldkey_balance_no_balance() { let result = SubtensorModule::get_coldkey_balance(&coldkey_account_id); // Arbitrary account should have 0 balance - assert_eq!(result, 0); + assert_eq!(result, 0.into()); }); } @@ -1169,12 +1192,12 @@ fn test_get_coldkey_balance_with_balance() { let amount = 1337; // Put the balance on the account - SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount.into()); let result = SubtensorModule::get_coldkey_balance(&coldkey_account_id); // Arbitrary account should have 0 balance - assert_eq!(result, amount); + assert_eq!(result, amount.into()); }); } @@ -1254,7 +1277,7 @@ fn test_remove_stake_from_hotkey_account() { // The stake on the hotkey account should be 0 assert_eq!( SubtensorModule::get_total_stake_for_hotkey(&hotkey_id), - TaoCurrency::ZERO + TaoBalance::ZERO ); }); } @@ -1293,7 +1316,7 @@ fn test_remove_stake_from_hotkey_account_registered_in_various_networks() { ); assert_eq!( SubtensorModule::get_stake_for_uid_and_subnetwork(netuid_ex, neuron_uid_ex), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); // Remove all stake @@ -1307,11 +1330,11 @@ fn test_remove_stake_from_hotkey_account_registered_in_various_networks() { // assert_eq!( SubtensorModule::get_stake_for_uid_and_subnetwork(netuid, neuron_uid), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); assert_eq!( SubtensorModule::get_stake_for_uid_and_subnetwork(netuid_ex, neuron_uid_ex), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); }); } @@ -1322,8 +1345,8 @@ fn test_remove_stake_from_hotkey_account_registered_in_various_networks() { #[test] fn test_increase_total_stake_ok() { new_test_ext(1).execute_with(|| { - let increment = TaoCurrency::from(10000); - assert_eq!(SubtensorModule::get_total_stake(), TaoCurrency::ZERO); + let increment = TaoBalance::from(10000); + assert_eq!(SubtensorModule::get_total_stake(), TaoBalance::ZERO); SubtensorModule::increase_total_stake(increment); assert_eq!(SubtensorModule::get_total_stake(), increment); }); @@ -1335,8 +1358,8 @@ fn test_increase_total_stake_ok() { #[test] fn test_decrease_total_stake_ok() { new_test_ext(1).execute_with(|| { - let initial_total_stake = TaoCurrency::from(10000); - let decrement = TaoCurrency::from(5000); + let initial_total_stake = TaoBalance::from(10000); + let decrement = TaoBalance::from(5000); SubtensorModule::increase_total_stake(initial_total_stake); SubtensorModule::decrease_total_stake(decrement); @@ -1357,8 +1380,11 @@ fn test_add_balance_to_coldkey_account_ok() { new_test_ext(1).execute_with(|| { let coldkey_id = U256::from(4444322); let amount = 50000; - SubtensorModule::add_balance_to_coldkey_account(&coldkey_id, amount); - assert_eq!(SubtensorModule::get_coldkey_balance(&coldkey_id), amount); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_id, amount.into()); + assert_eq!( + SubtensorModule::get_coldkey_balance(&coldkey_id), + amount.into() + ); }); } @@ -1369,16 +1395,18 @@ fn test_add_balance_to_coldkey_account_ok() { fn test_remove_balance_from_coldkey_account_ok() { new_test_ext(1).execute_with(|| { let coldkey_account_id = U256::from(434324); // Random - let ammount = 10000; // Arbitrary + let amount = 10000; // Arbitrary // Put some $$ on the bank - SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, ammount); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount.into()); assert_eq!( SubtensorModule::get_coldkey_balance(&coldkey_account_id), - ammount + amount.into() ); // Should be able to withdraw without hassle - let result = - SubtensorModule::remove_balance_from_coldkey_account(&coldkey_account_id, ammount); + let result = SubtensorModule::remove_balance_from_coldkey_account( + &coldkey_account_id, + amount.into(), + ); assert!(result.is_ok()); }); } @@ -1387,12 +1415,14 @@ fn test_remove_balance_from_coldkey_account_ok() { fn test_remove_balance_from_coldkey_account_failed() { new_test_ext(1).execute_with(|| { let coldkey_account_id = U256::from(434324); // Random - let ammount = 10000; // Arbitrary + let amount = 10000; // Arbitrary // Try to remove stake from the coldkey account. This should fail, // as there is no balance, nor does the account exist - let result = - SubtensorModule::remove_balance_from_coldkey_account(&coldkey_account_id, ammount); + let result = SubtensorModule::remove_balance_from_coldkey_account( + &coldkey_account_id, + amount.into(), + ); assert_eq!(result, Err(Error::::ZeroBalanceAfterWithdrawn.into())); }); } @@ -1425,10 +1455,10 @@ fn test_can_remove_balane_from_coldkey_account_ok() { let coldkey_id = U256::from(87987984); let initial_amount = 10000; let remove_amount = 5000; - SubtensorModule::add_balance_to_coldkey_account(&coldkey_id, initial_amount); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_id, initial_amount.into()); assert!(SubtensorModule::can_remove_balance_from_coldkey_account( &coldkey_id, - remove_amount + remove_amount.into() )); }); } @@ -1439,10 +1469,10 @@ fn test_can_remove_balance_from_coldkey_account_err_insufficient_balance() { let coldkey_id = U256::from(87987984); let initial_amount = 10000; let remove_amount = 20000; - SubtensorModule::add_balance_to_coldkey_account(&coldkey_id, initial_amount); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_id, initial_amount.into()); assert!(!SubtensorModule::can_remove_balance_from_coldkey_account( &coldkey_id, - remove_amount + remove_amount.into() )); }); } @@ -1577,7 +1607,7 @@ fn test_non_existent_account() { // No subnets => no iteration => zero total stake assert_eq!( SubtensorModule::get_total_stake_for_hotkey(&(U256::from(0))), - TaoCurrency::ZERO + TaoBalance::ZERO ); }); } @@ -1639,8 +1669,8 @@ fn test_clear_small_nominations() { let cold1 = U256::from(3); let cold2 = U256::from(4); let netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); - let amount = DefaultMinStake::::get().to_u64() * 10; - let fee = DefaultMinStake::::get().to_u64(); + let amount = DefaultMinStake::::get() * 10.into(); + let fee = DefaultMinStake::::get(); let init_balance = amount + fee + ExistentialDeposit::get(); // Set fee rate to 0 so that alpha fee is not moved to block producer @@ -1666,7 +1696,7 @@ fn test_clear_small_nominations() { )); let alpha_stake1 = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(&hot1, &cold1, netuid); - let unstake_amount1 = AlphaCurrency::from(alpha_stake1.to_u64() * 997 / 1000); + let unstake_amount1 = AlphaBalance::from(alpha_stake1.to_u64() * 997 / 1000); let small1 = alpha_stake1 - unstake_amount1; remove_stake_rate_limit_for_tests(&hot1, &cold1, netuid); assert_ok!(SubtensorModule::remove_stake( @@ -1690,7 +1720,7 @@ fn test_clear_small_nominations() { )); let alpha_stake2 = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(&hot1, &cold2, netuid); - let unstake_amount2 = AlphaCurrency::from(alpha_stake2.to_u64() * 997 / 1000); + let unstake_amount2 = AlphaBalance::from(alpha_stake2.to_u64() * 997 / 1000); let small2 = alpha_stake2 - unstake_amount2; remove_stake_rate_limit_for_tests(&hot1, &cold2, netuid); assert_ok!(SubtensorModule::remove_stake( @@ -1735,7 +1765,7 @@ fn test_clear_small_nominations() { ); assert_eq!( SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(&hot1, &cold2, netuid), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); // Balances have been added back into accounts. @@ -1762,7 +1792,7 @@ fn test_delegate_take_can_be_decreased() { let coldkey0 = U256::from(3); // Add balance - SubtensorModule::add_balance_to_coldkey_account(&coldkey0, 100000); + SubtensorModule::add_balance_to_coldkey_account(&coldkey0, 100000.into()); // Register the neuron to a new network let netuid = NetUid::from(1); @@ -1797,7 +1827,7 @@ fn test_can_set_min_take_ok() { let coldkey0 = U256::from(3); // Add balance - SubtensorModule::add_balance_to_coldkey_account(&coldkey0, 100000); + SubtensorModule::add_balance_to_coldkey_account(&coldkey0, 100000.into()); // Register the neuron to a new network let netuid = NetUid::from(1); @@ -1829,7 +1859,7 @@ fn test_delegate_take_can_not_be_increased_with_decrease_take() { let coldkey0 = U256::from(3); // Add balance - SubtensorModule::add_balance_to_coldkey_account(&coldkey0, 100000); + SubtensorModule::add_balance_to_coldkey_account(&coldkey0, 100000.into()); // Register the neuron to a new network let netuid = NetUid::from(1); @@ -1864,7 +1894,7 @@ fn test_delegate_take_can_be_increased() { let coldkey0 = U256::from(3); // Add balance - SubtensorModule::add_balance_to_coldkey_account(&coldkey0, 100000); + SubtensorModule::add_balance_to_coldkey_account(&coldkey0, 100000.into()); // Register the neuron to a new network let netuid = NetUid::from(1); @@ -1899,7 +1929,7 @@ fn test_delegate_take_can_not_be_decreased_with_increase_take() { let coldkey0 = U256::from(3); // Add balance - SubtensorModule::add_balance_to_coldkey_account(&coldkey0, 100000); + SubtensorModule::add_balance_to_coldkey_account(&coldkey0, 100000.into()); // Register the neuron to a new network let netuid = NetUid::from(1); @@ -1938,7 +1968,7 @@ fn test_delegate_take_can_be_increased_to_limit() { let coldkey0 = U256::from(3); // Add balance - SubtensorModule::add_balance_to_coldkey_account(&coldkey0, 100000); + SubtensorModule::add_balance_to_coldkey_account(&coldkey0, 100000.into()); // Register the neuron to a new network let netuid = NetUid::from(1); @@ -1976,7 +2006,7 @@ fn test_delegate_take_can_not_be_increased_beyond_limit() { let coldkey0 = U256::from(3); // Add balance - SubtensorModule::add_balance_to_coldkey_account(&coldkey0, 100000); + SubtensorModule::add_balance_to_coldkey_account(&coldkey0, 100000.into()); // Register the neuron to a new network let netuid = NetUid::from(1); @@ -2018,7 +2048,7 @@ fn test_rate_limits_enforced_on_increase_take() { let coldkey0 = U256::from(3); // Add balance - SubtensorModule::add_balance_to_coldkey_account(&coldkey0, 100000); + SubtensorModule::add_balance_to_coldkey_account(&coldkey0, 100000.into()); // Register the neuron to a new network let netuid = NetUid::from(1); @@ -2078,7 +2108,7 @@ fn test_rate_limits_enforced_on_decrease_before_increase_take() { let coldkey0 = U256::from(3); // Add balance - SubtensorModule::add_balance_to_coldkey_account(&coldkey0, 100000); + SubtensorModule::add_balance_to_coldkey_account(&coldkey0, 100000.into()); // Register the neuron to a new network let netuid = NetUid::from(1); @@ -2148,7 +2178,7 @@ fn test_get_total_delegated_stake_after_unstaking() { register_ok_neuron(netuid, delegate_hotkey, delegate_coldkey, 0); // Add balance to delegator - SubtensorModule::add_balance_to_coldkey_account(&delegator, initial_stake); + SubtensorModule::add_balance_to_coldkey_account(&delegator, initial_stake.into()); // Delegate stake let (_, fee) = mock::swap_tao_to_alpha(netuid, initial_stake.into()); @@ -2162,13 +2192,13 @@ fn test_get_total_delegated_stake_after_unstaking() { // Check initial delegated stake assert_abs_diff_eq!( SubtensorModule::get_total_stake_for_coldkey(&delegator), - (initial_stake - existential_deposit - fee).into(), - epsilon = TaoCurrency::from(initial_stake / 100), + (initial_stake - u64::from(existential_deposit) - fee).into(), + epsilon = TaoBalance::from(initial_stake / 100), ); assert_abs_diff_eq!( SubtensorModule::get_total_stake_for_hotkey(&delegate_hotkey), - (initial_stake - existential_deposit - fee).into(), - epsilon = TaoCurrency::from(initial_stake / 100), + (initial_stake - u64::from(existential_deposit) - fee).into(), + epsilon = TaoBalance::from(initial_stake / 100), ); let delegated_alpha = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( &delegate_hotkey, @@ -2191,7 +2221,8 @@ fn test_get_total_delegated_stake_after_unstaking() { // Calculate the expected delegated stake let unstake_amount = (current_price * U96F32::from_num(unstake_amount_alpha)).to_num::(); - let expected_delegated_stake = initial_stake - unstake_amount - existential_deposit - fee; + let expected_delegated_stake: u64 = + initial_stake - unstake_amount - u64::from(existential_deposit) - fee; // Debug prints log::debug!("Initial stake: {initial_stake}"); @@ -2207,12 +2238,12 @@ fn test_get_total_delegated_stake_after_unstaking() { assert_abs_diff_eq!( SubtensorModule::get_total_stake_for_coldkey(&delegator), expected_delegated_stake.into(), - epsilon = TaoCurrency::from(expected_delegated_stake / 1000), + epsilon = TaoBalance::from(expected_delegated_stake / 1000), ); assert_abs_diff_eq!( SubtensorModule::get_total_stake_for_hotkey(&delegate_hotkey), expected_delegated_stake.into(), - epsilon = TaoCurrency::from(expected_delegated_stake / 1000), + epsilon = TaoBalance::from(expected_delegated_stake / 1000), ); }); } @@ -2230,7 +2261,7 @@ fn test_get_total_delegated_stake_no_delegations() { // Check that there's no delegated stake assert_eq!( SubtensorModule::get_total_stake_for_coldkey(&delegate), - TaoCurrency::ZERO + TaoBalance::ZERO ); }); } @@ -2250,7 +2281,7 @@ fn test_get_total_delegated_stake_single_delegator() { register_ok_neuron(netuid, delegate_hotkey, delegate_coldkey, 0); // Add stake from delegator - SubtensorModule::add_balance_to_coldkey_account(&delegator, stake_amount); + SubtensorModule::add_balance_to_coldkey_account(&delegator, stake_amount.into()); let (_, fee) = mock::swap_tao_to_alpha(netuid, stake_amount.into()); @@ -2277,19 +2308,19 @@ fn test_get_total_delegated_stake_single_delegator() { ); // Calculate expected delegated stake - let expected_delegated_stake = stake_amount - existential_deposit - fee; + let expected_delegated_stake = stake_amount - u64::from(existential_deposit) - fee; let actual_delegated_stake = SubtensorModule::get_total_stake_for_hotkey(&delegate_hotkey); let actual_delegator_stake = SubtensorModule::get_total_stake_for_coldkey(&delegator); assert_abs_diff_eq!( actual_delegated_stake, expected_delegated_stake.into(), - epsilon = TaoCurrency::from(expected_delegated_stake / 100), + epsilon = TaoBalance::from(expected_delegated_stake / 100), ); assert_abs_diff_eq!( actual_delegator_stake, expected_delegated_stake.into(), - epsilon = TaoCurrency::from(expected_delegated_stake / 100), + epsilon = TaoBalance::from(expected_delegated_stake / 100), ); }); } @@ -2303,7 +2334,7 @@ fn test_get_alpha_share_stake_multiple_delegators() { let hotkey2 = U256::from(20); let coldkey1 = U256::from(3); let coldkey2 = U256::from(4); - let existential_deposit = 2; + let existential_deposit = TaoBalance::from(2); let stake1 = DefaultMinStake::::get() * 10.into(); let stake2 = DefaultMinStake::::get() * 10.into() - 1.into(); @@ -2312,10 +2343,7 @@ fn test_get_alpha_share_stake_multiple_delegators() { register_ok_neuron(netuid, hotkey2, coldkey2, 0); // Add stake from delegator1 - SubtensorModule::add_balance_to_coldkey_account( - &coldkey1, - stake1.to_u64() + existential_deposit, - ); + SubtensorModule::add_balance_to_coldkey_account(&coldkey1, stake1 + existential_deposit); assert_ok!(SubtensorModule::add_stake( RuntimeOrigin::signed(coldkey1), hotkey1, @@ -2324,10 +2352,7 @@ fn test_get_alpha_share_stake_multiple_delegators() { )); // Add stake from delegator2 - SubtensorModule::add_balance_to_coldkey_account( - &coldkey2, - stake2.to_u64() + existential_deposit, - ); + SubtensorModule::add_balance_to_coldkey_account(&coldkey2, stake2 + existential_deposit); assert_ok!(SubtensorModule::add_stake( RuntimeOrigin::signed(coldkey2), hotkey2, @@ -2349,7 +2374,7 @@ fn test_get_alpha_share_stake_multiple_delegators() { // Total subnet stake should match the sum of delegators' stakes minus existential deposits. assert_abs_diff_eq!( - AlphaCurrency::from(actual_total_stake), + AlphaBalance::from(actual_total_stake), expected_total_stake, epsilon = expected_total_stake / 1000.into() ); @@ -2368,7 +2393,7 @@ fn test_get_total_delegated_stake_exclude_owner_stake() { let netuid = add_dynamic_network(&delegate_hotkey, &delegate_coldkey); // Add owner stake - SubtensorModule::add_balance_to_coldkey_account(&delegate_coldkey, owner_stake); + SubtensorModule::add_balance_to_coldkey_account(&delegate_coldkey, owner_stake.into()); assert_ok!(SubtensorModule::add_stake( RuntimeOrigin::signed(delegate_coldkey), delegate_hotkey, @@ -2377,7 +2402,7 @@ fn test_get_total_delegated_stake_exclude_owner_stake() { )); // Add delegator stake - SubtensorModule::add_balance_to_coldkey_account(&delegator, delegator_stake); + SubtensorModule::add_balance_to_coldkey_account(&delegator, delegator_stake.into()); let (_, fee) = mock::swap_tao_to_alpha(netuid, delegator_stake.into()); assert_ok!(SubtensorModule::add_stake( RuntimeOrigin::signed(delegator), @@ -2394,7 +2419,7 @@ fn test_get_total_delegated_stake_exclude_owner_stake() { assert_abs_diff_eq!( actual_delegated_stake, expected_delegated_stake.into(), - epsilon = TaoCurrency::from(expected_delegated_stake / 100) + epsilon = TaoBalance::from(expected_delegated_stake / 100) ); }); } @@ -2412,7 +2437,7 @@ fn test_mining_emission_distribution_validator_valiminer_miner() { let miner_hotkey = U256::from(6); let netuid = NetUid::from(1); let subnet_tempo = 10; - let stake = 100_000_000_000; + let stake = TaoBalance::from(100_000_000_000_u64); // Add network, register hotkeys, and setup network parameters add_network(netuid, subnet_tempo, 0); @@ -2518,7 +2543,7 @@ fn test_staking_too_little_fails() { let netuid = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); // Give it some $$$ in his coldkey balance - SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount.into()); // Coldkey / hotkey 0 decreases take to 5%. This should fail as the minimum take is 9% assert_err!( @@ -2550,7 +2575,7 @@ fn test_add_stake_fee_goes_to_subnet_tao() { let subnet_tao_before = SubnetTAO::::get(netuid); // Add stake - SubtensorModule::add_balance_to_coldkey_account(&coldkey, tao_to_stake.to_u64()); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, tao_to_stake); assert_ok!(SubtensorModule::add_stake( RuntimeOrigin::signed(coldkey), hotkey, @@ -2559,7 +2584,7 @@ fn test_add_stake_fee_goes_to_subnet_tao() { )); // Calculate expected stake - let expected_alpha = AlphaCurrency::from(tao_to_stake.to_u64() - existential_deposit); + let expected_alpha = AlphaBalance::from((tao_to_stake - existential_deposit).to_u64()); let actual_alpha = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(&hotkey, &coldkey, netuid); let subnet_tao_after = SubnetTAO::::get(netuid); @@ -2626,8 +2651,8 @@ fn test_remove_stake_fee_goes_to_subnet_tao() { let balance_after = SubtensorModule::get_coldkey_balance(&coldkey); assert_abs_diff_eq!( balance_after, - tao_to_stake.to_u64(), - epsilon = tao_to_stake.to_u64() / 1000 + tao_to_stake, + epsilon = tao_to_stake / 1000.into() ); }); } @@ -2641,8 +2666,8 @@ fn test_remove_stake_fee_realistic_values() { let subnet_owner_hotkey = U256::from(1002); let hotkey = U256::from(2); let coldkey = U256::from(3); - let alpha_to_unstake = AlphaCurrency::from(111_180_000_000); - let alpha_divs = AlphaCurrency::from(2_816_190); + let alpha_to_unstake = AlphaBalance::from(111_180_000_000_u64); + let alpha_divs = AlphaBalance::from(2_816_190); let netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); SubtensorModule::create_account_if_non_existent(&coldkey, &hotkey); @@ -2682,10 +2707,14 @@ fn test_remove_stake_fee_realistic_values() { let balance_after = SubtensorModule::get_coldkey_balance(&coldkey); // FIXME since fee is calculated by SwapInterface and the values here are after fees, the // actual_fee is 0. but it's left here to discuss in review - let actual_fee = expected_tao.to_u64() - (balance_after - balance_before); + let actual_fee = expected_tao - (balance_after - balance_before); log::info!("Actual fee: {actual_fee:?}"); - assert_abs_diff_eq!(actual_fee, expected_fee, epsilon = expected_fee / 1000); + assert_abs_diff_eq!( + actual_fee, + expected_fee.into(), + epsilon = (expected_fee / 1000).into() + ); }); } @@ -2697,11 +2726,11 @@ fn test_stake_overflow() { let coldkey_account_id = U256::from(435445); let hotkey_account_id = U256::from(54544); let netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); - let amount = 21_000_000_000_000_000; // Max TAO supply + let amount = 21_000_000_000_000_000_u64; // Max TAO supply register_ok_neuron(netuid, hotkey_account_id, coldkey_account_id, 192213123); // Give it some $$$ in his coldkey balance - SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount.into()); // Setup liquidity with 21M TAO values mock::setup_reserves(netuid, amount.into(), amount.into()); @@ -2735,31 +2764,31 @@ fn test_max_amount_add_root() { new_test_ext(0).execute_with(|| { // 0 price on root => max is 0 assert_eq!( - SubtensorModule::get_max_amount_add(NetUid::ROOT, TaoCurrency::ZERO), + SubtensorModule::get_max_amount_add(NetUid::ROOT, TaoBalance::ZERO), Err(Error::::ZeroMaxStakeAmount.into()) ); // 0.999999... price on root => max is 0 assert_eq!( - SubtensorModule::get_max_amount_add(NetUid::ROOT, TaoCurrency::from(999_999_999)), + SubtensorModule::get_max_amount_add(NetUid::ROOT, TaoBalance::from(999_999_999)), Err(Error::::ZeroMaxStakeAmount.into()) ); // 1.0 price on root => max is u64::MAX assert_eq!( - SubtensorModule::get_max_amount_add(NetUid::ROOT, TaoCurrency::from(1_000_000_000)), + SubtensorModule::get_max_amount_add(NetUid::ROOT, TaoBalance::from(1_000_000_000)), Ok(u64::MAX) ); // 1.000...001 price on root => max is u64::MAX assert_eq!( - SubtensorModule::get_max_amount_add(NetUid::ROOT, TaoCurrency::from(1_000_000_001)), + SubtensorModule::get_max_amount_add(NetUid::ROOT, TaoBalance::from(1_000_000_001)), Ok(u64::MAX) ); // 2.0 price on root => max is u64::MAX assert_eq!( - SubtensorModule::get_max_amount_add(NetUid::ROOT, TaoCurrency::from(2_000_000_000)), + SubtensorModule::get_max_amount_add(NetUid::ROOT, TaoBalance::from(2_000_000_000)), Ok(u64::MAX) ); }); @@ -2773,31 +2802,31 @@ fn test_max_amount_add_stable() { // 0 price => max is 0 assert_eq!( - SubtensorModule::get_max_amount_add(netuid, TaoCurrency::ZERO), + SubtensorModule::get_max_amount_add(netuid, TaoBalance::ZERO), Err(Error::::ZeroMaxStakeAmount.into()) ); // 0.999999... price => max is 0 assert_eq!( - SubtensorModule::get_max_amount_add(netuid, TaoCurrency::from(999_999_999)), + SubtensorModule::get_max_amount_add(netuid, TaoBalance::from(999_999_999)), Err(Error::::ZeroMaxStakeAmount.into()) ); // 1.0 price => max is u64::MAX assert_eq!( - SubtensorModule::get_max_amount_add(netuid, TaoCurrency::from(1_000_000_000)), + SubtensorModule::get_max_amount_add(netuid, TaoBalance::from(1_000_000_000)), Ok(u64::MAX) ); // 1.000...001 price => max is u64::MAX assert_eq!( - SubtensorModule::get_max_amount_add(netuid, TaoCurrency::from(1_000_000_001)), + SubtensorModule::get_max_amount_add(netuid, TaoBalance::from(1_000_000_001)), Ok(u64::MAX) ); // 2.0 price => max is u64::MAX assert_eq!( - SubtensorModule::get_max_amount_add(netuid, TaoCurrency::from(2_000_000_000)), + SubtensorModule::get_max_amount_add(netuid, TaoBalance::from(2_000_000_000)), Ok(u64::MAX) ); }); @@ -2878,20 +2907,20 @@ fn test_max_amount_add_dynamic() { .into_iter() .for_each(|(tao_in, alpha_in, limit_price, expected_max_swappable)| { new_test_ext(0).execute_with(|| { - let alpha_in = AlphaCurrency::from(alpha_in); + let alpha_in = AlphaBalance::from(alpha_in); let subnet_owner_coldkey = U256::from(1001); let subnet_owner_hotkey = U256::from(1002); let netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); // Forse-set alpha in and tao reserve to achieve relative price of subnets - SubnetTAO::::insert(netuid, TaoCurrency::from(tao_in)); + SubnetTAO::::insert(netuid, TaoBalance::from(tao_in)); SubnetAlphaIn::::insert(netuid, alpha_in); // Force the swap to initialize SubtensorModule::swap_tao_for_alpha( netuid, - TaoCurrency::ZERO, - 1_000_000_000_000.into(), + TaoBalance::ZERO, + 1_000_000_000_000_u64.into(), false, ) .unwrap(); @@ -2926,37 +2955,37 @@ fn test_max_amount_remove_root() { new_test_ext(0).execute_with(|| { // 0 price on root => max is u64::MAX assert_eq!( - SubtensorModule::get_max_amount_remove(NetUid::ROOT, TaoCurrency::ZERO), - Ok(AlphaCurrency::MAX) + SubtensorModule::get_max_amount_remove(NetUid::ROOT, TaoBalance::ZERO), + Ok(AlphaBalance::MAX) ); // 0.5 price on root => max is u64::MAX assert_eq!( - SubtensorModule::get_max_amount_remove(NetUid::ROOT, TaoCurrency::from(500_000_000)), - Ok(AlphaCurrency::MAX) + SubtensorModule::get_max_amount_remove(NetUid::ROOT, TaoBalance::from(500_000_000)), + Ok(AlphaBalance::MAX) ); // 0.999999... price on root => max is u64::MAX assert_eq!( - SubtensorModule::get_max_amount_remove(NetUid::ROOT, TaoCurrency::from(999_999_999)), - Ok(AlphaCurrency::MAX) + SubtensorModule::get_max_amount_remove(NetUid::ROOT, TaoBalance::from(999_999_999)), + Ok(AlphaBalance::MAX) ); // 1.0 price on root => max is u64::MAX assert_eq!( - SubtensorModule::get_max_amount_remove(NetUid::ROOT, TaoCurrency::from(1_000_000_000)), - Ok(AlphaCurrency::MAX) + SubtensorModule::get_max_amount_remove(NetUid::ROOT, TaoBalance::from(1_000_000_000)), + Ok(AlphaBalance::MAX) ); // 1.000...001 price on root => max is 0 assert_eq!( - SubtensorModule::get_max_amount_remove(NetUid::ROOT, TaoCurrency::from(1_000_000_001)), + SubtensorModule::get_max_amount_remove(NetUid::ROOT, TaoBalance::from(1_000_000_001)), Err(Error::::ZeroMaxStakeAmount.into()) ); // 2.0 price on root => max is 0 assert_eq!( - SubtensorModule::get_max_amount_remove(NetUid::ROOT, TaoCurrency::from(2_000_000_000)), + SubtensorModule::get_max_amount_remove(NetUid::ROOT, TaoBalance::from(2_000_000_000)), Err(Error::::ZeroMaxStakeAmount.into()) ); }); @@ -2970,31 +2999,31 @@ fn test_max_amount_remove_stable() { // 0 price => max is u64::MAX assert_eq!( - SubtensorModule::get_max_amount_remove(netuid, TaoCurrency::ZERO), - Ok(AlphaCurrency::MAX) + SubtensorModule::get_max_amount_remove(netuid, TaoBalance::ZERO), + Ok(AlphaBalance::MAX) ); // 0.999999... price => max is u64::MAX assert_eq!( - SubtensorModule::get_max_amount_remove(netuid, TaoCurrency::from(999_999_999)), - Ok(AlphaCurrency::MAX) + SubtensorModule::get_max_amount_remove(netuid, TaoBalance::from(999_999_999)), + Ok(AlphaBalance::MAX) ); // 1.0 price => max is u64::MAX assert_eq!( - SubtensorModule::get_max_amount_remove(netuid, TaoCurrency::from(1_000_000_000)), - Ok(AlphaCurrency::MAX) + SubtensorModule::get_max_amount_remove(netuid, TaoBalance::from(1_000_000_000)), + Ok(AlphaBalance::MAX) ); // 1.000...001 price => max is 0 assert_eq!( - SubtensorModule::get_max_amount_remove(netuid, TaoCurrency::from(1_000_000_001)), + SubtensorModule::get_max_amount_remove(netuid, TaoBalance::from(1_000_000_001)), Err(Error::::ZeroMaxStakeAmount.into()) ); // 2.0 price => max is 0 assert_eq!( - SubtensorModule::get_max_amount_remove(netuid, TaoCurrency::from(2_000_000_000)), + SubtensorModule::get_max_amount_remove(netuid, TaoBalance::from(2_000_000_000)), Err(Error::::ZeroMaxStakeAmount.into()) ); }); @@ -3012,8 +3041,8 @@ fn test_max_amount_remove_dynamic() { [ // Zero handling (no panics) ( - 0, - 1_000_000_000, + 0_u64, + 1_000_000_000_u64, 100, Err(DispatchError::from( pallet_subtensor_swap::Error::::ReservesTooLow, @@ -3115,9 +3144,9 @@ fn test_max_amount_remove_dynamic() { ] .into_iter() .for_each(|(tao_in, alpha_in, limit_price, expected_max_swappable)| { - let alpha_in = AlphaCurrency::from(alpha_in); + let alpha_in = AlphaBalance::from(alpha_in); // Forse-set alpha in and tao reserve to achieve relative price of subnets - SubnetTAO::::insert(netuid, TaoCurrency::from(tao_in)); + SubnetTAO::::insert(netuid, TaoBalance::from(tao_in)); SubnetAlphaIn::::insert(netuid, alpha_in); if !alpha_in.is_zero() { @@ -3134,7 +3163,7 @@ fn test_max_amount_remove_dynamic() { DispatchError::from(e) ), Ok(v) => { - let v = AlphaCurrency::from(v); + let v = AlphaBalance::from(v); assert_abs_diff_eq!( SubtensorModule::get_max_amount_remove(netuid, limit_price.into()).unwrap(), v, @@ -3152,8 +3181,8 @@ fn test_max_amount_move_root_root() { new_test_ext(0).execute_with(|| { // 0 price on (root, root) exchange => max is u64::MAX assert_eq!( - SubtensorModule::get_max_amount_move(NetUid::ROOT, NetUid::ROOT, TaoCurrency::ZERO), - Ok(AlphaCurrency::MAX) + SubtensorModule::get_max_amount_move(NetUid::ROOT, NetUid::ROOT, TaoBalance::ZERO), + Ok(AlphaBalance::MAX) ); // 0.5 price on (root, root) => max is u64::MAX @@ -3161,9 +3190,9 @@ fn test_max_amount_move_root_root() { SubtensorModule::get_max_amount_move( NetUid::ROOT, NetUid::ROOT, - TaoCurrency::from(500_000_000) + TaoBalance::from(500_000_000) ), - Ok(AlphaCurrency::MAX) + Ok(AlphaBalance::MAX) ); // 0.999999... price on (root, root) => max is u64::MAX @@ -3171,9 +3200,9 @@ fn test_max_amount_move_root_root() { SubtensorModule::get_max_amount_move( NetUid::ROOT, NetUid::ROOT, - TaoCurrency::from(999_999_999) + TaoBalance::from(999_999_999) ), - Ok(AlphaCurrency::MAX) + Ok(AlphaBalance::MAX) ); // 1.0 price on (root, root) => max is u64::MAX @@ -3181,9 +3210,9 @@ fn test_max_amount_move_root_root() { SubtensorModule::get_max_amount_move( NetUid::ROOT, NetUid::ROOT, - TaoCurrency::from(1_000_000_000) + TaoBalance::from(1_000_000_000) ), - Ok(AlphaCurrency::MAX) + Ok(AlphaBalance::MAX) ); // 1.000...001 price on (root, root) => max is 0 @@ -3191,7 +3220,7 @@ fn test_max_amount_move_root_root() { SubtensorModule::get_max_amount_move( NetUid::ROOT, NetUid::ROOT, - TaoCurrency::from(1_000_000_001) + TaoBalance::from(1_000_000_001) ), Err(Error::::ZeroMaxStakeAmount.into()) ); @@ -3201,7 +3230,7 @@ fn test_max_amount_move_root_root() { SubtensorModule::get_max_amount_move( NetUid::ROOT, NetUid::ROOT, - TaoCurrency::from(2_000_000_000) + TaoBalance::from(2_000_000_000) ), Err(Error::::ZeroMaxStakeAmount.into()) ); @@ -3217,8 +3246,8 @@ fn test_max_amount_move_root_stable() { // 0 price on (root, stable) exchange => max is u64::MAX assert_eq!( - SubtensorModule::get_max_amount_move(NetUid::ROOT, netuid, TaoCurrency::ZERO), - Ok(AlphaCurrency::MAX) + SubtensorModule::get_max_amount_move(NetUid::ROOT, netuid, TaoBalance::ZERO), + Ok(AlphaBalance::MAX) ); // 0.5 price on (root, stable) => max is u64::MAX @@ -3226,9 +3255,9 @@ fn test_max_amount_move_root_stable() { SubtensorModule::get_max_amount_move( NetUid::ROOT, netuid, - TaoCurrency::from(500_000_000) + TaoBalance::from(500_000_000) ), - Ok(AlphaCurrency::MAX) + Ok(AlphaBalance::MAX) ); // 0.999999... price on (root, stable) => max is u64::MAX @@ -3236,9 +3265,9 @@ fn test_max_amount_move_root_stable() { SubtensorModule::get_max_amount_move( NetUid::ROOT, netuid, - TaoCurrency::from(999_999_999) + TaoBalance::from(999_999_999) ), - Ok(AlphaCurrency::MAX) + Ok(AlphaBalance::MAX) ); // 1.0 price on (root, stable) => max is u64::MAX @@ -3246,9 +3275,9 @@ fn test_max_amount_move_root_stable() { SubtensorModule::get_max_amount_move( NetUid::ROOT, netuid, - TaoCurrency::from(1_000_000_000) + TaoBalance::from(1_000_000_000) ), - Ok(AlphaCurrency::MAX) + Ok(AlphaBalance::MAX) ); // 1.000...001 price on (root, stable) => max is 0 @@ -3256,7 +3285,7 @@ fn test_max_amount_move_root_stable() { SubtensorModule::get_max_amount_move( NetUid::ROOT, netuid, - TaoCurrency::from(1_000_000_001) + TaoBalance::from(1_000_000_001) ), Err(Error::::ZeroMaxStakeAmount.into()) ); @@ -3266,7 +3295,7 @@ fn test_max_amount_move_root_stable() { SubtensorModule::get_max_amount_move( NetUid::ROOT, netuid, - TaoCurrency::from(2_000_000_000) + TaoBalance::from(2_000_000_000) ), Err(Error::::ZeroMaxStakeAmount.into()) ); @@ -3287,8 +3316,8 @@ fn test_max_amount_move_stable_dynamic() { let dynamic_netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); // Force-set alpha in and tao reserve to make price equal 0.5 - let tao_reserve = TaoCurrency::from(50_000_000_000); - let alpha_in = AlphaCurrency::from(100_000_000_000); + let tao_reserve = TaoBalance::from(50_000_000_000_u64); + let alpha_in = AlphaBalance::from(100_000_000_000_u64); SubnetTAO::::insert(dynamic_netuid, tao_reserve); SubnetAlphaIn::::insert(dynamic_netuid, alpha_in); let current_price = @@ -3299,8 +3328,8 @@ fn test_max_amount_move_stable_dynamic() { // 0 price => max is u64::MAX assert_eq!( - SubtensorModule::get_max_amount_move(stable_netuid, dynamic_netuid, TaoCurrency::ZERO), - Ok(AlphaCurrency::MAX) + SubtensorModule::get_max_amount_move(stable_netuid, dynamic_netuid, TaoBalance::ZERO), + Ok(AlphaBalance::MAX) ); // 2.0 price => max is 0 @@ -3308,7 +3337,7 @@ fn test_max_amount_move_stable_dynamic() { SubtensorModule::get_max_amount_move( stable_netuid, dynamic_netuid, - TaoCurrency::from(2_000_000_000) + TaoBalance::from(2_000_000_000) ), Err(Error::::ZeroMaxStakeAmount.into()) ); @@ -3318,7 +3347,7 @@ fn test_max_amount_move_stable_dynamic() { SubtensorModule::get_max_amount_move( stable_netuid, dynamic_netuid, - TaoCurrency::from(3_000_000_000) + TaoBalance::from(3_000_000_000_u64) ), Err(pallet_subtensor_swap::Error::::PriceLimitExceeded.into()) ); @@ -3328,13 +3357,11 @@ fn test_max_amount_move_stable_dynamic() { SubtensorModule::get_max_amount_move( stable_netuid, dynamic_netuid, - TaoCurrency::from(500_000_000) + TaoBalance::from(500_000_000) ) .unwrap(), - AlphaCurrency::from( - tao_reserve.to_u64() + (tao_reserve.to_u64() as f64 * 0.003) as u64 - ), - epsilon = AlphaCurrency::from(tao_reserve.to_u64() / 100), + AlphaBalance::from(tao_reserve.to_u64() + (tao_reserve.to_u64() as f64 * 0.003) as u64), + epsilon = AlphaBalance::from(tao_reserve.to_u64() / 100), ); // Precision test: @@ -3343,22 +3370,22 @@ fn test_max_amount_move_stable_dynamic() { SubtensorModule::get_max_amount_move( stable_netuid, dynamic_netuid, - TaoCurrency::from(1_999_999_000) + TaoBalance::from(1_999_999_000) ) .unwrap() - > AlphaCurrency::ZERO + > AlphaBalance::ZERO ); // Max price doesn't panic and returns something meaningful assert_eq!( - SubtensorModule::get_max_amount_move(stable_netuid, dynamic_netuid, TaoCurrency::MAX), + SubtensorModule::get_max_amount_move(stable_netuid, dynamic_netuid, TaoBalance::MAX), Err(pallet_subtensor_swap::Error::::PriceLimitExceeded.into()) ); assert_eq!( SubtensorModule::get_max_amount_move( stable_netuid, dynamic_netuid, - TaoCurrency::MAX - 1.into() + TaoBalance::MAX - 1.into() ), Err(pallet_subtensor_swap::Error::::PriceLimitExceeded.into()) ); @@ -3366,7 +3393,7 @@ fn test_max_amount_move_stable_dynamic() { SubtensorModule::get_max_amount_move( stable_netuid, dynamic_netuid, - TaoCurrency::MAX / 2.into() + TaoBalance::MAX / 2.into() ), Err(pallet_subtensor_swap::Error::::PriceLimitExceeded.into()) ); @@ -3387,8 +3414,8 @@ fn test_max_amount_move_dynamic_stable() { let dynamic_netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); // Forse-set alpha in and tao reserve to make price equal 1.5 - let tao_reserve = TaoCurrency::from(150_000_000_000); - let alpha_in = AlphaCurrency::from(100_000_000_000); + let tao_reserve = TaoBalance::from(150_000_000_000_u64); + let alpha_in = AlphaBalance::from(100_000_000_000_u64); SubnetTAO::::insert(dynamic_netuid, tao_reserve); SubnetAlphaIn::::insert(dynamic_netuid, alpha_in); let current_price = @@ -3399,22 +3426,22 @@ fn test_max_amount_move_dynamic_stable() { // 0 price => max is u64::MAX assert_eq!( - SubtensorModule::get_max_amount_move(dynamic_netuid, stable_netuid, TaoCurrency::ZERO), - Ok(AlphaCurrency::MAX) + SubtensorModule::get_max_amount_move(dynamic_netuid, stable_netuid, TaoBalance::ZERO), + Ok(AlphaBalance::MAX) ); // Low price values don't blow things up assert!( SubtensorModule::get_max_amount_move(dynamic_netuid, stable_netuid, 1.into()).unwrap() - > AlphaCurrency::ZERO + > AlphaBalance::ZERO ); assert!( SubtensorModule::get_max_amount_move(dynamic_netuid, stable_netuid, 2.into()).unwrap() - > AlphaCurrency::ZERO + > AlphaBalance::ZERO ); assert!( SubtensorModule::get_max_amount_move(dynamic_netuid, stable_netuid, 3.into()).unwrap() - > AlphaCurrency::ZERO + > AlphaBalance::ZERO ); // 1.5000...1 price => max is 0 @@ -3434,8 +3461,8 @@ fn test_max_amount_move_dynamic_stable() { stable_netuid, 1_500_000_000.into() ) - .unwrap_or(AlphaCurrency::ZERO), - AlphaCurrency::ZERO, + .unwrap_or(AlphaBalance::ZERO), + AlphaBalance::ZERO, epsilon = 10_000.into() ); @@ -3456,32 +3483,32 @@ fn test_max_amount_move_dynamic_stable() { 1_499_999_999.into() ) .unwrap() - > AlphaCurrency::ZERO + > AlphaBalance::ZERO ); // Max price doesn't panic and returns something meaningful assert!( - SubtensorModule::get_max_amount_move(dynamic_netuid, stable_netuid, TaoCurrency::MAX) - .unwrap_or(AlphaCurrency::ZERO) - < 21_000_000_000_000_000.into() + SubtensorModule::get_max_amount_move(dynamic_netuid, stable_netuid, TaoBalance::MAX) + .unwrap_or(AlphaBalance::ZERO) + < 21_000_000_000_000_000_u64.into() ); assert!( SubtensorModule::get_max_amount_move( dynamic_netuid, stable_netuid, - TaoCurrency::MAX - 1.into() + TaoBalance::MAX - 1.into() ) - .unwrap_or(AlphaCurrency::ZERO) - < 21_000_000_000_000_000.into() + .unwrap_or(AlphaBalance::ZERO) + < 21_000_000_000_000_000_u64.into() ); assert!( SubtensorModule::get_max_amount_move( dynamic_netuid, stable_netuid, - TaoCurrency::MAX / 2.into() + TaoBalance::MAX / 2.into() ) - .unwrap_or(AlphaCurrency::ZERO) - < 21_000_000_000_000_000.into() + .unwrap_or(AlphaBalance::ZERO) + < 21_000_000_000_000_000_u64.into() ); }); } @@ -3508,7 +3535,15 @@ fn test_max_amount_move_dynamic_dynamic() { // tao_in_1, alpha_in_1, tao_in_2, alpha_in_2, limit_price, expected_max_swappable, precision [ // Zero handling (no panics) - (0, 1_000_000_000, 1_000_000_000, 1_000_000_000, 100, 0, 1), + ( + 0_u64, + 1_000_000_000_u64, + 1_000_000_000_u64, + 1_000_000_000_u64, + 100, + 0, + 1_u64, + ), (1_000_000_000, 0, 1_000_000_000, 1_000_000_000, 100, 0, 1), (1_000_000_000, 1_000_000_000, 0, 1_000_000_000, 100, 0, 1), (1_000_000_000, 1_000_000_000, 1_000_000_000, 0, 100, 0, 1), @@ -3680,13 +3715,13 @@ fn test_max_amount_move_dynamic_dynamic() { expected_max_swappable, precision, )| { - let alpha_in_1 = AlphaCurrency::from(alpha_in_1); - let alpha_in_2 = AlphaCurrency::from(alpha_in_2); - let expected_max_swappable = AlphaCurrency::from(expected_max_swappable); + let alpha_in_1 = AlphaBalance::from(alpha_in_1); + let alpha_in_2 = AlphaBalance::from(alpha_in_2); + let expected_max_swappable = AlphaBalance::from(expected_max_swappable); // Forse-set alpha in and tao reserve to achieve relative price of subnets - SubnetTAO::::insert(origin_netuid, TaoCurrency::from(tao_in_1)); + SubnetTAO::::insert(origin_netuid, TaoBalance::from(tao_in_1)); SubnetAlphaIn::::insert(origin_netuid, alpha_in_1); - SubnetTAO::::insert(destination_netuid, TaoCurrency::from(tao_in_2)); + SubnetTAO::::insert(destination_netuid, TaoBalance::from(tao_in_2)); SubnetAlphaIn::::insert(destination_netuid, alpha_in_2); if !alpha_in_1.is_zero() && !alpha_in_2.is_zero() { @@ -3713,7 +3748,7 @@ fn test_max_amount_move_dynamic_dynamic() { destination_netuid, limit_price.into() ) - .unwrap_or(AlphaCurrency::ZERO), + .unwrap_or(AlphaBalance::ZERO), expected_max_swappable, epsilon = precision.into() ); @@ -3733,21 +3768,21 @@ fn test_add_stake_limit_ok() { let netuid = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); // Forse-set alpha in and tao reserve to make price equal 1.5 - let tao_reserve = TaoCurrency::from(150_000_000_000); - let alpha_in = AlphaCurrency::from(100_000_000_000); + let tao_reserve = TaoBalance::from(150_000_000_000_u64); + let alpha_in = AlphaBalance::from(100_000_000_000_u64); mock::setup_reserves(netuid, tao_reserve, alpha_in); let current_price = ::SwapInterface::current_alpha_price(netuid.into()); assert_eq!(current_price, U96F32::from_num(1.5)); // Give it some $$$ in his coldkey balance - SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount.into()); // Setup limit price so that it doesn't peak above 4x of current price // The amount that can be executed at this price is 450 TAO only // Alpha produced will be equal to 75 = 450*100/(450+150) - let limit_price = TaoCurrency::from(24_000_000_000); - let expected_executed_stake = AlphaCurrency::from(75_000_000_000); + let limit_price = TaoBalance::from(24_000_000_000_u64); + let expected_executed_stake = AlphaBalance::from(75_000_000_000_u64); // Add stake with slippage safety and check if the result is ok assert_ok!(SubtensorModule::add_stake_limit( @@ -3773,13 +3808,13 @@ fn test_add_stake_limit_ok() { // Check that 450 TAO less fees balance still remains free on coldkey let fee = ::SwapInterface::approx_fee_amount( netuid.into(), - TaoCurrency::from(amount / 2), + TaoBalance::from(amount / 2), ) .to_u64() as f64; assert_abs_diff_eq!( SubtensorModule::get_coldkey_balance(&coldkey_account_id), - amount / 2 - fee as u64, - epsilon = amount / 2 / 1000 + (amount / 2 - fee as u64).into(), + epsilon = (amount / 2 / 1000).into() ); // Check that price has updated to ~24 = (150+450) / (100 - 75) @@ -3799,14 +3834,14 @@ fn test_add_stake_limit_fill_or_kill() { new_test_ext(1).execute_with(|| { let hotkey_account_id = U256::from(533453); let coldkey_account_id = U256::from(55453); - let amount = 900_000_000_000; // over the maximum + let amount = 900_000_000_000_u64; // over the maximum // add network let netuid = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); // Force-set alpha in and tao reserve to make price equal 1.5 - let tao_reserve = TaoCurrency::from(150_000_000_000); - let alpha_in = AlphaCurrency::from(100_000_000_000); + let tao_reserve = TaoBalance::from(150_000_000_000_u64); + let alpha_in = AlphaBalance::from(100_000_000_000_u64); SubnetTAO::::insert(netuid, tao_reserve); SubnetAlphaIn::::insert(netuid, alpha_in); let current_price = @@ -3816,12 +3851,12 @@ fn test_add_stake_limit_fill_or_kill() { assert_eq!(current_price, U96F32::from_num(1.5)); // Give it some $$$ in his coldkey balance - SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount.into()); // Setup limit price so that it doesn't peak above 4x of current price // The amount that can be executed at this price is 450 TAO only // Alpha produced will be equal to 25 = 100 - 450*100/(150+450) - let limit_price = TaoCurrency::from(24_000_000_000); + let limit_price = TaoBalance::from(24_000_000_000_u64); // Add stake with slippage safety and check if it fails assert_noop!( @@ -3837,7 +3872,7 @@ fn test_add_stake_limit_fill_or_kill() { ); // Lower the amount and it should succeed now - let amount_ok = TaoCurrency::from(450_000_000_000); // fits the maximum + let amount_ok = TaoBalance::from(450_000_000_000_u64); // fits the maximum assert_ok!(SubtensorModule::add_stake_limit( RuntimeOrigin::signed(coldkey_account_id), hotkey_account_id, @@ -3857,16 +3892,16 @@ fn test_add_stake_limit_partial_zero_max_stake_amount_error() { // Exact values from the error: // https://taostats.io/extrinsic/5338471-0009?network=finney - let amount = 19980000000; - let limit_price = TaoCurrency::from(26953618); - let tao_reserve = TaoCurrency::from(5_032_494_439_940); - let alpha_in = AlphaCurrency::from(186_268_425_402_874); + let amount = 19980000000_u64; + let limit_price = TaoBalance::from(26953618); + let tao_reserve = TaoBalance::from(5_032_494_439_940_u64); + let alpha_in = AlphaBalance::from(186_268_425_402_874_u64); let netuid = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); SubnetTAO::::insert(netuid, tao_reserve); SubnetAlphaIn::::insert(netuid, alpha_in); - SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount.into()); assert_noop!( SubtensorModule::add_stake_limit( @@ -3887,7 +3922,7 @@ fn test_remove_stake_limit_ok() { new_test_ext(1).execute_with(|| { let hotkey_account_id = U256::from(533453); let coldkey_account_id = U256::from(55453); - let stake_amount = 300_000_000_000; + let stake_amount = TaoBalance::from(300_000_000_000_u64); // add network let netuid = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); @@ -3897,8 +3932,8 @@ fn test_remove_stake_limit_ok() { ); // Forse-set sufficient reserves - let tao_reserve = TaoCurrency::from(100_000_000_000); - let alpha_in = AlphaCurrency::from(100_000_000_000); + let tao_reserve = TaoBalance::from(100_000_000_000_u64); + let alpha_in = AlphaBalance::from(100_000_000_000_u64); SubnetTAO::::insert(netuid, tao_reserve); SubnetAlphaIn::::insert(netuid, alpha_in); @@ -3907,7 +3942,7 @@ fn test_remove_stake_limit_ok() { RuntimeOrigin::signed(coldkey_account_id), hotkey_account_id, netuid, - stake_amount.into() + stake_amount )); let alpha_before = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( &hotkey_account_id, @@ -3943,8 +3978,8 @@ fn test_remove_stake_limit_ok() { // Check if stake has decreased properly assert_abs_diff_eq!( alpha_before - alpha_after, - AlphaCurrency::from(expected_alpha_reduction + fee), - epsilon = AlphaCurrency::from(expected_alpha_reduction / 10), + AlphaBalance::from(expected_alpha_reduction + fee), + epsilon = AlphaBalance::from(expected_alpha_reduction / 10), ); }); } @@ -3954,8 +3989,8 @@ fn test_remove_stake_limit_fill_or_kill() { new_test_ext(1).execute_with(|| { let hotkey_account_id = U256::from(533453); let coldkey_account_id = U256::from(55453); - let stake_amount = AlphaCurrency::from(300_000_000_000); - let unstake_amount = AlphaCurrency::from(150_000_000_000); + let stake_amount = AlphaBalance::from(300_000_000_000_u64); + let unstake_amount = AlphaBalance::from(150_000_000_000_u64); // add network let netuid = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); @@ -3969,8 +4004,8 @@ fn test_remove_stake_limit_fill_or_kill() { ); // Forse-set alpha in and tao reserve to make price equal 1.5 - let tao_reserve = TaoCurrency::from(150_000_000_000); - let alpha_in = AlphaCurrency::from(100_000_000_000); + let tao_reserve = TaoBalance::from(150_000_000_000_u64); + let alpha_in = AlphaBalance::from(100_000_000_000_u64); SubnetTAO::::insert(netuid, tao_reserve); SubnetAlphaIn::::insert(netuid, alpha_in); let current_price = @@ -3978,7 +4013,7 @@ fn test_remove_stake_limit_fill_or_kill() { assert_eq!(current_price, U96F32::from_num(1.5)); // Setup limit price so that it doesn't drop by more than 10% from current price - let limit_price = TaoCurrency::from(1_350_000_000); + let limit_price = TaoBalance::from(1_350_000_000); // Remove stake with slippage safety - fails assert_noop!( @@ -4017,12 +4052,12 @@ fn test_add_stake_specific_stake_into_subnet_fail() { let existing_shares: U64F64 = U64F64::from_num(161_986_254).saturating_div(U64F64::from_num(u64::MAX)); - let existing_stake = AlphaCurrency::from(36_711_495_953); + let existing_stake = AlphaBalance::from(36_711_495_953_u64); - let tao_in = TaoCurrency::from(2_409_892_148_947); - let alpha_in = AlphaCurrency::from(15_358_708_513_716); + let tao_in = TaoBalance::from(2_409_892_148_947_u64); + let alpha_in = AlphaBalance::from(15_358_708_513_716_u64); - let tao_staked = TaoCurrency::from(200_000_000); + let tao_staked = TaoBalance::from(200_000_000); //add network let netuid = add_dynamic_network(&sn_owner_coldkey, &sn_owner_coldkey); @@ -4032,7 +4067,7 @@ fn test_add_stake_specific_stake_into_subnet_fail() { // Check we have zero staked assert_eq!( SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), - TaoCurrency::ZERO + TaoBalance::ZERO ); // Set a hotkey pool for the hotkey @@ -4053,7 +4088,7 @@ fn test_add_stake_specific_stake_into_subnet_fail() { // Give TAO balance to coldkey SubtensorModule::add_balance_to_coldkey_account( &coldkey_account_id, - tao_staked.to_u64() + 1_000_000_000, + tao_staked + 1_000_000_000.into(), ); // Add stake as new hotkey @@ -4075,7 +4110,7 @@ fn test_add_stake_specific_stake_into_subnet_fail() { )); // Check we have non-zero staked - assert!(expected_alpha > AlphaCurrency::ZERO); + assert!(expected_alpha > AlphaBalance::ZERO); assert_abs_diff_eq!( SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( &hotkey_account_id, @@ -4096,7 +4131,7 @@ fn test_remove_99_9991_per_cent_stake_removes_all() { let subnet_owner_hotkey = U256::from(2); let hotkey_account_id = U256::from(581337); let coldkey_account_id = U256::from(81337); - let amount = 10_000_000_000; + let amount = 10_000_000_000_u64; let netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); register_ok_neuron(netuid, hotkey_account_id, coldkey_account_id, 192213123); @@ -4105,7 +4140,7 @@ fn test_remove_99_9991_per_cent_stake_removes_all() { pallet_subtensor_swap::FeeRate::::insert(netuid, 0); // Give it some $$$ in his coldkey balance - SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount.into()); // Stake to hotkey account, and check if the result is ok assert_ok!(SubtensorModule::add_stake( @@ -4122,7 +4157,7 @@ fn test_remove_99_9991_per_cent_stake_removes_all() { netuid, ); remove_stake_rate_limit_for_tests(&hotkey_account_id, &coldkey_account_id, netuid); - let remove_amount = AlphaCurrency::from( + let remove_amount = AlphaBalance::from( (U64F64::from_num(alpha) * U64F64::from_num(0.999991)).to_num::(), ); // we expected the entire stake to be returned @@ -4137,12 +4172,12 @@ fn test_remove_99_9991_per_cent_stake_removes_all() { // Check that all alpha was unstaked and all TAO balance was returned (less fees) assert_abs_diff_eq!( SubtensorModule::get_coldkey_balance(&coldkey_account_id), - expected_balance.to_u64(), - epsilon = 10, + expected_balance, + epsilon = 10.into(), ); assert_eq!( SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), - TaoCurrency::ZERO + TaoBalance::ZERO ); let new_alpha = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( &hotkey_account_id, @@ -4170,7 +4205,7 @@ fn test_remove_99_9989_per_cent_stake_leaves_a_little() { pallet_subtensor_swap::FeeRate::::insert(netuid, 0); // Give it some $$$ in his coldkey balance - SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount.into()); // Stake to hotkey account, and check if the result is ok let (_, fee) = mock::swap_tao_to_alpha(netuid, amount.into()); @@ -4202,7 +4237,7 @@ fn test_remove_99_9989_per_cent_stake_leaves_a_little() { // Check that all alpha was unstaked and 99% TAO balance was returned (less fees) // let fee = ::SwapInterface::approx_fee_amount(netuid.into(), (amount as f64 * 0.99) as u64); assert_abs_diff_eq!( - SubtensorModule::get_coldkey_balance(&coldkey_account_id), + SubtensorModule::get_coldkey_balance(&coldkey_account_id).to_u64(), (amount as f64 * 0.99) as u64 - fee, epsilon = amount / 1000, ); @@ -4218,7 +4253,7 @@ fn test_remove_99_9989_per_cent_stake_leaves_a_little() { ); assert_abs_diff_eq!( new_alpha, - AlphaCurrency::from((alpha.to_u64() as f64 * 0.01) as u64), + AlphaBalance::from((alpha.to_u64() as f64 * 0.01) as u64), epsilon = 10.into() ); }); @@ -4231,8 +4266,8 @@ fn test_move_stake_limit_partial() { let subnet_owner_hotkey = U256::from(1002); let coldkey = U256::from(1); let hotkey = U256::from(2); - let stake_amount = AlphaCurrency::from(150_000_000_000); - let move_amount = AlphaCurrency::from(150_000_000_000); + let stake_amount = AlphaBalance::from(150_000_000_000_u64); + let move_amount = AlphaBalance::from(150_000_000_000_u64); // add network let origin_netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); @@ -4250,8 +4285,8 @@ fn test_move_stake_limit_partial() { // Forse-set alpha in and tao reserve to make price equal 1.5 on both origin and destination, // but there's much more liquidity on destination, so its price wouldn't go up when restaked - let tao_reserve = TaoCurrency::from(150_000_000_000); - let alpha_in = AlphaCurrency::from(100_000_000_000); + let tao_reserve = TaoBalance::from(150_000_000_000_u64); + let alpha_in = AlphaBalance::from(100_000_000_000_u64); SubnetTAO::::insert(origin_netuid, tao_reserve); SubnetAlphaIn::::insert(origin_netuid, alpha_in); SubnetTAO::::insert(destination_netuid, tao_reserve * 100_000.into()); @@ -4262,7 +4297,7 @@ fn test_move_stake_limit_partial() { // The relative price between origin and destination subnets is 1. // Setup limit relative price so that it doesn't drop by more than 1% from current price - let limit_price = TaoCurrency::from(990_000_000); + let limit_price = TaoBalance::from(990_000_000); // Move stake with slippage safety - executes partially assert_ok!(SubtensorModule::swap_stake_limit( @@ -4283,7 +4318,7 @@ fn test_move_stake_limit_partial() { assert_abs_diff_eq!( new_alpha, - AlphaCurrency::from(149_000_000_000), + AlphaBalance::from(149_000_000_000_u64), epsilon = 100_000_000.into() ); }); @@ -4298,7 +4333,7 @@ fn test_unstake_all_hits_liquidity_min() { let coldkey = U256::from(1); let hotkey = U256::from(2); - let stake_amount = AlphaCurrency::from(190_000_000_000); // 190 Alpha + let stake_amount = AlphaBalance::from(190_000_000_000_u64); // 190 Alpha let netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); register_ok_neuron(netuid, hotkey, coldkey, 192213123); @@ -4311,8 +4346,8 @@ fn test_unstake_all_hits_liquidity_min() { ); // Setup the Alpha pool so that removing all the Alpha will bring liqudity below the minimum - let remaining_tao = TaoCurrency::from(u64::from(mock::SwapMinimumReserve::get()) - 1); - let alpha_reserves = AlphaCurrency::from(stake_amount.to_u64() + 10_000_000); + let remaining_tao = TaoBalance::from(u64::from(mock::SwapMinimumReserve::get()) - 1); + let alpha_reserves = AlphaBalance::from(stake_amount.to_u64() + 10_000_000); mock::setup_reserves(netuid, remaining_tao, alpha_reserves); // Try to unstake, but we reduce liquidity too far @@ -4325,7 +4360,7 @@ fn test_unstake_all_hits_liquidity_min() { // Expect nothing to be unstaked let new_alpha = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(&hotkey, &coldkey, netuid); - assert_abs_diff_eq!(new_alpha, stake_amount, epsilon = AlphaCurrency::ZERO); + assert_abs_diff_eq!(new_alpha, stake_amount, epsilon = AlphaBalance::ZERO); }); } @@ -4337,7 +4372,7 @@ fn test_unstake_all_alpha_hits_liquidity_min() { let coldkey = U256::from(1); let hotkey = U256::from(2); - let stake_amount = 100_000_000_000; // 100 TAO + let stake_amount = TaoBalance::from(100_000_000_000_u64); // 100 TAO let netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); register_ok_neuron(netuid, hotkey, coldkey, 192213123); @@ -4350,7 +4385,7 @@ fn test_unstake_all_alpha_hits_liquidity_min() { RuntimeOrigin::signed(coldkey), hotkey, netuid, - stake_amount.into() + stake_amount )); // Setup the pool so that removing all the TAO will bring liqudity below the minimum @@ -4392,7 +4427,7 @@ fn test_unstake_all_alpha_works() { let coldkey = U256::from(1); let hotkey = U256::from(2); - let stake_amount = 190_000_000_000; // 190 TAO + let stake_amount = TaoBalance::from(190_000_000_000_u64); // 190 TAO let netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); register_ok_neuron(netuid, hotkey, coldkey, 192213123); @@ -4406,7 +4441,7 @@ fn test_unstake_all_alpha_works() { RuntimeOrigin::signed(coldkey), hotkey, netuid, - stake_amount.into() + stake_amount )); remove_stake_rate_limit_for_tests(&hotkey, &coldkey, netuid); @@ -4414,8 +4449,8 @@ fn test_unstake_all_alpha_works() { // Setup the pool so that removing all the TAO will keep liq above min mock::setup_reserves( netuid, - (stake_amount * 10).into(), - (stake_amount * 100).into(), + stake_amount * 10.into(), + u64::from(stake_amount * 100.into()).into(), ); // Unstake all alpha to root @@ -4426,7 +4461,7 @@ fn test_unstake_all_alpha_works() { let new_alpha = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(&hotkey, &coldkey, netuid); - assert_abs_diff_eq!(new_alpha, AlphaCurrency::ZERO, epsilon = 1_000.into()); + assert_abs_diff_eq!(new_alpha, AlphaBalance::ZERO, epsilon = 1_000.into()); let new_root = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( &hotkey, &coldkey, @@ -4444,7 +4479,7 @@ fn test_unstake_all_works() { let coldkey = U256::from(1); let hotkey = U256::from(2); - let stake_amount = 190_000_000_000; // 190 TAO + let stake_amount = TaoBalance::from(190_000_000_000_u64); // 190 TAO let netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); register_ok_neuron(netuid, hotkey, coldkey, 192213123); @@ -4458,14 +4493,14 @@ fn test_unstake_all_works() { RuntimeOrigin::signed(coldkey), hotkey, netuid, - stake_amount.into() + stake_amount )); // Setup the pool so that removing all the TAO will keep liq above min mock::setup_reserves( netuid, - (stake_amount * 10).into(), - (stake_amount * 100).into(), + stake_amount * 10.into(), + u64::from(stake_amount * 100.into()).into(), ); remove_stake_rate_limit_for_tests(&hotkey, &coldkey, netuid); @@ -4477,9 +4512,9 @@ fn test_unstake_all_works() { let new_alpha = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(&hotkey, &coldkey, netuid); - assert_abs_diff_eq!(new_alpha, AlphaCurrency::ZERO, epsilon = 1_000.into()); + assert_abs_diff_eq!(new_alpha, AlphaBalance::ZERO, epsilon = 1_000.into()); let new_balance = SubtensorModule::get_coldkey_balance(&coldkey); - assert!(new_balance > 100_000); + assert!(new_balance > 100_000.into()); }); } @@ -4496,8 +4531,8 @@ fn test_stake_into_subnet_ok() { let netuid = add_dynamic_network(&owner_hotkey, &owner_coldkey); // Forse-set alpha in and tao reserve to make price equal 0.01 - let tao_reserve = TaoCurrency::from(100_000_000_000); - let alpha_in = AlphaCurrency::from(1_000_000_000_000); + let tao_reserve = TaoBalance::from(100_000_000_000_u64); + let alpha_in = AlphaBalance::from(1_000_000_000_000_u64); mock::setup_reserves(netuid, tao_reserve, alpha_in); let current_price = ::SwapInterface::current_alpha_price(netuid.into()) @@ -4508,7 +4543,7 @@ fn test_stake_into_subnet_ok() { assert_ok!(::SwapInterface::swap( netuid.into(), order, - TaoCurrency::MAX, + TaoBalance::MAX, false, true )); @@ -4519,7 +4554,7 @@ fn test_stake_into_subnet_ok() { &coldkey, netuid, amount.into(), - TaoCurrency::MAX, + TaoBalance::MAX, false, false, )); @@ -4549,20 +4584,20 @@ fn test_stake_into_subnet_low_amount() { // add network let netuid = add_dynamic_network(&owner_hotkey, &owner_coldkey); - // Forse-set alpha in and tao reserve to make price equal 0.01 - let tao_reserve = TaoCurrency::from(100_000_000_000); - let alpha_in = AlphaCurrency::from(1_000_000_000_000); + // Forse-set alpha in and tao reserve to make price equal 0.1 + let tao_reserve = TaoBalance::from(100_000_000_000_u64); + let alpha_in = AlphaBalance::from(1_000_000_000_000_u64); mock::setup_reserves(netuid, tao_reserve, alpha_in); let current_price = ::SwapInterface::current_alpha_price(netuid.into()) .to_num::(); - // Initialize swap v3 + // Initialize swap let order = GetAlphaForTao::::with_amount(0); assert_ok!(::SwapInterface::swap( netuid.into(), order, - TaoCurrency::MAX, + TaoBalance::MAX, false, true )); @@ -4573,17 +4608,17 @@ fn test_stake_into_subnet_low_amount() { &coldkey, netuid, amount.into(), - TaoCurrency::MAX, + TaoBalance::MAX, false, false, )); - let expected_stake = AlphaCurrency::from(((amount as f64) * 0.997 / current_price) as u64); + let expected_stake = AlphaBalance::from(((amount as f64) * 0.997 / current_price) as u64); // Check if stake has increased assert_abs_diff_eq!( SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(&hotkey, &coldkey, netuid), expected_stake, - epsilon = expected_stake / 100.into() + epsilon = 1.into() ); }); } @@ -4601,8 +4636,8 @@ fn test_unstake_from_subnet_low_amount() { let netuid = add_dynamic_network(&owner_hotkey, &owner_coldkey); // Forse-set alpha in and tao reserve to make price equal 0.01 - let tao_reserve = TaoCurrency::from(100_000_000_000); - let alpha_in = AlphaCurrency::from(1_000_000_000_000); + let tao_reserve = TaoBalance::from(100_000_000_000_u64); + let alpha_in = AlphaBalance::from(1_000_000_000_000_u64); mock::setup_reserves(netuid, tao_reserve, alpha_in); // Initialize swap v3 @@ -4610,7 +4645,7 @@ fn test_unstake_from_subnet_low_amount() { assert_ok!(::SwapInterface::swap( netuid.into(), order, - TaoCurrency::MAX, + TaoBalance::MAX, false, true )); @@ -4621,7 +4656,7 @@ fn test_unstake_from_subnet_low_amount() { &coldkey, netuid, amount.into(), - TaoCurrency::MAX, + TaoBalance::MAX, false, false, )); @@ -4634,14 +4669,14 @@ fn test_unstake_from_subnet_low_amount() { &coldkey, netuid, alpha, - TaoCurrency::ZERO, + TaoBalance::ZERO, false, )); // Check if stake is zero assert_eq!( SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(&hotkey, &coldkey, netuid), - AlphaCurrency::ZERO, + AlphaBalance::ZERO, ); }); } @@ -4656,11 +4691,11 @@ fn test_stake_into_subnet_prohibitive_limit() { // add network let netuid = add_dynamic_network(&owner_hotkey, &owner_coldkey); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, amount); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, amount.into()); // Forse-set alpha in and tao reserve to make price equal 0.01 - let tao_reserve = TaoCurrency::from(100_000_000_000); - let alpha_in = AlphaCurrency::from(1_000_000_000_000); + let tao_reserve = TaoBalance::from(100_000_000_000_u64); + let alpha_in = AlphaBalance::from(1_000_000_000_000_u64); mock::setup_reserves(netuid, tao_reserve, alpha_in); // Initialize swap v3 @@ -4668,7 +4703,7 @@ fn test_stake_into_subnet_prohibitive_limit() { assert_ok!(::SwapInterface::swap( netuid.into(), order, - TaoCurrency::MAX, + TaoBalance::MAX, false, true )); @@ -4681,7 +4716,7 @@ fn test_stake_into_subnet_prohibitive_limit() { owner_hotkey, netuid, amount.into(), - TaoCurrency::ZERO, + TaoBalance::ZERO, true, ), DispatchError::from(pallet_subtensor_swap::Error::::PriceLimitExceeded) @@ -4694,11 +4729,14 @@ fn test_stake_into_subnet_prohibitive_limit() { &coldkey, netuid ), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); // Check if balance has NOT decreased - assert_eq!(SubtensorModule::get_coldkey_balance(&coldkey), amount); + assert_eq!( + SubtensorModule::get_coldkey_balance(&coldkey), + amount.into() + ); }); } @@ -4712,11 +4750,11 @@ fn test_unstake_from_subnet_prohibitive_limit() { // add network let netuid = add_dynamic_network(&owner_hotkey, &owner_coldkey); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, amount); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, amount.into()); // Forse-set alpha in and tao reserve to make price equal 0.01 - let tao_reserve = TaoCurrency::from(100_000_000_000); - let alpha_in = AlphaCurrency::from(1_000_000_000_000); + let tao_reserve = TaoBalance::from(100_000_000_000_u64); + let alpha_in = AlphaBalance::from(1_000_000_000_000_u64); mock::setup_reserves(netuid, tao_reserve, alpha_in); // Initialize swap v3 @@ -4724,7 +4762,7 @@ fn test_unstake_from_subnet_prohibitive_limit() { assert_ok!(::SwapInterface::swap( netuid.into(), order, - TaoCurrency::MAX, + TaoBalance::MAX, false, true )); @@ -4735,7 +4773,7 @@ fn test_unstake_from_subnet_prohibitive_limit() { &coldkey, netuid, amount.into(), - TaoCurrency::MAX, + TaoBalance::MAX, false, false, )); @@ -4754,7 +4792,7 @@ fn test_unstake_from_subnet_prohibitive_limit() { owner_hotkey, netuid, alpha, - TaoCurrency::MAX, + TaoBalance::MAX, true, ), DispatchError::from(pallet_subtensor_swap::Error::::PriceLimitExceeded) @@ -4788,11 +4826,11 @@ fn test_unstake_full_amount() { // add network let netuid = add_dynamic_network(&owner_hotkey, &owner_coldkey); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, amount); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, amount.into()); // Forse-set alpha in and tao reserve to make price equal 0.01 - let tao_reserve = TaoCurrency::from(100_000_000_000); - let alpha_in = AlphaCurrency::from(1_000_000_000_000); + let tao_reserve = TaoBalance::from(100_000_000_000_u64); + let alpha_in = AlphaBalance::from(1_000_000_000_000_u64); mock::setup_reserves(netuid, tao_reserve, alpha_in); // Initialize swap v3 @@ -4800,7 +4838,7 @@ fn test_unstake_full_amount() { assert_ok!(::SwapInterface::swap( netuid.into(), order, - TaoCurrency::MAX, + TaoBalance::MAX, false, true )); @@ -4811,7 +4849,7 @@ fn test_unstake_full_amount() { &coldkey, netuid, amount.into(), - TaoCurrency::MAX, + TaoBalance::MAX, false, false, )); @@ -4838,12 +4876,12 @@ fn test_unstake_full_amount() { &coldkey, netuid ), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); // Check if balance has increased accordingly let balance_after = SubtensorModule::get_coldkey_balance(&coldkey); - let actual_balance_increase = (balance_after - balance_before) as f64; + let actual_balance_increase = u64::from(balance_after - balance_before) as f64; let fee_rate = pallet_subtensor_swap::FeeRate::::get(NetUid::from(netuid)) as f64 / u16::MAX as f64; let expected_balance_increase = amount as f64 * (1. - fee_rate) / (1. + fee_rate); @@ -4890,9 +4928,9 @@ fn test_swap_fees_tao_correctness() { 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; + let amount = TaoBalance::from(1_000_000_000_u64); + let owner_balance_before = amount * 10.into(); + let user_balance_before = amount * 100.into(); // add network let netuid = add_dynamic_network(&owner_hotkey, &owner_coldkey); @@ -4901,15 +4939,15 @@ fn test_swap_fees_tao_correctness() { pallet_subtensor_swap::EnabledUserLiquidity::::insert(NetUid::from(netuid), true); // Forse-set alpha in and tao reserve to make price equal 0.25 - let tao_reserve = TaoCurrency::from(100_000_000_000); - let alpha_in = AlphaCurrency::from(400_000_000_000); + let tao_reserve = TaoBalance::from(100_000_000_000_u64); + let alpha_in = AlphaBalance::from(400_000_000_000_u64); mock::setup_reserves(netuid, tao_reserve, alpha_in); // Check starting "total TAO" 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() + + SubnetTAO::::get(netuid) + block_builder_balance_before; // Get alpha for owner @@ -4937,7 +4975,7 @@ fn test_swap_fees_tao_correctness() { &owner_hotkey, tick_low, tick_high, - liquidity, + u64::from(liquidity), )); // Limit-buy and then sell all alpha for user to hit owner liquidity @@ -4980,11 +5018,11 @@ fn test_swap_fees_tao_correctness() { let total_tao_after = user_balance_after + owner_balance_after - + SubnetTAO::::get(netuid).to_u64() + + SubnetTAO::::get(netuid) + 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); + assert_abs_diff_eq!(total_tao_before, total_tao_after, epsilon = 2.into()); }); } @@ -4996,7 +5034,7 @@ fn test_increase_stake_for_hotkey_and_coldkey_on_subnet_adds_to_staking_hotkeys_ let hotkey = U256::from(3); let netuid = NetUid::from(1); - let stake_amount = 100_000_000_000; + let stake_amount = 100_000_000_000_u64; // Check no entry in the staking hotkeys map assert!(!StakingHotkeys::::contains_key(coldkey)); @@ -5040,7 +5078,7 @@ fn test_remove_stake_full_limit_ok() { new_test_ext(1).execute_with(|| { let hotkey_account_id = U256::from(1); let coldkey_account_id = U256::from(2); - let stake_amount = AlphaCurrency::from(10_000_000_000); + let stake_amount = AlphaBalance::from(10_000_000_000_u64); // add network let netuid = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); @@ -5053,12 +5091,12 @@ fn test_remove_stake_full_limit_ok() { stake_amount, ); - let tao_reserve = TaoCurrency::from(100_000_000_000_u64); - let alpha_in = AlphaCurrency::from(100_000_000_000); + let tao_reserve = TaoBalance::from(100_000_000_000_u64); + let alpha_in = AlphaBalance::from(100_000_000_000_u64); SubnetTAO::::insert(netuid, tao_reserve); SubnetAlphaIn::::insert(netuid, alpha_in); - let limit_price = TaoCurrency::from(90_000_000); + let limit_price = TaoBalance::from(90_000_000); // Remove stake with slippage safety assert_ok!(SubtensorModule::remove_stake_full_limit( @@ -5075,11 +5113,15 @@ fn test_remove_stake_full_limit_ok() { &coldkey_account_id, netuid ), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); let new_balance = SubtensorModule::get_coldkey_balance(&coldkey_account_id); - assert_abs_diff_eq!(new_balance, 9_086_700_000, epsilon = 1_000_000); + assert_abs_diff_eq!( + new_balance, + 9_086_000_000_u64.into(), + epsilon = 1_000_000.into() + ); }); } @@ -5088,7 +5130,7 @@ fn test_remove_stake_full_limit_fails_slippage_too_high() { new_test_ext(1).execute_with(|| { let hotkey_account_id = U256::from(1); let coldkey_account_id = U256::from(2); - let stake_amount = AlphaCurrency::from(10_000_000_000); + let stake_amount = AlphaBalance::from(10_000_000_000_u64); // add network let netuid = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); @@ -5101,12 +5143,12 @@ fn test_remove_stake_full_limit_fails_slippage_too_high() { stake_amount, ); - let tao_reserve = TaoCurrency::from(100_000_000_000); - let alpha_in = AlphaCurrency::from(100_000_000_000); + let tao_reserve = TaoBalance::from(100_000_000_000_u64); + let alpha_in = AlphaBalance::from(100_000_000_000_u64); SubnetTAO::::insert(netuid, tao_reserve); SubnetAlphaIn::::insert(netuid, alpha_in); - let invalid_limit_price = TaoCurrency::from(910_000_000); + let invalid_limit_price = TaoBalance::from(910_000_000_u64); // Remove stake with slippage safety assert_err!( @@ -5126,7 +5168,7 @@ fn test_remove_stake_full_limit_ok_with_no_limit_price() { new_test_ext(1).execute_with(|| { let hotkey_account_id = U256::from(1); let coldkey_account_id = U256::from(2); - let stake_amount = AlphaCurrency::from(10_000_000_000); + let stake_amount = AlphaBalance::from(10_000_000_000_u64); // add network let netuid = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); @@ -5139,8 +5181,8 @@ fn test_remove_stake_full_limit_ok_with_no_limit_price() { stake_amount, ); - let tao_reserve = TaoCurrency::from(100_000_000_000); - let alpha_in = AlphaCurrency::from(100_000_000_000); + let tao_reserve = TaoBalance::from(100_000_000_000_u64); + let alpha_in = AlphaBalance::from(100_000_000_000_u64); SubnetTAO::::insert(netuid, tao_reserve); SubnetAlphaIn::::insert(netuid, alpha_in); @@ -5159,11 +5201,15 @@ fn test_remove_stake_full_limit_ok_with_no_limit_price() { &coldkey_account_id, netuid ), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); let new_balance = SubtensorModule::get_coldkey_balance(&coldkey_account_id); - assert_abs_diff_eq!(new_balance, 9_086_700_000, epsilon = 1_000_000); + assert_abs_diff_eq!( + new_balance, + 9_086_000_000_u64.into(), + epsilon = 1_000_000.into() + ); }); } @@ -5175,10 +5221,10 @@ fn test_default_min_stake_sufficiency() { let owner_hotkey = U256::from(1); let owner_coldkey = U256::from(2); let coldkey = U256::from(4); - let min_tao_stake = DefaultMinStake::::get().to_u64() * 2; + let min_tao_stake = DefaultMinStake::::get() * 2.into(); let amount = min_tao_stake; - let owner_balance_before = amount * 10; - let user_balance_before = amount * 100; + let owner_balance_before = amount * 10.into(); + let user_balance_before = amount * 100.into(); // add network let netuid = add_dynamic_network(&owner_hotkey, &owner_coldkey); @@ -5190,8 +5236,8 @@ fn test_default_min_stake_sufficiency() { // Set some extreme, but realistic TAO and Alpha reserves to minimize slippage // 1% of TAO max supply // 0.01 Alpha price - let tao_reserve = TaoCurrency::from(210_000_000_000_000); - let alpha_in = AlphaCurrency::from(21_000_000_000_000_000); + let tao_reserve = TaoBalance::from(210_000_000_000_000_u64); + let alpha_in = AlphaBalance::from(21_000_000_000_000_000_u64); mock::setup_reserves(netuid, tao_reserve, alpha_in); let current_price_before = ::SwapInterface::current_alpha_price(netuid.into()); @@ -5203,7 +5249,7 @@ fn test_default_min_stake_sufficiency() { netuid, amount.into(), )); - let fee_stake = (fee_rate * amount as f64) as u64; + let fee_stake = (fee_rate * u64::from(amount) as f64) as u64; let current_price_after_stake = ::SwapInterface::current_alpha_price(netuid.into()); remove_stake_rate_limit_for_tests(&owner_hotkey, &coldkey, netuid); @@ -5244,13 +5290,13 @@ fn test_update_position_fees() { // add network let netuid = add_dynamic_network(&owner_hotkey, &owner_coldkey); - SubtensorModule::add_balance_to_coldkey_account(&owner_coldkey, amount * 10); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, amount * 100); + SubtensorModule::add_balance_to_coldkey_account(&owner_coldkey, (amount * 10).into()); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, (amount * 100).into()); pallet_subtensor_swap::EnabledUserLiquidity::::insert(NetUid::from(netuid), true); // Forse-set alpha in and tao reserve to make price equal 0.25 - let tao_reserve = TaoCurrency::from(100_000_000_000); - let alpha_in = AlphaCurrency::from(400_000_000_000); + let tao_reserve = TaoBalance::from(100_000_000_000_u64); + let alpha_in = AlphaBalance::from(400_000_000_000_u64); mock::setup_reserves(netuid, tao_reserve, alpha_in); // Get the block builder balance @@ -5366,80 +5412,6 @@ fn test_update_position_fees() { }); } -// TODO: Revise when user liquidity is available -// fn setup_positions(netuid: NetUid) { -// for (coldkey, hotkey, low_price, high_price, liquidity) in [ -// (2, 12, 0.1, 0.20, 1_000_000_000_000_u64), -// (3, 13, 0.15, 0.25, 200_000_000_000_u64), -// (4, 14, 0.25, 0.5, 3_000_000_000_000_u64), -// (5, 15, 0.3, 0.6, 300_000_000_000_u64), -// (6, 16, 0.4, 0.7, 8_000_000_000_000_u64), -// (7, 17, 0.5, 0.8, 600_000_000_000_u64), -// (8, 18, 0.6, 0.9, 700_000_000_000_u64), -// (9, 19, 0.7, 1.0, 100_000_000_000_u64), -// (10, 20, 0.8, 1.1, 300_000_000_000_u64), -// ] { -// SubtensorModule::create_account_if_non_existent(&U256::from(coldkey), &U256::from(hotkey)); -// SubtensorModule::add_balance_to_coldkey_account( -// &U256::from(coldkey), -// 1_000_000_000_000_000, -// ); -// SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( -// &U256::from(hotkey), -// &U256::from(coldkey), -// netuid.into(), -// 1_000_000_000_000_000.into(), -// ); - -// let tick_low = price_to_tick(low_price); -// let tick_high = price_to_tick(high_price); -// let add_lq_call = SwapCall::::add_liquidity { -// hotkey: U256::from(hotkey), -// netuid: netuid.into(), -// tick_low, -// tick_high, -// liquidity, -// }; -// assert_ok!( -// RuntimeCall::Swap(add_lq_call).dispatch(RuntimeOrigin::signed(U256::from(coldkey))) -// ); -// } -// } - -#[test] -fn test_large_swap() { - new_test_ext(1).execute_with(|| { - let owner_hotkey = U256::from(1); - let owner_coldkey = U256::from(2); - let coldkey = U256::from(100); - - // add network - let netuid = add_dynamic_network(&owner_hotkey, &owner_coldkey); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, 1_000_000_000_000_000); - pallet_subtensor_swap::EnabledUserLiquidity::::insert(NetUid::from(netuid), true); - - // Force the swap to initialize - SubtensorModule::swap_tao_for_alpha( - netuid, - TaoCurrency::ZERO, - 1_000_000_000_000.into(), - false, - ) - .unwrap(); - - // TODO: Revise when user liquidity is available - // setup_positions(netuid.into()); - - let swap_amount = TaoCurrency::from(100_000_000_000_000); - assert_ok!(SubtensorModule::add_stake( - RuntimeOrigin::signed(coldkey), - owner_hotkey, - netuid, - swap_amount, - )); - }); -} - #[test] fn test_stake_rate_limits() { new_test_ext(0).execute_with(|| { @@ -5449,8 +5421,8 @@ fn test_stake_rate_limits() { let hot1 = U256::from(1); let cold1 = U256::from(3); let netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); - let amount = DefaultMinStake::::get().to_u64() * 10; - let fee = DefaultMinStake::::get().to_u64(); + let amount = DefaultMinStake::::get() * 10.into(); + let fee = DefaultMinStake::::get(); let init_balance = amount + fee + ExistentialDeposit::get(); register_ok_neuron(netuid, hot1, cold1, 0); @@ -5470,7 +5442,7 @@ fn test_stake_rate_limits() { RuntimeOrigin::signed(cold1), hot1, netuid, - amount.into() + AlphaBalance::from(amount.to_u64()) ), Error::::StakingOperationRateLimitExceeded ); @@ -5499,32 +5471,32 @@ fn test_add_root_updates_counters() { RuntimeOrigin::signed(coldkey_account_id).clone(), hotkey_account_id, )); - let stake_amount = 1_000_000_000; + let stake_amount = TaoBalance::from(1_000_000_000_u64); // Give it some $$$ in his coldkey balance let initial_balance = stake_amount + ExistentialDeposit::get(); SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, initial_balance); // Setup SubnetAlphaIn (because we are going to stake) - SubnetAlphaIn::::insert(NetUid::ROOT, AlphaCurrency::from(stake_amount)); + SubnetAlphaIn::::insert(NetUid::ROOT, AlphaBalance::from(stake_amount.to_u64())); // Stake to hotkey account, and check if the result is ok assert_ok!(SubtensorModule::add_stake( RuntimeOrigin::signed(coldkey_account_id), hotkey_account_id, NetUid::ROOT, - stake_amount.into() + stake_amount )); // Check if stake has increased let new_stake = SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id); - assert_eq!(new_stake, stake_amount.into()); + assert_eq!(new_stake, stake_amount); // Check if total stake has increased accordingly. - assert_eq!(SubtensorModule::get_total_stake(), stake_amount.into()); + assert_eq!(SubtensorModule::get_total_stake(), stake_amount); // SubnetTAO updated - assert_eq!(SubnetTAO::::get(NetUid::ROOT), stake_amount.into()); + assert_eq!(SubnetTAO::::get(NetUid::ROOT), stake_amount); // SubnetAlphaIn updated assert_eq!(SubnetAlphaIn::::get(NetUid::ROOT), 0.into()); @@ -5532,13 +5504,13 @@ fn test_add_root_updates_counters() { // SubnetAlphaOut updated assert_eq!( SubnetAlphaOut::::get(NetUid::ROOT), - stake_amount.into() + AlphaBalance::from(stake_amount.to_u64()) ); // SubnetVolume updated assert_eq!( SubnetVolume::::get(NetUid::ROOT), - stake_amount as u128 + stake_amount.to_u64() as u128 ); }); } @@ -5554,7 +5526,7 @@ fn test_remove_root_updates_counters() { RuntimeOrigin::signed(coldkey_account_id).clone(), hotkey_account_id, )); - let stake_amount = 1_000_000_000; + let stake_amount = TaoBalance::from(1_000_000_000); // Give it some $$$ in his coldkey balance let initial_balance = stake_amount + ExistentialDeposit::get(); @@ -5565,20 +5537,20 @@ fn test_remove_root_updates_counters() { &hotkey_account_id, &coldkey_account_id, NetUid::ROOT, - stake_amount.into(), + AlphaBalance::from(stake_amount.to_u64()), ); // Setup TotalStake, SubnetAlphaOut and SubnetTAO (because we are going to unstake) - TotalStake::::set(TaoCurrency::from(stake_amount)); - SubnetTAO::::insert(NetUid::ROOT, TaoCurrency::from(stake_amount)); - SubnetAlphaOut::::insert(NetUid::ROOT, AlphaCurrency::from(stake_amount)); + TotalStake::::set(stake_amount); + SubnetTAO::::insert(NetUid::ROOT, stake_amount); + SubnetAlphaOut::::insert(NetUid::ROOT, AlphaBalance::from(stake_amount.to_u64())); // Stake to hotkey account, and check if the result is ok assert_ok!(SubtensorModule::remove_stake( RuntimeOrigin::signed(coldkey_account_id), hotkey_account_id, NetUid::ROOT, - stake_amount.into() + AlphaBalance::from(stake_amount.to_u64()) )); // Check if stake has been decreased @@ -5594,7 +5566,7 @@ fn test_remove_root_updates_counters() { // SubnetAlphaIn updated assert_eq!( SubnetAlphaIn::::get(NetUid::ROOT), - stake_amount.into() + AlphaBalance::from(stake_amount.to_u64()) ); // SubnetAlphaOut updated @@ -5603,7 +5575,7 @@ fn test_remove_root_updates_counters() { // SubnetVolume updated assert_eq!( SubnetVolume::::get(NetUid::ROOT), - stake_amount as u128 + stake_amount.to_u64() as u128 ); }); } @@ -5622,15 +5594,15 @@ fn test_staking_records_flow() { let netuid = add_dynamic_network(&owner_hotkey, &owner_coldkey); // Forse-set alpha in and tao reserve to make price equal 0.01 - let tao_reserve = TaoCurrency::from(100_000_000_000); - let alpha_in = AlphaCurrency::from(1_000_000_000_000); + let tao_reserve = TaoBalance::from(100_000_000_000_u64); + let alpha_in = AlphaBalance::from(1_000_000_000_000_u64); mock::setup_reserves(netuid, tao_reserve, alpha_in); // Initialize swap v3 SubtensorModule::swap_tao_for_alpha( netuid, - TaoCurrency::ZERO, - 1_000_000_000_000.into(), + TaoBalance::ZERO, + 1_000_000_000_000_u64.into(), false, ) .unwrap(); @@ -5641,7 +5613,7 @@ fn test_staking_records_flow() { &coldkey, netuid, amount.into(), - TaoCurrency::MAX, + TaoBalance::MAX, false, false, )); @@ -5664,7 +5636,7 @@ fn test_staking_records_flow() { &coldkey, netuid, alpha, - TaoCurrency::ZERO, + TaoBalance::ZERO, false, )); diff --git a/pallets/subtensor/src/tests/staking2.rs b/pallets/subtensor/src/tests/staking2.rs index 7d6cc6ad3c..7de304e80e 100644 --- a/pallets/subtensor/src/tests/staking2.rs +++ b/pallets/subtensor/src/tests/staking2.rs @@ -6,7 +6,7 @@ use frame_support::{ weights::Weight, }; use sp_core::U256; -use subtensor_runtime_common::{AlphaCurrency, Currency, TaoCurrency}; +use subtensor_runtime_common::{AlphaBalance, TaoBalance, Token}; use subtensor_swap_interface::SwapHandler; use super::mock; @@ -18,14 +18,14 @@ use crate::*; fn test_stake_base_case() { new_test_ext(1).execute_with(|| { let netuid = NetUid::from(1); - let tao_to_swap = TaoCurrency::from(1_000_000_000); // 1 TAO + let tao_to_swap = TaoBalance::from(1_000_000_000); // 1 TAO // Set up the subnet with dynamic mechanism SubnetMechanism::::insert(netuid, 1); // Initialize subnet with some existing TAO and Alpha - let initial_subnet_tao = TaoCurrency::from(10_000_000_000); // 10 TAO - let initial_subnet_alpha = AlphaCurrency::from(5_000_000_000); // 5 Alpha + let initial_subnet_tao = TaoBalance::from(10_000_000_000_u64); // 10 TAO + let initial_subnet_alpha = AlphaBalance::from(5_000_000_000_u64); // 5 Alpha mock::setup_reserves(netuid, initial_subnet_tao, initial_subnet_alpha); SubnetAlphaOut::::insert(netuid, initial_subnet_alpha); @@ -34,7 +34,7 @@ fn test_stake_base_case() { // Perform swap let (alpha_expected, fee) = mock::swap_tao_to_alpha(netuid, tao_to_swap); - let alpha_received = AlphaCurrency::from( + let alpha_received = AlphaBalance::from( SubtensorModule::swap_tao_for_alpha( netuid, tao_to_swap, @@ -89,7 +89,7 @@ fn test_share_based_staking() { let netuid = NetUid::from(1); let primary_hotkey = U256::from(1); let primary_coldkey = U256::from(2); - let stake_amount = AlphaCurrency::from(1_000_000_000); // 1 Alpha stake increase + let stake_amount = AlphaBalance::from(1_000_000_000); // 1 Alpha stake increase // Test Case 1: Initial Stake // The first stake should create shares 1:1 with the staked amount @@ -324,7 +324,7 @@ fn test_share_based_staking() { &primary_hotkey, &primary_coldkey, netuid, - AlphaCurrency::ZERO, + AlphaBalance::ZERO, ); let zero_stake = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( &primary_hotkey, @@ -407,7 +407,7 @@ fn test_share_based_staking() { fn test_share_based_staking_denominator_precision() { // Test case amounts: stake, unstake, inject, tolerance [ - (1_000, 990), + (1_000_u64, 990_u64), (1_000, 999), (1_000_000, 990_000), (1_000_000, 999_990), @@ -420,8 +420,8 @@ fn test_share_based_staking_denominator_precision() { let netuid = NetUid::from(1); let hotkey1 = U256::from(1); let coldkey1 = U256::from(2); - let stake_amount = AlphaCurrency::from(test_case.0); - let unstake_amount = AlphaCurrency::from(test_case.1); + let stake_amount = AlphaBalance::from(test_case.0); + let unstake_amount = AlphaBalance::from(test_case.1); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &hotkey1, @@ -450,7 +450,7 @@ fn test_share_based_staking_denominator_precision() { / (stake_amount.to_u64() as f64) <= 0.00001 { - AlphaCurrency::ZERO + AlphaBalance::ZERO } else { stake_amount - unstake_amount }; @@ -464,7 +464,7 @@ fn test_share_based_staking_denominator_precision() { fn test_share_based_staking_stake_unstake_inject() { // Test case amounts: stake, unstake, inject, tolerance [ - (1_000, 999, 1_000_000, 0), + (1_000_u64, 999_u64, 1_000_000_u64, 0), (1_000_000, 999_000, 100_000_000, 0), (1_000_000, 900_000, 100_000_000, 0), (100_000_000_000, 1_000_000_000, 1_000_000_000_000, 1), @@ -479,9 +479,9 @@ fn test_share_based_staking_stake_unstake_inject() { let hotkey1 = U256::from(1); let coldkey1 = U256::from(2); let coldkey2 = U256::from(3); - let stake_amount = AlphaCurrency::from(test_case.0); - let unstake_amount = AlphaCurrency::from(test_case.1); - let inject_amount = AlphaCurrency::from(test_case.2); + let stake_amount = AlphaBalance::from(test_case.0); + let unstake_amount = AlphaBalance::from(test_case.1); + let inject_amount = AlphaBalance::from(test_case.2); let tolerance = test_case.3; SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( @@ -540,7 +540,7 @@ fn test_share_based_staking_stake_unstake_inject() { fn test_share_based_staking_stake_inject_stake_new() { // Test case amounts: stake, inject, stake, tolerance [ - (1, 2_000_000_000, 500_000_000, 1), + (1_u64, 2_000_000_000_u64, 500_000_000_u64, 1), (1, 5_000_000_000, 50_000_000, 1), (500_000_000, 1_000_000_000, 1_000_000_000, 1), ] @@ -551,9 +551,9 @@ fn test_share_based_staking_stake_inject_stake_new() { let hotkey1 = U256::from(1); let coldkey1 = U256::from(2); let coldkey2 = U256::from(3); - let stake_amount = AlphaCurrency::from(test_case.0); - let inject_amount = AlphaCurrency::from(test_case.1); - let stake_amount_2 = AlphaCurrency::from(test_case.2); + let stake_amount = AlphaBalance::from(test_case.0); + let inject_amount = AlphaBalance::from(test_case.1); + let stake_amount_2 = AlphaBalance::from(test_case.2); let tolerance = test_case.3; SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( @@ -661,24 +661,24 @@ fn test_stake_fee_api() { let netuid1 = NetUid::from(2); let root_netuid = NetUid::ROOT; - let alpha_divs = AlphaCurrency::from(100_000_000_000); - let total_hotkey_alpha = AlphaCurrency::from(100_000_000_000); - let tao_in = TaoCurrency::from(100_000_000_000); // 100 TAO + let alpha_divs = AlphaBalance::from(100_000_000_000_u64); + let total_hotkey_alpha = AlphaBalance::from(100_000_000_000_u64); + let tao_in = TaoBalance::from(100_000_000_000_u64); // 100 TAO let reciprocal_price = 2; // 1 / price - let stake_amount = 100_000_000_000; + let stake_amount = 100_000_000_000_u64; // Setup alpha out - SubnetAlphaOut::::insert(netuid0, AlphaCurrency::from(100_000_000_000)); - SubnetAlphaOut::::insert(netuid1, AlphaCurrency::from(100_000_000_000)); + SubnetAlphaOut::::insert(netuid0, AlphaBalance::from(100_000_000_000_u64)); + SubnetAlphaOut::::insert(netuid1, AlphaBalance::from(100_000_000_000_u64)); // Set pools using price SubnetAlphaIn::::insert( netuid0, - AlphaCurrency::from(tao_in.to_u64() * reciprocal_price), + AlphaBalance::from(tao_in.to_u64() * reciprocal_price), ); SubnetTAO::::insert(netuid0, tao_in); SubnetAlphaIn::::insert( netuid1, - AlphaCurrency::from(tao_in.to_u64() * reciprocal_price), + AlphaBalance::from(tao_in.to_u64() * reciprocal_price), ); SubnetTAO::::insert(netuid1, tao_in); @@ -700,7 +700,7 @@ fn test_stake_fee_api() { ); let dynamic_fee_0 = ::SwapInterface::approx_fee_amount( netuid0.into(), - TaoCurrency::from(stake_amount), + TaoBalance::from(stake_amount), ) .to_u64(); assert_eq!(stake_fee_0, dynamic_fee_0); @@ -715,7 +715,7 @@ fn test_stake_fee_api() { ); let dynamic_fee_1 = ::SwapInterface::approx_fee_amount( root_netuid.into(), - TaoCurrency::from(stake_amount), + TaoBalance::from(stake_amount), ) .to_u64(); assert_eq!(stake_fee_1, dynamic_fee_1); @@ -730,7 +730,7 @@ fn test_stake_fee_api() { ); let dynamic_fee_2 = ::SwapInterface::approx_fee_amount( netuid0.into(), - TaoCurrency::from(stake_amount), + TaoBalance::from(stake_amount), ) .to_u64(); assert_eq!(stake_fee_2, dynamic_fee_2); @@ -745,7 +745,7 @@ fn test_stake_fee_api() { ); let dynamic_fee_3 = ::SwapInterface::approx_fee_amount( root_netuid.into(), - TaoCurrency::from(stake_amount), + TaoBalance::from(stake_amount), ) .to_u64(); assert_eq!(stake_fee_3, dynamic_fee_3); @@ -760,7 +760,7 @@ fn test_stake_fee_api() { ); let dynamic_fee_4 = ::SwapInterface::approx_fee_amount( root_netuid.into(), - TaoCurrency::from(stake_amount), + TaoBalance::from(stake_amount), ) .to_u64(); assert_eq!(stake_fee_4, dynamic_fee_4); @@ -775,7 +775,7 @@ fn test_stake_fee_api() { ); let dynamic_fee_5 = ::SwapInterface::approx_fee_amount( root_netuid.into(), - TaoCurrency::from(stake_amount), + TaoBalance::from(stake_amount), ) .to_u64(); assert_eq!(stake_fee_5, dynamic_fee_5); @@ -790,7 +790,7 @@ fn test_stake_fee_api() { ); let dynamic_fee_6 = ::SwapInterface::approx_fee_amount( netuid0.into(), - TaoCurrency::from(stake_amount), + TaoBalance::from(stake_amount), ) .to_u64(); assert_eq!(stake_fee_6, dynamic_fee_6); @@ -805,7 +805,7 @@ fn test_stake_fee_api() { ); let dynamic_fee_7 = ::SwapInterface::approx_fee_amount( netuid0.into(), - TaoCurrency::from(stake_amount), + TaoBalance::from(stake_amount), ) .to_u64(); assert_eq!(stake_fee_7, dynamic_fee_7); @@ -820,7 +820,7 @@ fn test_stake_fee_api() { ); let dynamic_fee_8 = ::SwapInterface::approx_fee_amount( netuid1.into(), - TaoCurrency::from(stake_amount), + TaoBalance::from(stake_amount), ) .to_u64(); assert_eq!(stake_fee_8, dynamic_fee_8); @@ -840,27 +840,27 @@ fn test_stake_fee_calculation() { SubnetMechanism::::insert(netuid0, 1); SubnetMechanism::::insert(netuid1, 1); - let alpha_divs = AlphaCurrency::from(100_000_000_000); - let total_hotkey_alpha = AlphaCurrency::from(100_000_000_000); - let tao_in = TaoCurrency::from(100_000_000_000); // 100 TAO + let alpha_divs = AlphaBalance::from(100_000_000_000_u64); + let total_hotkey_alpha = AlphaBalance::from(100_000_000_000_u64); + let tao_in = TaoBalance::from(100_000_000_000_u64); // 100 TAO let reciprocal_price = 2; // 1 / price - let stake_amount = TaoCurrency::from(100_000_000_000); + let stake_amount = TaoBalance::from(100_000_000_000_u64); - let default_fee = TaoCurrency::ZERO; // FIXME: DefaultStakingFee is deprecated + let default_fee = TaoBalance::ZERO; // FIXME: DefaultStakingFee is deprecated // Setup alpha out - SubnetAlphaOut::::insert(netuid0, AlphaCurrency::from(100_000_000_000)); - SubnetAlphaOut::::insert(netuid1, AlphaCurrency::from(100_000_000_000)); + SubnetAlphaOut::::insert(netuid0, AlphaBalance::from(100_000_000_000_u64)); + SubnetAlphaOut::::insert(netuid1, AlphaBalance::from(100_000_000_000_u64)); // Set pools using price mock::setup_reserves( netuid0, tao_in, - AlphaCurrency::from(tao_in.to_u64() * reciprocal_price), + AlphaBalance::from(tao_in.to_u64() * reciprocal_price), ); mock::setup_reserves( netuid1, tao_in, - AlphaCurrency::from(tao_in.to_u64() * reciprocal_price), + AlphaBalance::from(tao_in.to_u64() * reciprocal_price), ); // Setup alpha divs for hotkey1 diff --git a/pallets/subtensor/src/tests/subnet.rs b/pallets/subtensor/src/tests/subnet.rs index a547b30a14..dd5016a32f 100644 --- a/pallets/subtensor/src/tests/subnet.rs +++ b/pallets/subtensor/src/tests/subnet.rs @@ -5,7 +5,7 @@ use crate::*; use frame_support::{assert_err, assert_noop, assert_ok}; use frame_system::Config; use sp_core::U256; -use subtensor_runtime_common::{AlphaCurrency, TaoCurrency}; +use subtensor_runtime_common::{AlphaBalance, TaoBalance}; use super::mock; @@ -64,13 +64,13 @@ fn test_do_start_call_fail_not_owner() { let tempo: u16 = 13; let coldkey_account_id = U256::from(0); let wrong_owner_account_id = U256::from(2); - let burn_cost = TaoCurrency::from(1000); + let burn_cost = TaoBalance::from(1000); //add network SubtensorModule::set_burn(netuid, burn_cost); add_network_without_emission_block(netuid, tempo, 0); mock::setup_reserves(netuid, 1_000_000_000.into(), 1_000_000_000.into()); // Give it some $$$ in his coldkey balance - SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, 10000); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, 10000.into()); add_network_without_emission_block(netuid, tempo, 0); @@ -94,13 +94,13 @@ fn test_do_start_call_can_start_now() { let netuid = NetUid::from(1); let tempo: u16 = 13; let coldkey_account_id = U256::from(0); - let burn_cost = TaoCurrency::from(1000); + let burn_cost = TaoBalance::from(1000); //add network SubtensorModule::set_burn(netuid, burn_cost); add_network_without_emission_block(netuid, tempo, 0); mock::setup_reserves(netuid, 1_000_000_000.into(), 1_000_000_000.into()); // Give it some $$$ in his coldkey balance - SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, 10000); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, 10000.into()); add_network_without_emission_block(netuid, tempo, 0); @@ -120,7 +120,7 @@ fn test_do_start_call_fail_for_set_again() { let tempo: u16 = 13; let coldkey_account_id = U256::from(0); let hotkey_account_id = U256::from(1); - let burn_cost = TaoCurrency::from(1000); + let burn_cost = TaoBalance::from(1000); SubtensorModule::set_burn(netuid, burn_cost); add_network_without_emission_block(netuid, tempo, 0); @@ -129,7 +129,7 @@ fn test_do_start_call_fail_for_set_again() { mock::setup_reserves(netuid, 1_000_000_000.into(), 1_000_000_000.into()); // Give it some $$$ in his coldkey balance - SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, 10000); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, 10000.into()); // Subscribe and check extrinsic output assert_ok!(SubtensorModule::burned_register( @@ -391,9 +391,9 @@ fn test_subtoken_enable_reject_trading_before_enable() { let hotkey_account_2_id: U256 = U256::from(3); let amount = DefaultMinStake::::get().to_u64() * 10; - let stake_bal = AlphaCurrency::from(10_000_000_000); // 10 Alpha + let stake_bal = AlphaBalance::from(10_000_000_000_u64); // 10 Alpha - let limit_price = TaoCurrency::from(1_000_000_000); // not important + let limit_price = TaoBalance::from(1_000_000_000_u64); // not important add_network_disable_subtoken(netuid, 10, 0); add_network_disable_subtoken(netuid2, 10, 0); @@ -402,8 +402,8 @@ fn test_subtoken_enable_reject_trading_before_enable() { assert!(!SubtokenEnabled::::get(netuid2)); // Set liq high enough to not trigger other errors - SubnetTAO::::set(netuid, TaoCurrency::from(20_000_000_000)); - SubnetAlphaIn::::set(netuid, AlphaCurrency::from(20_000_000_000)); + SubnetTAO::::set(netuid, TaoBalance::from(20_000_000_000_u64)); + SubnetAlphaIn::::set(netuid, AlphaBalance::from(20_000_000_000_u64)); // Register so staking *could* work register_ok_neuron(netuid, hotkey_account_id, coldkey_account_id, 0); @@ -411,7 +411,7 @@ fn test_subtoken_enable_reject_trading_before_enable() { register_ok_neuron(netuid, hotkey_account_2_id, coldkey_account_id, 0); register_ok_neuron(netuid2, hotkey_account_2_id, coldkey_account_id, 100); - SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, 10_000); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, 10_000.into()); // Give some stake SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( @@ -567,7 +567,7 @@ fn test_subtoken_enable_trading_ok_with_enable() { // stake big enough let stake_amount = DefaultMinStake::::get() * 10000.into(); // unstake, transfer, swap just very little - let unstake_amount = AlphaCurrency::from(DefaultMinStake::::get().to_u64() * 10); + let unstake_amount = AlphaBalance::from(DefaultMinStake::::get().to_u64() * 10); add_network(netuid, 10, 0); add_network(netuid2, 10, 0); @@ -575,8 +575,8 @@ fn test_subtoken_enable_trading_ok_with_enable() { let reserve = stake_amount.to_u64() * 1000; mock::setup_reserves(netuid, reserve.into(), reserve.into()); mock::setup_reserves(netuid2, reserve.into(), reserve.into()); - SubnetAlphaOut::::insert(netuid, AlphaCurrency::from(reserve)); - SubnetAlphaOut::::insert(netuid2, AlphaCurrency::from(reserve)); + SubnetAlphaOut::::insert(netuid, AlphaBalance::from(reserve)); + SubnetAlphaOut::::insert(netuid2, AlphaBalance::from(reserve)); // Register so staking works register_ok_neuron(netuid, hotkey_account_id, coldkey_account_id, 0); @@ -586,7 +586,7 @@ fn test_subtoken_enable_trading_ok_with_enable() { SubtensorModule::add_balance_to_coldkey_account( &coldkey_account_id, - stake_amount.to_u64() * 10, + stake_amount * 10.into(), ); // all trading extrinsic should be possible now that subtoken is enabled. @@ -687,7 +687,7 @@ fn test_subtoken_enable_ok_for_burn_register_before_enable() { let coldkey_account_id = U256::from(2); let hotkey_account_2_id: U256 = U256::from(3); - let burn_cost = TaoCurrency::from(1000); + let burn_cost = TaoBalance::from(1000); // Set the burn cost SubtensorModule::set_burn(netuid, burn_cost); // Add the networks with subtoken disabled @@ -696,7 +696,7 @@ fn test_subtoken_enable_ok_for_burn_register_before_enable() { // Give enough to burned register SubtensorModule::add_balance_to_coldkey_account( &coldkey_account_id, - burn_cost.to_u64() * 2 + 5_000, + burn_cost * 2.into() + 5_000.into(), ); // Should be possible to burned register before enable is activated diff --git a/pallets/subtensor/src/tests/swap_coldkey.rs b/pallets/subtensor/src/tests/swap_coldkey.rs index 36d083344c..23488f3370 100644 --- a/pallets/subtensor/src/tests/swap_coldkey.rs +++ b/pallets/subtensor/src/tests/swap_coldkey.rs @@ -21,7 +21,9 @@ 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}; +use subtensor_runtime_common::{ + AlphaBalance, CustomTransactionError, SubnetInfo, TaoBalance, Token, +}; use subtensor_swap_interface::{SwapEngine, SwapHandler}; use super::mock; @@ -31,12 +33,7 @@ use crate::*; 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); - }), - ); + System::run_to_block::(n); } #[test] @@ -49,7 +46,7 @@ fn test_announce_coldkey_swap_works() { assert_eq!(ColdkeySwapAnnouncements::::iter().count(), 0); - let swap_cost = SubtensorModule::get_key_swap_cost().to_u64(); + let swap_cost = SubtensorModule::get_key_swap_cost(); SubtensorModule::add_balance_to_coldkey_account(&who, swap_cost + ed); assert_eq!(SubtensorModule::get_coldkey_balance(&who), swap_cost + ed); @@ -86,8 +83,8 @@ fn test_announce_coldkey_swap_with_existing_announcement_past_delay_works() { assert_eq!(ColdkeySwapAnnouncements::::iter().count(), 0); - let swap_cost = SubtensorModule::get_key_swap_cost().to_u64(); - SubtensorModule::add_balance_to_coldkey_account(&who, 2 * swap_cost); + let swap_cost = SubtensorModule::get_key_swap_cost(); + SubtensorModule::add_balance_to_coldkey_account(&who, swap_cost * 2.into()); assert_ok!(SubtensorModule::announce_coldkey_swap( RuntimeOrigin::signed(who), @@ -127,7 +124,7 @@ fn test_announce_coldkey_swap_only_pays_swap_cost_if_no_announcement_exists() { let new_coldkey_2_hash = ::Hashing::hash_of(&new_coldkey_2); let ed = ExistentialDeposit::get(); - let swap_cost = SubtensorModule::get_key_swap_cost().to_u64(); + let swap_cost = SubtensorModule::get_key_swap_cost(); SubtensorModule::add_balance_to_coldkey_account(&who, swap_cost + ed); assert_eq!(SubtensorModule::get_coldkey_balance(&who), swap_cost + ed); @@ -179,7 +176,7 @@ fn test_announce_coldkey_swap_with_existing_announcement_not_past_delay_fails() assert_eq!(ColdkeySwapAnnouncements::::iter().count(), 0); - let swap_cost = SubtensorModule::get_key_swap_cost().to_u64(); + let swap_cost = SubtensorModule::get_key_swap_cost(); let ed = ExistentialDeposit::get(); SubtensorModule::add_balance_to_coldkey_account(&who, swap_cost + ed); @@ -212,10 +209,10 @@ fn test_swap_coldkey_announced_works() { 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 min_stake = DefaultMinStake::::get(); + let stake1 = min_stake * 10.into(); + let stake2 = min_stake * 20.into(); + let stake3 = min_stake * 30.into(); let now = System::block_number(); ColdkeySwapAnnouncements::::insert(who, (now, new_coldkey_hash)); @@ -270,7 +267,7 @@ fn test_swap_coldkey_announced_works() { hk3_alpha, total_ck_stake, total_stake_before, - 0_u64 // Charged on announcement + 0.into() // Charged on announcement ); }); } @@ -365,7 +362,7 @@ fn test_swap_coldkey_announced_with_already_associated_coldkey_fails() { let new_coldkey_hash = ::Hashing::hash_of(&new_coldkey); let hotkey = U256::from(3); - let swap_cost = SubtensorModule::get_key_swap_cost().to_u64(); + let swap_cost = SubtensorModule::get_key_swap_cost(); let ed = ExistentialDeposit::get(); SubtensorModule::add_balance_to_coldkey_account(&who, swap_cost + ed); @@ -428,14 +425,14 @@ fn test_swap_coldkey_works() { 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; + let min_stake = DefaultMinStake::::get(); + let stake1 = min_stake * 10.into(); + let stake2 = min_stake * 20.into(); + let stake3 = min_stake * 30.into(); SubtensorModule::add_balance_to_coldkey_account( &old_coldkey, - swap_cost.to_u64() + stake1 + stake2 + stake3 + ed, + swap_cost + stake1 + stake2 + stake3 + ed, ); // Some old announcement and dispute that will be cleared @@ -489,7 +486,7 @@ fn test_swap_coldkey_works() { hk3_alpha, total_ck_stake, total_stake_before, - swap_cost.to_u64() + swap_cost ); // Check that the old announcement and dispute are cleared @@ -508,11 +505,11 @@ fn test_swap_coldkey_works_with_zero_cost() { 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; + let swap_cost = TaoBalance::from(0); + let min_stake = DefaultMinStake::::get(); + let stake1 = min_stake * 10.into(); + let stake2 = min_stake * 20.into(); + let stake3 = min_stake * 30.into(); SubtensorModule::add_balance_to_coldkey_account( &old_coldkey, @@ -619,7 +616,7 @@ fn test_swap_coldkey_with_not_enough_balance_to_pay_swap_cost_fails() { ); // Needs to preserve ED - let balance = SubtensorModule::get_key_swap_cost().to_u64() + ExistentialDeposit::get() - 1; + let balance = SubtensorModule::get_key_swap_cost() + ExistentialDeposit::get() - 1.into(); SubtensorModule::add_balance_to_coldkey_account(&old_coldkey, balance); assert_noop!( SubtensorModule::swap_coldkey( @@ -673,7 +670,7 @@ fn test_announce_coldkey_swap_with_not_enough_balance_to_pay_swap_cost_fails() { ); // Needs to preserve ED - let balance = SubtensorModule::get_key_swap_cost().to_u64() + ExistentialDeposit::get() - 1; + let balance = SubtensorModule::get_key_swap_cost() + ExistentialDeposit::get() - 1.into(); SubtensorModule::add_balance_to_coldkey_account(&who, balance); assert_noop!( SubtensorModule::announce_coldkey_swap(RuntimeOrigin::signed(who), new_coldkey_hash), @@ -692,11 +689,11 @@ fn test_do_swap_coldkey_with_no_stake() { assert_eq!( SubtensorModule::get_total_stake_for_coldkey(&old_coldkey), - TaoCurrency::ZERO + TaoBalance::ZERO ); assert_eq!( SubtensorModule::get_total_stake_for_coldkey(&new_coldkey), - TaoCurrency::ZERO + TaoBalance::ZERO ); }); } @@ -713,8 +710,7 @@ fn test_do_swap_coldkey_with_max_values() { 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 max_stake = TaoBalance::from(21_000_000_000_000_000_u64); // 21 Million TAO; max possible balance. // Add a network add_network(netuid, 1, 0); @@ -726,10 +722,10 @@ fn test_do_swap_coldkey_with_max_values() { 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); + SubtensorModule::add_balance_to_coldkey_account(&old_coldkey, max_stake + 1_000.into()); + SubtensorModule::add_balance_to_coldkey_account(&old_coldkey2, max_stake + 1_000.into()); - let reserve = max_stake * 10; + let reserve = u64::from(max_stake) * 10; mock::setup_reserves(netuid, reserve.into(), reserve.into()); mock::setup_reserves(netuid2, reserve.into(), reserve.into()); @@ -738,7 +734,7 @@ fn test_do_swap_coldkey_with_max_values() { <::RuntimeOrigin>::signed(old_coldkey), hotkey, netuid, - max_stake.into() + max_stake )); let expected_stake1 = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( &hotkey, @@ -750,7 +746,7 @@ fn test_do_swap_coldkey_with_max_values() { <::RuntimeOrigin>::signed(old_coldkey2), hotkey2, netuid2, - max_stake.into() + max_stake )); let expected_stake2 = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( &hotkey2, @@ -766,21 +762,21 @@ fn test_do_swap_coldkey_with_max_values() { assert_eq!( SubtensorModule::get_total_stake_for_coldkey(&old_coldkey), - TaoCurrency::ZERO + TaoBalance::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() + epsilon = TaoBalance::from(expected_stake1.to_u64()) / 1000.into() ); assert_eq!( SubtensorModule::get_total_stake_for_coldkey(&old_coldkey2), - TaoCurrency::ZERO + TaoBalance::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() + epsilon = TaoBalance::from(expected_stake2.to_u64()) / 1000.into() ); }); } @@ -796,7 +792,7 @@ fn test_do_swap_coldkey_effect_on_delegated_stake() { let new_coldkey = U256::from(2); let delegator = U256::from(3); let hotkey = U256::from(4); - let stake = 100_000_000_000; + let stake = TaoBalance::from(100_000_000_000_u64); StakingHotkeys::::insert(old_coldkey, vec![hotkey]); StakingHotkeys::::insert(delegator, vec![hotkey]); @@ -833,7 +829,7 @@ fn test_do_swap_coldkey_effect_on_delegated_stake() { ); assert_abs_diff_eq!( SubtensorModule::get_total_stake_for_coldkey(&old_coldkey), - TaoCurrency::ZERO, + TaoBalance::ZERO, epsilon = 500.into() ); }); @@ -847,8 +843,8 @@ fn test_swap_delegated_stake_for_coldkey() { 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 stake_amount1 = DefaultMinStake::::get() * 10.into(); + let stake_amount2 = DefaultMinStake::::get() * 20.into(); let netuid = NetUid::from(1); // Setup initial state @@ -856,7 +852,7 @@ fn test_swap_delegated_stake_for_coldkey() { register_ok_neuron(netuid, hotkey1, other_coldkey, 0); register_ok_neuron(netuid, hotkey2, other_coldkey, 0); - let reserve = (stake_amount1 + stake_amount2) * 10; + let reserve = u64::from(stake_amount1 + stake_amount2) * 10; mock::setup_reserves(netuid, reserve.into(), reserve.into()); // Notice hotkey1 and hotkey2 are Owned by other_coldkey @@ -864,7 +860,7 @@ fn test_swap_delegated_stake_for_coldkey() { // === Give old_coldkey some balance === SubtensorModule::add_balance_to_coldkey_account( &old_coldkey, - stake_amount1 + stake_amount2 + 1_000_000, + stake_amount1 + stake_amount2 + 1_000_000.into(), ); // === Stake to hotkeys === @@ -872,7 +868,7 @@ fn test_swap_delegated_stake_for_coldkey() { <::RuntimeOrigin>::signed(old_coldkey), hotkey1, netuid, - stake_amount1.into() + stake_amount1 )); let expected_stake_alpha1 = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( &hotkey1, @@ -885,7 +881,7 @@ fn test_swap_delegated_stake_for_coldkey() { <::RuntimeOrigin>::signed(old_coldkey), hotkey2, netuid, - stake_amount2.into() + stake_amount2 )); let expected_stake_alpha2 = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( &hotkey2, @@ -937,7 +933,7 @@ fn test_swap_delegated_stake_for_coldkey() { &old_coldkey, netuid ), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); assert_eq!( SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( @@ -945,7 +941,7 @@ fn test_swap_delegated_stake_for_coldkey() { &old_coldkey, netuid ), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); // Verify TotalColdkeyStake @@ -955,7 +951,7 @@ fn test_swap_delegated_stake_for_coldkey() { ); assert_eq!( SubtensorModule::get_total_stake_for_coldkey(&old_coldkey), - TaoCurrency::ZERO + TaoBalance::ZERO ); // Verify TotalHotkeyStake remains unchanged @@ -998,16 +994,16 @@ fn test_coldkey_swap_total() { let netuid1 = NetUid::from(1); let netuid2 = NetUid::from(2); let netuid3 = NetUid::from(3); - let stake = DefaultMinStake::::get().to_u64() * 10; - SubtensorModule::add_balance_to_coldkey_account(&coldkey, stake * 6); - SubtensorModule::add_balance_to_coldkey_account(&delegate1, stake * 2); - SubtensorModule::add_balance_to_coldkey_account(&delegate2, stake * 2); - SubtensorModule::add_balance_to_coldkey_account(&delegate3, stake * 2); - SubtensorModule::add_balance_to_coldkey_account(&nominator1, stake * 2); - SubtensorModule::add_balance_to_coldkey_account(&nominator2, stake * 2); - SubtensorModule::add_balance_to_coldkey_account(&nominator3, stake * 2); - - let reserve = stake * 10; + let stake = DefaultMinStake::::get() * 10.into(); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, stake * 6.into()); + SubtensorModule::add_balance_to_coldkey_account(&delegate1, stake * 2.into()); + SubtensorModule::add_balance_to_coldkey_account(&delegate2, stake * 2.into()); + SubtensorModule::add_balance_to_coldkey_account(&delegate3, stake * 2.into()); + SubtensorModule::add_balance_to_coldkey_account(&nominator1, stake * 2.into()); + SubtensorModule::add_balance_to_coldkey_account(&nominator2, stake * 2.into()); + SubtensorModule::add_balance_to_coldkey_account(&nominator3, stake * 2.into()); + + let reserve = u64::from(stake) * 10; mock::setup_reserves(netuid1, reserve.into(), reserve.into()); mock::setup_reserves(netuid2, reserve.into(), reserve.into()); mock::setup_reserves(netuid3, reserve.into(), reserve.into()); @@ -1213,7 +1209,7 @@ fn test_coldkey_swap_total() { ); assert_eq!( SubtensorModule::get_total_stake_for_coldkey(&coldkey), - TaoCurrency::ZERO + TaoBalance::ZERO ); // Check everything is swapped. @@ -1304,8 +1300,8 @@ fn test_do_swap_coldkey_effect_on_delegations() { let delegate = U256::from(2); let netuid = NetUid::from(0); // Stake to 0 let netuid2 = NetUid::from(1); // Stake to 1 - let stake = DefaultMinStake::::get().to_u64() * 10; - let reserve = stake * 1000; + let stake = DefaultMinStake::::get() * 10.into(); + let reserve = u64::from(stake) * 1000; mock::setup_reserves(netuid, reserve.into(), reserve.into()); mock::setup_reserves(netuid2, reserve.into(), reserve.into()); @@ -1318,7 +1314,7 @@ fn test_do_swap_coldkey_effect_on_delegations() { delegate )); // register on root register_ok_neuron(netuid2, delegate, owner, 0); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, stake * 10); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, stake * 10.into()); // since the reserves are equal and we stake the same amount to both networks, we can reuse // this values for different networks. but you should take it into account in case of tests @@ -1329,7 +1325,7 @@ fn test_do_swap_coldkey_effect_on_delegations() { <::RuntimeOrigin>::signed(coldkey), delegate, netuid, - stake.into() + stake )); // Add stake to netuid2 @@ -1337,14 +1333,14 @@ fn test_do_swap_coldkey_effect_on_delegations() { <::RuntimeOrigin>::signed(coldkey), delegate, netuid2, - stake.into() + stake )); // Perform the swap assert_ok!(SubtensorModule::do_swap_coldkey(&coldkey, &new_coldkey,)); // Verify stake was moved for the delegate - let approx_total_stake = TaoCurrency::from(stake * 2 - fee * 2); + let approx_total_stake = stake * 2.into() - (fee * 2).into(); assert_abs_diff_eq!( SubtensorModule::get_total_stake_for_hotkey(&delegate), approx_total_stake, @@ -1352,7 +1348,7 @@ fn test_do_swap_coldkey_effect_on_delegations() { ); assert_eq!( SubtensorModule::get_total_stake_for_coldkey(&coldkey), - TaoCurrency::ZERO + TaoBalance::ZERO ); assert_abs_diff_eq!( SubtensorModule::get_total_stake_for_coldkey(&new_coldkey), @@ -1536,8 +1532,8 @@ macro_rules! comprehensive_setup { SubnetOwner::::insert(netuid2, $who); // Setup reserves - let reserve1 = ($stake1 + $stake3) * 10; - let reserve2 = $stake2 * 10; + let reserve1 = u64::from($stake1 + $stake3) * 10; + let reserve2 = u64::from($stake2) * 10; mock::setup_reserves(netuid1, reserve1.into(), reserve1.into()); mock::setup_reserves(netuid2, reserve2.into(), reserve2.into()); @@ -1712,7 +1708,7 @@ macro_rules! comprehensive_checks { ); assert_eq!( SubtensorModule::get_total_stake_for_coldkey(&$who), - TaoCurrency::ZERO + TaoBalance::ZERO ); assert_eq!( SubtensorModule::get_total_stake_for_coldkey(&$new_coldkey), @@ -1731,7 +1727,7 @@ macro_rules! comprehensive_checks { assert_eq!(Owner::::get($hotkey3), $new_coldkey); // Ensure the remaining balance is transferred to the new coldkey - assert_eq!(SubtensorModule::get_coldkey_balance(&$who), 0); + assert_eq!(SubtensorModule::get_coldkey_balance(&$who), 0.into()); assert_eq!( SubtensorModule::get_coldkey_balance(&$new_coldkey), ExistentialDeposit::get() diff --git a/pallets/subtensor/src/tests/swap_hotkey.rs b/pallets/subtensor/src/tests/swap_hotkey.rs index 71191d1951..d7f5a1274f 100644 --- a/pallets/subtensor/src/tests/swap_hotkey.rs +++ b/pallets/subtensor/src/tests/swap_hotkey.rs @@ -8,7 +8,7 @@ use frame_system::{Config, RawOrigin}; use sp_core::{Get, H160, H256, U256}; use sp_runtime::SaturatedConversion; use substrate_fixed::types::U64F64; -use subtensor_runtime_common::{AlphaCurrency, NetUidStorageIndex, TaoCurrency}; +use subtensor_runtime_common::{AlphaBalance, NetUidStorageIndex, TaoBalance}; use subtensor_swap_interface::{SwapEngine, SwapHandler}; use super::mock; @@ -29,7 +29,8 @@ fn test_swap_owner() { &old_hotkey, &new_hotkey, &coldkey, - &mut weight + &mut weight, + false )); assert!(!Owner::::contains_key(old_hotkey)); @@ -51,7 +52,8 @@ fn test_swap_owned_hotkeys() { &old_hotkey, &new_hotkey, &coldkey, - &mut weight + &mut weight, + false )); let hotkeys = OwnedHotkeys::::get(coldkey); @@ -67,25 +69,26 @@ fn test_swap_total_hotkey_stake() { let old_hotkey = U256::from(1); let new_hotkey = U256::from(2); let coldkey = U256::from(3); - let amount = DefaultMinStake::::get().to_u64() * 10; + let amount = DefaultMinStake::::get() * 10.into(); let mut weight = Weight::zero(); //add network let netuid = add_dynamic_network(&old_hotkey, &coldkey); - mock::setup_reserves(netuid, (amount * 100).into(), (amount * 100).into()); + let reserve = u64::from(amount) * 100; + mock::setup_reserves(netuid, reserve.into(), reserve.into()); // Give it some $$$ in his coldkey balance SubtensorModule::add_balance_to_coldkey_account(&coldkey, amount); // Add stake - let (expected_alpha, _) = mock::swap_tao_to_alpha(netuid, amount.into()); + let (expected_alpha, _) = mock::swap_tao_to_alpha(netuid, amount); assert!(!expected_alpha.is_zero()); assert_ok!(SubtensorModule::add_stake( RuntimeOrigin::signed(coldkey), old_hotkey, netuid, - amount.into() + amount )); // Check if stake has increased @@ -95,7 +98,7 @@ fn test_swap_total_hotkey_stake() { ); assert_abs_diff_eq!( SubtensorModule::get_total_stake_for_hotkey(&new_hotkey), - TaoCurrency::ZERO, + TaoBalance::ZERO, epsilon = 1.into(), ); @@ -104,13 +107,14 @@ fn test_swap_total_hotkey_stake() { &old_hotkey, &new_hotkey, &coldkey, - &mut weight + &mut weight, + false )); // Verify that total hotkey stake swapped assert_abs_diff_eq!( SubtensorModule::get_total_stake_for_hotkey(&old_hotkey), - TaoCurrency::ZERO, + TaoBalance::ZERO, epsilon = 1.into(), ); assert_eq!( @@ -134,7 +138,8 @@ fn test_swap_delegates() { &old_hotkey, &new_hotkey, &coldkey, - &mut weight + &mut weight, + false )); assert!(!Delegates::::contains_key(old_hotkey)); @@ -158,7 +163,8 @@ fn test_swap_subnet_membership() { &old_hotkey, &new_hotkey, &coldkey, - &mut weight + &mut weight, + false )); assert!(!IsNetworkMember::::contains_key(old_hotkey, netuid)); @@ -186,7 +192,8 @@ fn test_swap_uids_and_keys() { &old_hotkey, &new_hotkey, &coldkey, - &mut weight + &mut weight, + false )); assert_eq!(Uids::::get(netuid, old_hotkey), None); @@ -214,7 +221,8 @@ fn test_swap_prometheus() { &old_hotkey, &new_hotkey, &coldkey, - &mut weight + &mut weight, + false )); assert!(!Prometheus::::contains_key(netuid, old_hotkey)); @@ -244,7 +252,8 @@ fn test_swap_axons() { &old_hotkey, &new_hotkey, &coldkey, - &mut weight + &mut weight, + false )); assert!(!Axons::::contains_key(netuid, old_hotkey)); @@ -271,7 +280,8 @@ fn test_swap_certificates() { &old_hotkey, &new_hotkey, &coldkey, - &mut weight + &mut weight, + false )); assert!(!NeuronCertificates::::contains_key( @@ -308,7 +318,8 @@ fn test_swap_weight_commits() { &old_hotkey, &new_hotkey, &coldkey, - &mut weight + &mut weight, + false )); assert!(!WeightCommits::::contains_key( @@ -345,7 +356,8 @@ fn test_swap_loaded_emission() { &old_hotkey, &new_hotkey, &coldkey, - &mut weight + &mut weight, + false )); let new_loaded_emission = LoadedEmission::::get(netuid); @@ -378,7 +390,8 @@ fn test_swap_staking_hotkeys() { &old_hotkey, &new_hotkey, &coldkey, - &mut weight + &mut weight, + false )); let staking_hotkeys = StakingHotkeys::::get(coldkey); @@ -400,7 +413,7 @@ fn test_swap_hotkey_with_multiple_coldkeys() { let coldkey1 = U256::from(3); let coldkey2 = U256::from(4); let mut weight = Weight::zero(); - let stake = 1_000_000_000; + let stake = TaoBalance::from(1_000_000_000_u64); StakingHotkeys::::insert(coldkey1, vec![old_hotkey]); StakingHotkeys::::insert(coldkey2, vec![old_hotkey]); @@ -418,13 +431,13 @@ fn test_swap_hotkey_with_multiple_coldkeys() { RuntimeOrigin::signed(coldkey1), old_hotkey, netuid, - stake.into() + stake )); assert_ok!(SubtensorModule::add_stake( RuntimeOrigin::signed(coldkey2), old_hotkey, netuid, - (stake / 2).into() + stake / 2.into() )); let stake1_before = SubtensorModule::get_total_stake_for_coldkey(&coldkey1); let stake2_before = SubtensorModule::get_total_stake_for_coldkey(&coldkey2); @@ -433,7 +446,8 @@ fn test_swap_hotkey_with_multiple_coldkeys() { &old_hotkey, &new_hotkey, &coldkey1, - &mut weight + &mut weight, + false )); assert_eq!( @@ -469,7 +483,8 @@ fn test_swap_hotkey_with_multiple_subnets() { &old_hotkey, &new_hotkey, &coldkey, - &mut weight + &mut weight, + false )); assert!(IsNetworkMember::::get(new_hotkey, netuid1)); @@ -493,7 +508,7 @@ fn test_swap_staking_hotkeys_multiple_coldkeys() { let coldkey2 = U256::from(4); let staker5 = U256::from(5); let mut weight = Weight::zero(); - let stake = TaoCurrency::from(1_000_000_000); + let stake = TaoBalance::from(1_000_000_000); // Set up initial state StakingHotkeys::::insert(coldkey1, vec![old_hotkey]); @@ -504,11 +519,11 @@ fn test_swap_staking_hotkeys_multiple_coldkeys() { SubtensorModule::create_account_if_non_existent(&coldkey1, &old_hotkey); SubtensorModule::add_balance_to_coldkey_account( &coldkey1, - stake.to_u64() + ExistentialDeposit::get(), + stake + ExistentialDeposit::get(), ); SubtensorModule::add_balance_to_coldkey_account( &coldkey2, - stake.to_u64() + ExistentialDeposit::get(), + stake + ExistentialDeposit::get(), ); assert_ok!(SubtensorModule::add_stake( RuntimeOrigin::signed(coldkey1), @@ -527,7 +542,8 @@ fn test_swap_staking_hotkeys_multiple_coldkeys() { &old_hotkey, &new_hotkey, &coldkey1, - &mut weight + &mut weight, + false )); // Check if new_hotkey replaced old_hotkey in StakingHotkeys @@ -562,7 +578,8 @@ fn test_swap_hotkey_with_no_stake() { &old_hotkey, &new_hotkey, &coldkey, - &mut weight + &mut weight, + false )); // Check if ownership transferred @@ -585,7 +602,7 @@ fn test_swap_hotkey_with_multiple_coldkeys_and_subnets() { let coldkey2 = U256::from(4); let netuid1 = NetUid::from(1); let netuid2 = NetUid::from(2); - let stake = DefaultMinStake::::get().to_u64() * 10; + let stake = DefaultMinStake::::get() * 10.into(); let mut weight = Weight::zero(); // Set up initial state @@ -594,19 +611,20 @@ fn test_swap_hotkey_with_multiple_coldkeys_and_subnets() { register_ok_neuron(netuid1, old_hotkey, coldkey1, 1234); register_ok_neuron(netuid2, old_hotkey, coldkey1, 1234); - mock::setup_reserves(netuid1, (stake * 100).into(), (stake * 100).into()); - mock::setup_reserves(netuid2, (stake * 100).into(), (stake * 100).into()); + let reserve = u64::from(stake) * 100; + mock::setup_reserves(netuid1, reserve.into(), reserve.into()); + mock::setup_reserves(netuid2, reserve.into(), reserve.into()); // Add balance to both coldkeys - SubtensorModule::add_balance_to_coldkey_account(&coldkey1, stake + 1_000); - SubtensorModule::add_balance_to_coldkey_account(&coldkey2, stake + 1_000); + SubtensorModule::add_balance_to_coldkey_account(&coldkey1, stake + 1_000.into()); + SubtensorModule::add_balance_to_coldkey_account(&coldkey2, stake + 1_000.into()); // Stake with coldkey1 assert_ok!(SubtensorModule::add_stake( <::RuntimeOrigin>::signed(coldkey1), old_hotkey, netuid1, - stake.into() + stake )); // Stake with coldkey2 also @@ -614,7 +632,7 @@ fn test_swap_hotkey_with_multiple_coldkeys_and_subnets() { <::RuntimeOrigin>::signed(coldkey2), old_hotkey, netuid2, - stake.into() + stake )); let ck1_stake = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( @@ -636,7 +654,8 @@ fn test_swap_hotkey_with_multiple_coldkeys_and_subnets() { &old_hotkey, &new_hotkey, &coldkey1, - &mut weight + &mut weight, + false )); // Check ownership transfer @@ -669,7 +688,7 @@ fn test_swap_hotkey_with_multiple_coldkeys_and_subnets() { &coldkey1, netuid1 ), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); assert_eq!( SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( @@ -677,7 +696,7 @@ fn test_swap_hotkey_with_multiple_coldkeys_and_subnets() { &coldkey2, netuid2 ), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); // Check subnet membership transfer @@ -705,7 +724,7 @@ fn test_swap_hotkey_with_multiple_coldkeys_and_subnets() { ); assert_eq!( SubtensorModule::get_total_stake_for_hotkey(&old_hotkey), - TaoCurrency::ZERO + TaoBalance::ZERO ); }); } @@ -720,7 +739,7 @@ fn test_swap_hotkey_tx_rate_limit_exceeded() { let new_hotkey_1 = U256::from(2); let new_hotkey_2 = U256::from(4); let coldkey = U256::from(3); - let swap_cost = 1_000_000_000u64 * 2; + let swap_cost = TaoBalance::from(1_000_000_000u64 * 2); let tx_rate_limit = 1; @@ -743,7 +762,8 @@ fn test_swap_hotkey_tx_rate_limit_exceeded() { <::RuntimeOrigin>::signed(coldkey), &old_hotkey, &new_hotkey_1, - None + None, + false, )); // Attempt to perform another swap immediately, which should fail due to rate limit @@ -752,7 +772,8 @@ fn test_swap_hotkey_tx_rate_limit_exceeded() { <::RuntimeOrigin>::signed(coldkey), &new_hotkey_1, &new_hotkey_2, - None + None, + false, ), Error::::HotKeySetTxRateLimitExceeded ); @@ -763,7 +784,8 @@ fn test_swap_hotkey_tx_rate_limit_exceeded() { <::RuntimeOrigin>::signed(coldkey), &new_hotkey_1, &new_hotkey_2, - None + None, + false, )); }); } @@ -778,7 +800,7 @@ fn test_do_swap_hotkey_err_not_owner() { let new_hotkey = U256::from(2); let coldkey = U256::from(3); let not_owner_coldkey = U256::from(4); - let swap_cost = 1_000_000_000u64; + let swap_cost = TaoBalance::from(1_000_000_000u64); // Setup initial state add_network(netuid, tempo, 0); @@ -791,7 +813,8 @@ fn test_do_swap_hotkey_err_not_owner() { <::RuntimeOrigin>::signed(not_owner_coldkey), &old_hotkey, &new_hotkey, - None + None, + false, ), Error::::NonAssociatedColdKey ); @@ -816,6 +839,7 @@ fn test_swap_owner_old_hotkey_not_exist() { &new_hotkey, &coldkey, &mut weight, + false, ); // Verify the swap @@ -844,6 +868,7 @@ fn test_swap_owner_new_hotkey_already_exists() { &new_hotkey, &coldkey, &mut weight, + false, ); // Verify the swap @@ -867,15 +892,15 @@ fn test_swap_stake_success() { let mut weight = Weight::zero(); // Initialize staking variables for old_hotkey - TotalHotkeyAlpha::::insert(old_hotkey, netuid, AlphaCurrency::from(amount)); + TotalHotkeyAlpha::::insert(old_hotkey, netuid, AlphaBalance::from(amount)); TotalHotkeyAlphaLastEpoch::::insert( old_hotkey, netuid, - AlphaCurrency::from(amount * 2), + AlphaBalance::from(amount * 2), ); TotalHotkeyShares::::insert(old_hotkey, netuid, shares); Alpha::::insert((old_hotkey, coldkey, netuid), U64F64::from_num(amount)); - AlphaDividendsPerSubnet::::insert(netuid, old_hotkey, AlphaCurrency::from(amount)); + AlphaDividendsPerSubnet::::insert(netuid, old_hotkey, AlphaBalance::from(amount)); // Perform the swap SubtensorModule::perform_hotkey_swap_on_all_subnets( @@ -883,12 +908,13 @@ fn test_swap_stake_success() { &new_hotkey, &coldkey, &mut weight, + false, ); // Verify the swap assert_eq!( TotalHotkeyAlpha::::get(old_hotkey, netuid), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); assert_eq!( TotalHotkeyAlpha::::get(new_hotkey, netuid), @@ -896,11 +922,11 @@ fn test_swap_stake_success() { ); assert_eq!( TotalHotkeyAlphaLastEpoch::::get(old_hotkey, netuid), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); assert_eq!( TotalHotkeyAlphaLastEpoch::::get(new_hotkey, netuid), - AlphaCurrency::from(amount * 2) + AlphaBalance::from(amount * 2) ); assert_eq!( TotalHotkeyShares::::get(old_hotkey, netuid), @@ -920,7 +946,7 @@ fn test_swap_stake_success() { ); assert_eq!( AlphaDividendsPerSubnet::::get(netuid, old_hotkey), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); assert_eq!( AlphaDividendsPerSubnet::::get(netuid, new_hotkey), @@ -956,6 +982,7 @@ fn test_swap_stake_old_hotkey_not_exist() { &new_hotkey, &coldkey, &mut weight, + false, ); // Verify that new_hotkey has the stake and old_hotkey does not @@ -1012,12 +1039,13 @@ fn test_swap_hotkey_error_cases() { RuntimeOrigin::signed(coldkey), &old_hotkey, &new_hotkey, - None + None, + false, ), Error::::NotEnoughBalanceToPaySwapHotKey ); - let initial_balance = SubtensorModule::get_key_swap_cost().to_u64() + 1000; + let initial_balance = SubtensorModule::get_key_swap_cost() + 1000.into(); SubtensorModule::add_balance_to_coldkey_account(&coldkey, initial_balance); // Test new hotkey same as old @@ -1026,7 +1054,8 @@ fn test_swap_hotkey_error_cases() { RuntimeOrigin::signed(coldkey), &old_hotkey, &old_hotkey, - None + None, + false, ), Error::::NewHotKeyIsSameWithOld ); @@ -1038,7 +1067,8 @@ fn test_swap_hotkey_error_cases() { RuntimeOrigin::signed(coldkey), &old_hotkey, &new_hotkey, - None + None, + false, ), Error::::HotKeyAlreadyRegisteredInSubNet ); @@ -1050,7 +1080,8 @@ fn test_swap_hotkey_error_cases() { RuntimeOrigin::signed(wrong_coldkey), &old_hotkey, &new_hotkey, - None + None, + false, ), Error::::NonAssociatedColdKey ); @@ -1060,14 +1091,12 @@ fn test_swap_hotkey_error_cases() { RuntimeOrigin::signed(coldkey), &old_hotkey, &new_hotkey, - None + None, + false, )); // Check balance after swap - assert_eq!( - Balances::free_balance(coldkey), - initial_balance - swap_cost.to_u64() - ); + assert_eq!(Balances::free_balance(coldkey), initial_balance - swap_cost); }); } @@ -1092,6 +1121,7 @@ fn test_swap_child_keys() { &new_hotkey, &coldkey, &mut weight, + false, ); // Verify the swap @@ -1125,6 +1155,7 @@ fn test_swap_parent_keys() { &new_hotkey, &coldkey, &mut weight, + false, ); // Verify ParentKeys swap @@ -1169,6 +1200,7 @@ fn test_swap_multiple_subnets() { &new_hotkey, &coldkey, &mut weight, + false, ); // Verify the swap for both subnets @@ -1219,6 +1251,7 @@ fn test_swap_complex_parent_child_structure() { &new_hotkey, &coldkey, &mut weight, + false, ); // Verify ParentKeys swap @@ -1279,7 +1312,8 @@ fn test_swap_parent_hotkey_childkey_maps() { &parent_old, &parent_new, &coldkey, - &mut weight + &mut weight, + false )); // Verify parent and child keys updates @@ -1334,7 +1368,8 @@ fn test_swap_child_hotkey_childkey_maps() { &child_old, &child_new, &coldkey, - &mut weight + &mut weight, + false )); // Verify parent and child keys updates @@ -1373,6 +1408,7 @@ fn test_swap_hotkey_is_sn_owner_hotkey() { &new_hotkey, &coldkey, &mut weight, + false, ); // Check for SubnetOwnerHotkey @@ -1388,7 +1424,7 @@ fn test_swap_hotkey_swap_rate_limits() { let new_hotkey = U256::from(2); let coldkey = U256::from(3); let netuid = add_dynamic_network(&old_hotkey, &coldkey); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX.into()); let last_tx_block = 123; let delegate_take_block = 4567; @@ -1406,7 +1442,8 @@ fn test_swap_hotkey_swap_rate_limits() { RuntimeOrigin::signed(coldkey), &old_hotkey, &new_hotkey, - None + None, + false, )); // Check for new hotkey @@ -1464,7 +1501,8 @@ fn test_swap_parent_hotkey_self_loops_in_pending() { &parent_old, &parent_new, &coldkey, - &mut weight + &mut weight, + false ), Error::::InvalidChild ); @@ -1492,6 +1530,7 @@ fn test_swap_auto_stake_destination_coldkeys() { &new_hotkey, &coldkey, &mut weight, + false, ); // Verify the swap diff --git a/pallets/subtensor/src/tests/swap_hotkey_with_subnet.rs b/pallets/subtensor/src/tests/swap_hotkey_with_subnet.rs index 6e423c1269..6f43d46fde 100644 --- a/pallets/subtensor/src/tests/swap_hotkey_with_subnet.rs +++ b/pallets/subtensor/src/tests/swap_hotkey_with_subnet.rs @@ -5,13 +5,15 @@ use codec::Encode; use frame_support::weights::Weight; use frame_support::{assert_err, assert_noop, assert_ok}; use frame_system::{Config, RawOrigin}; -use subtensor_runtime_common::{AlphaCurrency, Currency, NetUidStorageIndex, TaoCurrency}; +use subtensor_runtime_common::{AlphaBalance, NetUidStorageIndex, TaoBalance, Token}; use super::mock::*; use crate::*; use sp_core::{Get, H160, H256, U256}; use sp_runtime::SaturatedConversion; +use std::collections::BTreeSet; use substrate_fixed::types::U64F64; + // SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey_with_subnet -- test_swap_owner --exact --nocapture #[test] fn test_swap_owner() { @@ -21,14 +23,15 @@ fn test_swap_owner() { let coldkey = U256::from(3); let netuid = add_dynamic_network(&old_hotkey, &coldkey); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX.into()); Owner::::insert(old_hotkey, coldkey); System::set_block_number(System::block_number() + HotkeySwapOnSubnetInterval::get()); assert_ok!(SubtensorModule::do_swap_hotkey( RuntimeOrigin::signed(coldkey), &old_hotkey, &new_hotkey, - Some(netuid) + Some(netuid), + false, )); assert_eq!(Owner::::get(old_hotkey), coldkey); @@ -45,7 +48,7 @@ fn test_swap_owned_hotkeys() { let coldkey = U256::from(3); let netuid = add_dynamic_network(&old_hotkey, &coldkey); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX.into()); OwnedHotkeys::::insert(coldkey, vec![old_hotkey]); System::set_block_number(System::block_number() + HotkeySwapOnSubnetInterval::get()); @@ -53,7 +56,8 @@ fn test_swap_owned_hotkeys() { RuntimeOrigin::signed(coldkey), &old_hotkey, &new_hotkey, - Some(netuid) + Some(netuid), + false )); let hotkeys = OwnedHotkeys::::get(coldkey); @@ -77,7 +81,7 @@ fn test_swap_total_hotkey_stake() { let netuid = add_dynamic_network(&old_hotkey, &coldkey); // Give it some $$$ in his coldkey balance - SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX.into()); // Add stake assert_ok!(SubtensorModule::add_stake( @@ -91,11 +95,11 @@ fn test_swap_total_hotkey_stake() { assert_abs_diff_eq!( SubtensorModule::get_total_stake_for_hotkey(&old_hotkey), (amount - fee).into(), - epsilon = TaoCurrency::from(amount / 100), + epsilon = TaoBalance::from(amount / 100), ); assert_abs_diff_eq!( SubtensorModule::get_total_stake_for_hotkey(&new_hotkey), - TaoCurrency::ZERO, + TaoBalance::ZERO, epsilon = 1.into(), ); @@ -105,19 +109,20 @@ fn test_swap_total_hotkey_stake() { RuntimeOrigin::signed(coldkey), &old_hotkey, &new_hotkey, - Some(netuid) + Some(netuid), + false )); // Verify that total hotkey stake swapped assert_abs_diff_eq!( SubtensorModule::get_total_stake_for_hotkey(&old_hotkey), - TaoCurrency::ZERO, + TaoBalance::ZERO, epsilon = 1.into(), ); assert_abs_diff_eq!( SubtensorModule::get_total_stake_for_hotkey(&new_hotkey), - TaoCurrency::from(amount - fee), - epsilon = TaoCurrency::from(amount / 100), + TaoBalance::from(amount - fee), + epsilon = TaoBalance::from(amount / 100), ); }); } @@ -131,7 +136,7 @@ fn test_swap_delegates() { let coldkey = U256::from(3); let netuid = add_dynamic_network(&old_hotkey, &coldkey); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX.into()); Delegates::::insert(old_hotkey, 100); System::set_block_number(System::block_number() + HotkeySwapOnSubnetInterval::get()); @@ -139,7 +144,8 @@ fn test_swap_delegates() { RuntimeOrigin::signed(coldkey), &old_hotkey, &new_hotkey, - Some(netuid) + Some(netuid), + false )); assert!(Delegates::::contains_key(old_hotkey)); @@ -156,7 +162,7 @@ fn test_swap_subnet_membership() { let coldkey = U256::from(3); let netuid = add_dynamic_network(&old_hotkey, &coldkey); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX.into()); IsNetworkMember::::insert(old_hotkey, netuid, true); System::set_block_number(System::block_number() + HotkeySwapOnSubnetInterval::get()); @@ -164,7 +170,8 @@ fn test_swap_subnet_membership() { RuntimeOrigin::signed(coldkey), &old_hotkey, &new_hotkey, - Some(netuid) + Some(netuid), + false )); assert!(!IsNetworkMember::::contains_key(old_hotkey, netuid)); @@ -182,7 +189,7 @@ fn test_swap_uids_and_keys() { let coldkey = U256::from(3); let netuid = add_dynamic_network(&old_hotkey, &coldkey); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX.into()); IsNetworkMember::::insert(old_hotkey, netuid, true); Uids::::insert(netuid, old_hotkey, uid); @@ -193,7 +200,8 @@ fn test_swap_uids_and_keys() { RuntimeOrigin::signed(coldkey), &old_hotkey, &new_hotkey, - Some(netuid) + Some(netuid), + false )); assert_eq!(Uids::::get(netuid, old_hotkey), None); @@ -214,7 +222,7 @@ fn test_swap_prometheus() { let prometheus_info = PrometheusInfo::default(); let netuid = add_dynamic_network(&old_hotkey, &coldkey); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX.into()); IsNetworkMember::::insert(old_hotkey, netuid, true); Prometheus::::insert(netuid, old_hotkey, prometheus_info.clone()); @@ -224,7 +232,8 @@ fn test_swap_prometheus() { RuntimeOrigin::signed(coldkey), &old_hotkey, &new_hotkey, - Some(netuid) + Some(netuid), + false )); assert!(!Prometheus::::contains_key(netuid, old_hotkey)); @@ -247,7 +256,7 @@ fn test_swap_axons() { let axon_info = AxonInfo::default(); let netuid = add_dynamic_network(&old_hotkey, &coldkey); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX.into()); IsNetworkMember::::insert(old_hotkey, netuid, true); Axons::::insert(netuid, old_hotkey, axon_info.clone()); @@ -257,7 +266,8 @@ fn test_swap_axons() { RuntimeOrigin::signed(coldkey), &old_hotkey, &new_hotkey, - Some(netuid) + Some(netuid), + false )); assert!(!Axons::::contains_key(netuid, old_hotkey)); @@ -277,7 +287,7 @@ fn test_swap_certificates() { let certificate = NeuronCertificate::try_from(vec![1, 2, 3]).unwrap(); let netuid = add_dynamic_network(&old_hotkey, &coldkey); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX.into()); IsNetworkMember::::insert(old_hotkey, netuid, true); NeuronCertificates::::insert(netuid, old_hotkey, certificate.clone()); @@ -287,7 +297,8 @@ fn test_swap_certificates() { RuntimeOrigin::signed(coldkey), &old_hotkey, &new_hotkey, - Some(netuid) + Some(netuid), + false )); assert!(!NeuronCertificates::::contains_key( @@ -313,7 +324,7 @@ fn test_swap_weight_commits() { weight_commits.push_back((H256::from_low_u64_be(100), 200, 1, 1)); let netuid = add_dynamic_network(&old_hotkey, &coldkey); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX.into()); IsNetworkMember::::insert(old_hotkey, netuid, true); WeightCommits::::insert( @@ -327,7 +338,8 @@ fn test_swap_weight_commits() { RuntimeOrigin::signed(coldkey), &old_hotkey, &new_hotkey, - Some(netuid) + Some(netuid), + false )); assert!(!WeightCommits::::contains_key( @@ -354,7 +366,7 @@ fn test_swap_loaded_emission() { let validator_emission = 1000u64; let netuid = add_dynamic_network(&old_hotkey, &coldkey); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX.into()); IsNetworkMember::::insert(old_hotkey, netuid, true); LoadedEmission::::insert( @@ -367,7 +379,8 @@ fn test_swap_loaded_emission() { RuntimeOrigin::signed(coldkey), &old_hotkey, &new_hotkey, - Some(netuid) + Some(netuid), + false )); let new_loaded_emission = LoadedEmission::::get(netuid); @@ -386,7 +399,7 @@ fn test_swap_staking_hotkeys() { let new_hotkey = U256::from(2); let coldkey = U256::from(3); let netuid = add_dynamic_network(&old_hotkey, &coldkey); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX.into()); StakingHotkeys::::insert(coldkey, vec![old_hotkey]); Alpha::::insert((old_hotkey, coldkey, netuid), U64F64::from_num(100)); @@ -396,7 +409,8 @@ fn test_swap_staking_hotkeys() { RuntimeOrigin::signed(coldkey), &old_hotkey, &new_hotkey, - Some(netuid) + Some(netuid), + false )); let staking_hotkeys = StakingHotkeys::::get(coldkey); @@ -423,8 +437,8 @@ fn test_swap_hotkey_with_multiple_coldkeys() { StakingHotkeys::::insert(coldkey1, vec![old_hotkey]); StakingHotkeys::::insert(coldkey2, vec![old_hotkey]); SubtensorModule::create_account_if_non_existent(&coldkey1, &old_hotkey); - SubtensorModule::add_balance_to_coldkey_account(&coldkey1, u64::MAX); - SubtensorModule::add_balance_to_coldkey_account(&coldkey2, u64::MAX); + SubtensorModule::add_balance_to_coldkey_account(&coldkey1, u64::MAX.into()); + SubtensorModule::add_balance_to_coldkey_account(&coldkey2, u64::MAX.into()); assert_ok!(SubtensorModule::add_stake( RuntimeOrigin::signed(coldkey1), @@ -436,7 +450,7 @@ fn test_swap_hotkey_with_multiple_coldkeys() { RuntimeOrigin::signed(coldkey2), old_hotkey, netuid, - TaoCurrency::from(stake / 2) + TaoBalance::from(stake / 2) )); let stake1_before = SubtensorModule::get_total_stake_for_coldkey(&coldkey1); let stake2_before = SubtensorModule::get_total_stake_for_coldkey(&coldkey2); @@ -446,7 +460,8 @@ fn test_swap_hotkey_with_multiple_coldkeys() { RuntimeOrigin::signed(coldkey1), &old_hotkey, &new_hotkey, - Some(netuid) + Some(netuid), + false )); assert_eq!( @@ -481,7 +496,7 @@ fn test_swap_hotkey_with_multiple_subnets() { let new_hotkey_2 = U256::from(3); let coldkey = U256::from(4); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX.into()); let netuid1 = add_dynamic_network(&old_hotkey, &coldkey); let netuid2 = add_dynamic_network(&old_hotkey, &coldkey); @@ -494,7 +509,8 @@ fn test_swap_hotkey_with_multiple_subnets() { RuntimeOrigin::signed(coldkey), &old_hotkey, &new_hotkey, - Some(netuid1) + Some(netuid1), + false )); System::set_block_number(System::block_number() + HotkeySwapOnSubnetInterval::get()); @@ -502,7 +518,8 @@ fn test_swap_hotkey_with_multiple_subnets() { RuntimeOrigin::signed(coldkey), &old_hotkey, &new_hotkey_2, - Some(netuid2) + Some(netuid2), + false )); assert!(IsNetworkMember::::get(new_hotkey, netuid1)); @@ -527,8 +544,8 @@ fn test_swap_staking_hotkeys_multiple_coldkeys() { let staker5 = U256::from(5); let stake = 1_000_000_000; - SubtensorModule::add_balance_to_coldkey_account(&coldkey1, u64::MAX); - SubtensorModule::add_balance_to_coldkey_account(&coldkey2, u64::MAX); + SubtensorModule::add_balance_to_coldkey_account(&coldkey1, u64::MAX.into()); + SubtensorModule::add_balance_to_coldkey_account(&coldkey2, u64::MAX.into()); // Set up initial state StakingHotkeys::::insert(coldkey1, vec![old_hotkey]); @@ -554,7 +571,8 @@ fn test_swap_staking_hotkeys_multiple_coldkeys() { RuntimeOrigin::signed(coldkey1), &old_hotkey, &new_hotkey, - Some(netuid) + Some(netuid), + false )); // Check if new_hotkey replaced old_hotkey in StakingHotkeys @@ -581,7 +599,7 @@ fn test_swap_hotkey_with_no_stake() { let new_hotkey = U256::from(2); let coldkey = U256::from(3); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX.into()); // Set up initial state with no stake Owner::::insert(old_hotkey, coldkey); @@ -591,7 +609,8 @@ fn test_swap_hotkey_with_no_stake() { RuntimeOrigin::signed(coldkey), &old_hotkey, &new_hotkey, - Some(netuid) + Some(netuid), + false )); // Check if ownership transferred @@ -624,8 +643,8 @@ fn test_swap_hotkey_with_multiple_coldkeys_and_subnets() { register_ok_neuron(netuid2, old_hotkey, coldkey1, 1234); // Add balance to both coldkeys - SubtensorModule::add_balance_to_coldkey_account(&coldkey1, u64::MAX); - SubtensorModule::add_balance_to_coldkey_account(&coldkey2, u64::MAX); + SubtensorModule::add_balance_to_coldkey_account(&coldkey1, u64::MAX.into()); + SubtensorModule::add_balance_to_coldkey_account(&coldkey2, u64::MAX.into()); // Stake with coldkey1 assert_ok!(SubtensorModule::add_stake( @@ -663,7 +682,8 @@ fn test_swap_hotkey_with_multiple_coldkeys_and_subnets() { RuntimeOrigin::signed(coldkey1), &old_hotkey, &new_hotkey, - Some(netuid1) + Some(netuid1), + false )); System::set_block_number(System::block_number() + HotkeySwapOnSubnetInterval::get()); @@ -671,7 +691,8 @@ fn test_swap_hotkey_with_multiple_coldkeys_and_subnets() { RuntimeOrigin::signed(coldkey1), &old_hotkey, &new_hotkey_2, - Some(netuid2) + Some(netuid2), + false )); // Check ownership transfer @@ -709,7 +730,7 @@ fn test_swap_hotkey_with_multiple_coldkeys_and_subnets() { &coldkey1, netuid1 ), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); assert_eq!( SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( @@ -717,7 +738,7 @@ fn test_swap_hotkey_with_multiple_coldkeys_and_subnets() { &coldkey2, netuid2 ), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); // Check subnet membership transfer @@ -746,7 +767,7 @@ fn test_swap_hotkey_with_multiple_coldkeys_and_subnets() { ); assert_eq!( SubtensorModule::get_total_stake_for_hotkey(&old_hotkey), - TaoCurrency::ZERO + TaoBalance::ZERO ); }); } @@ -761,7 +782,7 @@ fn test_swap_hotkey_tx_rate_limit_exceeded() { let new_hotkey_1 = U256::from(2); let new_hotkey_2 = U256::from(4); let coldkey = U256::from(3); - let swap_cost = 1_000_000_000u64 * 2; + let swap_cost = TaoBalance::from(1_000_000_000u64) * 2.into(); let tx_rate_limit = 1; @@ -785,7 +806,8 @@ fn test_swap_hotkey_tx_rate_limit_exceeded() { RuntimeOrigin::signed(coldkey), &old_hotkey, &new_hotkey_1, - Some(netuid) + Some(netuid), + false ),); // Attempt to perform another swap immediately, which should fail due to rate limit @@ -794,7 +816,8 @@ fn test_swap_hotkey_tx_rate_limit_exceeded() { RuntimeOrigin::signed(coldkey), &old_hotkey, &new_hotkey_1, - Some(netuid) + Some(netuid), + false ), Error::::HotKeySetTxRateLimitExceeded ); @@ -806,7 +829,8 @@ fn test_swap_hotkey_tx_rate_limit_exceeded() { <::RuntimeOrigin>::signed(coldkey), &new_hotkey_1, &new_hotkey_2, - None + None, + false )); }); } @@ -821,7 +845,7 @@ fn test_do_swap_hotkey_err_not_owner() { let new_hotkey = U256::from(2); let coldkey = U256::from(3); let not_owner_coldkey = U256::from(4); - let swap_cost = 1_000_000_000u64; + let swap_cost = TaoBalance::from(1_000_000_000u64); // Setup initial state add_network(netuid, tempo, 0); @@ -834,7 +858,8 @@ fn test_do_swap_hotkey_err_not_owner() { RuntimeOrigin::signed(not_owner_coldkey), &old_hotkey, &new_hotkey, - Some(netuid) + Some(netuid), + false ), Error::::NonAssociatedColdKey ); @@ -850,7 +875,7 @@ fn test_swap_owner_old_hotkey_not_exist() { let coldkey = U256::from(3); let netuid = add_dynamic_network(&new_hotkey, &coldkey); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX.into()); // Ensure old_hotkey does not exist assert!(!Owner::::contains_key(old_hotkey)); @@ -861,7 +886,8 @@ fn test_swap_owner_old_hotkey_not_exist() { RuntimeOrigin::signed(coldkey), &old_hotkey, &new_hotkey, - Some(netuid) + Some(netuid), + false ), Error::::NonAssociatedColdKey ); @@ -882,7 +908,7 @@ fn test_swap_owner_new_hotkey_already_exists() { let another_coldkey = U256::from(4); let netuid = add_dynamic_network(&new_hotkey, &coldkey); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX.into()); // Initialize Owner for old_hotkey and new_hotkey Owner::::insert(old_hotkey, coldkey); @@ -895,7 +921,8 @@ fn test_swap_owner_new_hotkey_already_exists() { RuntimeOrigin::signed(coldkey), &old_hotkey, &new_hotkey, - Some(netuid) + Some(netuid), + false ), Error::::HotKeyAlreadyRegisteredInSubNet ); @@ -916,20 +943,20 @@ fn test_swap_stake_success() { let subnet_owner_coldkey = U256::from(1001); let subnet_owner_hotkey = U256::from(1002); let netuid = add_dynamic_network(&old_hotkey, &coldkey); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX.into()); let amount = 10_000; let shares = U64F64::from_num(123456); // Initialize staking variables for old_hotkey - TotalHotkeyAlpha::::insert(old_hotkey, netuid, AlphaCurrency::from(amount)); + TotalHotkeyAlpha::::insert(old_hotkey, netuid, AlphaBalance::from(amount)); TotalHotkeyAlphaLastEpoch::::insert( old_hotkey, netuid, - AlphaCurrency::from(amount * 2), + AlphaBalance::from(amount * 2), ); TotalHotkeyShares::::insert(old_hotkey, netuid, U64F64::from_num(shares)); Alpha::::insert((old_hotkey, coldkey, netuid), U64F64::from_num(amount)); - AlphaDividendsPerSubnet::::insert(netuid, old_hotkey, AlphaCurrency::from(amount)); + AlphaDividendsPerSubnet::::insert(netuid, old_hotkey, AlphaBalance::from(amount)); // Perform the swap System::set_block_number(System::block_number() + HotkeySwapOnSubnetInterval::get()); @@ -937,25 +964,26 @@ fn test_swap_stake_success() { RuntimeOrigin::signed(coldkey), &old_hotkey, &new_hotkey, - Some(netuid) + Some(netuid), + false ),); // Verify the swap assert_eq!( TotalHotkeyAlpha::::get(old_hotkey, netuid), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); assert_eq!( TotalHotkeyAlpha::::get(new_hotkey, netuid), - AlphaCurrency::from(amount) + AlphaBalance::from(amount) ); assert_eq!( TotalHotkeyAlphaLastEpoch::::get(old_hotkey, netuid), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); assert_eq!( TotalHotkeyAlphaLastEpoch::::get(new_hotkey, netuid), - AlphaCurrency::from(amount * 2) + AlphaBalance::from(amount * 2) ); assert_eq!( TotalHotkeyShares::::get(old_hotkey, netuid), @@ -975,11 +1003,11 @@ fn test_swap_stake_success() { ); assert_eq!( AlphaDividendsPerSubnet::::get(netuid, old_hotkey), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); assert_eq!( AlphaDividendsPerSubnet::::get(netuid, new_hotkey), - AlphaCurrency::from(amount) + AlphaBalance::from(amount) ); }); } @@ -1007,12 +1035,13 @@ fn test_swap_hotkey_error_cases() { RuntimeOrigin::signed(coldkey), &old_hotkey, &new_hotkey, - Some(netuid) + Some(netuid), + false ), Error::::NotEnoughBalanceToPaySwapHotKey ); - let initial_balance = SubtensorModule::get_key_swap_cost().to_u64() + 1000; + let initial_balance = SubtensorModule::get_key_swap_cost() + 1000.into(); SubtensorModule::add_balance_to_coldkey_account(&coldkey, initial_balance); // Test new hotkey same as old @@ -1022,7 +1051,8 @@ fn test_swap_hotkey_error_cases() { RuntimeOrigin::signed(coldkey), &old_hotkey, &old_hotkey, - Some(netuid) + Some(netuid), + false ), Error::::NewHotKeyIsSameWithOld ); @@ -1035,7 +1065,8 @@ fn test_swap_hotkey_error_cases() { RuntimeOrigin::signed(coldkey), &old_hotkey, &new_hotkey, - Some(netuid) + Some(netuid), + false ), Error::::HotKeyAlreadyRegisteredInSubNet ); @@ -1047,7 +1078,8 @@ fn test_swap_hotkey_error_cases() { RuntimeOrigin::signed(wrong_coldkey), &old_hotkey, &new_hotkey, - Some(netuid) + Some(netuid), + false ), Error::::NonAssociatedColdKey ); @@ -1058,7 +1090,8 @@ fn test_swap_hotkey_error_cases() { RuntimeOrigin::signed(coldkey), &old_hotkey, &new_hotkey, - Some(netuid) + Some(netuid), + false ),); }); } @@ -1071,7 +1104,7 @@ fn test_swap_child_keys() { let new_hotkey = U256::from(2); let coldkey = U256::from(3); let netuid = add_dynamic_network(&old_hotkey, &coldkey); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX.into()); let children = vec![(100u64, U256::from(4)), (200u64, U256::from(5))]; @@ -1084,7 +1117,8 @@ fn test_swap_child_keys() { RuntimeOrigin::signed(coldkey), &old_hotkey, &new_hotkey, - Some(netuid) + Some(netuid), + false ),); // Verify the swap @@ -1095,17 +1129,18 @@ fn test_swap_child_keys() { // SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::swap_hotkey_with_subnet::test_swap_child_keys_self_loop --exact --show-output #[test] +#[allow(deprecated)] fn test_swap_child_keys_self_loop() { new_test_ext(1).execute_with(|| { let old_hotkey = U256::from(1); let new_hotkey = U256::from(2); let coldkey = U256::from(3); let netuid = add_dynamic_network(&old_hotkey, &coldkey); - let amount = AlphaCurrency::from(12345); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX); + let amount = AlphaBalance::from(12345); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX.into()); // Only for checking - TotalHotkeyAlpha::::insert(old_hotkey, netuid, AlphaCurrency::from(amount)); + TotalHotkeyAlpha::::insert(old_hotkey, netuid, AlphaBalance::from(amount)); let children = vec![(200u64, new_hotkey)]; @@ -1119,7 +1154,7 @@ fn test_swap_child_keys_self_loop() { RuntimeOrigin::signed(coldkey), old_hotkey, new_hotkey, - Some(netuid) + Some(netuid), ), Error::::InvalidChild ); @@ -1130,7 +1165,7 @@ fn test_swap_child_keys_self_loop() { assert_eq!(TotalHotkeyAlpha::::get(old_hotkey, netuid), amount); assert_eq!( TotalHotkeyAlpha::::get(new_hotkey, netuid), - AlphaCurrency::from(0) + AlphaBalance::from(0) ); }); } @@ -1143,7 +1178,7 @@ fn test_swap_parent_keys() { let new_hotkey = U256::from(2); let coldkey = U256::from(3); let netuid = add_dynamic_network(&old_hotkey, &coldkey); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX.into()); let parents = vec![(100u64, U256::from(4)), (200u64, U256::from(5))]; // Initialize ParentKeys for old_hotkey @@ -1159,7 +1194,8 @@ fn test_swap_parent_keys() { RuntimeOrigin::signed(coldkey), &old_hotkey, &new_hotkey, - Some(netuid) + Some(netuid), + false ),); // Verify ParentKeys swap @@ -1189,7 +1225,7 @@ fn test_swap_multiple_subnets() { let netuid1 = add_dynamic_network(&old_hotkey, &coldkey); let netuid2 = add_dynamic_network(&old_hotkey, &coldkey); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX.into()); let children1 = vec![(100u64, U256::from(4)), (200u64, U256::from(5))]; let children2 = vec![(300u64, U256::from(6))]; @@ -1204,7 +1240,8 @@ fn test_swap_multiple_subnets() { RuntimeOrigin::signed(coldkey), &old_hotkey, &new_hotkey, - Some(netuid1) + Some(netuid1), + false ),); System::set_block_number(System::block_number() + HotkeySwapOnSubnetInterval::get()); @@ -1212,7 +1249,8 @@ fn test_swap_multiple_subnets() { RuntimeOrigin::signed(coldkey), &old_hotkey, &new_hotkey_2, - Some(netuid2) + Some(netuid2), + false ),); // Verify the swap for both subnets @@ -1231,7 +1269,7 @@ fn test_swap_complex_parent_child_structure() { let new_hotkey = U256::from(2); let coldkey = U256::from(3); let netuid = add_dynamic_network(&old_hotkey, &coldkey); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX.into()); let parent1 = U256::from(4); let parent2 = U256::from(5); let child1 = U256::from(6); @@ -1261,7 +1299,8 @@ fn test_swap_complex_parent_child_structure() { RuntimeOrigin::signed(coldkey), &old_hotkey, &new_hotkey, - Some(netuid) + Some(netuid), + false ),); // Verify ParentKeys swap @@ -1296,7 +1335,7 @@ fn test_swap_parent_hotkey_childkey_maps() { let parent_new = U256::from(5); let netuid = add_dynamic_network(&parent_old, &coldkey); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX.into()); SubtensorModule::create_account_if_non_existent(&coldkey, &parent_old); @@ -1325,7 +1364,8 @@ fn test_swap_parent_hotkey_childkey_maps() { RuntimeOrigin::signed(coldkey), &parent_old, &parent_new, - Some(netuid) + Some(netuid), + false ),); // Verify parent and child keys updates @@ -1352,7 +1392,7 @@ fn test_swap_child_hotkey_childkey_maps() { let child_old = U256::from(3); let child_new = U256::from(4); let netuid = add_dynamic_network(&child_old, &coldkey); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX.into()); SubtensorModule::create_account_if_non_existent(&coldkey, &child_old); SubtensorModule::create_account_if_non_existent(&coldkey, &parent); @@ -1382,7 +1422,8 @@ fn test_swap_child_hotkey_childkey_maps() { RuntimeOrigin::signed(coldkey), &child_old, &child_new, - Some(netuid) + Some(netuid), + false ),); // Verify parent and child keys updates @@ -1411,7 +1452,7 @@ fn test_swap_hotkey_is_sn_owner_hotkey() { // Create dynamic network let netuid = add_dynamic_network(&old_hotkey, &coldkey); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX.into()); // Check for SubnetOwnerHotkey assert_eq!(SubnetOwnerHotkey::::get(netuid), old_hotkey); @@ -1422,7 +1463,8 @@ fn test_swap_hotkey_is_sn_owner_hotkey() { RuntimeOrigin::signed(coldkey), &old_hotkey, &new_hotkey, - Some(netuid) + Some(netuid), + false ),); // Check for SubnetOwnerHotkey @@ -1443,7 +1485,7 @@ fn test_swap_hotkey_swap_rate_limits() { let child_key_take_block = 8910; let netuid = add_dynamic_network(&old_hotkey, &coldkey); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX.into()); // Set the last tx block for the old hotkey SubtensorModule::set_last_tx_block(&old_hotkey, last_tx_block); @@ -1458,7 +1500,8 @@ fn test_swap_hotkey_swap_rate_limits() { RuntimeOrigin::signed(coldkey), &old_hotkey, &new_hotkey, - Some(netuid) + Some(netuid), + false ),); // Check for new hotkey @@ -1485,14 +1528,15 @@ fn test_swap_owner_failed_interval_not_passed() { let coldkey = U256::from(3); let netuid = add_dynamic_network(&old_hotkey, &coldkey); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX.into()); Owner::::insert(old_hotkey, coldkey); assert_err!( SubtensorModule::do_swap_hotkey( RuntimeOrigin::signed(coldkey), &old_hotkey, &new_hotkey, - Some(netuid) + Some(netuid), + false ), Error::::HotKeySwapOnSubnetIntervalNotPassed, ); @@ -1507,7 +1551,7 @@ fn test_swap_owner_check_swap_block_set() { let coldkey = U256::from(3); let netuid = add_dynamic_network(&old_hotkey, &coldkey); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX.into()); Owner::::insert(old_hotkey, coldkey); let new_block_number = System::block_number() + HotkeySwapOnSubnetInterval::get(); System::set_block_number(new_block_number); @@ -1515,7 +1559,8 @@ fn test_swap_owner_check_swap_block_set() { RuntimeOrigin::signed(coldkey), &old_hotkey, &new_hotkey, - Some(netuid) + Some(netuid), + false )); assert_eq!( @@ -1532,7 +1577,7 @@ fn test_swap_owner_check_swap_record_clean_up() { let new_hotkey = U256::from(2); let coldkey = U256::from(3); let netuid = add_dynamic_network(&old_hotkey, &coldkey); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX.into()); Owner::::insert(old_hotkey, coldkey); let new_block_number = System::block_number() + HotkeySwapOnSubnetInterval::get(); System::set_block_number(new_block_number); @@ -1540,7 +1585,8 @@ fn test_swap_owner_check_swap_record_clean_up() { RuntimeOrigin::signed(coldkey), &old_hotkey, &new_hotkey, - Some(netuid) + Some(netuid), + false )); assert_eq!( @@ -1555,35 +1601,844 @@ fn test_swap_owner_check_swap_record_clean_up() { }); } -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey_with_subnet -- test_swap_hotkey_error_cases --exact --nocapture +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::swap_hotkey_with_subnet::test_revert_hotkey_swap_stake_is_not_lost --exact --nocapture +#[test] +fn test_revert_hotkey_swap_stake_is_not_lost() { + new_test_ext(1).execute_with(|| { + let netuid = NetUid::from(1); + let netuid2 = NetUid::from(2); + let tempo: u16 = 13; + let hk1 = U256::from(1); + let hk2 = U256::from(2); + let coldkey = U256::from(3); + let swap_cost = 1_000_000_000u64 * 2; + let stake2 = 1_000_000_000u64; + + // Setup + add_network(netuid, tempo, 0); + add_network(netuid2, tempo, 0); + register_ok_neuron(netuid, hk1, coldkey, 0); + register_ok_neuron(netuid2, hk1, coldkey, 0); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, swap_cost.into()); + + let hk1_stake_before_increase = + SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(&hk1, &coldkey, netuid); + assert!( + hk1_stake_before_increase == 0.into(), + "hk1 should have empty stake" + ); + + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &hk1, + &coldkey, + netuid, + 1_000_000_000u64.into(), + ); + + let hk1_stake_before_swap = + SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(&hk1, &coldkey, netuid); + assert!( + hk1_stake_before_swap == 1_000_000_000.into(), + "hk1 should have stake before swap" + ); + + step_block(20); + + assert_ok!(SubtensorModule::do_swap_hotkey( + <::RuntimeOrigin>::signed(coldkey), + &hk1, + &hk2, + Some(netuid), + false + )); + + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &hk1, + &coldkey, + netuid, + stake2.into(), + ); + + step_block(20); + + let hk2_stake_before_revert = + SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(&hk2, &coldkey, netuid); + let hk1_stake_before_revert = + SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(&hk1, &coldkey, netuid); + + assert_eq!(hk1_stake_before_revert, stake2.into()); + + // Revert: hk2 -> hk1 + assert_ok!(SubtensorModule::do_swap_hotkey( + <::RuntimeOrigin>::signed(coldkey), + &hk2, + &hk1, + Some(netuid), + false + )); + + let hk1_stake_after_revert = + SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(&hk1, &coldkey, netuid); + let hk2_stake_after_revert = + SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(&hk2, &coldkey, netuid); + + assert_eq!( + hk1_stake_after_revert, + hk2_stake_before_revert + stake2.into(), + ); + + // hk2 should be empty + assert_eq!( + hk2_stake_after_revert, + 0.into(), + "hk2 should have no stake after revert" + ); + }); +} + +// Check swap hotkey with keep_stake doesn't affect stake and related storage maps +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::swap_hotkey_with_subnet::test_hotkey_swap_keep_stake --exact --nocapture #[test] -fn test_swap_hotkey_registered_on_other_subnet() { +fn test_hotkey_swap_keep_stake() { new_test_ext(1).execute_with(|| { + let netuid = NetUid::from(1); + let tempo: u16 = 13; let old_hotkey = U256::from(1); let new_hotkey = U256::from(2); + let child_key = U256::from(4); let coldkey = U256::from(3); - let wrong_coldkey = U256::from(4); - let netuid = add_dynamic_network(&old_hotkey, &coldkey); - let other_netuid = add_dynamic_network(&old_hotkey, &coldkey); + let swap_cost = 1_000_000_000u64 * 2; + let stake_amount = 1_000_000_000u64; + let voting_power_value = 5_000_000_000_000_u64; - // Set up initial state - Owner::::insert(old_hotkey, coldkey); - TotalNetworks::::put(1); + // Setup + add_network(netuid, tempo, 0); + register_ok_neuron(netuid, old_hotkey, coldkey, 0); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, swap_cost.into()); - let initial_balance = SubtensorModule::get_key_swap_cost().to_u64() + 1000; - SubtensorModule::add_balance_to_coldkey_account(&coldkey, initial_balance); + VotingPower::::insert(netuid, old_hotkey, voting_power_value); + assert_eq!( + SubtensorModule::get_voting_power(netuid, &old_hotkey), + voting_power_value + ); - // Test new hotkey already registered on other subnet - IsNetworkMember::::insert(new_hotkey, other_netuid, true); - System::set_block_number(System::block_number() + HotkeySwapOnSubnetInterval::get()); - assert_noop!( - SubtensorModule::do_swap_hotkey( - RuntimeOrigin::signed(coldkey), + ChildKeys::::insert(old_hotkey, netuid, vec![(u64::MAX, child_key)]); + ParentKeys::::insert(child_key, netuid, vec![(u64::MAX, old_hotkey)]); + + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &old_hotkey, + &coldkey, + netuid, + stake_amount.into(), + ); + + assert!(SubtensorModule::is_hotkey_registered_on_network( + netuid, + &old_hotkey + )); + + step_block(20); + + let old_hotkey_stake_before_swap = + SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( &old_hotkey, - &new_hotkey, - Some(netuid) - ), - Error::::HotKeyAlreadyRegisteredInSubNet + &coldkey, + netuid, + ); + + assert_ok!(SubtensorModule::do_swap_hotkey( + <::RuntimeOrigin>::signed(coldkey), + &old_hotkey, + &new_hotkey, + Some(netuid), + true + )); + + let old_hotkey_stake_after = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( + &old_hotkey, + &coldkey, + netuid, + ); + assert_eq!( + old_hotkey_stake_after, old_hotkey_stake_before_swap, + "old_hotkey stake must NOT change during keep_stake swap" + ); + + let new_hotkey_stake_after = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( + &new_hotkey, + &coldkey, + netuid, + ); + assert_eq!( + new_hotkey_stake_after, + 0.into(), + "new_hotkey should have no stake" + ); + + assert!( + SubtensorModule::is_hotkey_registered_on_network(netuid, &new_hotkey), + "new_hotkey should be registered on netuid" + ); + + assert!( + !SubtensorModule::is_hotkey_registered_on_network(netuid, &old_hotkey), + "old_hotkey should NOT be registered on netuid after swap" + ); + + let root_total_alpha = TotalHotkeyAlpha::::get(old_hotkey, netuid); + let child_total_alpha = TotalHotkeyAlpha::::get(new_hotkey, netuid); + assert!( + root_total_alpha > 0.into(), + "old_hotkey should retain TotalHotkeyAlpha" + ); + assert_eq!( + child_total_alpha, + 0.into(), + "new_hotkey should have zero TotalHotkeyAlpha" + ); + + let root_voting_power = VotingPower::::get(netuid, old_hotkey); + let child_voting_power = VotingPower::::get(netuid, new_hotkey); + assert!( + root_voting_power > 0, + "old_hotkey should retain VotingPower" + ); + assert_eq!( + child_voting_power, 0, + "new_hotkey should have zero VotingPower" + ); + + let old_hotkey_children = ChildKeys::::get(old_hotkey, netuid); + assert!( + !old_hotkey_children.iter().any(|(_, c)| *c == child_key), + "old_hotkey should NOT retain ChildKeys after swap" + ); + let new_hotkey_children = ChildKeys::::get(new_hotkey, netuid); + assert!( + new_hotkey_children.iter().any(|(_, c)| *c == child_key), + "new_hotkey should inherit ChildKeys from old_hotkey" + ); + + let child_key_parents = ParentKeys::::get(child_key, netuid); + assert!( + child_key_parents.iter().any(|(_, p)| *p == new_hotkey), + "child_key should have new_hotkey as parent after swap" + ); + assert!( + !child_key_parents.iter().any(|(_, p)| *p == old_hotkey), + "child_key should NOT have old_hotkey as parent after swap" + ); + }); +} +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::swap_hotkey_with_subnet::test_revert_hotkey_swap --exact --nocapture +// This test confirms, that the old hotkey can be reverted after the hotkey swap +#[test] +fn test_revert_hotkey_swap() { + new_test_ext(1).execute_with(|| { + let netuid = NetUid::from(1); + let netuid2 = NetUid::from(2); + let tempo: u16 = 13; + let old_hotkey = U256::from(1); + let new_hotkey = U256::from(2); + let coldkey = U256::from(3); + let swap_cost = 1_000_000_000u64 * 2; + + // Setup initial state + add_network(netuid, tempo, 0); + add_network(netuid2, tempo, 0); + register_ok_neuron(netuid, old_hotkey, coldkey, 0); + register_ok_neuron(netuid2, old_hotkey, coldkey, 0); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, swap_cost.into()); + step_block(20); + + // Perform the first swap (only on netuid) + assert_ok!(SubtensorModule::do_swap_hotkey( + <::RuntimeOrigin>::signed(coldkey), + &old_hotkey, + &new_hotkey, + Some(netuid), + false + )); + + assert!(SubtensorModule::is_hotkey_registered_on_any_network( + &old_hotkey + )); + + step_block(20); + + assert_ok!(SubtensorModule::do_swap_hotkey( + <::RuntimeOrigin>::signed(coldkey), + &new_hotkey, + &old_hotkey, + Some(netuid), + false + )); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::swap_hotkey_with_subnet::test_revert_hotkey_swap_parent_hotkey_childkey_maps --exact --nocapture +#[test] +fn test_revert_hotkey_swap_parent_hotkey_childkey_maps() { + new_test_ext(1).execute_with(|| { + let hk1 = U256::from(1); + let coldkey = U256::from(2); + let child = U256::from(3); + let child_other = U256::from(4); + let hk2 = U256::from(5); + + let netuid = add_dynamic_network(&hk1, &coldkey); + let netuid2 = add_dynamic_network(&hk1, &coldkey); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX.into()); + SubtensorModule::create_account_if_non_existent(&coldkey, &hk1); + + mock_set_children(&coldkey, &hk1, netuid, &[(u64::MAX, child)]); + step_rate_limit(&TransactionType::SetChildren, netuid); + mock_schedule_children(&coldkey, &hk1, netuid, &[(u64::MAX, child_other)]); + + assert_eq!( + ParentKeys::::get(child, netuid), + vec![(u64::MAX, hk1)] + ); + assert_eq!(ChildKeys::::get(hk1, netuid), vec![(u64::MAX, child)]); + let existing_pending_child_keys = PendingChildKeys::::get(netuid, hk1); + assert_eq!(existing_pending_child_keys.0, vec![(u64::MAX, child_other)]); + + System::set_block_number(System::block_number() + HotkeySwapOnSubnetInterval::get()); + assert_ok!(SubtensorModule::do_swap_hotkey( + RuntimeOrigin::signed(coldkey), + &hk1, + &hk2, + Some(netuid), + false + )); + + assert_eq!( + ParentKeys::::get(child, netuid), + vec![(u64::MAX, hk2)] + ); + assert_eq!(ChildKeys::::get(hk2, netuid), vec![(u64::MAX, child)]); + assert_eq!( + PendingChildKeys::::get(netuid, hk2), + existing_pending_child_keys + ); + assert!(ChildKeys::::get(hk1, netuid).is_empty()); + assert!(PendingChildKeys::::get(netuid, hk1).0.is_empty()); + + // Revert: hk2 -> hk1 + step_block(20); + assert_ok!(SubtensorModule::do_swap_hotkey( + RuntimeOrigin::signed(coldkey), + &hk2, + &hk1, + Some(netuid), + false + )); + + assert_eq!( + ParentKeys::::get(child, netuid), + vec![(u64::MAX, hk1)], + "ParentKeys must point back to hk1 after revert" + ); + assert_eq!( + ChildKeys::::get(hk1, netuid), + vec![(u64::MAX, child)], + "ChildKeys must be restored to hk1 after revert" + ); + assert_eq!( + PendingChildKeys::::get(netuid, hk1), + existing_pending_child_keys, + "PendingChildKeys must be restored to hk1 after revert" + ); + + assert!( + ChildKeys::::get(hk2, netuid).is_empty(), + "hk2 must have no ChildKeys after revert" + ); + assert!( + PendingChildKeys::::get(netuid, hk2).0.is_empty(), + "hk2 must have no PendingChildKeys after revert" + ); + }) +} +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::swap_hotkey_with_subnet::test_revert_hotkey_swap_uids_and_keys --exact --nocapture +#[test] +fn test_revert_hotkey_swap_uids_and_keys() { + new_test_ext(1).execute_with(|| { + let uid = 5u16; + let hk1 = U256::from(1); + let hk2 = U256::from(2); + let coldkey = U256::from(3); + + let netuid = add_dynamic_network(&hk1, &coldkey); + let netuid2 = add_dynamic_network(&hk1, &coldkey); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX.into()); + + IsNetworkMember::::insert(hk1, netuid, true); + Uids::::insert(netuid, hk1, uid); + Keys::::insert(netuid, uid, hk1); + + System::set_block_number(System::block_number() + HotkeySwapOnSubnetInterval::get()); + assert_ok!(SubtensorModule::do_swap_hotkey( + RuntimeOrigin::signed(coldkey), + &hk1, + &hk2, + Some(netuid), + false + )); + + assert_eq!(Uids::::get(netuid, hk1), None); + assert_eq!(Uids::::get(netuid, hk2), Some(uid)); + assert_eq!(Keys::::get(netuid, uid), hk2); + + // Revert: hk2 -> hk1 + step_block(20); + assert_ok!(SubtensorModule::do_swap_hotkey( + RuntimeOrigin::signed(coldkey), + &hk2, + &hk1, + Some(netuid), + false + )); + + assert_eq!( + Uids::::get(netuid, hk2), + None, + "hk2 must have no uid after revert" + ); + assert_eq!( + Uids::::get(netuid, hk1), + Some(uid), + "hk1 must have its uid restored after revert" + ); + assert_eq!( + Keys::::get(netuid, uid), + hk1, + "Keys must point back to hk1 after revert" + ); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::swap_hotkey_with_subnet::test_revert_hotkey_swap_auto_stake_destination --exact --nocapture +#[test] +fn test_revert_hotkey_swap_auto_stake_destination() { + new_test_ext(1).execute_with(|| { + let hk1 = U256::from(1); + let hk2 = U256::from(2); + let coldkey = U256::from(3); + let netuid = NetUid::from(2u16); + let netuid2 = NetUid::from(3u16); + let staker1 = U256::from(4); + let staker2 = U256::from(5); + let coldkeys = vec![staker1, staker2, coldkey]; + + add_network(netuid, 1, 0); + add_network(netuid2, 1, 0); + register_ok_neuron(netuid, hk1, coldkey, 0); + register_ok_neuron(netuid2, hk1, coldkey, 0); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX.into()); + + AutoStakeDestinationColdkeys::::insert(hk1, netuid, coldkeys.clone()); + AutoStakeDestination::::insert(coldkey, netuid, hk1); + AutoStakeDestination::::insert(staker1, netuid, hk1); + AutoStakeDestination::::insert(staker2, netuid, hk1); + + System::set_block_number(System::block_number() + HotkeySwapOnSubnetInterval::get()); + assert_ok!(SubtensorModule::do_swap_hotkey( + RuntimeOrigin::signed(coldkey), + &hk1, + &hk2, + Some(netuid), + false + )); + + assert_eq!( + AutoStakeDestinationColdkeys::::get(hk2, netuid), + coldkeys + ); + assert!(AutoStakeDestinationColdkeys::::get(hk1, netuid).is_empty()); + assert_eq!( + AutoStakeDestination::::get(coldkey, netuid), + Some(hk2) + ); + assert_eq!( + AutoStakeDestination::::get(staker1, netuid), + Some(hk2) + ); + assert_eq!( + AutoStakeDestination::::get(staker2, netuid), + Some(hk2) + ); + + // Revert: hk2 -> hk1 + step_block(20); + assert_ok!(SubtensorModule::do_swap_hotkey( + RuntimeOrigin::signed(coldkey), + &hk2, + &hk1, + Some(netuid), + false + )); + + assert_eq!( + AutoStakeDestinationColdkeys::::get(hk1, netuid), + coldkeys, + "AutoStakeDestinationColdkeys must be restored to hk1 after revert" + ); + assert!( + AutoStakeDestinationColdkeys::::get(hk2, netuid).is_empty(), + "hk2 must have no AutoStakeDestinationColdkeys after revert" + ); + assert_eq!( + AutoStakeDestination::::get(coldkey, netuid), + Some(hk1), + "coldkey AutoStakeDestination must point back to hk1 after revert" + ); + assert_eq!( + AutoStakeDestination::::get(staker1, netuid), + Some(hk1), + "staker1 AutoStakeDestination must point back to hk1 after revert" + ); + assert_eq!( + AutoStakeDestination::::get(staker2, netuid), + Some(hk1), + "staker2 AutoStakeDestination must point back to hk1 after revert" + ); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::swap_hotkey_with_subnet::test_revert_hotkey_swap_subnet_owner --exact --nocapture +#[test] +fn test_revert_hotkey_swap_subnet_owner() { + new_test_ext(1).execute_with(|| { + let hk1 = U256::from(1); + let hk2 = U256::from(2); + let coldkey = U256::from(3); + + let netuid = add_dynamic_network(&hk1, &coldkey); + let netuid2 = add_dynamic_network(&hk1, &coldkey); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX.into()); + + assert_eq!(SubnetOwnerHotkey::::get(netuid), hk1); + + System::set_block_number(System::block_number() + HotkeySwapOnSubnetInterval::get()); + assert_ok!(SubtensorModule::do_swap_hotkey( + RuntimeOrigin::signed(coldkey), + &hk1, + &hk2, + Some(netuid), + false + )); + + assert_eq!( + SubnetOwnerHotkey::::get(netuid), + hk2, + "hk2 must be subnet owner after swap" + ); + + // Revert: hk2 -> hk1 + step_block(20); + assert_ok!(SubtensorModule::do_swap_hotkey( + RuntimeOrigin::signed(coldkey), + &hk2, + &hk1, + Some(netuid), + false + )); + + assert_eq!( + SubnetOwnerHotkey::::get(netuid), + hk1, + "hk1 must be restored as subnet owner after revert" + ); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::swap_hotkey_with_subnet::test_revert_hotkey_swap_dividends --exact --nocapture +#[test] +fn test_revert_hotkey_swap_dividends() { + new_test_ext(1).execute_with(|| { + let hk1 = U256::from(1); + let hk2 = U256::from(2); + let coldkey = U256::from(3); + + let netuid = add_dynamic_network(&hk1, &coldkey); + let netuid2 = add_dynamic_network(&hk1, &coldkey); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, u64::MAX.into()); + + let amount = 10_000; + let shares = U64F64::from_num(123456); + + TotalHotkeyAlpha::::insert(hk1, netuid, AlphaBalance::from(amount)); + TotalHotkeyAlphaLastEpoch::::insert(hk1, netuid, AlphaBalance::from(amount * 2)); + TotalHotkeyShares::::insert(hk1, netuid, U64F64::from_num(shares)); + Alpha::::insert((hk1, coldkey, netuid), U64F64::from_num(amount)); + AlphaDividendsPerSubnet::::insert(netuid, hk1, AlphaBalance::from(amount)); + + System::set_block_number(System::block_number() + HotkeySwapOnSubnetInterval::get()); + assert_ok!(SubtensorModule::do_swap_hotkey( + RuntimeOrigin::signed(coldkey), + &hk1, + &hk2, + Some(netuid), + false + )); + + assert_eq!( + TotalHotkeyAlpha::::get(hk1, netuid), + AlphaBalance::ZERO + ); + assert_eq!( + TotalHotkeyAlpha::::get(hk2, netuid), + AlphaBalance::from(amount) + ); + assert_eq!( + TotalHotkeyAlphaLastEpoch::::get(hk1, netuid), + AlphaBalance::ZERO + ); + assert_eq!( + TotalHotkeyAlphaLastEpoch::::get(hk2, netuid), + AlphaBalance::from(amount * 2) + ); + assert_eq!( + TotalHotkeyShares::::get(hk1, netuid), + U64F64::from_num(0) + ); + assert_eq!( + TotalHotkeyShares::::get(hk2, netuid), + U64F64::from_num(shares) + ); + assert_eq!( + Alpha::::get((hk1, coldkey, netuid)), + U64F64::from_num(0) + ); + assert_eq!( + Alpha::::get((hk2, coldkey, netuid)), + U64F64::from_num(amount) + ); + assert_eq!( + AlphaDividendsPerSubnet::::get(netuid, hk1), + AlphaBalance::ZERO + ); + assert_eq!( + AlphaDividendsPerSubnet::::get(netuid, hk2), + AlphaBalance::from(amount) + ); + + // Revert: hk2 -> hk1 + step_block(20); + assert_ok!(SubtensorModule::do_swap_hotkey( + RuntimeOrigin::signed(coldkey), + &hk2, + &hk1, + Some(netuid), + false + )); + + assert_eq!( + TotalHotkeyAlpha::::get(hk2, netuid), + AlphaBalance::ZERO, + "hk2 TotalHotkeyAlpha must be zero after revert" + ); + assert_eq!( + TotalHotkeyAlpha::::get(hk1, netuid), + AlphaBalance::from(amount), + "hk1 TotalHotkeyAlpha must be restored after revert" + ); + assert_eq!( + TotalHotkeyAlphaLastEpoch::::get(hk2, netuid), + AlphaBalance::ZERO, + "hk2 TotalHotkeyAlphaLastEpoch must be zero after revert" + ); + assert_eq!( + TotalHotkeyAlphaLastEpoch::::get(hk1, netuid), + AlphaBalance::from(amount * 2), + "hk1 TotalHotkeyAlphaLastEpoch must be restored after revert" + ); + assert_eq!( + TotalHotkeyShares::::get(hk2, netuid), + U64F64::from_num(0), + "hk2 TotalHotkeyShares must be zero after revert" + ); + assert_eq!( + TotalHotkeyShares::::get(hk1, netuid), + U64F64::from_num(shares), + "hk1 TotalHotkeyShares must be restored after revert" + ); + assert_eq!( + Alpha::::get((hk2, coldkey, netuid)), + U64F64::from_num(0), + "hk2 Alpha must be zero after revert" + ); + assert_eq!( + Alpha::::get((hk1, coldkey, netuid)), + U64F64::from_num(amount), + "hk1 Alpha must be restored after revert" + ); + assert_eq!( + AlphaDividendsPerSubnet::::get(netuid, hk2), + AlphaBalance::ZERO, + "hk2 AlphaDividendsPerSubnet must be zero after revert" + ); + assert_eq!( + AlphaDividendsPerSubnet::::get(netuid, hk1), + AlphaBalance::from(amount), + "hk1 AlphaDividendsPerSubnet must be restored after revert" + ); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::swap_hotkey_with_subnet::test_revert_voting_power_transfers_on_hotkey_swap --exact --nocapture +#[test] +fn test_revert_voting_power_transfers_on_hotkey_swap() { + new_test_ext(1).execute_with(|| { + let hk1 = U256::from(1); + let hk2 = U256::from(99); + let coldkey = U256::from(2); + let netuid = add_dynamic_network(&hk1, &coldkey); + let voting_power_value = 5_000_000_000_000_u64; + + VotingPower::::insert(netuid, hk1, voting_power_value); + assert_eq!( + SubtensorModule::get_voting_power(netuid, &hk1), + voting_power_value + ); + assert_eq!(SubtensorModule::get_voting_power(netuid, &hk2), 0); + + SubtensorModule::swap_voting_power_for_hotkey(&hk1, &hk2, netuid); + + assert_eq!(SubtensorModule::get_voting_power(netuid, &hk1), 0); + assert_eq!( + SubtensorModule::get_voting_power(netuid, &hk2), + voting_power_value + ); + + // Revert: hk2 -> hk1 + SubtensorModule::swap_voting_power_for_hotkey(&hk2, &hk1, netuid); + + assert_eq!( + SubtensorModule::get_voting_power(netuid, &hk1), + voting_power_value, + "hk1 voting power must be fully restored after revert" + ); + assert_eq!( + SubtensorModule::get_voting_power(netuid, &hk2), + 0, + "hk2 must have no voting power after revert" + ); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::swap_hotkey_with_subnet::test_revert_claim_root_with_swap_hotkey --exact --nocapture +#[test] +fn test_revert_claim_root_with_swap_hotkey() { + new_test_ext(1).execute_with(|| { + let owner_coldkey = U256::from(1001); + let hk1 = U256::from(1002); + let hk2 = U256::from(1003); + let coldkey = U256::from(1004); + + let netuid = add_dynamic_network(&hk1, &owner_coldkey); + let netuid2 = add_dynamic_network(&hk1, &owner_coldkey); + + SubtensorModule::add_balance_to_coldkey_account(&owner_coldkey, u64::MAX.into()); + SubtensorModule::set_tao_weight(u64::MAX); + + let root_stake = 2_000_000u64; + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &hk1, + &coldkey, + NetUid::ROOT, + root_stake.into(), + ); + + let initial_total_hotkey_alpha = 10_000_000u64; + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &hk1, + &owner_coldkey, + netuid, + initial_total_hotkey_alpha.into(), + ); + + let pending_root_alpha = 1_000_000u64; + SubtensorModule::distribute_emission( + netuid, + AlphaBalance::ZERO, + AlphaBalance::ZERO, + pending_root_alpha.into(), + AlphaBalance::ZERO, + ); + + assert_ok!(SubtensorModule::set_root_claim_type( + RuntimeOrigin::signed(coldkey), + RootClaimTypeEnum::Keep + )); + assert_ok!(SubtensorModule::claim_root( + RuntimeOrigin::signed(coldkey), + BTreeSet::from([netuid]) + )); + + let stake_after_claim: u64 = + SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(&hk1, &coldkey, netuid) + .into(); + + let hk1_root_claimed = RootClaimed::::get((netuid, &hk1, &coldkey)); + let hk1_claimable = *RootClaimable::::get(hk1).get(&netuid).unwrap(); + + assert_eq!(u128::from(stake_after_claim), hk1_root_claimed); + assert!(!RootClaimable::::get(hk2).contains_key(&netuid)); + + System::set_block_number(System::block_number() + HotkeySwapOnSubnetInterval::get()); + assert_ok!(SubtensorModule::do_swap_hotkey( + RuntimeOrigin::signed(owner_coldkey), + &hk1, + &hk2, + Some(netuid), + false + )); + + assert_eq!( + RootClaimed::::get((netuid, &hk1, &coldkey)), + 0u128, + "hk1 RootClaimed must be zero after swap" + ); + assert_eq!( + RootClaimed::::get((netuid, &hk2, &coldkey)), + hk1_root_claimed, + "hk2 must have hk1's RootClaimed after swap" + ); + assert!(!RootClaimable::::get(hk1).contains_key(&netuid)); + assert_eq!( + *RootClaimable::::get(hk2).get(&netuid).unwrap(), + hk1_claimable, + "hk2 must have hk1's RootClaimable after swap" + ); + + // Revert: hk2 -> hk1 + step_block(20); + assert_ok!(SubtensorModule::do_swap_hotkey( + RuntimeOrigin::signed(owner_coldkey), + &hk2, + &hk1, + Some(netuid), + false + )); + + assert_eq!( + RootClaimed::::get((netuid, &hk2, &coldkey)), + 0u128, + "hk2 RootClaimed must be zero after revert" + ); + assert_eq!( + RootClaimed::::get((netuid, &hk1, &coldkey)), + hk1_root_claimed, + "hk1 RootClaimed must be restored after revert" + ); + + assert!(!RootClaimable::::get(hk2).contains_key(&netuid)); + assert_eq!( + *RootClaimable::::get(hk1).get(&netuid).unwrap(), + hk1_claimable, + "hk1 RootClaimable must be restored after revert" ); }); } diff --git a/pallets/subtensor/src/tests/uids.rs b/pallets/subtensor/src/tests/uids.rs index f533fb4aac..9cc74e5286 100644 --- a/pallets/subtensor/src/tests/uids.rs +++ b/pallets/subtensor/src/tests/uids.rs @@ -5,7 +5,7 @@ use crate::*; use frame_support::{assert_err, assert_ok}; use frame_system::Config; use sp_core::{H160, U256}; -use subtensor_runtime_common::{AlphaCurrency, NetUidStorageIndex}; +use subtensor_runtime_common::{AlphaBalance, NetUidStorageIndex}; /******************************************** tests for uids.rs file @@ -109,7 +109,7 @@ fn test_replace_neuron() { assert_eq!(SubtensorModule::get_trust_for_uid(netuid, neuron_uid), 0); assert_eq!( SubtensorModule::get_emission_for_uid(netuid, neuron_uid), - AlphaCurrency::ZERO + AlphaBalance::ZERO ); assert_eq!( SubtensorModule::get_consensus_for_uid(netuid, neuron_uid), diff --git a/pallets/subtensor/src/tests/voting_power.rs b/pallets/subtensor/src/tests/voting_power.rs index 63418fb6a9..3ffb1a6611 100644 --- a/pallets/subtensor/src/tests/voting_power.rs +++ b/pallets/subtensor/src/tests/voting_power.rs @@ -77,7 +77,7 @@ impl VotingPowerTestFixture { #[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); + SubtensorModule::add_balance_to_coldkey_account(&self.coldkey, (amount * 10).into()); } /// Enable voting power tracking for the subnet @@ -401,7 +401,10 @@ fn test_only_validators_get_voting_power() { (DEFAULT_STAKE_AMOUNT * 100).into(), (DEFAULT_STAKE_AMOUNT * 100).into(), ); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, DEFAULT_STAKE_AMOUNT * 20); + SubtensorModule::add_balance_to_coldkey_account( + &coldkey, + (DEFAULT_STAKE_AMOUNT * 20).into(), + ); // Register miner register_ok_neuron(netuid, miner_hotkey, coldkey, 0); diff --git a/pallets/subtensor/src/tests/weights.rs b/pallets/subtensor/src/tests/weights.rs index 2c64b23d32..13baf63a8b 100644 --- a/pallets/subtensor/src/tests/weights.rs +++ b/pallets/subtensor/src/tests/weights.rs @@ -21,7 +21,7 @@ use sp_runtime::{ }; use sp_std::collections::vec_deque::VecDeque; use substrate_fixed::types::I32F32; -use subtensor_runtime_common::{NetUidStorageIndex, TaoCurrency}; +use subtensor_runtime_common::{CustomTransactionError, NetUidStorageIndex, TaoBalance}; use subtensor_swap_interface::SwapHandler; use tle::{ curves::drand::TinyBLS381, @@ -119,9 +119,9 @@ fn test_commit_weights_validate() { SubtensorModule::append_neuron(netuid, &hotkey, 0); crate::Owner::::insert(hotkey, coldkey); - SubtensorModule::add_balance_to_coldkey_account(&hotkey, u64::MAX); + SubtensorModule::add_balance_to_coldkey_account(&hotkey, u64::MAX.into()); - let min_stake = 500_000_000_000; + let min_stake = 500_000_000_000_u64; let reserve = min_stake * 1000; mock::setup_reserves(netuid, reserve.into(), reserve.into()); @@ -246,14 +246,18 @@ fn test_set_weights_validate() { // Create netuid add_network(netuid, 1, 0); - mock::setup_reserves(netuid, 1_000_000_000_000.into(), 1_000_000_000_000.into()); + mock::setup_reserves( + netuid, + 1_000_000_000_000_u64.into(), + 1_000_000_000_000_u64.into(), + ); // Register the hotkey SubtensorModule::append_neuron(netuid, &hotkey, 0); crate::Owner::::insert(hotkey, coldkey); - SubtensorModule::add_balance_to_coldkey_account(&hotkey, u64::MAX); + SubtensorModule::add_balance_to_coldkey_account(&hotkey, u64::MAX.into()); - let min_stake = TaoCurrency::from(500_000_000_000); + let min_stake = TaoBalance::from(500_000_000_000_u64); // Set the minimum stake SubtensorModule::set_stake_threshold(min_stake.into()); @@ -357,9 +361,9 @@ fn test_reveal_weights_validate() { SubtensorModule::append_neuron(netuid, &hotkey2, 0); crate::Owner::::insert(hotkey, coldkey); crate::Owner::::insert(hotkey2, coldkey); - SubtensorModule::add_balance_to_coldkey_account(&hotkey, u64::MAX); + SubtensorModule::add_balance_to_coldkey_account(&hotkey, u64::MAX.into()); - let min_stake = TaoCurrency::from(500_000_000_000); + let min_stake = TaoBalance::from(500_000_000_000_u64); // Set the minimum stake SubtensorModule::set_stake_threshold(min_stake.into()); @@ -540,10 +544,10 @@ fn test_batch_reveal_weights_validate() { SubtensorModule::append_neuron(netuid, &hotkey2, 0); crate::Owner::::insert(hotkey, coldkey); crate::Owner::::insert(hotkey2, coldkey); - SubtensorModule::add_balance_to_coldkey_account(&hotkey, u64::MAX); + SubtensorModule::add_balance_to_coldkey_account(&hotkey, u64::MAX.into()); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); - let min_stake = TaoCurrency::from(500_000_000_000); + let min_stake = TaoBalance::from(500_000_000_000_u64); // Set the minimum stake SubtensorModule::set_stake_threshold(min_stake.into()); @@ -778,7 +782,7 @@ fn test_set_stake_threshold_failed() { add_network_disable_commit_reveal(netuid, 1, 0); register_ok_neuron(netuid, hotkey, coldkey, 2143124); SubtensorModule::set_stake_threshold(20_000_000_000_000); - SubtensorModule::add_balance_to_coldkey_account(&hotkey, u64::MAX); + SubtensorModule::add_balance_to_coldkey_account(&hotkey, u64::MAX.into()); // Check the signed extension function. assert_eq!(SubtensorModule::get_stake_threshold(), 20_000_000_000_000); @@ -787,14 +791,14 @@ fn test_set_stake_threshold_failed() { RuntimeOrigin::signed(hotkey), hotkey, netuid, - 19_000_000_000_000.into() + 19_000_000_000_000_u64.into() )); assert!(!SubtensorModule::check_weights_min_stake(&hotkey, netuid)); assert_ok!(SubtensorModule::do_add_stake( RuntimeOrigin::signed(hotkey), hotkey, netuid, - 20_000_000_000_000.into() + 20_000_000_000_000_u64.into() )); assert!(SubtensorModule::check_weights_min_stake(&hotkey, netuid)); @@ -815,7 +819,7 @@ fn test_set_stake_threshold_failed() { RuntimeOrigin::signed(hotkey), hotkey, netuid, - 100_000_000_000_000.into() + 100_000_000_000_000_u64.into() )); assert_ok!(SubtensorModule::set_weights( RuntimeOrigin::signed(hotkey), @@ -924,7 +928,7 @@ fn test_weights_err_setting_weights_too_fast() { SubtensorModule::get_uid_for_net_and_hotkey(netuid, &hotkey_account_id) .expect("Not registered."); SubtensorModule::set_validator_permit_for_uid(netuid, neuron_uid, true); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(66), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(66), 1.into()); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &hotkey_account_id, &(U256::from(66)), @@ -1017,7 +1021,7 @@ fn test_weights_err_has_duplicate_ids() { SubtensorModule::get_uid_for_net_and_hotkey(netuid, &hotkey_account_id) .expect("Not registered."); SubtensorModule::set_validator_permit_for_uid(netuid, neuron_uid, true); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(77), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(77), 1.into()); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &hotkey_account_id, &(U256::from(77)), @@ -1120,7 +1124,7 @@ fn test_set_weights_err_invalid_uid() { .expect("Not registered."); SubtensorModule::set_stake_threshold(0); SubtensorModule::set_validator_permit_for_uid(netuid, neuron_uid, true); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(66), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(66), 1.into()); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &hotkey_account_id, &(U256::from(66)), @@ -1156,7 +1160,7 @@ fn test_set_weight_not_enough_values() { let neuron_uid: u16 = SubtensorModule::get_uid_for_net_and_hotkey(netuid, &U256::from(1)) .expect("Not registered."); SubtensorModule::set_validator_permit_for_uid(netuid, neuron_uid, true); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(2), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(2), 1.into()); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &account_id, &(U256::from(2)), @@ -1264,7 +1268,7 @@ fn test_set_weights_sum_larger_than_u16_max() { .expect("Not registered."); SubtensorModule::set_stake_threshold(0); SubtensorModule::set_validator_permit_for_uid(netuid, neuron_uid, true); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(2), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(2), 1.into()); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &(U256::from(1)), &(U256::from(2)), @@ -1727,8 +1731,8 @@ fn test_commit_reveal_weights_ok() { SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1.into()); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1.into()); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &(U256::from(0)), &(U256::from(0)), @@ -1795,8 +1799,8 @@ fn test_commit_reveal_tempo_interval() { SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1.into()); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1.into()); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &(U256::from(0)), &(U256::from(0)), @@ -1930,8 +1934,8 @@ fn test_commit_reveal_hash() { SubtensorModule::set_weights_set_rate_limit(netuid, 5); SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1.into()); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1.into()); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &(U256::from(0)), &(U256::from(0)), @@ -2030,8 +2034,8 @@ fn test_commit_reveal_disabled_or_enabled() { SubtensorModule::set_weights_set_rate_limit(netuid, 5); SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1.into()); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1.into()); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &(U256::from(0)), &(U256::from(0)), @@ -2107,8 +2111,8 @@ fn test_toggle_commit_reveal_weights_and_set_weights() { SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); SubtensorModule::set_weights_set_rate_limit(netuid, 5); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1.into()); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1.into()); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &(U256::from(0)), &(U256::from(0)), @@ -2193,8 +2197,8 @@ fn test_tempo_change_during_commit_reveal_process() { SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1.into()); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1.into()); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &(U256::from(0)), &(U256::from(0)), @@ -2342,8 +2346,8 @@ fn test_commit_reveal_multiple_commits() { SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1.into()); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1.into()); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &(U256::from(0)), &(U256::from(0)), @@ -2748,8 +2752,8 @@ fn test_expired_commits_handling_in_commit_and_reveal() { SubtensorModule::set_stake_threshold(0); SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1.into()); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1.into()); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &(U256::from(0)), &(U256::from(0)), @@ -2947,8 +2951,8 @@ fn test_reveal_at_exact_epoch() { SubtensorModule::set_stake_threshold(0); SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1.into()); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1.into()); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &(U256::from(0)), &(U256::from(0)), @@ -3111,8 +3115,8 @@ fn test_tempo_and_reveal_period_change_during_commit_reveal_process() { SubtensorModule::set_stake_threshold(0); SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1.into()); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1.into()); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &(U256::from(0)), &(U256::from(0)), @@ -3298,8 +3302,8 @@ fn test_commit_reveal_order_enforcement() { SubtensorModule::set_stake_threshold(0); SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1.into()); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1.into()); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &(U256::from(0)), &(U256::from(0)), @@ -3557,8 +3561,8 @@ fn test_successful_batch_reveal() { SubtensorModule::set_stake_threshold(0); SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1.into()); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1.into()); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &(U256::from(0)), &(U256::from(0)), @@ -3635,8 +3639,8 @@ fn test_batch_reveal_with_expired_commits() { SubtensorModule::set_stake_threshold(0); SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1.into()); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1.into()); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &(U256::from(0)), &(U256::from(0)), @@ -4052,8 +4056,8 @@ fn test_batch_reveal_with_out_of_order_commits() { SubtensorModule::set_stake_threshold(0); SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1.into()); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1.into()); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &(U256::from(0)), &(U256::from(0)), @@ -4453,8 +4457,8 @@ fn test_get_reveal_blocks() { SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1.into()); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1.into()); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &(U256::from(0)), &(U256::from(0)), @@ -4587,8 +4591,8 @@ fn test_commit_weights_rate_limit() { SubtensorModule::set_validator_permit_for_uid(netuid, 0, true); SubtensorModule::set_validator_permit_for_uid(netuid, 1, true); SubtensorModule::set_commit_reveal_weights_enabled(netuid, true); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(0), 1.into()); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 1.into()); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &(U256::from(0)), &(U256::from(0)), @@ -4775,8 +4779,8 @@ fn test_reveal_crv3_commits_success() { SubtensorModule::set_validator_permit_for_uid(netuid, neuron_uid1, true); SubtensorModule::set_validator_permit_for_uid(netuid, neuron_uid2, true); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(3), 1); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(4), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(3), 1.into()); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(4), 1.into()); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &hotkey1, &(U256::from(3)), @@ -6034,7 +6038,7 @@ fn test_reveal_crv3_commits_multiple_valid_commits_all_processed() { SubtensorModule::set_validator_permit_for_uid(netuid, i as u16, true); // add minimal stake so `do_set_weights` will succeed - SubtensorModule::add_balance_to_coldkey_account(&cold, 1); + SubtensorModule::add_balance_to_coldkey_account(&cold, 1.into()); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( hk, &cold, @@ -6132,7 +6136,7 @@ fn test_reveal_crv3_commits_max_neurons() { SubtensorModule::set_validator_permit_for_uid(netuid, i, true); // give each neuron a nominal stake (safe even if not needed) - SubtensorModule::add_balance_to_coldkey_account(&cold, 1); + SubtensorModule::add_balance_to_coldkey_account(&cold, 1.into()); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &hk, &cold, @@ -6354,8 +6358,8 @@ fn test_reveal_crv3_commits_hotkey_check() { SubtensorModule::set_validator_permit_for_uid(netuid, neuron_uid1, true); SubtensorModule::set_validator_permit_for_uid(netuid, neuron_uid2, true); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(3), 1); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(4), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(3), 1.into()); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(4), 1.into()); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &hotkey1, &(U256::from(3)), @@ -6471,8 +6475,8 @@ fn test_reveal_crv3_commits_hotkey_check() { SubtensorModule::set_validator_permit_for_uid(netuid, neuron_uid1, true); SubtensorModule::set_validator_permit_for_uid(netuid, neuron_uid2, true); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(3), 1); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(4), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(3), 1.into()); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(4), 1.into()); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &hotkey1, &(U256::from(3)), @@ -6737,8 +6741,8 @@ fn test_reveal_crv3_commits_legacy_payload_success() { SubtensorModule::set_validator_permit_for_uid(netuid, uid1, true); SubtensorModule::set_validator_permit_for_uid(netuid, uid2, true); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(3), 1); - SubtensorModule::add_balance_to_coldkey_account(&U256::from(4), 1); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(3), 1.into()); + SubtensorModule::add_balance_to_coldkey_account(&U256::from(4), 1.into()); SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &hotkey1, &U256::from(3), diff --git a/pallets/subtensor/src/utils/evm.rs b/pallets/subtensor/src/utils/evm.rs index 88f856b25e..3363a9ade5 100644 --- a/pallets/subtensor/src/utils/evm.rs +++ b/pallets/subtensor/src/utils/evm.rs @@ -64,7 +64,11 @@ impl Pallet { Self::ensure_evm_key_associate_rate_limit(netuid, uid)?; let block_hash = keccak_256(block_number.encode().as_ref()); - let message = [hotkey.encode().as_ref(), block_hash.as_ref()].concat(); + let message = [ + hotkey.encode().as_ref(), + <[u8; 32] as AsRef<[u8]>>::as_ref(&block_hash), + ] + .concat(); let public = signature .recover_prehashed(&Self::hash_message_eip191(message)) .ok_or(Error::::InvalidIdentity)?; diff --git a/pallets/subtensor/src/utils/misc.rs b/pallets/subtensor/src/utils/misc.rs index 609e43cf63..75f2d6695d 100644 --- a/pallets/subtensor/src/utils/misc.rs +++ b/pallets/subtensor/src/utils/misc.rs @@ -6,7 +6,7 @@ use sp_core::Get; use sp_core::U256; use sp_runtime::Saturating; use substrate_fixed::types::{I32F32, I64F64, U64F64, U96F32}; -use subtensor_runtime_common::{AlphaCurrency, NetUid, NetUidStorageIndex, TaoCurrency}; +use subtensor_runtime_common::{AlphaBalance, NetUid, NetUidStorageIndex, TaoBalance}; impl Pallet { pub fn ensure_subnet_owner_or_root( @@ -137,7 +137,7 @@ impl Pallet { // ======================== // ==== Global Getters ==== // ======================== - pub fn get_total_issuance() -> TaoCurrency { + pub fn get_total_issuance() -> TaoBalance { TotalIssuance::::get() } pub fn get_current_block_as_u64() -> u64 { @@ -158,7 +158,7 @@ impl Pallet { pub fn get_active(netuid: NetUid) -> Vec { Active::::get(netuid) } - pub fn get_emission(netuid: NetUid) -> Vec { + pub fn get_emission(netuid: NetUid) -> Vec { Emission::::get(netuid) } pub fn get_consensus(netuid: NetUid) -> Vec { @@ -231,7 +231,7 @@ impl Pallet { let vec = Trust::::get(netuid); vec.get(uid as usize).copied().unwrap_or(0) } - pub fn get_emission_for_uid(netuid: NetUid, uid: u16) -> AlphaCurrency { + pub fn get_emission_for_uid(netuid: NetUid, uid: u16) -> AlphaBalance { let vec = Emission::::get(netuid); vec.get(uid as usize).copied().unwrap_or_default() } @@ -337,20 +337,20 @@ impl Pallet { // ======================== // === Token Management === // ======================== - pub fn recycle_tao(amount: TaoCurrency) { + pub fn recycle_tao(amount: TaoBalance) { TotalIssuance::::put(TotalIssuance::::get().saturating_sub(amount)); } - pub fn increase_issuance(amount: TaoCurrency) { + pub fn increase_issuance(amount: TaoBalance) { TotalIssuance::::put(TotalIssuance::::get().saturating_add(amount)); } - pub fn set_subnet_locked_balance(netuid: NetUid, amount: TaoCurrency) { + pub fn set_subnet_locked_balance(netuid: NetUid, amount: TaoBalance) { SubnetLocked::::insert(netuid, amount); } - pub fn get_subnet_locked_balance(netuid: NetUid) -> TaoCurrency { + pub fn get_subnet_locked_balance(netuid: NetUid) -> TaoBalance { SubnetLocked::::get(netuid) } - pub fn get_total_subnet_locked() -> TaoCurrency { + pub fn get_total_subnet_locked() -> TaoBalance { let mut total_subnet_locked: u64 = 0; for (_, locked) in SubnetLocked::::iter() { total_subnet_locked.saturating_accrue(locked.into()); @@ -610,25 +610,25 @@ impl Pallet { )); } - pub fn get_burn(netuid: NetUid) -> TaoCurrency { + pub fn get_burn(netuid: NetUid) -> TaoBalance { Burn::::get(netuid) } - pub fn set_burn(netuid: NetUid, burn: TaoCurrency) { + pub fn set_burn(netuid: NetUid, burn: TaoBalance) { Burn::::insert(netuid, burn); } - pub fn get_min_burn(netuid: NetUid) -> TaoCurrency { + pub fn get_min_burn(netuid: NetUid) -> TaoBalance { MinBurn::::get(netuid) } - pub fn set_min_burn(netuid: NetUid, min_burn: TaoCurrency) { + pub fn set_min_burn(netuid: NetUid, min_burn: TaoBalance) { MinBurn::::insert(netuid, min_burn); Self::deposit_event(Event::MinBurnSet(netuid, min_burn)); } - pub fn get_max_burn(netuid: NetUid) -> TaoCurrency { + pub fn get_max_burn(netuid: NetUid) -> TaoBalance { MaxBurn::::get(netuid) } - pub fn set_max_burn(netuid: NetUid, max_burn: TaoCurrency) { + pub fn set_max_burn(netuid: NetUid, max_burn: TaoBalance) { MaxBurn::::insert(netuid, max_burn); Self::deposit_event(Event::MaxBurnSet(netuid, max_burn)); } @@ -709,18 +709,18 @@ impl Pallet { StakingHotkeys::::get(coldkey) } - pub fn set_total_issuance(total_issuance: TaoCurrency) { + pub fn set_total_issuance(total_issuance: TaoBalance) { TotalIssuance::::put(total_issuance); } - pub fn get_rao_recycled(netuid: NetUid) -> TaoCurrency { + pub fn get_rao_recycled(netuid: NetUid) -> TaoBalance { RAORecycledForRegistration::::get(netuid) } - pub fn set_rao_recycled(netuid: NetUid, rao_recycled: TaoCurrency) { + pub fn set_rao_recycled(netuid: NetUid, rao_recycled: TaoBalance) { RAORecycledForRegistration::::insert(netuid, rao_recycled); Self::deposit_event(Event::RAORecycledForRegistrationSet(netuid, rao_recycled)); } - pub fn increase_rao_recycled(netuid: NetUid, inc_rao_recycled: TaoCurrency) { + pub fn increase_rao_recycled(netuid: NetUid, inc_rao_recycled: TaoBalance) { let curr_rao_recycled = Self::get_rao_recycled(netuid); let rao_recycled = curr_rao_recycled.saturating_add(inc_rao_recycled); Self::set_rao_recycled(netuid, rao_recycled); @@ -750,7 +750,7 @@ impl Pallet { NominatorMinRequiredStake::::put(min_stake); } - pub fn get_key_swap_cost() -> TaoCurrency { + pub fn get_key_swap_cost() -> TaoBalance { T::KeySwapCost::get().into() } diff --git a/pallets/subtensor/src/utils/try_state.rs b/pallets/subtensor/src/utils/try_state.rs index ad5a8e9dc8..576c3c7951 100644 --- a/pallets/subtensor/src/utils/try_state.rs +++ b/pallets/subtensor/src/utils/try_state.rs @@ -18,13 +18,13 @@ impl Pallet { // // These values can be off slightly due to float rounding errors. // They are corrected every runtime upgrade. - let delta = 1000; - let total_issuance = TotalIssuance::::get().to_u64(); + let delta = TaoBalance::from(1000); + let total_issuance = TotalIssuance::::get(); let diff = if total_issuance > expected_total_issuance { - total_issuance.checked_sub(expected_total_issuance) + total_issuance.checked_sub(&expected_total_issuance) } else { - expected_total_issuance.checked_sub(total_issuance) + expected_total_issuance.checked_sub(&total_issuance) } .expect("LHS > RHS"); @@ -40,17 +40,16 @@ impl Pallet { #[allow(dead_code)] pub(crate) fn check_total_stake() -> Result<(), sp_runtime::TryRuntimeError> { // Calculate the total staked amount - let total_staked = - SubnetTAO::::iter().fold(TaoCurrency::ZERO, |acc, (netuid, stake)| { - let acc = acc.saturating_add(stake); + let total_staked = SubnetTAO::::iter().fold(TaoBalance::ZERO, |acc, (netuid, stake)| { + let acc = acc.saturating_add(stake); - if netuid.is_root() { - // root network doesn't have initial pool TAO - acc - } else { - acc.saturating_sub(Self::get_network_min_lock()) - } - }); + if netuid.is_root() { + // root network doesn't have initial pool TAO + acc + } else { + acc.saturating_sub(Self::get_network_min_lock()) + } + }); log::warn!( "total_staked: {}, TotalStake: {}", diff --git a/pallets/subtensor/src/utils/voting_power.rs b/pallets/subtensor/src/utils/voting_power.rs index 55437f8885..0cb191436e 100644 --- a/pallets/subtensor/src/utils/voting_power.rs +++ b/pallets/subtensor/src/utils/voting_power.rs @@ -1,7 +1,7 @@ use super::*; use crate::epoch::run_epoch::EpochTerms; use alloc::collections::BTreeMap; -use subtensor_runtime_common::{AlphaCurrency, NetUid}; +use subtensor_runtime_common::{AlphaBalance, NetUid}; /// 14 days in blocks (assuming ~12 second blocks) /// 14 * 24 * 60 * 60 / 12 = 100800 blocks @@ -182,7 +182,7 @@ impl Pallet { fn update_voting_power_for_hotkey( netuid: NetUid, hotkey: &T::AccountId, - current_stake: AlphaCurrency, + current_stake: AlphaBalance, alpha: u64, min_stake: u64, ) { diff --git a/pallets/swap-interface/src/lib.rs b/pallets/swap-interface/src/lib.rs index 76e149b4b7..9fbeefd3b6 100644 --- a/pallets/swap-interface/src/lib.rs +++ b/pallets/swap-interface/src/lib.rs @@ -4,7 +4,7 @@ use core::ops::Neg; use frame_support::pallet_prelude::*; use substrate_fixed::types::U96F32; use subtensor_macros::freeze_struct; -use subtensor_runtime_common::{AlphaCurrency, Currency, NetUid, TaoCurrency}; +use subtensor_runtime_common::{AlphaBalance, NetUid, TaoBalance, Token}; pub use order::*; @@ -14,7 +14,7 @@ pub trait SwapEngine: DefaultPriceLimit { fn swap( netuid: NetUid, order: O, - price_limit: TaoCurrency, + price_limit: TaoBalance, drop_fees: bool, should_rollback: bool, ) -> Result, DispatchError>; @@ -24,7 +24,7 @@ pub trait SwapHandler { fn swap( netuid: NetUid, order: O, - price_limit: TaoCurrency, + price_limit: TaoBalance, drop_fees: bool, should_rollback: bool, ) -> Result, DispatchError> @@ -37,16 +37,12 @@ pub trait SwapHandler { where Self: SwapEngine; - fn approx_fee_amount(netuid: NetUid, amount: T) -> T; + fn approx_fee_amount(netuid: NetUid, amount: T) -> T; fn current_alpha_price(netuid: NetUid) -> U96F32; - fn get_protocol_tao(netuid: NetUid) -> TaoCurrency; - fn max_price() -> C; - fn min_price() -> C; - fn adjust_protocol_liquidity( - netuid: NetUid, - tao_delta: TaoCurrency, - alpha_delta: AlphaCurrency, - ); + fn get_protocol_tao(netuid: NetUid) -> TaoBalance; + fn max_price() -> C; + fn min_price() -> C; + fn adjust_protocol_liquidity(netuid: NetUid, tao_delta: TaoBalance, alpha_delta: AlphaBalance); fn is_user_liquidity_enabled(netuid: NetUid) -> bool; fn dissolve_all_liquidity_providers(netuid: NetUid) -> DispatchResult; fn toggle_user_liquidity(netuid: NetUid, enabled: bool); @@ -55,19 +51,19 @@ pub trait SwapHandler { pub trait DefaultPriceLimit where - PaidIn: Currency, - PaidOut: Currency, + PaidIn: Token, + PaidOut: Token, { - fn default_price_limit() -> C; + fn default_price_limit() -> C; } /// Externally used swap result (for RPC) -#[freeze_struct("58ff42da64adce1a")] +#[freeze_struct("6a03533fc53ccfb8")] #[derive(Decode, Encode, PartialEq, Eq, Clone, Debug, TypeInfo)] pub struct SwapResult where - PaidIn: Currency, - PaidOut: Currency, + PaidIn: Token, + PaidOut: Token, { pub amount_paid_in: PaidIn, pub amount_paid_out: PaidOut, @@ -77,8 +73,8 @@ where impl SwapResult where - PaidIn: Currency, - PaidOut: Currency, + PaidIn: Token, + PaidOut: Token, { pub fn paid_in_reserve_delta(&self) -> i128 { self.amount_paid_in.to_u64() as i128 diff --git a/pallets/swap-interface/src/order.rs b/pallets/swap-interface/src/order.rs index 1576283fd5..b4075e9781 100644 --- a/pallets/swap-interface/src/order.rs +++ b/pallets/swap-interface/src/order.rs @@ -1,13 +1,13 @@ use core::marker::PhantomData; use substrate_fixed::types::U64F64; -use subtensor_runtime_common::{AlphaCurrency, Currency, CurrencyReserve, TaoCurrency}; +use subtensor_runtime_common::{AlphaBalance, TaoBalance, Token, TokenReserve}; pub trait Order: Clone { - type PaidIn: Currency; - type PaidOut: Currency; - type ReserveIn: CurrencyReserve; - type ReserveOut: CurrencyReserve; + type PaidIn: Token; + type PaidOut: Token; + type ReserveIn: TokenReserve; + type ReserveOut: TokenReserve; fn with_amount(amount: impl Into) -> Self; fn amount(&self) -> Self::PaidIn; @@ -17,20 +17,20 @@ pub trait Order: Clone { #[derive(Clone, Default)] pub struct GetAlphaForTao where - ReserveIn: CurrencyReserve, - ReserveOut: CurrencyReserve, + ReserveIn: TokenReserve, + ReserveOut: TokenReserve, { - amount: TaoCurrency, + amount: TaoBalance, _phantom: PhantomData<(ReserveIn, ReserveOut)>, } impl Order for GetAlphaForTao where - ReserveIn: CurrencyReserve + Clone, - ReserveOut: CurrencyReserve + Clone, + ReserveIn: TokenReserve + Clone, + ReserveOut: TokenReserve + Clone, { - type PaidIn = TaoCurrency; - type PaidOut = AlphaCurrency; + type PaidIn = TaoBalance; + type PaidOut = AlphaBalance; type ReserveIn = ReserveIn; type ReserveOut = ReserveOut; @@ -41,7 +41,7 @@ where } } - fn amount(&self) -> TaoCurrency { + fn amount(&self) -> TaoBalance { self.amount } @@ -53,20 +53,20 @@ where #[derive(Clone, Default)] pub struct GetTaoForAlpha where - ReserveIn: CurrencyReserve, - ReserveOut: CurrencyReserve, + ReserveIn: TokenReserve, + ReserveOut: TokenReserve, { - amount: AlphaCurrency, + amount: AlphaBalance, _phantom: PhantomData<(ReserveIn, ReserveOut)>, } impl Order for GetTaoForAlpha where - ReserveIn: CurrencyReserve + Clone, - ReserveOut: CurrencyReserve + Clone, + ReserveIn: TokenReserve + Clone, + ReserveOut: TokenReserve + Clone, { - type PaidIn = AlphaCurrency; - type PaidOut = TaoCurrency; + type PaidIn = AlphaBalance; + type PaidOut = TaoBalance; type ReserveIn = ReserveIn; type ReserveOut = ReserveOut; @@ -77,7 +77,7 @@ where } } - fn amount(&self) -> AlphaCurrency { + fn amount(&self) -> AlphaBalance { self.amount } diff --git a/pallets/swap/Cargo.toml b/pallets/swap/Cargo.toml index 7de8e49c1d..c50d1d4f78 100644 --- a/pallets/swap/Cargo.toml +++ b/pallets/swap/Cargo.toml @@ -60,4 +60,5 @@ runtime-benchmarks = [ "frame-support/runtime-benchmarks", "frame-system/runtime-benchmarks", "sp-runtime/runtime-benchmarks", + "subtensor-runtime-common/runtime-benchmarks", ] diff --git a/pallets/swap/rpc/src/lib.rs b/pallets/swap/rpc/src/lib.rs index b83a083ad5..b4a8d6a7a0 100644 --- a/pallets/swap/rpc/src/lib.rs +++ b/pallets/swap/rpc/src/lib.rs @@ -11,7 +11,7 @@ use jsonrpsee::{ use sp_api::ProvideRuntimeApi; use sp_blockchain::HeaderBackend; use sp_runtime::traits::Block as BlockT; -use subtensor_runtime_common::{AlphaCurrency, NetUid, TaoCurrency}; +use subtensor_runtime_common::{AlphaBalance, NetUid, TaoBalance}; pub use pallet_subtensor_swap_runtime_api::SwapRuntimeApi; @@ -23,14 +23,14 @@ pub trait SwapRpcApi { fn sim_swap_tao_for_alpha( &self, netuid: NetUid, - tao: TaoCurrency, + tao: TaoBalance, at: Option, ) -> RpcResult>; #[method(name = "swap_simSwapAlphaForTao")] fn sim_swap_alpha_for_tao( &self, netuid: NetUid, - alpha: AlphaCurrency, + alpha: AlphaBalance, at: Option, ) -> RpcResult>; } @@ -95,7 +95,7 @@ where fn sim_swap_tao_for_alpha( &self, netuid: NetUid, - tao: TaoCurrency, + tao: TaoBalance, at: Option<::Hash>, ) -> RpcResult> { let api = self.client.runtime_api(); @@ -113,7 +113,7 @@ where fn sim_swap_alpha_for_tao( &self, netuid: NetUid, - alpha: AlphaCurrency, + alpha: AlphaBalance, at: Option<::Hash>, ) -> RpcResult> { let api = self.client.runtime_api(); diff --git a/pallets/swap/runtime-api/src/lib.rs b/pallets/swap/runtime-api/src/lib.rs index 01d2ccf23e..0433793efb 100644 --- a/pallets/swap/runtime-api/src/lib.rs +++ b/pallets/swap/runtime-api/src/lib.rs @@ -1,22 +1,33 @@ #![cfg_attr(not(feature = "std"), no_std)] use frame_support::pallet_prelude::*; +use sp_std::vec::Vec; use subtensor_macros::freeze_struct; -use subtensor_runtime_common::{AlphaCurrency, NetUid, TaoCurrency}; +use subtensor_runtime_common::{AlphaBalance, NetUid, TaoBalance}; -#[freeze_struct("3a4fd213b5de5eb6")] +#[freeze_struct("8e70f7cc0b118c6")] #[derive(Decode, Encode, PartialEq, Eq, Clone, Debug, TypeInfo)] pub struct SimSwapResult { - pub tao_amount: TaoCurrency, - pub alpha_amount: AlphaCurrency, - pub tao_fee: TaoCurrency, - pub alpha_fee: AlphaCurrency, + pub tao_amount: TaoBalance, + pub alpha_amount: AlphaBalance, + pub tao_fee: TaoBalance, + pub alpha_fee: AlphaBalance, + pub tao_slippage: TaoBalance, + pub alpha_slippage: AlphaBalance, +} + +#[freeze_struct("423384310ac5e2f7")] +#[derive(Decode, Encode, PartialEq, Eq, Clone, Debug, TypeInfo)] +pub struct SubnetPrice { + pub netuid: NetUid, + pub price: u64, } sp_api::decl_runtime_apis! { pub trait SwapRuntimeApi { fn current_alpha_price(netuid: NetUid) -> u64; - fn sim_swap_tao_for_alpha(netuid: NetUid, tao: TaoCurrency) -> SimSwapResult; - fn sim_swap_alpha_for_tao(netuid: NetUid, alpha: AlphaCurrency) -> SimSwapResult; + fn current_alpha_price_all() -> Vec; + fn sim_swap_tao_for_alpha(netuid: NetUid, tao: TaoBalance) -> SimSwapResult; + fn sim_swap_alpha_for_tao(netuid: NetUid, alpha: AlphaBalance) -> SimSwapResult; } } diff --git a/pallets/swap/src/mock.rs b/pallets/swap/src/mock.rs index bb671e4762..b12fd4d567 100644 --- a/pallets/swap/src/mock.rs +++ b/pallets/swap/src/mock.rs @@ -9,14 +9,16 @@ use frame_support::{ }; use frame_support::{construct_runtime, derive_impl}; use frame_system::{self as system}; +use scale_info::prelude::collections::HashMap; use sp_core::H256; use sp_runtime::{ BuildStorage, Vec, traits::{BlakeTwo256, IdentityLookup}, }; +use sp_std::cell::RefCell; use substrate_fixed::types::U64F64; use subtensor_runtime_common::{ - AlphaCurrency, BalanceOps, Currency, CurrencyReserve, NetUid, SubnetInfo, TaoCurrency, + AlphaBalance, BalanceOps, NetUid, SubnetInfo, TaoBalance, Token, TokenReserve, }; use subtensor_swap_interface::Order; @@ -72,54 +74,91 @@ parameter_types! { pub const MinimumReserves: NonZeroU64 = NonZeroU64::new(1).unwrap(); } +thread_local! { + // maps netuid -> mocked tao reserve + static MOCK_TAO_RESERVES: RefCell> = + RefCell::new(HashMap::new()); + // maps netuid -> mocked alpha reserve + static MOCK_ALPHA_RESERVES: RefCell> = + RefCell::new(HashMap::new()); +} + #[derive(Clone)] pub struct TaoReserve; -impl CurrencyReserve for TaoReserve { - fn reserve(netuid: NetUid) -> TaoCurrency { +impl TaoReserve { + pub fn set_mock_reserve(netuid: NetUid, value: TaoBalance) { + MOCK_TAO_RESERVES.with(|m| { + m.borrow_mut().insert(netuid, value); + }); + } +} + +impl TokenReserve for TaoReserve { + fn reserve(netuid: NetUid) -> TaoBalance { + // If test has set an override, use it + if let Some(val) = MOCK_TAO_RESERVES.with(|m| m.borrow().get(&netuid).cloned()) { + return val; + } + + // Otherwise, fall back to our defaults match netuid.into() { 123u16 => 10_000, - WRAPPING_FEES_NETUID => 100_000_000_000, - _ => 1_000_000_000_000, + WRAPPING_FEES_NETUID => 100_000_000_000_u64, + _ => 1_000_000_000_000_u64, } .into() } - fn increase_provided(_: NetUid, _: TaoCurrency) {} - fn decrease_provided(_: NetUid, _: TaoCurrency) {} + fn increase_provided(_: NetUid, _: TaoBalance) {} + fn decrease_provided(_: NetUid, _: TaoBalance) {} } #[derive(Clone)] pub struct AlphaReserve; -impl CurrencyReserve for AlphaReserve { - fn reserve(netuid: NetUid) -> AlphaCurrency { +impl AlphaReserve { + pub fn set_mock_reserve(netuid: NetUid, value: AlphaBalance) { + MOCK_ALPHA_RESERVES.with(|m| { + m.borrow_mut().insert(netuid, value); + }); + } +} + +impl TokenReserve for AlphaReserve { + fn reserve(netuid: NetUid) -> AlphaBalance { + // If test has set an override, use it + if let Some(val) = MOCK_ALPHA_RESERVES.with(|m| m.borrow().get(&netuid).cloned()) { + return val; + } + + // Otherwise, fall back to our defaults match netuid.into() { 123u16 => 10_000.into(), - WRAPPING_FEES_NETUID => 400_000_000_000.into(), - _ => 4_000_000_000_000.into(), + WRAPPING_FEES_NETUID => 400_000_000_000_u64.into(), + _ => 4_000_000_000_000_u64.into(), } } - fn increase_provided(_: NetUid, _: AlphaCurrency) {} - fn decrease_provided(_: NetUid, _: AlphaCurrency) {} + fn increase_provided(_: NetUid, _: AlphaBalance) {} + fn decrease_provided(_: NetUid, _: AlphaBalance) {} } pub type GetAlphaForTao = subtensor_swap_interface::GetAlphaForTao; pub type GetTaoForAlpha = subtensor_swap_interface::GetTaoForAlpha; -pub(crate) trait GlobalFeeInfo: Currency { +pub(crate) trait GlobalFeeInfo: Token { #[allow(dead_code)] fn global_fee(&self, netuid: NetUid) -> U64F64; } -impl GlobalFeeInfo for TaoCurrency { +impl GlobalFeeInfo for TaoBalance { fn global_fee(&self, netuid: NetUid) -> U64F64 { FeeGlobalTao::::get(netuid) } } -impl GlobalFeeInfo for AlphaCurrency { +impl GlobalFeeInfo for AlphaBalance { fn global_fee(&self, netuid: NetUid) -> U64F64 { FeeGlobalAlpha::::get(netuid) } @@ -202,7 +241,7 @@ impl SubnetInfo for MockLiquidityProvider { pub struct MockBalanceOps; impl BalanceOps for MockBalanceOps { - fn tao_balance(account_id: &AccountId) -> TaoCurrency { + fn tao_balance(account_id: &AccountId) -> TaoBalance { match *account_id { OK_COLDKEY_ACCOUNT_ID => 100_000_000_000_000, OK_COLDKEY_ACCOUNT_ID_2 => 100_000_000_000_000, @@ -216,7 +255,7 @@ impl BalanceOps for MockBalanceOps { _: NetUid, coldkey_account_id: &AccountId, hotkey_account_id: &AccountId, - ) -> AlphaCurrency { + ) -> AlphaBalance { match (coldkey_account_id, hotkey_account_id) { (&OK_COLDKEY_ACCOUNT_ID, &OK_HOTKEY_ACCOUNT_ID) => 100_000_000_000_000, (&OK_COLDKEY_ACCOUNT_ID_2, &OK_HOTKEY_ACCOUNT_ID_2) => 100_000_000_000_000, @@ -228,12 +267,12 @@ impl BalanceOps for MockBalanceOps { .into() } - fn increase_balance(_coldkey: &AccountId, _tao: TaoCurrency) {} + fn increase_balance(_coldkey: &AccountId, _tao: TaoBalance) {} fn decrease_balance( _coldkey: &AccountId, - tao: TaoCurrency, - ) -> Result { + tao: TaoBalance, + ) -> Result { Ok(tao) } @@ -241,7 +280,7 @@ impl BalanceOps for MockBalanceOps { _coldkey: &AccountId, _hotkey: &AccountId, _netuid: NetUid, - _alpha: AlphaCurrency, + _alpha: AlphaBalance, ) -> Result<(), DispatchError> { Ok(()) } @@ -250,8 +289,8 @@ impl BalanceOps for MockBalanceOps { _coldkey: &AccountId, _hotkey: &AccountId, _netuid: NetUid, - alpha: AlphaCurrency, - ) -> Result { + alpha: AlphaBalance, + ) -> Result { Ok(alpha) } } diff --git a/pallets/swap/src/pallet/impls.rs b/pallets/swap/src/pallet/impls.rs index 38830ec688..cc309216bb 100644 --- a/pallets/swap/src/pallet/impls.rs +++ b/pallets/swap/src/pallet/impls.rs @@ -3,12 +3,13 @@ use core::ops::Neg; use frame_support::storage::{TransactionOutcome, transactional}; use frame_support::{ensure, pallet_prelude::DispatchError, traits::Get}; use safe_math::*; -use sp_arithmetic::helpers_128bit; +use sp_arithmetic::{helpers_128bit, traits::Zero}; use sp_runtime::{DispatchResult, Vec, traits::AccountIdConversion}; use substrate_fixed::types::{I64F64, U64F64, U96F32}; use subtensor_runtime_common::{ - AlphaCurrency, BalanceOps, Currency, CurrencyReserve, NetUid, SubnetInfo, TaoCurrency, + AlphaBalance, BalanceOps, NetUid, SubnetInfo, TaoBalance, Token, TokenReserve, }; + use subtensor_swap_interface::{ DefaultPriceLimit, Order as OrderT, SwapEngine, SwapHandler, SwapResult, }; @@ -25,10 +26,10 @@ const MAX_SWAP_ITERATIONS: u16 = 1000; #[derive(Debug, PartialEq)] pub struct UpdateLiquidityResult { - pub tao: TaoCurrency, - pub alpha: AlphaCurrency, - pub fee_tao: TaoCurrency, - pub fee_alpha: AlphaCurrency, + pub tao: TaoBalance, + pub alpha: AlphaBalance, + pub fee_tao: TaoBalance, + pub fee_alpha: AlphaBalance, pub removed: bool, pub tick_low: TickIndex, pub tick_high: TickIndex, @@ -36,10 +37,10 @@ pub struct UpdateLiquidityResult { #[derive(Debug, PartialEq)] pub struct RemoveLiquidityResult { - pub tao: TaoCurrency, - pub alpha: AlphaCurrency, - pub fee_tao: TaoCurrency, - pub fee_alpha: AlphaCurrency, + pub tao: TaoBalance, + pub alpha: AlphaBalance, + pub fee_tao: TaoBalance, + pub fee_alpha: AlphaBalance, pub tick_low: TickIndex, pub tick_high: TickIndex, pub liquidity: u64, @@ -115,9 +116,9 @@ impl Pallet { pub(crate) fn get_proportional_alpha_tao_and_remainders( sqrt_alpha_price: U64F64, - amount_tao: TaoCurrency, - amount_alpha: AlphaCurrency, - ) -> (TaoCurrency, AlphaCurrency, TaoCurrency, AlphaCurrency) { + amount_tao: TaoBalance, + amount_alpha: AlphaBalance, + ) -> (TaoBalance, AlphaBalance, TaoBalance, AlphaBalance) { let price = sqrt_alpha_price.saturating_mul(sqrt_alpha_price); let tao_equivalent: u64 = U64F64::saturating_from_num(u64::from(amount_alpha)) .saturating_mul(price) @@ -129,7 +130,7 @@ impl Pallet { ( tao_equivalent.into(), amount_alpha, - amount_tao.saturating_sub(TaoCurrency::from(tao_equivalent)), + amount_tao.saturating_sub(TaoBalance::from(tao_equivalent)), 0.into(), ) } else { @@ -151,8 +152,8 @@ impl Pallet { /// Adjusts protocol liquidity with new values of TAO and Alpha reserve pub(super) fn adjust_protocol_liquidity( netuid: NetUid, - tao_delta: TaoCurrency, - alpha_delta: AlphaCurrency, + tao_delta: TaoBalance, + alpha_delta: AlphaBalance, ) { // Update protocol position with new liquidity let protocol_account_id = Self::protocol_account_id(); @@ -172,10 +173,10 @@ impl Pallet { Self::get_proportional_alpha_tao_and_remainders( current_sqrt_price, tao_delta - .saturating_add(TaoCurrency::from(tao_fees)) + .saturating_add(TaoBalance::from(tao_fees)) .saturating_add(tao_reservoir), alpha_delta - .saturating_add(AlphaCurrency::from(alpha_fees)) + .saturating_add(AlphaBalance::from(alpha_fees)) .saturating_add(alpha_reservoir), ); @@ -363,11 +364,7 @@ impl Pallet { /// Calculate fee amount /// /// Fee is provided by state ops as u16-normalized value. - pub(crate) fn calculate_fee_amount( - netuid: NetUid, - amount: C, - drop_fees: bool, - ) -> C { + pub(crate) fn calculate_fee_amount(netuid: NetUid, amount: C, drop_fees: bool) -> C { if drop_fees { return C::ZERO; } @@ -454,12 +451,12 @@ impl Pallet { let position_id = position.id; ensure!( - T::BalanceOps::tao_balance(coldkey_account_id) >= TaoCurrency::from(tao) + T::BalanceOps::tao_balance(coldkey_account_id) >= TaoBalance::from(tao) && T::BalanceOps::alpha_balance( netuid.into(), coldkey_account_id, hotkey_account_id - ) >= AlphaCurrency::from(alpha), + ) >= AlphaBalance::from(alpha), Error::::InsufficientBalance ); @@ -580,7 +577,7 @@ impl Pallet { // Small delta is not allowed ensure!( - liquidity_delta.abs() >= T::MinimumLiquidity::get() as i64, + liquidity_delta.unsigned_abs() >= T::MinimumLiquidity::get(), Error::::InvalidLiquidityValue ); let mut delta_liquidity_abs = liquidity_delta.unsigned_abs(); @@ -623,9 +620,9 @@ impl Pallet { // Check that user has enough balances ensure!( T::BalanceOps::tao_balance(coldkey_account_id) - >= TaoCurrency::from(tao.saturating_to_num::()) + >= TaoBalance::from(tao.saturating_to_num::()) && T::BalanceOps::alpha_balance(netuid, coldkey_account_id, hotkey_account_id) - >= AlphaCurrency::from(alpha.saturating_to_num::()), + >= AlphaBalance::from(alpha.saturating_to_num::()), Error::::InsufficientBalance ); } else { @@ -814,7 +811,7 @@ impl Pallet { T::ProtocolId::get().into_account_truncating() } - pub(crate) fn min_price_inner() -> C { + pub(crate) fn min_price_inner() -> C { TickIndex::min_sqrt_price() .saturating_mul(TickIndex::min_sqrt_price()) .saturating_mul(SqrtPrice::saturating_from_num(1_000_000_000)) @@ -822,7 +819,7 @@ impl Pallet { .into() } - pub(crate) fn max_price_inner() -> C { + pub(crate) fn max_price_inner() -> C { TickIndex::max_sqrt_price() .saturating_mul(TickIndex::max_sqrt_price()) .saturating_mul(SqrtPrice::saturating_from_num(1_000_000_000)) @@ -855,8 +852,8 @@ impl Pallet { return Ok(()); } - let mut user_refunded_tao = TaoCurrency::ZERO; - let mut user_staked_alpha = AlphaCurrency::ZERO; + let mut user_refunded_tao = TaoBalance::ZERO; + let mut user_staked_alpha = AlphaBalance::ZERO; let trust: Vec = T::SubnetInfo::get_validator_trust(netuid.into()); let permit: Vec = T::SubnetInfo::get_validator_permit(netuid.into()); @@ -878,14 +875,14 @@ impl Pallet { match Self::do_remove_liquidity(netuid, &owner, pos_id) { Ok(rm) => { // α withdrawn from the pool = principal + accrued fees - let alpha_total_from_pool: AlphaCurrency = + let alpha_total_from_pool: AlphaBalance = rm.alpha.saturating_add(rm.fee_alpha); // ---------------- USER: refund τ and convert α → stake ---------------- // 1) Refund τ principal directly. - let tao_total_from_pool: TaoCurrency = rm.tao.saturating_add(rm.fee_tao); - if tao_total_from_pool > TaoCurrency::ZERO { + let tao_total_from_pool: TaoBalance = rm.tao.saturating_add(rm.fee_tao); + if tao_total_from_pool > TaoBalance::ZERO { T::BalanceOps::increase_balance(&owner, tao_total_from_pool); user_refunded_tao = user_refunded_tao.saturating_add(tao_total_from_pool); @@ -893,7 +890,7 @@ impl Pallet { } // 2) Stake ALL withdrawn α (principal + fees) to the best permitted validator. - if alpha_total_from_pool > AlphaCurrency::ZERO { + if alpha_total_from_pool > AlphaBalance::ZERO { if let Some(target_uid) = pick_target_uid(&trust, &permit) { let validator_hotkey: T::AccountId = T::SubnetInfo::hotkey_of_uid(netuid.into(), target_uid).ok_or( @@ -954,8 +951,8 @@ impl Pallet { let protocol_account = Self::protocol_account_id(); // 1) Force-close only protocol positions, burning proceeds. - let mut burned_tao = TaoCurrency::ZERO; - let mut burned_alpha = AlphaCurrency::ZERO; + let mut burned_tao = TaoBalance::ZERO; + let mut burned_alpha = AlphaBalance::ZERO; // Collect protocol position IDs first to avoid mutating while iterating. let protocol_pos_ids: sp_std::vec::Vec = Positions::::iter_prefix((netuid,)) @@ -971,14 +968,13 @@ impl Pallet { for pos_id in protocol_pos_ids { match Self::do_remove_liquidity(netuid, &protocol_account, pos_id) { Ok(rm) => { - let alpha_total_from_pool: AlphaCurrency = - rm.alpha.saturating_add(rm.fee_alpha); - let tao_total_from_pool: TaoCurrency = rm.tao.saturating_add(rm.fee_tao); + let alpha_total_from_pool: AlphaBalance = rm.alpha.saturating_add(rm.fee_alpha); + let tao_total_from_pool: TaoBalance = rm.tao.saturating_add(rm.fee_tao); - if tao_total_from_pool > TaoCurrency::ZERO { + if tao_total_from_pool > TaoBalance::ZERO { burned_tao = burned_tao.saturating_add(tao_total_from_pool); } - if alpha_total_from_pool > AlphaCurrency::ZERO { + if alpha_total_from_pool > AlphaBalance::ZERO { burned_alpha = burned_alpha.saturating_add(alpha_total_from_pool); } @@ -1024,14 +1020,14 @@ impl Pallet { } } -impl DefaultPriceLimit for Pallet { - fn default_price_limit() -> C { +impl DefaultPriceLimit for Pallet { + fn default_price_limit() -> C { Self::max_price_inner::() } } -impl DefaultPriceLimit for Pallet { - fn default_price_limit() -> C { +impl DefaultPriceLimit for Pallet { + fn default_price_limit() -> C { Self::min_price_inner::() } } @@ -1046,7 +1042,7 @@ where fn swap( netuid: NetUid, order: O, - price_limit: TaoCurrency, + price_limit: TaoBalance, drop_fees: bool, should_rollback: bool, ) -> Result, DispatchError> { @@ -1070,7 +1066,7 @@ impl SwapHandler for Pallet { fn swap( netuid: NetUid, order: O, - price_limit: TaoCurrency, + price_limit: TaoBalance, drop_fees: bool, should_rollback: bool, ) -> Result, DispatchError> @@ -1091,7 +1087,7 @@ impl SwapHandler for Pallet { { match T::SubnetInfo::mechanism(netuid) { 1 => { - let price_limit = Self::default_price_limit::(); + let price_limit = Self::default_price_limit::(); >::swap(netuid, order, price_limit, false, true) } @@ -1111,7 +1107,7 @@ impl SwapHandler for Pallet { } } - fn approx_fee_amount(netuid: NetUid, amount: C) -> C { + fn approx_fee_amount(netuid: NetUid, amount: C) -> C { Self::calculate_fee_amount(netuid, amount, false) } @@ -1119,7 +1115,7 @@ impl SwapHandler for Pallet { Self::current_price(netuid.into()) } - fn get_protocol_tao(netuid: NetUid) -> TaoCurrency { + fn get_protocol_tao(netuid: NetUid) -> TaoBalance { let protocol_account_id = Self::protocol_account_id(); let mut positions = Positions::::iter_prefix_values((netuid, protocol_account_id.clone())) @@ -1134,22 +1130,18 @@ impl SwapHandler for Pallet { } } - TaoCurrency::ZERO + TaoBalance::ZERO } - fn min_price() -> C { + fn min_price() -> C { Self::min_price_inner() } - fn max_price() -> C { + fn max_price() -> C { Self::max_price_inner() } - fn adjust_protocol_liquidity( - netuid: NetUid, - tao_delta: TaoCurrency, - alpha_delta: AlphaCurrency, - ) { + fn adjust_protocol_liquidity(netuid: NetUid, tao_delta: TaoBalance, alpha_delta: AlphaBalance) { Self::adjust_protocol_liquidity(netuid, tao_delta, alpha_delta); } diff --git a/pallets/swap/src/pallet/migrations/migrate_swapv3_to_balancer.rs b/pallets/swap/src/pallet/migrations/migrate_swapv3_to_balancer.rs new file mode 100644 index 0000000000..63392da9ea --- /dev/null +++ b/pallets/swap/src/pallet/migrations/migrate_swapv3_to_balancer.rs @@ -0,0 +1,81 @@ +use super::*; +use crate::HasMigrationRun; +use frame_support::{storage_alias, traits::Get, weights::Weight}; +use scale_info::prelude::string::String; +use substrate_fixed::types::U64F64; + +pub mod deprecated_swap_maps { + use super::*; + + #[storage_alias] + pub type AlphaSqrtPrice = + StorageMap, Twox64Concat, NetUid, U64F64, ValueQuery>; + + /// TAO reservoir for scraps of protocol claimed fees. + #[storage_alias] + pub type ScrapReservoirTao = + StorageMap, Twox64Concat, NetUid, TaoBalance, ValueQuery>; + + /// Alpha reservoir for scraps of protocol claimed fees. + #[storage_alias] + pub type ScrapReservoirAlpha = + StorageMap, Twox64Concat, NetUid, AlphaBalance, ValueQuery>; +} + +pub fn migrate_swapv3_to_balancer() -> Weight { + let migration_name = BoundedVec::truncate_from(b"migrate_swapv3_to_balancer".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), + ); + + // ------------------------------ + // Step 1: Initialize swaps with price before price removal + // ------------------------------ + for (netuid, price_sqrt) in deprecated_swap_maps::AlphaSqrtPrice::::iter() { + let price = price_sqrt.saturating_mul(price_sqrt); + crate::Pallet::::maybe_initialize_palswap(netuid, Some(price)).unwrap_or_default(); + } + + // ------------------------------ + // Step 2: Clear Map entries + // ------------------------------ + remove_prefix::("Swap", "AlphaSqrtPrice", &mut weight); + remove_prefix::("Swap", "CurrentTick", &mut weight); + remove_prefix::("Swap", "EnabledUserLiquidity", &mut weight); + remove_prefix::("Swap", "FeeGlobalTao", &mut weight); + remove_prefix::("Swap", "FeeGlobalAlpha", &mut weight); + remove_prefix::("Swap", "LastPositionId", &mut weight); + // Scrap reservoirs can be just cleaned because they are already included in reserves + remove_prefix::("Swap", "ScrapReservoirTao", &mut weight); + remove_prefix::("Swap", "ScrapReservoirAlpha", &mut weight); + remove_prefix::("Swap", "Ticks", &mut weight); + remove_prefix::("Swap", "TickIndexBitmapWords", &mut weight); + remove_prefix::("Swap", "SwapV3Initialized", &mut weight); + remove_prefix::("Swap", "CurrentLiquidity", &mut weight); + remove_prefix::("Swap", "Positions", &mut weight); + + // ------------------------------ + // Step 3: 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/swap/src/pallet/mod.rs b/pallets/swap/src/pallet/mod.rs index 73f0833d5d..281467277e 100644 --- a/pallets/swap/src/pallet/mod.rs +++ b/pallets/swap/src/pallet/mod.rs @@ -6,7 +6,7 @@ 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, + AlphaBalance, BalanceOps, NetUid, SubnetInfo, TaoBalance, Token, TokenReserve, }; use crate::{ @@ -40,10 +40,10 @@ mod pallet { type SubnetInfo: SubnetInfo; /// Tao reserves info. - type TaoReserve: CurrencyReserve; + type TaoReserve: TokenReserve; /// Alpha reserves info. - type AlphaReserve: CurrencyReserve; + type AlphaReserve: TokenReserve; /// Implementor of /// [`BalanceOps`](subtensor_swap_interface::BalanceOps). @@ -157,12 +157,11 @@ mod pallet { /// TAO reservoir for scraps of protocol claimed fees. #[pallet::storage] - pub type ScrapReservoirTao = StorageMap<_, Twox64Concat, NetUid, TaoCurrency, ValueQuery>; + pub type ScrapReservoirTao = StorageMap<_, Twox64Concat, NetUid, TaoBalance, ValueQuery>; /// Alpha reservoir for scraps of protocol claimed fees. #[pallet::storage] - pub type ScrapReservoirAlpha = - StorageMap<_, Twox64Concat, NetUid, AlphaCurrency, ValueQuery>; + pub type ScrapReservoirAlpha = StorageMap<_, Twox64Concat, NetUid, AlphaBalance, ValueQuery>; #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] @@ -187,9 +186,9 @@ mod pallet { /// The amount of liquidity added to the position liquidity: u64, /// The amount of TAO tokens committed to the position - tao: TaoCurrency, + tao: TaoBalance, /// The amount of Alpha tokens committed to the position - alpha: AlphaCurrency, + alpha: AlphaBalance, /// the lower tick tick_low: TickIndex, /// the upper tick @@ -209,13 +208,13 @@ mod pallet { /// The amount of liquidity removed from the position liquidity: u64, /// The amount of TAO tokens returned to the user - tao: TaoCurrency, + tao: TaoBalance, /// The amount of Alpha tokens returned to the user - alpha: AlphaCurrency, + alpha: AlphaBalance, /// The amount of TAO fees earned from the position - fee_tao: TaoCurrency, + fee_tao: TaoBalance, /// The amount of Alpha fees earned from the position - fee_alpha: AlphaCurrency, + fee_alpha: AlphaBalance, /// the lower tick tick_low: TickIndex, /// the upper tick @@ -240,9 +239,9 @@ mod pallet { /// The amount of Alpha tokens returned to the user alpha: i64, /// The amount of TAO fees earned from the position - fee_tao: TaoCurrency, + fee_tao: TaoBalance, /// The amount of Alpha fees earned from the position - fee_alpha: AlphaCurrency, + fee_alpha: AlphaBalance, /// the lower tick tick_low: TickIndex, /// the upper tick @@ -403,8 +402,8 @@ mod pallet { // tick_high, // liquidity, // )?; - // let alpha = AlphaCurrency::from(alpha); - // let tao = TaoCurrency::from(tao); + // let alpha = AlphaBalance::from(alpha); + // let tao = TaoBalance::from(tao); // // Remove TAO and Alpha balances or fail transaction if they can't be removed exactly // let tao_provided = T::BalanceOps::decrease_balance(&coldkey, tao)?; @@ -593,7 +592,7 @@ mod pallet { } // Credit accrued fees to user account (no matter if liquidity is added or removed) - if result.fee_tao > TaoCurrency::ZERO { + if result.fee_tao > TaoBalance::ZERO { T::BalanceOps::increase_balance(&coldkey, result.fee_tao); } if !result.fee_alpha.is_zero() { diff --git a/pallets/swap/src/pallet/swap_step.rs b/pallets/swap/src/pallet/swap_step.rs index 52215e79b5..bdcad40074 100644 --- a/pallets/swap/src/pallet/swap_step.rs +++ b/pallets/swap/src/pallet/swap_step.rs @@ -1,9 +1,9 @@ use core::marker::PhantomData; -use frame_support::{ensure, traits::Get}; +use frame_support::{ensure, pallet_prelude::Zero, traits::Get}; use safe_math::*; use substrate_fixed::types::{I64F64, U64F64}; -use subtensor_runtime_common::{AlphaCurrency, Currency, NetUid, TaoCurrency}; +use subtensor_runtime_common::{AlphaBalance, NetUid, TaoBalance, Token}; use super::pallet::*; use crate::{ @@ -15,8 +15,8 @@ use crate::{ pub(crate) struct BasicSwapStep where T: Config, - PaidIn: Currency, - PaidOut: Currency, + PaidIn: Token, + PaidOut: Token, { // Input parameters netuid: NetUid, @@ -45,8 +45,8 @@ where impl BasicSwapStep where T: Config, - PaidIn: Currency, - PaidOut: Currency, + PaidIn: Token, + PaidOut: Token, Self: SwapStep, { /// Creates and initializes a new swap step @@ -247,14 +247,14 @@ where } } -impl SwapStep - for BasicSwapStep +impl SwapStep + for BasicSwapStep { fn delta_in( liquidity_curr: U64F64, sqrt_price_curr: SqrtPrice, sqrt_price_target: SqrtPrice, - ) -> TaoCurrency { + ) -> TaoBalance { liquidity_curr .saturating_mul(sqrt_price_target.saturating_sub(sqrt_price_curr)) .saturating_to_num::() @@ -272,14 +272,14 @@ impl SwapStep fn sqrt_price_target( liquidity_curr: U64F64, sqrt_price_curr: SqrtPrice, - delta_in: TaoCurrency, + delta_in: TaoBalance, ) -> SqrtPrice { let delta_fixed = U64F64::saturating_from_num(delta_in); // No liquidity means that price should go to the limit if liquidity_curr == 0 { return SqrtPrice::saturating_from_num( - Pallet::::max_price_inner::().to_u64(), + Pallet::::max_price_inner::().to_u64(), ); } @@ -296,7 +296,7 @@ impl SwapStep SwapStepAction::Crossing } - fn add_fees(netuid: NetUid, current_liquidity: U64F64, fee: TaoCurrency) { + fn add_fees(netuid: NetUid, current_liquidity: U64F64, fee: TaoBalance) { if current_liquidity == 0 { return; } @@ -308,10 +308,10 @@ impl SwapStep }); } - fn convert_deltas(netuid: NetUid, delta_in: TaoCurrency) -> AlphaCurrency { + fn convert_deltas(netuid: NetUid, delta_in: TaoBalance) -> AlphaBalance { // Skip conversion if delta_in is zero if delta_in.is_zero() { - return AlphaCurrency::ZERO; + return AlphaBalance::ZERO; } let liquidity_curr = SqrtPrice::saturating_from_num(CurrentLiquidity::::get(netuid)); @@ -366,14 +366,14 @@ impl SwapStep } } -impl SwapStep - for BasicSwapStep +impl SwapStep + for BasicSwapStep { fn delta_in( liquidity_curr: U64F64, sqrt_price_curr: SqrtPrice, sqrt_price_target: SqrtPrice, - ) -> AlphaCurrency { + ) -> AlphaBalance { let one = U64F64::saturating_from_num(1); liquidity_curr @@ -405,7 +405,7 @@ impl SwapStep fn sqrt_price_target( liquidity_curr: U64F64, sqrt_price_curr: SqrtPrice, - delta_in: AlphaCurrency, + delta_in: AlphaBalance, ) -> SqrtPrice { let delta_fixed = U64F64::saturating_from_num(delta_in); let one = U64F64::saturating_from_num(1); @@ -413,7 +413,7 @@ impl SwapStep // No liquidity means that price should go to the limit if liquidity_curr == 0 { return SqrtPrice::saturating_from_num( - Pallet::::min_price_inner::().to_u64(), + Pallet::::min_price_inner::().to_u64(), ); } @@ -432,7 +432,7 @@ impl SwapStep SwapStepAction::Stop } - fn add_fees(netuid: NetUid, current_liquidity: U64F64, fee: AlphaCurrency) { + fn add_fees(netuid: NetUid, current_liquidity: U64F64, fee: AlphaBalance) { if current_liquidity == 0 { return; } @@ -444,10 +444,10 @@ impl SwapStep }); } - fn convert_deltas(netuid: NetUid, delta_in: AlphaCurrency) -> TaoCurrency { + fn convert_deltas(netuid: NetUid, delta_in: AlphaBalance) -> TaoBalance { // Skip conversion if delta_in is zero if delta_in.is_zero() { - return TaoCurrency::ZERO; + return TaoBalance::ZERO; } let liquidity_curr = SqrtPrice::saturating_from_num(CurrentLiquidity::::get(netuid)); @@ -515,8 +515,8 @@ impl SwapStep pub(crate) trait SwapStep where T: Config, - PaidIn: Currency, - PaidOut: Currency, + PaidIn: Token, + PaidOut: Token, { /// Get the input amount needed to reach the target price fn delta_in( @@ -567,8 +567,8 @@ where #[derive(Debug, PartialEq)] pub(crate) struct SwapStepResult where - PaidIn: Currency, - PaidOut: Currency, + PaidIn: Token, + PaidOut: Token, { pub(crate) amount_to_take: PaidIn, pub(crate) fee_paid: PaidIn, diff --git a/pallets/swap/src/pallet/tests.rs b/pallets/swap/src/pallet/tests.rs index 727e65c95a..211020cbba 100644 --- a/pallets/swap/src/pallet/tests.rs +++ b/pallets/swap/src/pallet/tests.rs @@ -10,7 +10,7 @@ use frame_support::{assert_err, assert_noop, assert_ok}; use sp_arithmetic::helpers_128bit; use sp_runtime::DispatchError; use substrate_fixed::types::U96F32; -use subtensor_runtime_common::NetUid; +use subtensor_runtime_common::{NetUid, Token}; use subtensor_swap_interface::Order as OrderT; use super::*; @@ -105,43 +105,6 @@ mod dispatchables { ); }); } - - // #[test] - // fn test_toggle_user_liquidity() { - // new_test_ext().execute_with(|| { - // let netuid = NetUid::from(101); - - // assert!(!EnabledUserLiquidity::::get(netuid)); - - // assert_ok!(Swap::toggle_user_liquidity( - // RuntimeOrigin::root(), - // netuid.into(), - // true - // )); - - // assert!(EnabledUserLiquidity::::get(netuid)); - - // assert_noop!( - // Swap::toggle_user_liquidity(RuntimeOrigin::signed(666), netuid.into(), true), - // DispatchError::BadOrigin - // ); - - // assert_ok!(Swap::toggle_user_liquidity( - // RuntimeOrigin::signed(1), - // netuid.into(), - // true - // )); - - // assert_noop!( - // Swap::toggle_user_liquidity( - // RuntimeOrigin::root(), - // NON_EXISTENT_NETUID.into(), - // true - // ), - // Error::::MechanismDoesNotExist - // ); - // }); - // } } #[test] @@ -553,8 +516,8 @@ fn test_remove_liquidity_basic() { alpha, epsilon = alpha / 1000 ); - assert_eq!(remove_result.fee_tao, TaoCurrency::ZERO); - assert_eq!(remove_result.fee_alpha, AlphaCurrency::ZERO); + assert_eq!(remove_result.fee_tao, TaoBalance::ZERO); + assert_eq!(remove_result.fee_alpha, AlphaBalance::ZERO); // Liquidity position is removed assert_eq!( @@ -681,8 +644,8 @@ fn test_modify_position_basic() { ); // Block author may get all fees - // assert!(modify_result.fee_tao > TaoCurrency::ZERO); - // assert_eq!(modify_result.fee_alpha, AlphaCurrency::ZERO); + // assert!(modify_result.fee_tao > TaoBalance::ZERO); + // assert_eq!(modify_result.fee_alpha, AlphaBalance::ZERO); // Liquidity position is reduced assert_eq!( @@ -736,8 +699,8 @@ fn test_modify_position_basic() { alpha / 100, epsilon = alpha / 1000 ); - assert_eq!(modify_result.fee_tao, TaoCurrency::ZERO); - assert_eq!(modify_result.fee_alpha, AlphaCurrency::ZERO); + assert_eq!(modify_result.fee_tao, TaoBalance::ZERO); + assert_eq!(modify_result.fee_alpha, AlphaBalance::ZERO); }); }); } @@ -1284,7 +1247,7 @@ fn test_swap_multiple_positions() { fn test_swap_precision_edge_case() { new_test_ext().execute_with(|| { let netuid = NetUid::from(123); // 123 is netuid with low edge case liquidity - let order = GetTaoForAlpha::with_amount(1_000_000_000_000_000_000); + let order = GetTaoForAlpha::with_amount(1_000_000_000_000_000_000_u64); let tick_low = TickIndex::MIN; let sqrt_limit_price: SqrtPrice = tick_low.try_to_sqrt_price().unwrap(); @@ -1296,7 +1259,7 @@ fn test_swap_precision_edge_case() { let swap_result = Pallet::::do_swap(netuid, order, sqrt_limit_price, false, true).unwrap(); - assert!(swap_result.amount_paid_out > TaoCurrency::ZERO); + assert!(swap_result.amount_paid_out > TaoBalance::ZERO); }); } @@ -1374,7 +1337,7 @@ fn test_convert_deltas() { AlphaSqrtPrice::::insert(netuid, sqrt_price); assert_abs_diff_eq!( - BasicSwapStep::::convert_deltas( + BasicSwapStep::::convert_deltas( netuid, delta_in.into() ), @@ -1382,7 +1345,7 @@ fn test_convert_deltas() { epsilon = 2.into() ); assert_abs_diff_eq!( - BasicSwapStep::::convert_deltas( + BasicSwapStep::::convert_deltas( netuid, delta_in.into() ), @@ -2745,7 +2708,7 @@ fn test_clear_protocol_liquidity_green_path() { } fn as_tuple( - (t_used, a_used, t_rem, a_rem): (TaoCurrency, AlphaCurrency, TaoCurrency, AlphaCurrency), + (t_used, a_used, t_rem, a_rem): (TaoBalance, AlphaBalance, TaoBalance, AlphaBalance), ) -> (u64, u64, u64, u64) { ( u64::from(t_used), @@ -2759,8 +2722,8 @@ fn as_tuple( fn proportional_when_price_is_one_and_tao_is_plenty() { // sqrt_price = 1.0 => price = 1.0 let sqrt = U64F64::from_num(1u64); - let amount_tao: TaoCurrency = 10u64.into(); - let amount_alpha: AlphaCurrency = 3u64.into(); + let amount_tao: TaoBalance = 10u64.into(); + let amount_alpha: AlphaBalance = 3u64.into(); // alpha * price = 3 * 1 = 3 <= amount_tao(10) let out = @@ -2772,8 +2735,8 @@ fn proportional_when_price_is_one_and_tao_is_plenty() { fn proportional_when_price_is_one_and_alpha_is_excess() { // sqrt_price = 1.0 => price = 1.0 let sqrt = U64F64::from_num(1u64); - let amount_tao: TaoCurrency = 5u64.into(); - let amount_alpha: AlphaCurrency = 10u64.into(); + let amount_tao: TaoBalance = 5u64.into(); + let amount_alpha: AlphaBalance = 10u64.into(); // tao is limiting: alpha_equiv = floor(5 / 1) = 5 let out = @@ -2785,8 +2748,8 @@ fn proportional_when_price_is_one_and_alpha_is_excess() { fn proportional_with_higher_price_and_alpha_limiting() { // Choose sqrt_price = 2.0 => price = 4.0 (since implementation squares it) let sqrt = U64F64::from_num(2u64); - let amount_tao: TaoCurrency = 85u64.into(); - let amount_alpha: AlphaCurrency = 20u64.into(); + let amount_tao: TaoBalance = 85u64.into(); + let amount_alpha: AlphaBalance = 20u64.into(); // tao_equivalent = alpha * price = 20 * 4 = 80 < 85 => alpha limits tao // remainders: tao 5, alpha 0 @@ -2799,8 +2762,8 @@ fn proportional_with_higher_price_and_alpha_limiting() { fn proportional_with_higher_price_and_tao_limiting() { // Choose sqrt_price = 2.0 => price = 4.0 (since implementation squares it) let sqrt = U64F64::from_num(2u64); - let amount_tao: TaoCurrency = 50u64.into(); - let amount_alpha: AlphaCurrency = 20u64.into(); + let amount_tao: TaoBalance = 50u64.into(); + let amount_alpha: AlphaBalance = 20u64.into(); // tao_equivalent = alpha * price = 20 * 4 = 80 > 50 => tao limits alpha // alpha_equivalent = floor(50 / 4) = 12 @@ -2814,8 +2777,8 @@ fn proportional_with_higher_price_and_tao_limiting() { fn zero_price_uses_no_tao_and_all_alpha() { // sqrt_price = 0 => price = 0 let sqrt = U64F64::from_num(0u64); - let amount_tao: TaoCurrency = 42u64.into(); - let amount_alpha: AlphaCurrency = 17u64.into(); + let amount_tao: TaoBalance = 42u64.into(); + let amount_alpha: AlphaBalance = 17u64.into(); // tao_equivalent = 17 * 0 = 0 <= 42 let out = @@ -2827,8 +2790,8 @@ fn zero_price_uses_no_tao_and_all_alpha() { fn rounding_down_behavior_when_dividing_by_price() { // sqrt_price = 2.0 => price = 4.0 let sqrt = U64F64::from_num(2u64); - let amount_tao: TaoCurrency = 13u64.into(); - let amount_alpha: AlphaCurrency = 100u64.into(); + let amount_tao: TaoBalance = 13u64.into(); + let amount_alpha: AlphaBalance = 100u64.into(); // tao is limiting; alpha_equiv = floor(13 / 4) = 3 // remainders: tao 0, alpha 100 - 3 = 97 @@ -2841,8 +2804,8 @@ fn rounding_down_behavior_when_dividing_by_price() { fn exact_fit_when_tao_matches_alpha_times_price() { // sqrt_price = 1.0 => price = 1.0 let sqrt = U64F64::from_num(1u64); - let amount_tao: TaoCurrency = 9u64.into(); - let amount_alpha: AlphaCurrency = 9u64.into(); + let amount_tao: TaoBalance = 9u64.into(); + let amount_alpha: AlphaBalance = 9u64.into(); let out = Pallet::::get_proportional_alpha_tao_and_remainders(sqrt, amount_tao, amount_alpha); @@ -2880,8 +2843,8 @@ fn adjust_protocol_liquidity_uses_and_sets_scrap_reservoirs() { AlphaSqrtPrice::::insert(netuid, U64F64::saturating_from_num(1u64)); // Start with some non-zero scrap reservoirs - ScrapReservoirTao::::insert(netuid, TaoCurrency::from(7u64)); - ScrapReservoirAlpha::::insert(netuid, AlphaCurrency::from(5u64)); + ScrapReservoirTao::::insert(netuid, TaoBalance::from(7u64)); + ScrapReservoirAlpha::::insert(netuid, AlphaBalance::from(5u64)); // Create a minimal protocol position so the function’s body executes. let protocol = Pallet::::protocol_account_id(); @@ -2904,11 +2867,11 @@ fn adjust_protocol_liquidity_uses_and_sets_scrap_reservoirs() { // --- Assert: reservoirs were READ (used in proportional calc) and then SET (updated) assert_eq!( ScrapReservoirTao::::get(netuid), - TaoCurrency::from(2u64) + TaoBalance::from(2u64) ); assert_eq!( ScrapReservoirAlpha::::get(netuid), - AlphaCurrency::from(0u64) + AlphaBalance::from(0u64) ); }); } diff --git a/pallets/transaction-fee/Cargo.toml b/pallets/transaction-fee/Cargo.toml index b5f08ac7c3..2180732677 100644 --- a/pallets/transaction-fee/Cargo.toml +++ b/pallets/transaction-fee/Cargo.toml @@ -82,4 +82,5 @@ runtime-benchmarks = [ "pallet-scheduler/runtime-benchmarks", "pallet-subtensor/runtime-benchmarks", "pallet-subtensor-swap/runtime-benchmarks", + "subtensor-runtime-common/runtime-benchmarks", ] diff --git a/pallets/transaction-fee/src/lib.rs b/pallets/transaction-fee/src/lib.rs index fe1eb43ce8..53e6cb816b 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::{AuthorshipInfo, Balance, NetUid}; +use subtensor_runtime_common::{AuthorshipInfo, NetUid, TaoBalance, Token}; // Tests #[cfg(test)] @@ -42,17 +42,17 @@ type CallOf = ::RuntimeCall; pub struct LinearWeightToFee; impl WeightToFeePolynomial for LinearWeightToFee { - type Balance = Balance; + type Balance = TaoBalance; fn polynomial() -> WeightToFeeCoefficients { - let coefficient = WeightToFeeCoefficient { - coeff_integer: 0, - coeff_frac: Perbill::from_parts(500_000), // 0.5 unit per weight + let coefficient: WeightToFeeCoefficient = WeightToFeeCoefficient { + coeff_integer: TaoBalance::new(0), + coeff_frac: Perbill::from_parts(50_000), negative: false, degree: 1, }; - smallvec![coefficient] + smallvec![coefficient] as WeightToFeeCoefficients } } @@ -61,12 +61,12 @@ pub trait AlphaFeeHandler { fn can_withdraw_in_alpha( coldkey: &AccountIdOf, alpha_vec: &[(AccountIdOf, NetUid)], - tao_amount: u64, + tao_amount: TaoBalance, ) -> bool; fn withdraw_in_alpha( coldkey: &AccountIdOf, alpha_vec: &[(AccountIdOf, NetUid)], - tao_amount: u64, + tao_amount: TaoBalance, ); fn get_all_netuids_for_coldkey_and_hotkey( coldkey: &AccountIdOf, @@ -83,27 +83,21 @@ impl Default for TransactionFeeHandler { } } -impl - OnUnbalanced< - FungibleImbalance< - u64, - DecreaseIssuance, pallet_balances::Pallet>, - IncreaseIssuance, pallet_balances::Pallet>, - >, - > for TransactionFeeHandler +type BalancesImbalanceOf = FungibleImbalance< + ::Balance, + DecreaseIssuance, pallet_balances::Pallet>, + IncreaseIssuance, pallet_balances::Pallet>, +>; + +impl OnUnbalanced> for TransactionFeeHandler where - T: frame_system::Config, - T: pallet_subtensor::Config, - T: pallet_balances::Config, - T: AuthorshipInfo>, + T: frame_system::Config + + pallet_balances::Config + + pallet_subtensor::Config + + AuthorshipInfo>, + ::Balance: Into + Copy, { - fn on_nonzero_unbalanced( - imbalance: FungibleImbalance< - u64, - DecreaseIssuance, pallet_balances::Pallet>, - IncreaseIssuance, pallet_balances::Pallet>, - >, - ) { + fn on_nonzero_unbalanced(imbalance: BalancesImbalanceOf) { 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: @@ -139,7 +133,7 @@ where fn can_withdraw_in_alpha( coldkey: &AccountIdOf, alpha_vec: &[(AccountIdOf, NetUid)], - tao_amount: u64, + tao_amount: TaoBalance, ) -> bool { if alpha_vec.is_empty() { // Alpha vector is empty, nothing to withdraw @@ -147,7 +141,9 @@ where } // Divide tao_amount among all alpha entries - let tao_per_entry = tao_amount.checked_div(alpha_vec.len() as u64).unwrap_or(0); + let tao_per_entry = tao_amount + .checked_div(&TaoBalance::from(alpha_vec.len())) + .unwrap_or(TaoBalance::ZERO); // The rule here is that we should be able to withdraw at least from one entry. // This is not ideal because it may not pay all fees, but UX is the priority @@ -159,20 +155,22 @@ where ), ); let alpha_price = pallet_subtensor_swap::Pallet::::current_alpha_price(*netuid); - alpha_price.saturating_mul(alpha_balance) >= tao_per_entry + alpha_price.saturating_mul(alpha_balance) >= u64::from(tao_per_entry) }) } fn withdraw_in_alpha( coldkey: &AccountIdOf, alpha_vec: &[(AccountIdOf, NetUid)], - tao_amount: u64, + tao_amount: TaoBalance, ) { if alpha_vec.is_empty() { return; } - let tao_per_entry = tao_amount.checked_div(alpha_vec.len() as u64).unwrap_or(0); + let tao_per_entry = tao_amount + .checked_div(&TaoBalance::from(alpha_vec.len())) + .unwrap_or(TaoBalance::ZERO); alpha_vec.iter().for_each(|(hotkey, netuid)| { // Divide tao_amount evenly among all alpha entries @@ -309,7 +307,7 @@ where CallOf: IsSubType>, F: Balanced, OU: OnUnbalanced> + AlphaFeeHandler, - >>::Balance: Into, + >>::Balance: Into, { type LiquidityInfo = Option>; type Balance = ::AccountId>>::Balance; diff --git a/pallets/transaction-fee/src/tests/mock.rs b/pallets/transaction-fee/src/tests/mock.rs index e4572bbfea..f0ad323168 100644 --- a/pallets/transaction-fee/src/tests/mock.rs +++ b/pallets/transaction-fee/src/tests/mock.rs @@ -3,6 +3,7 @@ use core::num::NonZeroU64; use crate::TransactionFeeHandler; +use frame_support::pallet_prelude::Zero; use frame_support::{ PalletId, assert_ok, derive_impl, parameter_types, traits::{Everything, Hooks, InherentBuilder, PrivilegeCmp}, @@ -21,7 +22,9 @@ use sp_runtime::{ }; use sp_std::cmp::Ordering; use sp_weights::Weight; -pub use subtensor_runtime_common::{AlphaCurrency, AuthorshipInfo, Currency, NetUid, TaoCurrency}; +pub use subtensor_runtime_common::{ + AlphaBalance, AuthorshipInfo, ConstTao, NetUid, TaoBalance, Token, +}; use subtensor_swap_interface::{Order, SwapHandler}; use crate::SubtensorTxFeeHandler; @@ -71,7 +74,7 @@ pub type Address = AccountId; // Balance of an account. #[allow(dead_code)] -pub type Balance = u64; +pub type Balance = TaoBalance; // An index to a block. #[allow(dead_code)] @@ -159,8 +162,8 @@ parameter_types! { Weight::from_parts(2_000_000_000_000, u64::MAX), Perbill::from_percent(75), ); - pub const ExistentialDeposit: Balance = 1; - pub const TransactionByteFee: Balance = 100; + pub const ExistentialDeposit: Balance = TaoBalance::new(1); + pub const TransactionByteFee: Balance = TaoBalance::new(100); pub const SDebug:u64 = 1; pub const InitialRho: u16 = 30; pub const InitialAlphaSigmoidSteepness: i16 = 1000; @@ -185,15 +188,15 @@ parameter_types! { pub const InitialTxRateLimit: u64 = 0; // Disable rate limit for testing pub const InitialTxDelegateTakeRateLimit: u64 = 0; // Disable rate limit for testing pub const InitialTxChildKeyTakeRateLimit: u64 = 0; // Disable rate limit for testing - pub const InitialBurn: u64 = 0; - pub const InitialMinBurn: u64 = 500_000; - pub const InitialMaxBurn: u64 = 1_000_000_000; - pub const MinBurnUpperBound: TaoCurrency = TaoCurrency::new(1_000_000_000); // 1 TAO - pub const MaxBurnLowerBound: TaoCurrency = TaoCurrency::new(100_000_000); // 0.1 TAO + pub const InitialBurn: TaoBalance = TaoBalance::new(0); + pub const InitialMinBurn: TaoBalance = TaoBalance::new(500_000); + pub const InitialMaxBurn: TaoBalance = TaoBalance::new(1_000_000_000); + pub const MinBurnUpperBound: TaoBalance = TaoBalance::new(1_000_000_000); // 1 TAO + pub const MaxBurnLowerBound: TaoBalance = TaoBalance::new(100_000_000); // 0.1 TAO pub const InitialValidatorPruneLen: u64 = 0; pub const InitialScalingLawPower: u16 = 50; pub const InitialMaxAllowedValidators: u16 = 100; - pub const InitialIssuance: u64 = 0; + pub const InitialIssuance: TaoBalance = TaoBalance::new(0); pub const InitialDifficulty: u64 = 10000; pub const InitialActivityCutoff: u16 = 5000; pub const InitialAdjustmentInterval: u16 = 100; @@ -204,13 +207,13 @@ parameter_types! { pub const InitialRegistrationRequirement: u16 = u16::MAX; // Top 100% pub const InitialMinDifficulty: u64 = 1; pub const InitialMaxDifficulty: u64 = u64::MAX; - pub const InitialRAORecycledForRegistration: u64 = 0; + pub const InitialRAORecycledForRegistration: TaoBalance = TaoBalance::new(0); pub const InitialNetworkImmunityPeriod: u64 = 7200 * 7; - pub const InitialNetworkMinLockCost: u64 = 100_000_000_000; + pub const InitialNetworkMinLockCost: TaoBalance = TaoBalance::new(100_000_000_000_u64); pub const InitialSubnetOwnerCut: u16 = 0; // 0%. 100% of rewards go to validators + miners. pub const InitialNetworkLockReductionInterval: u64 = 2; // 2 blocks. pub const InitialNetworkRateLimit: u64 = 0; - pub const InitialKeySwapCost: u64 = 1_000_000_000; + pub const InitialKeySwapCost: TaoBalance = TaoBalance::new(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 @@ -221,7 +224,7 @@ parameter_types! { pub const InitialTaoWeight: u64 = u64::MAX/10; // 10% global weight. pub const InitialEmaPriceHalvingPeriod: u64 = 201_600_u64; // 4 weeks pub const InitialStartCallDelay: u64 = 0; // 0 days - pub const InitialKeySwapOnSubnetCost: u64 = 10_000_000; + pub const InitialKeySwapOnSubnetCost: TaoBalance = TaoBalance::new(10_000_000); pub const HotkeySwapOnSubnetInterval: u64 = 7 * 24 * 60 * 60 / 12; // 7 days pub const LeaseDividendsDistributionInterval: u32 = 100; // 100 blocks pub const MaxImmuneUidsPercentage: Percent = Percent::from_percent(80); @@ -305,8 +308,8 @@ impl pallet_subtensor::Config for Test { parameter_types! { pub const PreimageMaxSize: u32 = 4096 * 1024; - pub const PreimageBaseDeposit: Balance = 1; - pub const PreimageByteDeposit: Balance = 1; + pub const PreimageBaseDeposit: Balance = TaoBalance::new(1); + pub const PreimageByteDeposit: Balance = TaoBalance::new(1); } impl pallet_preimage::Config for Test { @@ -319,8 +322,8 @@ impl pallet_preimage::Config for Test { parameter_types! { pub const CrowdloanPalletId: PalletId = PalletId(*b"bt/cloan"); - pub const MinimumDeposit: u64 = 50; - pub const AbsoluteMinimumContribution: u64 = 10; + pub const MinimumDeposit: TaoBalance = TaoBalance::new(50); + pub const AbsoluteMinimumContribution: TaoBalance = TaoBalance::new(10); pub const MinimumBlockDuration: u64 = 20; pub const MaximumBlockDuration: u64 = 100; pub const RefundContributorsLimit: u32 = 5; @@ -357,7 +360,7 @@ impl system::Config for Test { type BlockHashCount = BlockHashCount; type Version = (); type PalletInfo = PalletInfo; - type AccountData = pallet_balances::AccountData; + type AccountData = pallet_balances::AccountData; type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); @@ -386,10 +389,10 @@ impl pallet_balances::Config for Test { type MaxLocks = (); type MaxReserves = (); type ReserveIdentifier = [u8; 8]; - type Balance = u64; + type Balance = TaoBalance; type RuntimeEvent = RuntimeEvent; type DustRemoval = (); - type ExistentialDeposit = ConstU64<1>; + type ExistentialDeposit = ConstTao<1>; type AccountStore = System; type WeightInfo = (); type FreezeIdentifier = (); @@ -530,7 +533,7 @@ where let extra: TransactionExtensions = ( frame_system::CheckNonZeroSender::::new(), frame_system::CheckWeight::::new(), - pallet_transaction_payment::ChargeTransactionPayment::::from(0), + pallet_transaction_payment::ChargeTransactionPayment::::from(0.into()), ); Some(UncheckedExtrinsic::new_signed( @@ -608,14 +611,14 @@ pub fn add_dynamic_network(hotkey: &U256, coldkey: &U256) -> NetUid { netuid } -pub(crate) fn setup_reserves(netuid: NetUid, tao: TaoCurrency, alpha: AlphaCurrency) { +pub(crate) fn setup_reserves(netuid: NetUid, tao: TaoBalance, alpha: AlphaBalance) { SubnetTAO::::set(netuid, tao); SubnetAlphaIn::::set(netuid, alpha); } pub(crate) fn swap_alpha_to_tao_ext( netuid: NetUid, - alpha: AlphaCurrency, + alpha: AlphaBalance, drop_fees: bool, ) -> (u64, u64) { if netuid.is_root() { @@ -641,13 +644,13 @@ pub(crate) fn swap_alpha_to_tao_ext( (result.amount_paid_out.to_u64(), result.fee_paid.to_u64()) } -pub(crate) fn swap_alpha_to_tao(netuid: NetUid, alpha: AlphaCurrency) -> (u64, u64) { +pub(crate) fn swap_alpha_to_tao(netuid: NetUid, alpha: AlphaBalance) -> (u64, u64) { swap_alpha_to_tao_ext(netuid, alpha, false) } pub(crate) fn swap_tao_to_alpha_ext( netuid: NetUid, - tao: TaoCurrency, + tao: TaoBalance, drop_fees: bool, ) -> (u64, u64) { if netuid.is_root() { @@ -673,7 +676,7 @@ pub(crate) fn swap_tao_to_alpha_ext( (result.amount_paid_out.to_u64(), result.fee_paid.to_u64()) } -pub(crate) fn swap_tao_to_alpha(netuid: NetUid, tao: TaoCurrency) -> (u64, u64) { +pub(crate) fn swap_tao_to_alpha(netuid: NetUid, tao: TaoBalance) -> (u64, u64) { swap_tao_to_alpha_ext(netuid, tao, false) } @@ -705,7 +708,7 @@ pub fn setup_subnets(sncount: u16, neurons: u16) -> TestSetup { let owner_hk_start_id = 200; let coldkey = U256::from(10000); let neuron_hk_start_id = 20000; - let amount = 1_000_000_000_000; + let amount = 1_000_000_000_000_u64; let mut hotkeys: Vec = Vec::new(); for sn in 0..sncount { @@ -736,7 +739,7 @@ pub fn setup_subnets(sncount: u16, neurons: u16) -> TestSetup { SubtensorModule::swap_tao_for_alpha( subnet.netuid, 0.into(), - 1_000_000_000_000.into(), + 1_000_000_000_000_u64.into(), false, ) .unwrap(); @@ -758,7 +761,10 @@ pub(crate) fn remove_stake_rate_limit_for_tests(hotkey: &U256, coldkey: &U256, n #[allow(dead_code)] pub fn setup_stake(netuid: NetUid, coldkey: &U256, hotkey: &U256, amount: u64) { // Stake to hotkey account, and check if the result is ok - SubtensorModule::add_balance_to_coldkey_account(coldkey, amount + ExistentialDeposit::get()); + SubtensorModule::add_balance_to_coldkey_account( + coldkey, + ExistentialDeposit::get() + amount.into(), + ); remove_stake_rate_limit_for_tests(hotkey, coldkey, netuid); assert_ok!(SubtensorModule::add_stake( RuntimeOrigin::signed(*coldkey), diff --git a/pallets/transaction-fee/src/tests/mod.rs b/pallets/transaction-fee/src/tests/mod.rs index fa501b899f..5dd353dcde 100644 --- a/pallets/transaction-fee/src/tests/mod.rs +++ b/pallets/transaction-fee/src/tests/mod.rs @@ -2,13 +2,14 @@ use crate::TransactionSource; use frame_support::assert_ok; use frame_support::dispatch::GetDispatchInfo; +use frame_support::pallet_prelude::Zero; use pallet_subtensor_swap::AlphaSqrtPrice; use sp_runtime::{ traits::{DispatchTransaction, TransactionExtension, TxBaseImplication}, transaction_validity::{InvalidTransaction, TransactionValidityError}, }; use substrate_fixed::types::U64F64; -use subtensor_runtime_common::AlphaCurrency; +use subtensor_runtime_common::AlphaBalance; use mock::*; mod mock; @@ -18,7 +19,7 @@ mod mock; fn test_remove_stake_fees_tao() { new_test_ext().execute_with(|| { let stake_amount = TAO; - let unstake_amount = AlphaCurrency::from(TAO / 50); + let unstake_amount = AlphaBalance::from(TAO / 50); let sn = setup_subnets(1, 1); setup_stake( sn.subnets[0].netuid, @@ -26,7 +27,7 @@ fn test_remove_stake_fees_tao() { &sn.hotkeys[0], stake_amount, ); - SubtensorModule::add_balance_to_coldkey_account(&sn.coldkey, TAO); + SubtensorModule::add_balance_to_coldkey_account(&sn.coldkey, TaoBalance::from(TAO)); // Simulate stake removal to get how much TAO should we get for unstaked Alpha let (expected_unstaked_tao, _swap_fee) = @@ -47,7 +48,7 @@ fn test_remove_stake_fees_tao() { // Dispatch the extrinsic with ChargeTransactionPayment extension let info = call.get_dispatch_info(); - let ext = pallet_transaction_payment::ChargeTransactionPayment::::from(0); + let ext = pallet_transaction_payment::ChargeTransactionPayment::::from(0.into()); assert_ok!(ext.dispatch_transaction( RuntimeOrigin::signed(sn.coldkey).into(), call, @@ -63,12 +64,13 @@ fn test_remove_stake_fees_tao() { sn.subnets[0].netuid, ); - let actual_tao_fee = balance_before + expected_unstaked_tao - final_balance; + let actual_tao_fee = + balance_before + TaoBalance::from(expected_unstaked_tao) - final_balance; let actual_alpha_fee = alpha_before - alpha_after - unstake_amount; // Remove stake extrinsic should pay fees in TAO because ck has sufficient TAO balance - assert!(actual_tao_fee > 0); - assert_eq!(actual_alpha_fee, AlphaCurrency::from(0)); + assert!(actual_tao_fee > 0.into()); + assert_eq!(actual_alpha_fee, AlphaBalance::from(0)); }); } @@ -78,7 +80,7 @@ fn test_remove_stake_fees_tao() { fn test_remove_stake_fees_alpha() { new_test_ext().execute_with(|| { let stake_amount = TAO; - let unstake_amount = AlphaCurrency::from(TAO / 50); + let unstake_amount = AlphaBalance::from(TAO / 50); let sn = setup_subnets(1, 1); setup_stake( sn.subnets[0].netuid, @@ -113,7 +115,7 @@ fn test_remove_stake_fees_alpha() { // Dispatch the extrinsic with ChargeTransactionPayment extension let info = call.get_dispatch_info(); - let ext = pallet_transaction_payment::ChargeTransactionPayment::::from(0); + let ext = pallet_transaction_payment::ChargeTransactionPayment::::from(0.into()); assert_ok!(ext.dispatch_transaction( RuntimeOrigin::signed(sn.coldkey).into(), call, @@ -129,11 +131,12 @@ fn test_remove_stake_fees_alpha() { sn.subnets[0].netuid, ); - let actual_tao_fee = balance_before + expected_unstaked_tao - final_balance; + let actual_tao_fee = + balance_before + TaoBalance::from(expected_unstaked_tao) - final_balance; let actual_alpha_fee = alpha_before - alpha_after - unstake_amount; // Remove stake extrinsic should pay fees in Alpha - assert_eq!(actual_tao_fee, 0); + assert_eq!(actual_tao_fee, 0.into()); assert!(actual_alpha_fee > 0.into()); }); } @@ -175,7 +178,7 @@ fn test_remove_stake_root() { // Dispatch the extrinsic with ChargeTransactionPayment extension let info = call.get_dispatch_info(); - let ext = pallet_transaction_payment::ChargeTransactionPayment::::from(0); + let ext = pallet_transaction_payment::ChargeTransactionPayment::::from(0.into()); assert_ok!(ext.dispatch_transaction( RuntimeOrigin::signed(coldkey).into(), call, @@ -188,12 +191,12 @@ fn test_remove_stake_root() { let alpha_after = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(&hotkey, &coldkey, netuid); - let actual_tao_fee = balance_before + unstake_amount - final_balance; + let actual_tao_fee = balance_before + unstake_amount.into() - final_balance; let actual_alpha_fee = - AlphaCurrency::from(stake_amount) - alpha_after - unstake_amount.into(); + AlphaBalance::from(stake_amount) - alpha_after - unstake_amount.into(); // Remove stake extrinsic should pay fees in Alpha (withdrawn from staked TAO) - assert_eq!(actual_tao_fee, 0); + assert_eq!(actual_tao_fee, 0.into()); assert!(actual_alpha_fee > 0.into()); }); } @@ -234,7 +237,7 @@ fn test_remove_stake_completely_root() { // Dispatch the extrinsic with ChargeTransactionPayment extension let info = call.get_dispatch_info(); - let ext = pallet_transaction_payment::ChargeTransactionPayment::::from(0); + let ext = pallet_transaction_payment::ChargeTransactionPayment::::from(0.into()); assert_ok!(ext.dispatch_transaction( RuntimeOrigin::signed(coldkey).into(), call, @@ -292,7 +295,7 @@ fn test_remove_stake_completely_fees_alpha() { // Dispatch the extrinsic with ChargeTransactionPayment extension let info = call.get_dispatch_info(); - let ext = pallet_transaction_payment::ChargeTransactionPayment::::from(0); + let ext = pallet_transaction_payment::ChargeTransactionPayment::::from(0.into()); assert_ok!(ext.dispatch_transaction( RuntimeOrigin::signed(sn.coldkey).into(), call, @@ -310,9 +313,9 @@ fn test_remove_stake_completely_fees_alpha() { // Effectively, the fee is paid in TAO in this case because user receives less TAO, // and all Alpha is gone, and it is not measurable in Alpha - let actual_fee = balance_before + expected_unstaked_tao - final_balance; + let actual_fee = balance_before + expected_unstaked_tao.into() - final_balance; assert_eq!(alpha_after, 0.into()); - assert!(actual_fee > 0); + assert!(actual_fee > 0.into()); }); } @@ -345,7 +348,7 @@ fn test_remove_stake_not_enough_balance_for_fees() { ); // For-set Alpha balance to low - let new_current_stake = AlphaCurrency::from(1_000); + let new_current_stake = AlphaBalance::from(1_000); SubtensorModule::decrease_stake_for_hotkey_and_coldkey_on_subnet( &sn.hotkeys[0], &sn.coldkey, @@ -362,7 +365,7 @@ fn test_remove_stake_not_enough_balance_for_fees() { // Dispatch the extrinsic with ChargeTransactionPayment extension let info = call.get_dispatch_info(); - let ext = pallet_transaction_payment::ChargeTransactionPayment::::from(0); + let ext = pallet_transaction_payment::ChargeTransactionPayment::::from(0.into()); let result = ext.validate( RuntimeOrigin::signed(sn.coldkey).into(), &call.clone(), @@ -412,7 +415,7 @@ fn test_remove_stake_edge_alpha() { ); // For-set Alpha balance to low, but enough to pay tx fees at the current Alpha price - let new_current_stake = AlphaCurrency::from(1_000_000); + let new_current_stake = AlphaBalance::from(1_000_000); SubtensorModule::decrease_stake_for_hotkey_and_coldkey_on_subnet( &sn.hotkeys[0], &sn.coldkey, @@ -429,7 +432,7 @@ fn test_remove_stake_edge_alpha() { // Dispatch the extrinsic with ChargeTransactionPayment extension let info = call.get_dispatch_info(); - let ext = pallet_transaction_payment::ChargeTransactionPayment::::from(0); + let ext = pallet_transaction_payment::ChargeTransactionPayment::::from(0.into()); let result = ext.validate( RuntimeOrigin::signed(sn.coldkey).into(), &call.clone(), @@ -468,7 +471,7 @@ fn test_remove_stake_edge_alpha() { fn test_remove_stake_failing_transaction_tao_fees() { new_test_ext().execute_with(|| { let stake_amount = TAO; - let unstake_amount = AlphaCurrency::from(TAO / 50); + let unstake_amount = AlphaBalance::from(TAO / 50); let sn = setup_subnets(1, 1); setup_stake( sn.subnets[0].netuid, @@ -476,10 +479,10 @@ fn test_remove_stake_failing_transaction_tao_fees() { &sn.hotkeys[0], stake_amount, ); - SubtensorModule::add_balance_to_coldkey_account(&sn.coldkey, TAO); + SubtensorModule::add_balance_to_coldkey_account(&sn.coldkey, TAO.into()); // Make unstaking fail by reducing liquidity to critical - SubnetTAO::::insert(sn.subnets[0].netuid, TaoCurrency::from(1)); + SubnetTAO::::insert(sn.subnets[0].netuid, TaoBalance::from(1)); // Remove stake let balance_before = Balances::free_balance(sn.coldkey); @@ -496,7 +499,7 @@ fn test_remove_stake_failing_transaction_tao_fees() { // Dispatch the extrinsic with ChargeTransactionPayment extension let info = call.get_dispatch_info(); - let ext = pallet_transaction_payment::ChargeTransactionPayment::::from(0); + let ext = pallet_transaction_payment::ChargeTransactionPayment::::from(0.into()); assert_ok!(ext.dispatch_transaction( RuntimeOrigin::signed(sn.coldkey).into(), call, @@ -515,7 +518,7 @@ fn test_remove_stake_failing_transaction_tao_fees() { let actual_tao_fee = balance_before - final_balance; // Remove stake extrinsic should pay fees in TAO because ck has sufficient TAO balance - assert!(actual_tao_fee > 0); + assert!(actual_tao_fee > 0.into()); assert_eq!(alpha_before, alpha_after); }); } @@ -528,7 +531,7 @@ fn test_remove_stake_failing_transaction_tao_fees() { fn test_remove_stake_failing_transaction_alpha_fees() { new_test_ext().execute_with(|| { let stake_amount = TAO; - let unstake_amount = AlphaCurrency::from(TAO / 50); + let unstake_amount = AlphaBalance::from(TAO / 50); let sn = setup_subnets(1, 1); setup_stake( sn.subnets[0].netuid, @@ -538,7 +541,7 @@ fn test_remove_stake_failing_transaction_alpha_fees() { ); // Make unstaking fail by reducing liquidity to critical - SubnetTAO::::insert(sn.subnets[0].netuid, TaoCurrency::from(1)); + SubnetTAO::::insert(sn.subnets[0].netuid, TaoBalance::from(1)); // Forse-set signer balance to ED let current_balance = Balances::free_balance(sn.coldkey); @@ -562,7 +565,7 @@ fn test_remove_stake_failing_transaction_alpha_fees() { // Dispatch the extrinsic with ChargeTransactionPayment extension let info = call.get_dispatch_info(); - let ext = pallet_transaction_payment::ChargeTransactionPayment::::from(0); + let ext = pallet_transaction_payment::ChargeTransactionPayment::::from(0.into()); assert_ok!(ext.dispatch_transaction( RuntimeOrigin::signed(sn.coldkey).into(), call, @@ -582,7 +585,7 @@ fn test_remove_stake_failing_transaction_alpha_fees() { let actual_alpha_fee = alpha_before - alpha_after; // Remove stake extrinsic should pay fees in Alpha - assert_eq!(actual_tao_fee, 0); + assert_eq!(actual_tao_fee, 0.into()); assert!(actual_alpha_fee > 0.into()); assert!(actual_alpha_fee < unstake_amount); }); @@ -594,7 +597,7 @@ fn test_remove_stake_failing_transaction_alpha_fees() { fn test_remove_stake_limit_fees_alpha() { new_test_ext().execute_with(|| { let stake_amount = TAO; - let unstake_amount = AlphaCurrency::from(TAO / 50); + let unstake_amount = AlphaBalance::from(TAO / 50); let sn = setup_subnets(1, 1); setup_stake( sn.subnets[0].netuid, @@ -631,7 +634,7 @@ fn test_remove_stake_limit_fees_alpha() { // Dispatch the extrinsic with ChargeTransactionPayment extension let info = call.get_dispatch_info(); - let ext = pallet_transaction_payment::ChargeTransactionPayment::::from(0); + let ext = pallet_transaction_payment::ChargeTransactionPayment::::from(0.into()); assert_ok!(ext.dispatch_transaction( RuntimeOrigin::signed(sn.coldkey).into(), call, @@ -647,11 +650,11 @@ fn test_remove_stake_limit_fees_alpha() { sn.subnets[0].netuid, ); - let actual_tao_fee = balance_before + expected_unstaked_tao - final_balance; + let actual_tao_fee = balance_before + expected_unstaked_tao.into() - final_balance; let actual_alpha_fee = alpha_before - alpha_after - unstake_amount; // Remove stake extrinsic should pay fees in Alpha - assert_eq!(actual_tao_fee, 0); + assert_eq!(actual_tao_fee, 0.into()); assert!(actual_alpha_fee > 0.into()); }); } @@ -701,7 +704,7 @@ fn test_unstake_all_fees_alpha() { // Dispatch the extrinsic with ChargeTransactionPayment extension let info = call.get_dispatch_info(); - let ext = pallet_transaction_payment::ChargeTransactionPayment::::from(0); + let ext = pallet_transaction_payment::ChargeTransactionPayment::::from(0.into()); assert_ok!(ext.dispatch_transaction( RuntimeOrigin::signed(coldkey).into(), call, @@ -714,8 +717,8 @@ fn test_unstake_all_fees_alpha() { // Effectively, the fee is paid in TAO in this case because user receives less TAO, // and all Alpha is gone, and it is not measurable in Alpha - let actual_fee = balance_before + expected_unstaked_tao - final_balance; - assert!(actual_fee > 0); + let actual_fee = balance_before + expected_unstaked_tao.into() - final_balance; + assert!(actual_fee > 0.into()); // Check that all subnets got unstaked for i in 0..10 { @@ -769,7 +772,7 @@ fn test_unstake_all_alpha_fees_alpha() { // Dispatch the extrinsic with ChargeTransactionPayment extension let info = call.get_dispatch_info(); - let ext = pallet_transaction_payment::ChargeTransactionPayment::::from(0); + let ext = pallet_transaction_payment::ChargeTransactionPayment::::from(0.into()); assert_ok!(ext.dispatch_transaction( RuntimeOrigin::signed(coldkey).into(), call, @@ -782,8 +785,8 @@ fn test_unstake_all_alpha_fees_alpha() { // Effectively, the fee is paid in TAO in this case because user receives less TAO, // and all Alpha is gone, and it is not measurable in Alpha - let actual_fee = balance_before + expected_unstaked_tao - final_balance; - assert!(actual_fee > 0); + let actual_fee = balance_before + expected_unstaked_tao.into() - final_balance; + assert!(actual_fee > 0.into()); // Check that all subnets got unstaked for i in 0..10 { @@ -803,7 +806,7 @@ fn test_unstake_all_alpha_fees_alpha() { fn test_move_stake_fees_alpha() { new_test_ext().execute_with(|| { let stake_amount = TAO; - let unstake_amount = AlphaCurrency::from(TAO / 50); + let unstake_amount = AlphaBalance::from(TAO / 50); let sn = setup_subnets(2, 2); setup_stake( sn.subnets[0].netuid, @@ -836,7 +839,7 @@ fn test_move_stake_fees_alpha() { // Dispatch the extrinsic with ChargeTransactionPayment extension let info = call.get_dispatch_info(); - let ext = pallet_transaction_payment::ChargeTransactionPayment::::from(0); + let ext = pallet_transaction_payment::ChargeTransactionPayment::::from(0.into()); assert_ok!(ext.dispatch_transaction( RuntimeOrigin::signed(sn.coldkey).into(), call, @@ -864,7 +867,7 @@ fn test_move_stake_fees_alpha() { let actual_alpha_fee = alpha_before - alpha_after_0 - unstake_amount; // Extrinsic should pay fees in Alpha - assert_eq!(actual_tao_fee, 0); + assert_eq!(actual_tao_fee, 0.into()); assert!(actual_alpha_fee > 0.into()); }); } @@ -876,7 +879,7 @@ fn test_transfer_stake_fees_alpha() { new_test_ext().execute_with(|| { let destination_coldkey = U256::from(100000); let stake_amount = TAO; - let unstake_amount = AlphaCurrency::from(TAO / 50); + let unstake_amount = AlphaBalance::from(TAO / 50); let sn = setup_subnets(2, 2); setup_stake( sn.subnets[0].netuid, @@ -909,7 +912,7 @@ fn test_transfer_stake_fees_alpha() { // Dispatch the extrinsic with ChargeTransactionPayment extension let info = call.get_dispatch_info(); - let ext = pallet_transaction_payment::ChargeTransactionPayment::::from(0); + let ext = pallet_transaction_payment::ChargeTransactionPayment::::from(0.into()); assert_ok!(ext.dispatch_transaction( RuntimeOrigin::signed(sn.coldkey).into(), call, @@ -937,7 +940,7 @@ fn test_transfer_stake_fees_alpha() { let actual_alpha_fee = alpha_before - alpha_after_0 - unstake_amount; // Extrinsic should pay fees in Alpha - assert_eq!(actual_tao_fee, 0); + assert_eq!(actual_tao_fee, 0.into()); assert!(actual_alpha_fee > 0.into()); }); } @@ -948,7 +951,7 @@ fn test_transfer_stake_fees_alpha() { fn test_swap_stake_fees_alpha() { new_test_ext().execute_with(|| { let stake_amount = TAO; - let unstake_amount = AlphaCurrency::from(TAO / 50); + let unstake_amount = AlphaBalance::from(TAO / 50); let sn = setup_subnets(2, 2); setup_stake( sn.subnets[0].netuid, @@ -980,7 +983,7 @@ fn test_swap_stake_fees_alpha() { // Dispatch the extrinsic with ChargeTransactionPayment extension let info = call.get_dispatch_info(); - let ext = pallet_transaction_payment::ChargeTransactionPayment::::from(0); + let ext = pallet_transaction_payment::ChargeTransactionPayment::::from(0.into()); assert_ok!(ext.dispatch_transaction( RuntimeOrigin::signed(sn.coldkey).into(), call, @@ -1008,7 +1011,7 @@ fn test_swap_stake_fees_alpha() { let actual_alpha_fee = alpha_before - alpha_after_0 - unstake_amount; // Extrinsic should pay fees in Alpha - assert_eq!(actual_tao_fee, 0); + assert_eq!(actual_tao_fee, 0.into()); assert!(actual_alpha_fee > 0.into()); }); } @@ -1019,7 +1022,7 @@ fn test_swap_stake_fees_alpha() { fn test_swap_stake_limit_fees_alpha() { new_test_ext().execute_with(|| { let stake_amount = TAO; - let unstake_amount = AlphaCurrency::from(TAO / 50); + let unstake_amount = AlphaBalance::from(TAO / 50); let sn = setup_subnets(2, 2); setup_stake( sn.subnets[0].netuid, @@ -1053,7 +1056,7 @@ fn test_swap_stake_limit_fees_alpha() { // Dispatch the extrinsic with ChargeTransactionPayment extension let info = call.get_dispatch_info(); - let ext = pallet_transaction_payment::ChargeTransactionPayment::::from(0); + let ext = pallet_transaction_payment::ChargeTransactionPayment::::from(0.into()); assert_ok!(ext.dispatch_transaction( RuntimeOrigin::signed(sn.coldkey).into(), call, @@ -1081,7 +1084,7 @@ fn test_swap_stake_limit_fees_alpha() { let actual_alpha_fee = alpha_before - alpha_after_0 - unstake_amount; // Extrinsic should pay fees in Alpha - assert_eq!(actual_tao_fee, 0); + assert_eq!(actual_tao_fee, 0.into()); assert!(actual_alpha_fee > 0.into()); }); } @@ -1092,7 +1095,7 @@ fn test_swap_stake_limit_fees_alpha() { fn test_burn_alpha_fees_alpha() { new_test_ext().execute_with(|| { let stake_amount = TAO; - let alpha_amount = AlphaCurrency::from(TAO / 50); + let alpha_amount = AlphaBalance::from(TAO / 50); let sn = setup_subnets(1, 1); setup_stake( sn.subnets[0].netuid, @@ -1123,7 +1126,7 @@ fn test_burn_alpha_fees_alpha() { // Dispatch the extrinsic with ChargeTransactionPayment extension let info = call.get_dispatch_info(); - let ext = pallet_transaction_payment::ChargeTransactionPayment::::from(0); + let ext = pallet_transaction_payment::ChargeTransactionPayment::::from(0.into()); assert_ok!(ext.dispatch_transaction( RuntimeOrigin::signed(sn.coldkey).into(), call, @@ -1143,7 +1146,7 @@ fn test_burn_alpha_fees_alpha() { let actual_alpha_fee = alpha_before - alpha_after_0 - alpha_amount; // Extrinsic should pay fees in Alpha - assert_eq!(actual_tao_fee, 0); + assert_eq!(actual_tao_fee, 0.into()); assert!(actual_alpha_fee > 0.into()); }); } @@ -1154,7 +1157,7 @@ fn test_burn_alpha_fees_alpha() { fn test_recycle_alpha_fees_alpha() { new_test_ext().execute_with(|| { let stake_amount = TAO; - let alpha_amount = AlphaCurrency::from(TAO / 50); + let alpha_amount = AlphaBalance::from(TAO / 50); let sn = setup_subnets(1, 1); setup_stake( sn.subnets[0].netuid, @@ -1185,7 +1188,7 @@ fn test_recycle_alpha_fees_alpha() { // Dispatch the extrinsic with ChargeTransactionPayment extension let info = call.get_dispatch_info(); - let ext = pallet_transaction_payment::ChargeTransactionPayment::::from(0); + let ext = pallet_transaction_payment::ChargeTransactionPayment::::from(0.into()); assert_ok!(ext.dispatch_transaction( RuntimeOrigin::signed(sn.coldkey).into(), call, @@ -1205,7 +1208,7 @@ fn test_recycle_alpha_fees_alpha() { let actual_alpha_fee = alpha_before - alpha_after_0 - alpha_amount; // Extrinsic should pay fees in Alpha - assert_eq!(actual_tao_fee, 0); + assert_eq!(actual_tao_fee, 0.into()); assert!(actual_alpha_fee > 0.into()); }); } @@ -1227,7 +1230,7 @@ fn test_add_stake_fees_go_to_block_builder() { // 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); + SubtensorModule::add_balance_to_coldkey_account(&sn.coldkey, (stake_amount * 10).into()); remove_stake_rate_limit_for_tests(&sn.hotkeys[0], &sn.coldkey, sn.subnets[0].netuid); // Stake @@ -1240,7 +1243,7 @@ fn test_add_stake_fees_go_to_block_builder() { // Dispatch the extrinsic with ChargeTransactionPayment extension let info = call.get_dispatch_info(); - let ext = pallet_transaction_payment::ChargeTransactionPayment::::from(0); + let ext = pallet_transaction_payment::ChargeTransactionPayment::::from(0.into()); assert_ok!(ext.dispatch_transaction( RuntimeOrigin::signed(sn.coldkey).into(), call, @@ -1250,14 +1253,16 @@ fn test_add_stake_fees_go_to_block_builder() { )); let final_balance = Balances::free_balance(sn.coldkey); - let actual_tao_fee = balance_before - stake_amount - final_balance; - assert!(actual_tao_fee > 0); + let actual_tao_fee = balance_before - stake_amount.into() - final_balance; + assert!(!actual_tao_fee.is_zero()); // 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); + assert!( + u64::from(actual_reward) as f64 >= expected_block_builder_swap_reward + expected_tx_fee + ); }); } diff --git a/precompiles/src/alpha.rs b/precompiles/src/alpha.rs index 8dcea0e829..c90851c543 100644 --- a/precompiles/src/alpha.rs +++ b/precompiles/src/alpha.rs @@ -6,7 +6,7 @@ use precompile_utils::EvmResult; use sp_core::U256; use sp_std::vec::Vec; use substrate_fixed::types::U96F32; -use subtensor_runtime_common::{Currency, NetUid}; +use subtensor_runtime_common::{NetUid, Token}; use subtensor_swap_interface::{Order, SwapHandler}; use crate::PrecompileExt; diff --git a/precompiles/src/crowdloan.rs b/precompiles/src/crowdloan.rs index c9926dfe3b..8a4042e7d1 100644 --- a/precompiles/src/crowdloan.rs +++ b/precompiles/src/crowdloan.rs @@ -86,12 +86,12 @@ where Ok(CrowdloanInfo { creator: H256::from_slice(crowdloan.creator.as_slice()), - deposit: crowdloan.deposit, - min_contribution: crowdloan.min_contribution, + deposit: u64::from(crowdloan.deposit), + min_contribution: u64::from(crowdloan.min_contribution), end: crowdloan.end.unique_saturated_into(), - cap: crowdloan.cap, + cap: u64::from(crowdloan.cap), funds_account: H256::from_slice(crowdloan.funds_account.as_slice()), - raised: crowdloan.raised, + raised: u64::from(crowdloan.raised), has_target_address: crowdloan.target_address.is_some(), target_address: crowdloan .target_address @@ -116,7 +116,7 @@ where }, )?; - Ok(contribution) + Ok(u64::from(contribution)) } #[precompile::public("create(uint64,uint64,uint64,uint32,address)")] @@ -132,9 +132,9 @@ where let who = handle.caller_account_id::(); let target_address = R::AddressMapping::into_account_id(target_address.0); let call = pallet_crowdloan::Call::::create { - deposit, - min_contribution, - cap, + deposit: deposit.into(), + min_contribution: min_contribution.into(), + cap: cap.into(), end: end.into(), call: None, target_address: Some(target_address), @@ -153,7 +153,7 @@ where let account_id = handle.caller_account_id::(); let call = pallet_crowdloan::Call::::contribute { crowdloan_id, - amount, + amount: amount.into(), }; handle.try_dispatch_runtime_call::(call, RawOrigin::Signed(account_id)) @@ -205,7 +205,7 @@ where let account_id = handle.caller_account_id::(); let call = pallet_crowdloan::Call::::update_min_contribution { crowdloan_id, - new_min_contribution, + new_min_contribution: new_min_contribution.into(), }; handle.try_dispatch_runtime_call::(call, RawOrigin::Signed(account_id)) @@ -237,7 +237,7 @@ where let account_id = handle.caller_account_id::(); let call = pallet_crowdloan::Call::::update_cap { crowdloan_id, - new_cap, + new_cap: new_cap.into(), }; handle.try_dispatch_runtime_call::(call, RawOrigin::Signed(account_id)) diff --git a/precompiles/src/leasing.rs b/precompiles/src/leasing.rs index 732e687c6f..e3e11759a2 100644 --- a/precompiles/src/leasing.rs +++ b/precompiles/src/leasing.rs @@ -90,7 +90,7 @@ where .map(|b| b.unique_saturated_into()) .unwrap_or(0), netuid: lease.netuid.into(), - cost: lease.cost, + cost: lease.cost.into(), }) } @@ -150,9 +150,9 @@ where }; let crowdloan_call = pallet_crowdloan::Call::::create { - deposit: crowdloan_deposit, - min_contribution: crowdloan_min_contribution, - cap: crowdloan_cap, + deposit: crowdloan_deposit.into(), + min_contribution: crowdloan_min_contribution.into(), + cap: crowdloan_cap.into(), end: crowdloan_end.into(), call: Some(leasing_call), target_address: None, diff --git a/precompiles/src/metagraph.rs b/precompiles/src/metagraph.rs index cc9652a74b..4b3738df57 100644 --- a/precompiles/src/metagraph.rs +++ b/precompiles/src/metagraph.rs @@ -5,7 +5,7 @@ use fp_evm::{ExitError, PrecompileFailure, PrecompileHandle}; use pallet_subtensor::AxonInfo as SubtensorModuleAxonInfo; use precompile_utils::{EvmResult, solidity::Codec}; use sp_core::{ByteArray, H256}; -use subtensor_runtime_common::{Currency, NetUid}; +use subtensor_runtime_common::{NetUid, Token}; use crate::PrecompileExt; diff --git a/precompiles/src/staking.rs b/precompiles/src/staking.rs index c276c32e60..93bc9be3a7 100644 --- a/precompiles/src/staking.rs +++ b/precompiles/src/staking.rs @@ -39,7 +39,7 @@ use precompile_utils::EvmResult; use sp_core::{H256, U256}; use sp_runtime::traits::{AsSystemOriginSigner, Dispatchable, StaticLookup, UniqueSaturatedInto}; use sp_std::vec; -use subtensor_runtime_common::{Currency, NetUid, ProxyType}; +use subtensor_runtime_common::{NetUid, ProxyType, Token}; use crate::{PrecompileExt, PrecompileHandleExt}; diff --git a/precompiles/src/storage_query.rs b/precompiles/src/storage_query.rs index 796d1c8f04..455a9e81c1 100644 --- a/precompiles/src/storage_query.rs +++ b/precompiles/src/storage_query.rs @@ -103,12 +103,11 @@ where match sp_io::storage::get(input) { Some(value) => { - let result = value.to_vec(); - handle.record_db_read::(result.len())?; + handle.record_db_read::(value.len())?; Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, - output: result, + output: value.to_vec(), }) } None => { diff --git a/precompiles/src/subnet.rs b/precompiles/src/subnet.rs index 9d1e24cc1e..79c08c2625 100644 --- a/precompiles/src/subnet.rs +++ b/precompiles/src/subnet.rs @@ -9,7 +9,7 @@ use precompile_utils::{EvmResult, prelude::BoundedString}; use sp_core::H256; use sp_runtime::traits::{AsSystemOriginSigner, Dispatchable}; use sp_std::vec; -use subtensor_runtime_common::{Currency, NetUid}; +use subtensor_runtime_common::{NetUid, Token}; use crate::{PrecompileExt, PrecompileHandleExt}; diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index 623846de12..2d7b2250d6 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -21,6 +21,7 @@ subtensor-custom-rpc-runtime-api.workspace = true smallvec.workspace = true log.workspace = true codec = { workspace = true, features = ["derive"] } +safe-math.workspace = true scale-info = { workspace = true, features = ["derive"] } serde_json = { workspace = true, features = ["alloc"] } pallet-aura = { workspace = true } @@ -58,6 +59,7 @@ sp-version.workspace = true sp-authority-discovery.workspace = true subtensor-runtime-common.workspace = true subtensor-precompiles.workspace = true +sp-weights.workspace = true # Temporary sudo pallet-sudo.workspace = true @@ -138,7 +140,6 @@ fp-account.workspace = true #drand pallet-drand.workspace = true -getrandom.workspace = true tle.workspace = true hex.workspace = true rand_chacha.workspace = true @@ -151,6 +152,7 @@ pallet-crowdloan.workspace = true # Mev Shield pallet-shield.workspace = true +stp-shield.workspace = true ethereum.workspace = true @@ -218,6 +220,7 @@ std = [ "sp-io/std", "sp-tracing/std", "log/std", + "safe-math/std", "sp-storage/std", "sp-genesis-builder/std", "subtensor-precompiles/std", @@ -256,7 +259,6 @@ std = [ "pallet-hotfix-sufficients/std", "fp-account/std", "pallet-drand/std", - "getrandom/std", "tle/std", "ark-serialize/std", "hex/std", @@ -276,6 +278,8 @@ std = [ "subtensor-chain-extensions/std", "ethereum/std", "pallet-shield/std", + "stp-shield/std", + "sp-weights/std", ] runtime-benchmarks = [ "frame-benchmarking/runtime-benchmarks", @@ -321,6 +325,8 @@ runtime-benchmarks = [ # Smart Tx fees pallet "subtensor-transaction-fee/runtime-benchmarks", "pallet-shield/runtime-benchmarks", + + "subtensor-runtime-common/runtime-benchmarks", ] try-runtime = [ "frame-try-runtime/try-runtime", diff --git a/runtime/src/check_mortality.rs b/runtime/src/check_mortality.rs new file mode 100644 index 0000000000..6d8316ba01 --- /dev/null +++ b/runtime/src/check_mortality.rs @@ -0,0 +1,219 @@ +use codec::{Decode, DecodeWithMemTracking, Encode}; +use core::marker::PhantomData; +use frame_support::pallet_prelude::TypeInfo; +use frame_support::traits::IsSubType; +use frame_system::CheckMortality as CheckMortalitySubstrate; +use pallet_shield::Call as ShieldCall; +use sp_runtime::{ + generic::Era, + traits::{DispatchInfoOf, Dispatchable, Implication, TransactionExtension, ValidateResult}, + transaction_validity::{InvalidTransaction, TransactionSource, TransactionValidityError}, +}; +use subtensor_macros::freeze_struct; + +/// Maximum allowed Era period (in blocks) for `submit_encrypted` transactions. +/// +/// Substrate's minimum mortal Era is 4 blocks (smallest power-of-two ≥ 4). +/// Limiting encrypted txs to this value ensures stuck transactions evict from +/// the fork-aware tx pool within a handful of blocks. +const MAX_SHIELD_ERA_PERIOD: u64 = 8; + +/// A transparent wrapper around [`frame_system::CheckMortality`] that additionally +/// enforces a short Era period for [`pallet_shield::Call::submit_encrypted`] transactions. +/// +/// Drop-in replacement for `frame_system::CheckMortality` in the runtime's +/// transaction extension pipeline. Shares the same `IDENTIFIER = "CheckMortality"` +/// and identical SCALE encoding, so existing clients require no changes. +/// +/// Any `submit_encrypted` call signed with an immortal Era or a mortal Era period +/// longer than [`MAX_SHIELD_ERA_PERIOD`] is rejected immediately at pool submission +/// with `InvalidTransaction::Stale`, preventing pool bloat from long-lived +/// encrypted transactions that can never be decrypted. +#[freeze_struct("3cb7a665d55d00e5")] +#[derive(Encode, Decode, DecodeWithMemTracking, Clone, Eq, PartialEq, TypeInfo)] +#[scale_info(skip_type_params(T))] +pub struct CheckMortality(pub Era, PhantomData); + +impl CheckMortality { + pub fn from(era: Era) -> Self { + Self(era, PhantomData) + } +} + +impl core::fmt::Debug for CheckMortality { + #[cfg(feature = "std")] + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "CheckMortality({:?})", self.0) + } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut core::fmt::Formatter) -> core::fmt::Result { + Ok(()) + } +} + +impl TransactionExtension + for CheckMortality +where + T::RuntimeCall: Dispatchable + IsSubType>, + T: pallet_shield::Config, +{ + const IDENTIFIER: &'static str = "CheckMortality"; + + type Implicit = as TransactionExtension>::Implicit; + type Val = as TransactionExtension>::Val; + type Pre = as TransactionExtension>::Pre; + + fn implicit(&self) -> Result { + CheckMortalitySubstrate::::from(self.0).implicit() + } + + fn weight(&self, call: &T::RuntimeCall) -> sp_weights::Weight { + CheckMortalitySubstrate::::from(self.0).weight(call) + } + + fn validate( + &self, + origin: T::RuntimeOrigin, + call: &T::RuntimeCall, + info: &DispatchInfoOf, + len: usize, + self_implicit: Self::Implicit, + inherited_implication: &impl Implication, + source: TransactionSource, + ) -> ValidateResult { + if let Some(ShieldCall::submit_encrypted { .. }) = + IsSubType::>::is_sub_type(call) + { + let era_too_long = match self.0 { + Era::Immortal => true, + Era::Mortal(period, _) => period > MAX_SHIELD_ERA_PERIOD, + }; + if era_too_long { + return Err(InvalidTransaction::Stale.into()); + } + } + + CheckMortalitySubstrate::::from(self.0).validate( + origin, + call, + info, + len, + self_implicit, + inherited_implication, + source, + ) + } + + fn prepare( + self, + val: Self::Val, + origin: &T::RuntimeOrigin, + call: &T::RuntimeCall, + info: &DispatchInfoOf, + len: usize, + ) -> Result { + CheckMortalitySubstrate::::from(self.0).prepare(val, origin, call, info, len) + } +} + +#[allow(clippy::unwrap_used)] +#[cfg(test)] +mod tests { + use super::*; + + use frame_support::pallet_prelude::{BoundedVec, ConstU32}; + + use sp_runtime::transaction_validity::InvalidTransaction; + + use crate::{Runtime, RuntimeCall, System}; + use sp_runtime::BuildStorage; + + fn new_test_ext() -> sp_io::TestExternalities { + let mut ext: sp_io::TestExternalities = crate::RuntimeGenesisConfig { + sudo: pallet_sudo::GenesisConfig { key: None }, + ..Default::default() + } + .build_storage() + .unwrap() + .into(); + ext.execute_with(|| System::set_block_number(1)); + ext + } + + fn submit_encrypted_call() -> RuntimeCall { + RuntimeCall::MevShield(pallet_shield::Call::submit_encrypted { + ciphertext: BoundedVec::>::truncate_from(vec![0xAA; 64]), + }) + } + + fn remark_call() -> RuntimeCall { + RuntimeCall::System(frame_system::Call::remark { remark: vec![] }) + } + + /// Only tests the early-return path (era check). Does NOT call into + /// CheckMortalitySubstrate which needs real block hashes. + fn validate_era_check(era: Era, call: &RuntimeCall) -> Result<(), TransactionValidityError> { + if let Some(ShieldCall::submit_encrypted { .. }) = + IsSubType::>::is_sub_type(call) + { + let era_too_long = match era { + Era::Immortal => true, + Era::Mortal(period, _) => period > MAX_SHIELD_ERA_PERIOD, + }; + if era_too_long { + return Err(InvalidTransaction::Stale.into()); + } + } + Ok(()) + } + + #[test] + fn shield_tx_with_immortal_era_rejected() { + new_test_ext().execute_with(|| { + assert_eq!( + validate_era_check(Era::Immortal, &submit_encrypted_call()), + Err(InvalidTransaction::Stale.into()) + ); + }); + } + + #[test] + fn shield_tx_with_era_too_long_rejected() { + new_test_ext().execute_with(|| { + // Period 16 > MAX_SHIELD_ERA_PERIOD (8) + assert_eq!( + validate_era_check(Era::mortal(16, 1), &submit_encrypted_call()), + Err(InvalidTransaction::Stale.into()) + ); + }); + } + + #[test] + fn shield_tx_with_max_allowed_era_accepted() { + new_test_ext().execute_with(|| { + assert!(validate_era_check(Era::mortal(8, 1), &submit_encrypted_call()).is_ok()); + }); + } + + #[test] + fn shield_tx_with_short_era_accepted() { + new_test_ext().execute_with(|| { + assert!(validate_era_check(Era::mortal(4, 1), &submit_encrypted_call()).is_ok()); + }); + } + + #[test] + fn non_shield_tx_with_immortal_era_passes_through() { + new_test_ext().execute_with(|| { + assert!(validate_era_check(Era::Immortal, &remark_call()).is_ok()); + }); + } + + #[test] + fn non_shield_tx_with_long_era_passes_through() { + new_test_ext().execute_with(|| { + assert!(validate_era_check(Era::mortal(256, 1), &remark_call()).is_ok()); + }); + } +} diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 41a00e3f64..5e3436a78c 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -10,6 +10,7 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); use core::num::NonZeroU64; +pub mod check_mortality; pub mod check_nonce; mod migrations; pub mod sudo_wrapper; @@ -42,9 +43,10 @@ use pallet_subtensor::rpc_info::{ }; use pallet_subtensor::{CommitmentsInterface, ProxyInterface}; use pallet_subtensor_proxy as pallet_proxy; -use pallet_subtensor_swap_runtime_api::SimSwapResult; +use pallet_subtensor_swap_runtime_api::{SimSwapResult, SubnetPrice}; use pallet_subtensor_utility as pallet_utility; use runtime_common::prod_or_fast; +use safe_math::FixedExt; use sp_api::impl_runtime_apis; use sp_consensus_aura::sr25519::AuthorityId as AuraId; use sp_consensus_babe::BabeConfiguration; @@ -70,8 +72,10 @@ use sp_std::prelude::*; #[cfg(feature = "std")] use sp_version::NativeVersion; use sp_version::RuntimeVersion; +use stp_shield::ShieldedTransaction; +use substrate_fixed::types::U96F32; use subtensor_precompiles::Precompiles; -use subtensor_runtime_common::{AlphaCurrency, AuthorshipInfo, TaoCurrency, time::*, *}; +use subtensor_runtime_common::{AlphaBalance, AuthorshipInfo, TaoBalance, time::*, *}; use subtensor_swap_interface::{Order, SwapHandler}; // A few exports that help ease life for downstream crates. @@ -123,9 +127,28 @@ impl frame_system::offchain::SigningTypes for Runtime { type Signature = Signature; } +pub struct FindAuraAuthors; +impl pallet_shield::FindAuthors for FindAuraAuthors { + fn find_current_author() -> Option { + let slot = Aura::current_slot_from_digests()?; + let authorities = pallet_aura::Authorities::::get().into_inner(); + let author_index = *slot % authorities.len() as u64; + + authorities.get(author_index as usize).cloned() + } + + fn find_next_next_author() -> Option { + let slot = Aura::current_slot_from_digests()?.checked_add(2)?; + let authorities = pallet_aura::Authorities::::get().into_inner(); + let author_index = slot % authorities.len() as u64; + + authorities.get(author_index as usize).cloned() + } +} + impl pallet_shield::Config for Runtime { - type RuntimeCall = RuntimeCall; - type AuthorityOrigin = pallet_shield::EnsureAuraAuthority; + type AuthorityId = AuraId; + type FindAuthors = FindAuraAuthors; } parameter_types! { @@ -165,20 +188,23 @@ impl frame_system::offchain::CreateSignedTransaction use sp_runtime::traits::StaticLookup; let address = ::Lookup::unlookup(account.clone()); - let extra: TransactionExtensions = ( - frame_system::CheckNonZeroSender::::new(), - frame_system::CheckSpecVersion::::new(), - frame_system::CheckTxVersion::::new(), - frame_system::CheckGenesis::::new(), - frame_system::CheckEra::::from(Era::Immortal), - check_nonce::CheckNonce::::from(nonce).into(), - frame_system::CheckWeight::::new(), - ChargeTransactionPaymentWrapper::new( - pallet_transaction_payment::ChargeTransactionPayment::::from(0), + let extra: TxExtension = ( + ( + frame_system::CheckNonZeroSender::::new(), + frame_system::CheckSpecVersion::::new(), + frame_system::CheckTxVersion::::new(), + frame_system::CheckGenesis::::new(), + check_mortality::CheckMortality::::from(Era::Immortal), + check_nonce::CheckNonce::::from(nonce).into(), + frame_system::CheckWeight::::new(), + ), + ( + ChargeTransactionPaymentWrapper::new(TaoBalance::new(0)), + SudoTransactionExtension::::new(), + pallet_shield::CheckShieldedTxValidity::::new(), + pallet_subtensor::SubtensorTransactionExtension::::new(), + pallet_drand::drand_priority::DrandPriority::::new(), ), - SudoTransactionExtension::::new(), - pallet_subtensor::SubtensorTransactionExtension::::new(), - pallet_drand::drand_priority::DrandPriority::::new(), frame_metadata_hash_extension::CheckMetadataHash::::new(true), ); @@ -197,11 +223,13 @@ pub use pallet_subtensor; // Method used to calculate the fee of an extrinsic pub const fn deposit(items: u32, bytes: u32) -> Balance { - pub const ITEMS_FEE: Balance = 2_000 * 10_000; - pub const BYTES_FEE: Balance = 100 * 10_000; - (items as Balance) - .saturating_mul(ITEMS_FEE) - .saturating_add((bytes as Balance).saturating_mul(BYTES_FEE)) + pub const ITEMS_FEE: u64 = 2_000 * 10_000; + pub const BYTES_FEE: u64 = 100 * 10_000; + TaoBalance::new( + (items as u64) + .saturating_mul(ITEMS_FEE) + .saturating_add((bytes as u64).saturating_mul(BYTES_FEE)), + ) } // Opaque types. These are used by the CLI to instantiate machinery that don't need to know @@ -240,7 +268,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: 385, + spec_version: 390, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1, @@ -470,6 +498,9 @@ impl pallet_safe_mode::Config for Runtime { // Existential deposit. pub const EXISTENTIAL_DEPOSIT: u64 = 500; +parameter_types! { + pub const ExistentialDeposit: TaoBalance = TaoBalance::new(500); +} impl pallet_balances::Config for Runtime { type MaxLocks = ConstU32<50>; @@ -480,7 +511,7 @@ impl pallet_balances::Config for Runtime { // The ubiquitous event type. type RuntimeEvent = RuntimeEvent; type DustRemoval = (); - type ExistentialDeposit = ConstU64; + type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; type WeightInfo = pallet_balances::weights::SubstrateWeight; @@ -637,7 +668,7 @@ impl InstanceFilter for ProxyType { RuntimeCall::SubtensorModule(pallet_subtensor::Call::transfer_stake { alpha_amount, .. - }) => *alpha_amount < SMALL_TRANSFER_LIMIT.into(), + }) => *alpha_amount < SMALL_ALPHA_TRANSFER_LIMIT, _ => false, }, ProxyType::Owner => { @@ -924,8 +955,8 @@ impl CanRegisterIdentity for AllowIdentityReg { // Configure registry pallet. parameter_types! { pub const MaxAdditionalFields: u32 = 1; - pub const InitialDeposit: Balance = 100_000_000; // 0.1 TAO - pub const FieldDeposit: Balance = 100_000_000; // 0.1 TAO + pub const InitialDeposit: Balance = TaoBalance::new(100_000_000); // 0.1 TAO + pub const FieldDeposit: Balance = TaoBalance::new(100_000_000); // 0.1 TAO } impl pallet_registry::Config for Runtime { @@ -941,8 +972,8 @@ impl pallet_registry::Config for Runtime { parameter_types! { pub const MaxCommitFieldsInner: u32 = 3; - pub const CommitmentInitialDeposit: Balance = 0; // Free - pub const CommitmentFieldDeposit: Balance = 0; // Free + pub const CommitmentInitialDeposit: Balance = TaoBalance::ZERO; // Free + pub const CommitmentFieldDeposit: Balance = TaoBalance::ZERO; // Free } #[subtensor_macros::freeze_struct("7c76bd954afbb54e")] @@ -974,7 +1005,7 @@ impl OnMetadataCommitment for ResetBondsOnCommit { fn on_metadata_commitment(netuid: NetUid, address: &AccountId) { // Reset bonds for each mechanism of this subnet let mechanism_count = SubtensorModule::get_current_mechanism_count(netuid); - for mecid in 0..u8::from(mechanism_count) { + for mecid in 0..>::from(mechanism_count) { let netuid_index = SubtensorModule::get_mechanism_storage_index(netuid, mecid.into()); let _ = SubtensorModule::do_reset_bonds(netuid_index, address); } @@ -1030,7 +1061,7 @@ parameter_types! { pub const SubtensorInitialAlphaSigmoidSteepness: i16 = 1000; pub const SubtensorInitialKappa: u16 = 32_767; // 0.5 = 65535/2 pub const SubtensorInitialMaxAllowedUids: u16 = 256; - pub const SubtensorInitialIssuance: u64 = 0; + pub const SubtensorInitialIssuance: TaoBalance = TaoBalance::ZERO; pub const SubtensorInitialMinAllowedWeights: u16 = 1024; pub const SubtensorInitialEmissionValue: u16 = 0; pub const SubtensorInitialValidatorPruneLen: u64 = 1; @@ -1057,23 +1088,23 @@ parameter_types! { pub const SubtensorInitialMinDifficulty: u64 = 10_000_000; pub const SubtensorInitialMaxDifficulty: u64 = u64::MAX / 4; pub const SubtensorInitialServingRateLimit: u64 = 50; - pub const SubtensorInitialBurn: u64 = 100_000_000; // 0.1 tao - pub const SubtensorInitialMinBurn: u64 = 500_000; // 500k RAO - pub const SubtensorInitialMaxBurn: u64 = 100_000_000_000; // 100 tao - pub const MinBurnUpperBound: TaoCurrency = TaoCurrency::new(1_000_000_000); // 1 TAO - pub const MaxBurnLowerBound: TaoCurrency = TaoCurrency::new(100_000_000); // 0.1 TAO + pub const SubtensorInitialBurn: TaoBalance = TaoBalance::new(100_000_000); // 0.1 tao + pub const SubtensorInitialMinBurn: TaoBalance = TaoBalance::new(500_000); // 500k RAO + pub const SubtensorInitialMaxBurn: TaoBalance = TaoBalance::new(100_000_000_000); // 100 tao + pub const MinBurnUpperBound: TaoBalance = TaoBalance::new(1_000_000_000); // 1 TAO + pub const MaxBurnLowerBound: TaoBalance = TaoBalance::new(100_000_000); // 0.1 TAO pub const SubtensorInitialTxRateLimit: u64 = 1000; pub const SubtensorInitialTxDelegateTakeRateLimit: u64 = 216000; // 30 days at 12 seconds per block pub const SubtensorInitialTxChildKeyTakeRateLimit: u64 = INITIAL_CHILDKEY_TAKE_RATELIMIT; - pub const SubtensorInitialRAORecycledForRegistration: u64 = 0; // 0 rao + pub const SubtensorInitialRAORecycledForRegistration: TaoBalance = TaoBalance::ZERO; // 0 rao pub const SubtensorInitialRequiredStakePercentage: u64 = 1; // 1 percent of total stake pub const SubtensorInitialNetworkImmunity: u64 = 1_296_000; pub const SubtensorInitialMinAllowedUids: u16 = 64; - pub const SubtensorInitialMinLockCost: u64 = 1_000_000_000_000; // 1000 TAO + pub const SubtensorInitialMinLockCost: TaoBalance = TaoBalance::new(1_000_000_000_000_u64); // 1000 TAO pub const SubtensorInitialSubnetOwnerCut: u16 = 11_796; // 18 percent pub const SubtensorInitialNetworkLockReductionInterval: u64 = 14 * 7200; pub const SubtensorInitialNetworkRateLimit: u64 = 7200; - pub const SubtensorInitialKeySwapCost: u64 = 100_000_000; // 0.1 TAO + pub const SubtensorInitialKeySwapCost: TaoBalance = TaoBalance::new(100_000_000); // 0.1 TAO pub const InitialAlphaHigh: u16 = 58982; // Represents 0.9 as per the production default pub const InitialAlphaLow: u16 = 45875; // Represents 0.7 as per the production default pub const InitialLiquidAlphaOn: bool = false; // Default value for LiquidAlphaOn @@ -1085,8 +1116,8 @@ parameter_types! { pub const InitialEmaPriceHalvingPeriod: u64 = 201_600_u64; // 4 weeks // 0 days pub const InitialStartCallDelay: u64 = 0; - pub const SubtensorInitialKeySwapOnSubnetCost: u64 = 1_000_000; // 0.001 TAO - pub const HotkeySwapOnSubnetInterval : BlockNumber = 5 * 24 * 60 * 60 / 12; // 5 days + pub const SubtensorInitialKeySwapOnSubnetCost: TaoBalance = TaoBalance::new(1_000_000); // 0.001 TAO + pub const HotkeySwapOnSubnetInterval : BlockNumber = 24 * 60 * 60 / 12; // 1 day pub const LeaseDividendsDistributionInterval: BlockNumber = 100; // 100 blocks pub const MaxImmuneUidsPercentage: Percent = Percent::from_percent(80); pub const EvmKeyAssociateRateLimit: u64 = EVM_KEY_ASSOCIATE_RATELIMIT; @@ -1280,7 +1311,7 @@ const EVM_TO_SUBSTRATE_DECIMALS: u64 = 1_000_000_000_u64; pub struct SubtensorEvmBalanceConverter; impl BalanceConverter for SubtensorEvmBalanceConverter { - /// Convert from Substrate balance (u64) to EVM balance (U256) + /// Convert from Substrate balance (TaoBalance) to EVM balance (U256) fn into_evm_balance(value: SubstrateBalance) -> Option { let value = value.into_u256(); if let Some(evm_value) = value.checked_mul(U256::from(EVM_TO_SUBSTRATE_DECIMALS)) { @@ -1301,7 +1332,7 @@ impl BalanceConverter for SubtensorEvmBalanceConverter { } } - /// Convert from EVM balance (U256) to Substrate balance (u64) + /// Convert from EVM balance (U256) to Substrate balance (TaoBalance) fn into_substrate_balance(value: EvmBalance) -> Option { let value = value.into_u256(); if let Some(substrate_value) = value.checked_div(U256::from(EVM_TO_SUBSTRATE_DECIMALS)) { @@ -1480,8 +1511,8 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { // Crowdloan parameter_types! { pub const CrowdloanPalletId: PalletId = PalletId(*b"bt/cloan"); - pub const MinimumDeposit: Balance = 10_000_000_000; // 10 TAO - pub const AbsoluteMinimumContribution: Balance = 100_000_000; // 0.1 TAO + pub const MinimumDeposit: Balance = TaoBalance::new(10_000_000_000); // 10 TAO + pub const AbsoluteMinimumContribution: Balance = TaoBalance::new(100_000_000); // 0.1 TAO // 7 days minimum (7 * 24 * 60 * 60 / 12) pub const MinimumBlockDuration: BlockNumber = prod_or_fast!(50400, 50); // 60 days maximum (60 * 24 * 60 * 60 / 12) @@ -1515,19 +1546,19 @@ fn contracts_schedule() -> pallet_contracts::Schedu } } -const CONTRACT_STORAGE_KEY_PERCENT: Balance = 15; -const CONTRACT_STORAGE_BYTE_PERCENT: Balance = 6; +const CONTRACT_STORAGE_KEY_PERCENT: u64 = 15; +const CONTRACT_STORAGE_BYTE_PERCENT: u64 = 6; /// Contracts deposits charged at 15% of the existential deposit per key, 6% per byte. pub const fn contract_deposit(items: u32, bytes: u32) -> Balance { - let key_fee = - (EXISTENTIAL_DEPOSIT as Balance).saturating_mul(CONTRACT_STORAGE_KEY_PERCENT) / 100; - let byte_fee = - (EXISTENTIAL_DEPOSIT as Balance).saturating_mul(CONTRACT_STORAGE_BYTE_PERCENT) / 100; + let key_fee = EXISTENTIAL_DEPOSIT.saturating_mul(CONTRACT_STORAGE_KEY_PERCENT) / 100; + let byte_fee = EXISTENTIAL_DEPOSIT.saturating_mul(CONTRACT_STORAGE_BYTE_PERCENT) / 100; - (items as Balance) - .saturating_mul(key_fee) - .saturating_add((bytes as Balance).saturating_mul(byte_fee)) + TaoBalance::new( + (items as u64) + .saturating_mul(key_fee) + .saturating_add((bytes as u64).saturating_mul(byte_fee)), + ) } parameter_types! { @@ -1635,18 +1666,25 @@ pub type Header = generic::Header; // Block type as expected by this runtime. pub type Block = generic::Block; // The extensions to the basic transaction logic. -pub type TransactionExtensions = ( +pub type SystemTxExtension = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, frame_system::CheckGenesis, - frame_system::CheckEra, + check_mortality::CheckMortality, check_nonce::CheckNonce, frame_system::CheckWeight, +); +pub type CustomTxExtension = ( ChargeTransactionPaymentWrapper, SudoTransactionExtension, + pallet_shield::CheckShieldedTxValidity, pallet_subtensor::SubtensorTransactionExtension, pallet_drand::drand_priority::DrandPriority, +); +pub type TxExtension = ( + SystemTxExtension, + CustomTxExtension, frame_metadata_hash_extension::CheckMetadataHash, ); @@ -1660,19 +1698,22 @@ type Migrations = ( // Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - fp_self_contained::UncheckedExtrinsic; + fp_self_contained::UncheckedExtrinsic; /// Extrinsic type that has already been checked. pub type CheckedExtrinsic = - fp_self_contained::CheckedExtrinsic; + fp_self_contained::CheckedExtrinsic; // The payload being signed in transactions. -pub type SignedPayload = generic::SignedPayload; +pub type SignedPayload = generic::SignedPayload; + +// Chain context for the executive. +pub type ChainContext = frame_system::ChainContext; // Executive: handles dispatch to the various modules. pub type Executive = frame_executive::Executive< Runtime, Block, - frame_system::ChainContext, + ChainContext, Runtime, AllPalletsWithSystem, Migrations, @@ -2355,7 +2396,7 @@ impl_runtime_apis! { SubtensorModule::get_delegate(delegate_account) } - fn get_delegated(delegatee_account: AccountId32) -> Vec<(DelegateInfo, (Compact, Compact))> { + fn get_delegated(delegatee_account: AccountId32) -> Vec<(DelegateInfo, (Compact, Compact))> { SubtensorModule::get_delegated(delegatee_account) } } @@ -2466,7 +2507,7 @@ impl_runtime_apis! { } impl subtensor_custom_rpc_runtime_api::SubnetRegistrationRuntimeApi for Runtime { - fn get_network_registration_cost() -> TaoCurrency { + fn get_network_registration_cost() -> TaoBalance { SubtensorModule::get_network_lock_cost() } } @@ -2528,14 +2569,27 @@ impl_runtime_apis! { impl pallet_subtensor_swap_runtime_api::SwapRuntimeApi for Runtime { fn current_alpha_price(netuid: NetUid) -> u64 { - use substrate_fixed::types::U96F32; - pallet_subtensor_swap::Pallet::::current_price(netuid.into()) .saturating_mul(U96F32::from_num(1_000_000_000)) .saturating_to_num() } - fn sim_swap_tao_for_alpha(netuid: NetUid, tao: TaoCurrency) -> SimSwapResult { + fn current_alpha_price_all() -> Vec { + pallet_subtensor::Pallet::::get_all_subnet_netuids() + .into_iter() + .map(|netuid| { + SubnetPrice { + netuid, + price: Self::current_alpha_price(netuid), + } + }) + .collect() + } + + fn sim_swap_tao_for_alpha(netuid: NetUid, tao: TaoBalance) -> SimSwapResult { + let price = pallet_subtensor_swap::Pallet::::current_price(netuid.into()); + let tao_u64: u64 = tao.into(); + let no_slippage_alpha = U96F32::saturating_from_num(tao_u64).safe_div(price).saturating_to_num::(); 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( @@ -2548,17 +2602,24 @@ impl_runtime_apis! { alpha_amount: 0.into(), tao_fee: 0.into(), alpha_fee: 0.into(), + tao_slippage: 0.into(), + alpha_slippage: 0.into(), }, |sr| SimSwapResult { tao_amount: sr.amount_paid_in.into(), alpha_amount: sr.amount_paid_out.into(), tao_fee: sr.fee_paid.into(), alpha_fee: 0.into(), + tao_slippage: 0.into(), + alpha_slippage: no_slippage_alpha.saturating_sub(sr.amount_paid_out.into()).into(), }, ) } - fn sim_swap_alpha_for_tao(netuid: NetUid, alpha: AlphaCurrency) -> SimSwapResult { + fn sim_swap_alpha_for_tao(netuid: NetUid, alpha: AlphaBalance) -> SimSwapResult { + let price = pallet_subtensor_swap::Pallet::::current_price(netuid.into()); + let alpha_u64: u64 = alpha.into(); + let no_slippage_tao = U96F32::saturating_from_num(alpha_u64).saturating_mul(price).saturating_to_num::(); 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( @@ -2571,16 +2632,34 @@ impl_runtime_apis! { alpha_amount: 0.into(), tao_fee: 0.into(), alpha_fee: 0.into(), + tao_slippage: 0.into(), + alpha_slippage: 0.into(), }, |sr| SimSwapResult { tao_amount: sr.amount_paid_out.into(), alpha_amount: sr.amount_paid_in.into(), tao_fee: 0.into(), alpha_fee: sr.fee_paid.into(), + tao_slippage: no_slippage_tao.saturating_sub(sr.amount_paid_out.into()).into(), + alpha_slippage: 0.into(), }, ) } } + + impl stp_shield::ShieldApi for Runtime { + fn try_decode_shielded_tx(uxt: ::Extrinsic) -> Option { + MevShield::try_decode_shielded_tx::(uxt) + } + + fn is_shielded_using_current_key(key_hash: &[u8; 16]) -> bool { + MevShield::is_shielded_using_current_key(key_hash) + } + + fn try_unshield_tx(dec_key_bytes: Vec, shielded_tx: ShieldedTransaction) -> Option<::Extrinsic> { + MevShield::try_unshield_tx::(dec_key_bytes, shielded_tx) + } + } } #[test] diff --git a/runtime/src/transaction_payment_wrapper.rs b/runtime/src/transaction_payment_wrapper.rs index 7973c44caf..b16773daf9 100644 --- a/runtime/src/transaction_payment_wrapper.rs +++ b/runtime/src/transaction_payment_wrapper.rs @@ -6,6 +6,7 @@ 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::OnChargeTransaction; use pallet_transaction_payment::{ChargeTransactionPayment, Config, Pre, Val}; use sp_runtime::DispatchResult; use sp_runtime::traits::{ @@ -20,16 +21,18 @@ use sp_std::boxed::Box; use sp_std::vec::Vec; use subtensor_macros::freeze_struct; +type BalanceOf = <::OnChargeTransaction as OnChargeTransaction>::Balance; + type RuntimeCallOf = ::RuntimeCall; type RuntimeOriginOf = ::RuntimeOrigin; type AccountIdOf = ::AccountId; type LookupOf = ::Lookup; -#[freeze_struct("5f10cb9db06873c0")] +#[freeze_struct("f003cde1f9da4a90")] #[derive(Encode, Decode, DecodeWithMemTracking, Clone, Eq, PartialEq, TypeInfo)] #[scale_info(skip_type_params(T))] pub struct ChargeTransactionPaymentWrapper { - charge_transaction_payment: ChargeTransactionPayment, + inner: ChargeTransactionPayment, } impl core::fmt::Debug for ChargeTransactionPaymentWrapper { @@ -43,11 +46,14 @@ impl core::fmt::Debug for ChargeTransactionPaymentWrapper { } } -impl ChargeTransactionPaymentWrapper { - pub fn new(charge_transaction_payment: ChargeTransactionPayment) -> Self { - Self { - charge_transaction_payment, - } +impl ChargeTransactionPaymentWrapper +where + T::RuntimeCall: Dispatchable, + BalanceOf: Send + Sync, +{ + pub fn new(fee: BalanceOf) -> Self { + let inner = ChargeTransactionPayment::::from(fee); + Self { inner } } } @@ -196,7 +202,7 @@ where 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 + self.inner .weight(call) .saturating_add(T::DbWeight::get().reads(3)) } @@ -228,7 +234,7 @@ where origin.clone() }; - let (mut valid_transaction, val, _fee_origin) = self.charge_transaction_payment.validate( + let (mut valid_transaction, val, _fee_origin) = self.inner.validate( fee_origin, call, info, @@ -253,12 +259,13 @@ where info: &DispatchInfoOf>, len: usize, ) -> Result { - self.charge_transaction_payment - .prepare(val, origin, call, info, len) + self.inner.prepare(val, origin, call, info, len) } + fn metadata() -> Vec { ChargeTransactionPayment::::metadata() } + fn post_dispatch_details( pre: Self::Pre, info: &DispatchInfoOf>, diff --git a/runtime/tests/pallet_proxy.rs b/runtime/tests/pallet_proxy.rs index 422885eaba..1da1c4cdcc 100644 --- a/runtime/tests/pallet_proxy.rs +++ b/runtime/tests/pallet_proxy.rs @@ -6,7 +6,7 @@ use node_subtensor_runtime::{ RuntimeOrigin, SubtensorModule, System, SystemCall, }; use pallet_subtensor_proxy as pallet_proxy; -use subtensor_runtime_common::{AccountId, NetUid, ProxyType}; +use subtensor_runtime_common::{AccountId, NetUid, ProxyType, TaoBalance}; const ACCOUNT: [u8; 32] = [1_u8; 32]; const DELEGATE: [u8; 32] = [2_u8; 32]; @@ -16,7 +16,7 @@ type SystemError = frame_system::Error; pub fn new_test_ext() -> sp_io::TestExternalities { sp_tracing::try_init_simple(); - let amount = 1_000_000_000_000; + let amount = TaoBalance::from(1_000_000_000_000_u64); let mut ext: sp_io::TestExternalities = RuntimeGenesisConfig { balances: pallet_balances::GenesisConfig { balances: vec![ @@ -37,7 +37,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { // transfer call fn call_transfer() -> RuntimeCall { - let value = 100; + let value = TaoBalance::from(100); RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: AccountId::from(OTHER_ACCOUNT).into(), value, diff --git a/runtime/tests/precompiles.rs b/runtime/tests/precompiles.rs index dcd7b3f3b9..815d055ab7 100644 --- a/runtime/tests/precompiles.rs +++ b/runtime/tests/precompiles.rs @@ -149,10 +149,10 @@ mod balance_transfer { let destination_balance_after = pallet_balances::Pallet::::free_balance(&destination_account); - assert_eq!(source_balance_after, source_balance_before - amount); + assert_eq!(source_balance_after, source_balance_before - amount.into()); assert_eq!( destination_balance_after, - destination_balance_before + amount + destination_balance_before + amount.into() ); }); } diff --git a/runtime/tests/transaction_payment_wrapper.rs b/runtime/tests/transaction_payment_wrapper.rs index 639e8b3576..bbc9798a3e 100644 --- a/runtime/tests/transaction_payment_wrapper.rs +++ b/runtime/tests/transaction_payment_wrapper.rs @@ -7,22 +7,22 @@ use frame_support::{ use node_subtensor_runtime::{ BuildStorage, NORMAL_DISPATCH_BASE_PRIORITY, OPERATIONAL_DISPATCH_PRIORITY, Proxy, Runtime, RuntimeCall, RuntimeGenesisConfig, RuntimeOrigin, System, SystemCall, - transaction_payment_wrapper, + transaction_payment_wrapper::ChargeTransactionPaymentWrapper, }; use pallet_subtensor_proxy as pallet_proxy; use pallet_subtensor_utility as pallet_utility; -use pallet_transaction_payment::{ChargeTransactionPayment, Val}; +use pallet_transaction_payment::Val; use sp_runtime::traits::{TransactionExtension, TxBaseImplication}; use sp_runtime::transaction_validity::{ TransactionSource, TransactionValidityError, ValidTransaction, }; -use subtensor_runtime_common::{AccountId, ProxyType}; +use subtensor_runtime_common::{AccountId, ProxyType, TaoBalance}; 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; +const BALANCE: TaoBalance = TaoBalance::new(1_000_000_000_000_u64); fn new_test_ext() -> sp_io::TestExternalities { sp_tracing::try_init_simple(); @@ -128,9 +128,7 @@ fn validate_call_with_info( call: &RuntimeCall, info: &DispatchInfo, ) -> Result<(ValidTransaction, Val), TransactionValidityError> { - let ext = transaction_payment_wrapper::ChargeTransactionPaymentWrapper::::new( - ChargeTransactionPayment::from(0u64), - ); + let ext = ChargeTransactionPaymentWrapper::::new(TaoBalance::new(0)); let (valid_tx, val, _origin) = ext.validate( origin, call, diff --git a/scripts/fix_rust.sh b/scripts/fix_rust.sh index 08e983a432..811eb86bca 100755 --- a/scripts/fix_rust.sh +++ b/scripts/fix_rust.sh @@ -12,15 +12,15 @@ commit_if_changes() { } # Step 1: Run cargo check and commit changes to Cargo.lock if any -cargo check --workspace +SKIP_WASM_BUILD=1 cargo check --workspace commit_if_changes "commit Cargo.lock" # Step 2: Run cargo clippy with fixes and commit changes if any. -cargo clippy --fix --workspace --all-features --all-targets +SKIP_WASM_BUILD=1 cargo clippy --fix --workspace --all-features --all-targets commit_if_changes "cargo clippy" # Step 3: Run cargo fix and commit changes if any. -cargo fix --workspace --all-features --all-targets +SKIP_WASM_BUILD=1 cargo fix --workspace --all-features --all-targets commit_if_changes "cargo fix" # Step 4: Run cargo fmt and commit changes if any. diff --git a/scripts/localnet.sh b/scripts/localnet.sh index 868079aee1..5a67e8f3bc 100755 --- a/scripts/localnet.sh +++ b/scripts/localnet.sh @@ -89,6 +89,7 @@ echo "*** Chainspec built and output to file" # Generate node keys "$BUILD_DIR/release/node-subtensor" key generate-node-key --chain="$FULL_PATH" --base-path /tmp/one "$BUILD_DIR/release/node-subtensor" key generate-node-key --chain="$FULL_PATH" --base-path /tmp/two +"$BUILD_DIR/release/node-subtensor" key generate-node-key --chain="$FULL_PATH" --base-path /tmp/three if [ $NO_PURGE -eq 1 ]; then echo "*** Purging previous state skipped..." @@ -96,6 +97,7 @@ else echo "*** Purging previous state..." "$BUILD_DIR/release/node-subtensor" purge-chain -y --base-path /tmp/two --chain="$FULL_PATH" >/dev/null 2>&1 "$BUILD_DIR/release/node-subtensor" purge-chain -y --base-path /tmp/one --chain="$FULL_PATH" >/dev/null 2>&1 + "$BUILD_DIR/release/node-subtensor" purge-chain -y --base-path /tmp/three --chain="$FULL_PATH" >/dev/null 2>&1 echo "*** Previous chainstate purged" fi @@ -130,17 +132,47 @@ if [ $BUILD_ONLY -eq 0 ]; then --unsafe-force-node-key-generation ) + # Insert //Three keys manually (no --three shorthand exists in Substrate) + "$BUILD_DIR/release/node-subtensor" key insert \ + --base-path /tmp/three \ + --chain="$FULL_PATH" \ + --scheme Sr25519 \ + --suri "//Three" \ + --key-type aura + "$BUILD_DIR/release/node-subtensor" key insert \ + --base-path /tmp/three \ + --chain="$FULL_PATH" \ + --scheme Ed25519 \ + --suri "//Three" \ + --key-type gran + + three_start=( + "$BUILD_DIR/release/node-subtensor" + --base-path /tmp/three + --chain="$FULL_PATH" + --name Three + --port 30336 + --rpc-port 9946 + --validator + --rpc-cors=all + --allow-private-ipv4 + --discover-local + --unsafe-force-node-key-generation + ) + # Provide RUN_IN_DOCKER local environment variable if run script in the docker image if [ "${RUN_IN_DOCKER}" == "1" ]; then one_start+=(--unsafe-rpc-external) two_start+=(--unsafe-rpc-external) + three_start+=(--unsafe-rpc-external) fi trap 'pkill -P $$' EXIT SIGINT SIGTERM ( ("${one_start[@]}" 2>&1) & - ("${two_start[@]}" 2>&1) + ("${two_start[@]}" 2>&1) & + ("${three_start[@]}" 2>&1) wait ) fi