From 9a179bb2ceea0d0f00f8d50473c68120c3324cc5 Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Fri, 12 Jul 2024 11:01:05 -0400 Subject: [PATCH 01/58] feature-gate hash --- runtime/build.rs | 11 ++++++++++- scripts/build.sh | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/runtime/build.rs b/runtime/build.rs index 8f021e838..4d65d12a7 100644 --- a/runtime/build.rs +++ b/runtime/build.rs @@ -1,5 +1,5 @@ fn main() { - #[cfg(feature = "std")] + #[cfg(all(feature = "std", not(feature = "metadata-hash")))] { substrate_wasm_builder::WasmBuilder::new() .with_current_project() @@ -7,4 +7,13 @@ fn main() { .import_memory() .build(); } + #[cfg(all(feature = "std", feature = "metadata-hash"))] + { + substrate_wasm_builder::WasmBuilder::new() + .with_current_project() + .export_heap_base() + .import_memory() + .enable_metadata_hash("TAO", 9) + .build(); + } } diff --git a/scripts/build.sh b/scripts/build.sh index 548af664b..3f588a1cc 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -1,2 +1,2 @@ -cargo build --profile production --features runtime-benchmarks +cargo build --profile production --features "runtime-benchmarks metadata-hash" From 5039e5bdb83e2f677e46773d9da3335a0298a98e Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Fri, 12 Jul 2024 11:45:49 -0400 Subject: [PATCH 02/58] use 1.10.0-rc2 --- Cargo.toml | 139 +++++++++++++++++++++++++++-------------------------- 1 file changed, 70 insertions(+), 69 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 8d9eff122..8bfb9d2b0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,80 +39,81 @@ litep2p = { git = "https://github.com/paritytech/litep2p", branch = "master" } subtensor-macros = { path = "support/macros" } -frame-benchmarking = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0", default-features = false } -frame-benchmarking-cli = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0" } -frame-executive = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0", default-features = false } -frame-support = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0", default-features = false } -frame-system = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0", default-features = false } -frame-system-benchmarking = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0", default-features = false } -frame-system-rpc-runtime-api = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0", default-features = false } -frame-try-runtime = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0", default-features = false } +frame-benchmarking = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } +frame-benchmarking-cli = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } +frame-executive = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } +frame-metadata-hash-extension = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" , default-features = false } +frame-support = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } +frame-system = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } +frame-system-benchmarking = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } +frame-system-rpc-runtime-api = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } +frame-try-runtime = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } -pallet-aura = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0", default-features = false } -pallet-balances = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0", default-features = false } -pallet-grandpa = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0", default-features = false } -pallet-insecure-randomness-collective-flip = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0", default-features = false } -pallet-membership = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0", default-features = false } -pallet-multisig = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0", default-features = false } -pallet-preimage = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0", default-features = false } -pallet-proxy = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0", default-features = false } -pallet-safe-mode = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0", default-features = false } -pallet-scheduler = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0", default-features = false } -pallet-sudo = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0", default-features = false } -pallet-timestamp = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0", default-features = false } -pallet-transaction-payment = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0", default-features = false } -pallet-transaction-payment-rpc = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0" } -pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0", default-features = false } -pallet-utility = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0", default-features = false } +pallet-aura = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } +pallet-balances = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } +pallet-grandpa = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } +pallet-insecure-randomness-collective-flip = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } +pallet-membership = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } +pallet-multisig = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } +pallet-preimage = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } +pallet-proxy = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } +pallet-safe-mode = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } +pallet-scheduler = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } +pallet-sudo = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } +pallet-timestamp = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } +pallet-transaction-payment = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } +pallet-transaction-payment-rpc = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } +pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } +pallet-utility = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } -sc-basic-authorship = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0" } -sc-cli = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0" } -sc-client-api = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0" } -sc-consensus = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0" } -sc-consensus-aura = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0" } -sc-consensus-grandpa = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0" } -sc-consensus-grandpa-rpc = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0" } -sc-chain-spec-derive = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0" } -sc-chain-spec = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0" } -sc-consensus-slots = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0" } -sc-executor = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0" } -sc-keystore = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0" } -sc-network = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0" } -sc-offchain = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0" } -sc-rpc = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0" } -sc-rpc-api = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0" } -sc-service = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0" } -sc-telemetry = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0" } -sc-transaction-pool = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0" } -sc-transaction-pool-api = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0" } +sc-basic-authorship = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } +sc-cli = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } +sc-client-api = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } +sc-consensus = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } +sc-consensus-aura = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } +sc-consensus-grandpa = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } +sc-consensus-grandpa-rpc = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } +sc-chain-spec-derive = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } +sc-chain-spec = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } +sc-consensus-slots = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } +sc-executor = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } +sc-keystore = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } +sc-network = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } +sc-offchain = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } +sc-rpc = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } +sc-rpc-api = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } +sc-service = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } +sc-telemetry = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } +sc-transaction-pool = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } +sc-transaction-pool-api = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } -sp-api = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0", default-features = false } -sp-block-builder = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0", default-features = false } -sp-blockchain = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0", default-features = false } -sp-consensus = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0" } -sp-consensus-aura = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0", default-features = false } -sp-consensus-grandpa = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0" } -sp-genesis-builder = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0", default-features = false } -sp-core = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0", default-features = false } -sp-inherents = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0", default-features = false } -sp-io = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0", default-features = false } -sp-keyring = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0" } -sp-offchain = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0", default-features = false } -sp-rpc = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0", default-features = false } -sp-runtime = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0", default-features = false } -sp-session = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0", default-features = false } -sp-std = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0", default-features = false } -sp-storage = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0", default-features = false } -sp-timestamp = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0" } -sp-tracing = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0", default-features = false } -sp-transaction-pool = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0", default-features = false } -sp-version = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0", default-features = false } -sp-weights = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0", default-features = false } +sp-api = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } +sp-block-builder = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } +sp-blockchain = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } +sp-consensus = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } +sp-consensus-aura = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } +sp-consensus-grandpa = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } +sp-genesis-builder = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } +sp-core = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } +sp-inherents = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } +sp-io = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } +sp-keyring = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } +sp-offchain = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } +sp-rpc = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } +sp-session = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } +sp-std = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } +sp-storage = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } +sp-timestamp = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } +sp-tracing = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } +sp-transaction-pool = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } +sp-version = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } +sp-weights = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } -substrate-build-script-utils = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0" } +substrate-build-script-utils = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } substrate-fixed = { git = "https://github.com/encointer/substrate-fixed.git", tag = "v0.5.9" } -substrate-frame-rpc-system = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0" } -substrate-wasm-builder = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.10.0" } +substrate-frame-rpc-system = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } +substrate-wasm-builder = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } frame-metadata = "16" [profile.release] From 322752b502eb428e99c23a09b63b47b21b5934a9 Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Fri, 12 Jul 2024 11:46:09 -0400 Subject: [PATCH 03/58] add feature --- runtime/Cargo.toml | 3 +++ runtime/src/lib.rs | 2 ++ 2 files changed, 5 insertions(+) diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index fcb02a24c..042d0337c 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -41,6 +41,7 @@ pallet-timestamp = { workspace = true } pallet-transaction-payment = { workspace = true } pallet-utility = { workspace = true } frame-executive = { workspace = true } +frame-metadata-hash-extension = { workspace = true } sp-api = { workspace = true } sp-block-builder = { workspace = true } sp-consensus-aura = { workspace = true } @@ -111,6 +112,7 @@ std = [ "codec/std", "scale-info/std", "frame-executive/std", + "frame-metadata-hash-extension/std", "frame-support/std", "frame-system-rpc-runtime-api/std", "frame-system/std", @@ -204,3 +206,4 @@ try-runtime = [ "pallet-commitments/try-runtime", "pallet-registry/try-runtime" ] +metadata-hash = ["substrate-wasm-builder/metadata-hash"] diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index de8be6e61..3457ecb5f 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -23,6 +23,7 @@ use pallet_commitments::CanCommit; use pallet_grandpa::{ fg_primitives, AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList, }; +use frame_metadata_hash_extension::CheckMetadataHash; use pallet_registry::CanRegisterIdentity; use scale_info::TypeInfo; use smallvec::smallvec; @@ -1283,6 +1284,7 @@ pub type SignedExtra = ( pallet_transaction_payment::ChargeTransactionPayment, pallet_subtensor::SubtensorSignedExtension, pallet_commitments::CommitmentsSignedExtension, + frame_metadata_hash_extension::CheckMetadataHash, ); type Migrations = pallet_grandpa::migrations::MigrateV4ToV5; From 78a71f904e94380091edd4790dcc62219949d1e2 Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Mon, 15 Jul 2024 12:25:33 -0400 Subject: [PATCH 04/58] lock file update --- Cargo.lock | 484 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 276 insertions(+), 208 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 868e85b89..ceeb1098e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2308,7 +2308,7 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "fork-tree" version = "12.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "parity-scale-codec", ] @@ -2331,7 +2331,7 @@ checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" [[package]] name = "frame-benchmarking" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "frame-support", "frame-support-procedural", @@ -2347,16 +2347,16 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-runtime-interface 24.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", - "sp-storage 19.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-runtime-interface 24.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-storage 19.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "static_assertions", ] [[package]] name = "frame-benchmarking-cli" version = "32.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "Inflector", "array-bytes 6.2.3", @@ -2388,15 +2388,15 @@ dependencies = [ "sp-blockchain", "sp-core", "sp-database", - "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "sp-inherents", "sp-io", "sp-keystore", "sp-runtime", "sp-state-machine", - "sp-storage 19.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-storage 19.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "sp-trie", - "sp-wasm-interface 20.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-wasm-interface 20.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "thiserror", "thousands", ] @@ -2404,7 +2404,7 @@ dependencies = [ [[package]] name = "frame-executive" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "aquamarine 0.3.3", "frame-support", @@ -2416,8 +2416,8 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", - "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", ] [[package]] @@ -2432,10 +2432,25 @@ dependencies = [ "serde", ] +[[package]] +name = "frame-metadata-hash-extension" +version = "0.1.0" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +dependencies = [ + "array-bytes 6.2.3", + "docify", + "frame-support", + "frame-system", + "log", + "parity-scale-codec", + "scale-info", + "sp-runtime", +] + [[package]] name = "frame-support" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "aquamarine 0.5.0", "array-bytes 6.2.3", @@ -2458,7 +2473,7 @@ dependencies = [ "sp-arithmetic", "sp-core", "sp-crypto-hashing-proc-macro", - "sp-debug-derive 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-debug-derive 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "sp-genesis-builder", "sp-inherents", "sp-io", @@ -2466,8 +2481,8 @@ dependencies = [ "sp-runtime", "sp-staking", "sp-state-machine", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", - "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "sp-weights", "static_assertions", "tt-call", @@ -2476,7 +2491,7 @@ dependencies = [ [[package]] name = "frame-support-procedural" version = "23.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "Inflector", "cfg-expr", @@ -2495,7 +2510,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools" version = "10.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "frame-support-procedural-tools-derive", "proc-macro-crate 3.1.0", @@ -2507,7 +2522,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools-derive" version = "11.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "proc-macro2", "quote", @@ -2517,7 +2532,7 @@ dependencies = [ [[package]] name = "frame-system" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "cfg-if", "docify", @@ -2529,7 +2544,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "sp-version", "sp-weights", ] @@ -2537,7 +2552,7 @@ dependencies = [ [[package]] name = "frame-system-benchmarking" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "frame-benchmarking", "frame-support", @@ -2546,13 +2561,13 @@ dependencies = [ "scale-info", "sp-core", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", ] [[package]] name = "frame-system-rpc-runtime-api" version = "26.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "parity-scale-codec", "sp-api", @@ -2561,13 +2576,13 @@ dependencies = [ [[package]] name = "frame-try-runtime" version = "0.34.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "frame-support", "parity-scale-codec", "sp-api", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", ] [[package]] @@ -4334,6 +4349,20 @@ dependencies = [ "hash-db", ] +[[package]] +name = "merkleized-metadata" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f313fcff1d2a4bcaa2deeaa00bf7530d77d5f7bd0467a117dde2e29a75a7a17a" +dependencies = [ + "array-bytes 6.2.3", + "blake3", + "frame-metadata", + "parity-scale-codec", + "scale-decode", + "scale-info", +] + [[package]] name = "merlin" version = "3.0.0" @@ -4699,6 +4728,7 @@ dependencies = [ "frame-benchmarking", "frame-executive", "frame-metadata", + "frame-metadata-hash-extension", "frame-support", "frame-system", "frame-system-benchmarking", @@ -4739,9 +4769,9 @@ dependencies = [ "sp-offchain", "sp-runtime", "sp-session", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", - "sp-storage 19.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", - "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-storage 19.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "sp-transaction-pool", "sp-version", "substrate-wasm-builder", @@ -4952,7 +4982,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "sp-weights", "substrate-fixed", "subtensor-macros", @@ -4961,7 +4991,7 @@ dependencies = [ [[package]] name = "pallet-aura" version = "27.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "frame-support", "frame-system", @@ -4972,13 +5002,13 @@ dependencies = [ "sp-application-crypto", "sp-consensus-aura", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", ] [[package]] name = "pallet-authorship" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "frame-support", "frame-system", @@ -4986,13 +5016,13 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", ] [[package]] name = "pallet-balances" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "docify", "frame-benchmarking", @@ -5002,7 +5032,7 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", ] [[package]] @@ -5018,7 +5048,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "subtensor-macros", ] @@ -5036,14 +5066,14 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "subtensor-macros", ] [[package]] name = "pallet-grandpa" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "frame-benchmarking", "frame-support", @@ -5060,13 +5090,13 @@ dependencies = [ "sp-runtime", "sp-session", "sp-staking", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", ] [[package]] name = "pallet-insecure-randomness-collective-flip" version = "16.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "frame-support", "frame-system", @@ -5074,13 +5104,13 @@ dependencies = [ "safe-mix", "scale-info", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", ] [[package]] name = "pallet-membership" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "frame-benchmarking", "frame-support", @@ -5091,13 +5121,13 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", ] [[package]] name = "pallet-multisig" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "frame-benchmarking", "frame-support", @@ -5107,13 +5137,13 @@ dependencies = [ "scale-info", "sp-io", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", ] [[package]] name = "pallet-preimage" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "frame-benchmarking", "frame-support", @@ -5124,13 +5154,13 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", ] [[package]] name = "pallet-proxy" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "frame-benchmarking", "frame-support", @@ -5139,7 +5169,7 @@ dependencies = [ "scale-info", "sp-io", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", ] [[package]] @@ -5155,14 +5185,14 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "subtensor-macros", ] [[package]] name = "pallet-safe-mode" version = "9.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "docify", "frame-benchmarking", @@ -5175,13 +5205,13 @@ dependencies = [ "scale-info", "sp-arithmetic", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", ] [[package]] name = "pallet-scheduler" version = "29.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "docify", "frame-benchmarking", @@ -5192,14 +5222,14 @@ dependencies = [ "scale-info", "sp-io", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "sp-weights", ] [[package]] name = "pallet-session" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "frame-support", "frame-system", @@ -5214,7 +5244,7 @@ dependencies = [ "sp-session", "sp-staking", "sp-state-machine", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "sp-trie", ] @@ -5246,8 +5276,8 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", - "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "sp-version", "substrate-fixed", "subtensor-macros", @@ -5256,7 +5286,7 @@ dependencies = [ [[package]] name = "pallet-sudo" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "docify", "frame-benchmarking", @@ -5266,13 +5296,13 @@ dependencies = [ "scale-info", "sp-io", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", ] [[package]] name = "pallet-timestamp" version = "27.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "docify", "frame-benchmarking", @@ -5284,15 +5314,15 @@ dependencies = [ "sp-inherents", "sp-io", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", - "sp-storage 19.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-storage 19.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "sp-timestamp", ] [[package]] name = "pallet-transaction-payment" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "frame-support", "frame-system", @@ -5302,13 +5332,13 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", ] [[package]] name = "pallet-transaction-payment-rpc" version = "30.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "jsonrpsee", "pallet-transaction-payment-rpc-runtime-api", @@ -5324,7 +5354,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc-runtime-api" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "pallet-transaction-payment", "parity-scale-codec", @@ -5336,7 +5366,7 @@ dependencies = [ [[package]] name = "pallet-utility" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "frame-benchmarking", "frame-support", @@ -5346,7 +5376,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", ] [[package]] @@ -6684,18 +6714,18 @@ dependencies = [ [[package]] name = "sc-allocator" version = "23.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "log", "sp-core", - "sp-wasm-interface 20.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-wasm-interface 20.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "thiserror", ] [[package]] name = "sc-basic-authorship" version = "0.34.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "futures", "futures-timer", @@ -6717,7 +6747,7 @@ dependencies = [ [[package]] name = "sc-block-builder" version = "0.33.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "parity-scale-codec", "sp-api", @@ -6732,7 +6762,7 @@ dependencies = [ [[package]] name = "sc-chain-spec" version = "27.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "array-bytes 6.2.3", "docify", @@ -6758,7 +6788,7 @@ dependencies = [ [[package]] name = "sc-chain-spec-derive" version = "11.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", @@ -6769,7 +6799,7 @@ dependencies = [ [[package]] name = "sc-cli" version = "0.36.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "array-bytes 6.2.3", "chrono", @@ -6810,7 +6840,7 @@ dependencies = [ [[package]] name = "sc-client-api" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "fnv", "futures", @@ -6825,11 +6855,11 @@ dependencies = [ "sp-consensus", "sp-core", "sp-database", - "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "sp-runtime", "sp-state-machine", "sp-statement-store", - "sp-storage 19.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-storage 19.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "sp-trie", "substrate-prometheus-endpoint", ] @@ -6837,7 +6867,7 @@ dependencies = [ [[package]] name = "sc-client-db" version = "0.35.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "hash-db", "kvdb", @@ -6863,7 +6893,7 @@ dependencies = [ [[package]] name = "sc-consensus" version = "0.33.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "async-trait", "futures", @@ -6888,7 +6918,7 @@ dependencies = [ [[package]] name = "sc-consensus-aura" version = "0.34.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "async-trait", "futures", @@ -6917,7 +6947,7 @@ dependencies = [ [[package]] name = "sc-consensus-grandpa" version = "0.19.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "ahash 0.8.11", "array-bytes 6.2.3", @@ -6960,7 +6990,7 @@ dependencies = [ [[package]] name = "sc-consensus-grandpa-rpc" version = "0.19.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "finality-grandpa", "futures", @@ -6980,7 +7010,7 @@ dependencies = [ [[package]] name = "sc-consensus-slots" version = "0.33.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "async-trait", "futures", @@ -7003,7 +7033,7 @@ dependencies = [ [[package]] name = "sc-executor" version = "0.32.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "parity-scale-codec", "parking_lot 0.12.3", @@ -7013,25 +7043,25 @@ dependencies = [ "schnellru", "sp-api", "sp-core", - "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "sp-io", "sp-panic-handler", - "sp-runtime-interface 24.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-runtime-interface 24.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "sp-trie", "sp-version", - "sp-wasm-interface 20.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-wasm-interface 20.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "tracing", ] [[package]] name = "sc-executor-common" version = "0.29.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "polkavm", "sc-allocator", "sp-maybe-compressed-blob", - "sp-wasm-interface 20.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-wasm-interface 20.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "thiserror", "wasm-instrument", ] @@ -7039,18 +7069,18 @@ dependencies = [ [[package]] name = "sc-executor-polkavm" version = "0.29.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "log", "polkavm", "sc-executor-common", - "sp-wasm-interface 20.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-wasm-interface 20.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", ] [[package]] name = "sc-executor-wasmtime" version = "0.29.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "anyhow", "cfg-if", @@ -7060,15 +7090,15 @@ dependencies = [ "rustix 0.36.17", "sc-allocator", "sc-executor-common", - "sp-runtime-interface 24.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", - "sp-wasm-interface 20.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-runtime-interface 24.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-wasm-interface 20.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "wasmtime", ] [[package]] name = "sc-informant" version = "0.33.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "ansi_term", "futures", @@ -7085,7 +7115,7 @@ dependencies = [ [[package]] name = "sc-keystore" version = "25.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "array-bytes 6.2.3", "parking_lot 0.12.3", @@ -7099,7 +7129,7 @@ dependencies = [ [[package]] name = "sc-mixnet" version = "0.4.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "array-bytes 4.2.0", "arrayvec", @@ -7128,7 +7158,7 @@ dependencies = [ [[package]] name = "sc-network" version = "0.34.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "array-bytes 6.2.3", "async-channel", @@ -7171,7 +7201,7 @@ dependencies = [ [[package]] name = "sc-network-bitswap" version = "0.33.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "async-channel", "cid", @@ -7191,7 +7221,7 @@ dependencies = [ [[package]] name = "sc-network-common" version = "0.33.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "async-trait", "bitflags 1.3.2", @@ -7208,7 +7238,7 @@ dependencies = [ [[package]] name = "sc-network-gossip" version = "0.34.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "ahash 0.8.11", "futures", @@ -7227,7 +7257,7 @@ dependencies = [ [[package]] name = "sc-network-light" version = "0.33.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "array-bytes 6.2.3", "async-channel", @@ -7248,7 +7278,7 @@ dependencies = [ [[package]] name = "sc-network-sync" version = "0.33.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "array-bytes 6.2.3", "async-channel", @@ -7284,7 +7314,7 @@ dependencies = [ [[package]] name = "sc-network-transactions" version = "0.33.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "array-bytes 6.2.3", "futures", @@ -7303,7 +7333,7 @@ dependencies = [ [[package]] name = "sc-offchain" version = "29.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "array-bytes 6.2.3", "bytes", @@ -7326,7 +7356,7 @@ dependencies = [ "sc-utils", "sp-api", "sp-core", - "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "sp-keystore", "sp-offchain", "sp-runtime", @@ -7337,7 +7367,7 @@ dependencies = [ [[package]] name = "sc-proposer-metrics" version = "0.17.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "log", "substrate-prometheus-endpoint", @@ -7346,7 +7376,7 @@ dependencies = [ [[package]] name = "sc-rpc" version = "29.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "futures", "jsonrpsee", @@ -7378,7 +7408,7 @@ dependencies = [ [[package]] name = "sc-rpc-api" version = "0.33.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "jsonrpsee", "parity-scale-codec", @@ -7398,7 +7428,7 @@ dependencies = [ [[package]] name = "sc-rpc-server" version = "11.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "futures", "governor", @@ -7416,7 +7446,7 @@ dependencies = [ [[package]] name = "sc-rpc-spec-v2" version = "0.34.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "array-bytes 6.2.3", "futures", @@ -7447,7 +7477,7 @@ dependencies = [ [[package]] name = "sc-service" version = "0.35.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "async-trait", "directories", @@ -7489,12 +7519,12 @@ dependencies = [ "sp-blockchain", "sp-consensus", "sp-core", - "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "sp-keystore", "sp-runtime", "sp-session", "sp-state-machine", - "sp-storage 19.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-storage 19.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "sp-transaction-pool", "sp-transaction-storage-proof", "sp-trie", @@ -7511,7 +7541,7 @@ dependencies = [ [[package]] name = "sc-state-db" version = "0.30.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "log", "parity-scale-codec", @@ -7522,7 +7552,7 @@ dependencies = [ [[package]] name = "sc-sysinfo" version = "27.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "derive_more", "futures", @@ -7537,13 +7567,13 @@ dependencies = [ "sp-core", "sp-crypto-hashing", "sp-io", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", ] [[package]] name = "sc-telemetry" version = "15.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "chrono", "futures", @@ -7562,7 +7592,7 @@ dependencies = [ [[package]] name = "sc-tracing" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "ansi_term", "chrono", @@ -7582,7 +7612,7 @@ dependencies = [ "sp-core", "sp-rpc", "sp-runtime", - "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "thiserror", "tracing", "tracing-log 0.1.4", @@ -7592,7 +7622,7 @@ dependencies = [ [[package]] name = "sc-tracing-proc-macro" version = "11.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", @@ -7603,7 +7633,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "async-trait", "futures", @@ -7621,7 +7651,7 @@ dependencies = [ "sp-core", "sp-crypto-hashing", "sp-runtime", - "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "sp-transaction-pool", "substrate-prometheus-endpoint", "thiserror", @@ -7630,7 +7660,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool-api" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "async-trait", "futures", @@ -7646,7 +7676,7 @@ dependencies = [ [[package]] name = "sc-utils" version = "14.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "async-channel", "futures", @@ -7658,6 +7688,29 @@ dependencies = [ "sp-arithmetic", ] +[[package]] +name = "scale-bits" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e57b1e7f6b65ed1f04e79a85a57d755ad56d76fdf1e9bddcc9ae14f71fcdcf54" +dependencies = [ + "parity-scale-codec", + "scale-type-resolver", +] + +[[package]] +name = "scale-decode" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e98f3262c250d90e700bb802eb704e1f841e03331c2eb815e46516c4edbf5b27" +dependencies = [ + "derive_more", + "parity-scale-codec", + "scale-bits", + "scale-type-resolver", + "smallvec", +] + [[package]] name = "scale-info" version = "2.11.3" @@ -7684,6 +7737,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "scale-type-resolver" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0cded6518aa0bd6c1be2b88ac81bf7044992f0f154bfbabd5ad34f43512abcb" + [[package]] name = "schannel" version = "0.1.23" @@ -8129,7 +8188,7 @@ dependencies = [ [[package]] name = "sp-api" version = "26.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "hash-db", "log", @@ -8137,12 +8196,12 @@ dependencies = [ "scale-info", "sp-api-proc-macro", "sp-core", - "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "sp-metadata-ir", "sp-runtime", - "sp-runtime-interface 24.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-runtime-interface 24.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "sp-state-machine", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "sp-trie", "sp-version", "thiserror", @@ -8151,7 +8210,7 @@ dependencies = [ [[package]] name = "sp-api-proc-macro" version = "15.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "Inflector", "blake2 0.10.6", @@ -8165,20 +8224,20 @@ dependencies = [ [[package]] name = "sp-application-crypto" version = "30.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "parity-scale-codec", "scale-info", "serde", "sp-core", "sp-io", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", ] [[package]] name = "sp-arithmetic" version = "23.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "docify", "integer-sqrt", @@ -8186,7 +8245,7 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "static_assertions", ] @@ -8211,7 +8270,7 @@ dependencies = [ [[package]] name = "sp-block-builder" version = "26.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "sp-api", "sp-inherents", @@ -8221,7 +8280,7 @@ dependencies = [ [[package]] name = "sp-blockchain" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "futures", "log", @@ -8239,7 +8298,7 @@ dependencies = [ [[package]] name = "sp-consensus" version = "0.32.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "async-trait", "futures", @@ -8254,7 +8313,7 @@ dependencies = [ [[package]] name = "sp-consensus-aura" version = "0.32.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "async-trait", "parity-scale-codec", @@ -8270,7 +8329,7 @@ dependencies = [ [[package]] name = "sp-consensus-grandpa" version = "13.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "finality-grandpa", "log", @@ -8287,7 +8346,7 @@ dependencies = [ [[package]] name = "sp-consensus-slots" version = "0.32.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "parity-scale-codec", "scale-info", @@ -8298,7 +8357,7 @@ dependencies = [ [[package]] name = "sp-core" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "array-bytes 6.2.3", "bandersnatch_vrfs", @@ -8329,11 +8388,11 @@ dependencies = [ "secrecy", "serde", "sp-crypto-hashing", - "sp-debug-derive 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", - "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", - "sp-runtime-interface 24.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", - "sp-storage 19.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-debug-derive 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-runtime-interface 24.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-storage 19.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "ss58-registry", "substrate-bip39", "thiserror", @@ -8365,7 +8424,7 @@ dependencies = [ [[package]] name = "sp-crypto-hashing" version = "0.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "blake2b_simd", "byteorder", @@ -8378,7 +8437,7 @@ dependencies = [ [[package]] name = "sp-crypto-hashing-proc-macro" version = "0.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "quote", "sp-crypto-hashing", @@ -8388,7 +8447,7 @@ dependencies = [ [[package]] name = "sp-database" version = "10.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "kvdb", "parking_lot 0.12.3", @@ -8397,7 +8456,7 @@ dependencies = [ [[package]] name = "sp-debug-derive" version = "14.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "proc-macro2", "quote", @@ -8417,11 +8476,11 @@ dependencies = [ [[package]] name = "sp-externalities" version = "0.25.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "environmental", "parity-scale-codec", - "sp-storage 19.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-storage 19.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", ] [[package]] @@ -8437,7 +8496,7 @@ dependencies = [ [[package]] name = "sp-genesis-builder" version = "0.7.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "serde_json", "sp-api", @@ -8447,7 +8506,7 @@ dependencies = [ [[package]] name = "sp-inherents" version = "26.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "async-trait", "impl-trait-for-tuples", @@ -8460,7 +8519,7 @@ dependencies = [ [[package]] name = "sp-io" version = "30.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "bytes", "ed25519-dalek", @@ -8472,12 +8531,12 @@ dependencies = [ "secp256k1", "sp-core", "sp-crypto-hashing", - "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "sp-keystore", - "sp-runtime-interface 24.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-runtime-interface 24.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "sp-state-machine", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", - "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "sp-trie", "tracing", "tracing-core", @@ -8486,7 +8545,7 @@ dependencies = [ [[package]] name = "sp-keyring" version = "31.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "sp-core", "sp-runtime", @@ -8496,18 +8555,18 @@ dependencies = [ [[package]] name = "sp-keystore" version = "0.34.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "parity-scale-codec", "parking_lot 0.12.3", "sp-core", - "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", ] [[package]] name = "sp-maybe-compressed-blob" version = "11.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "thiserror", "zstd 0.12.4", @@ -8516,7 +8575,7 @@ dependencies = [ [[package]] name = "sp-metadata-ir" version = "0.6.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "frame-metadata", "parity-scale-codec", @@ -8526,7 +8585,7 @@ dependencies = [ [[package]] name = "sp-mixnet" version = "0.4.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "parity-scale-codec", "scale-info", @@ -8537,7 +8596,7 @@ dependencies = [ [[package]] name = "sp-offchain" version = "26.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "sp-api", "sp-core", @@ -8547,7 +8606,7 @@ dependencies = [ [[package]] name = "sp-panic-handler" version = "13.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "backtrace", "lazy_static", @@ -8557,7 +8616,7 @@ dependencies = [ [[package]] name = "sp-rpc" version = "26.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "rustc-hash", "serde", @@ -8567,7 +8626,7 @@ dependencies = [ [[package]] name = "sp-runtime" version = "31.0.1" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "docify", "either", @@ -8584,26 +8643,26 @@ dependencies = [ "sp-arithmetic", "sp-core", "sp-io", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "sp-weights", ] [[package]] name = "sp-runtime-interface" version = "24.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "bytes", "impl-trait-for-tuples", "parity-scale-codec", "polkavm-derive", "primitive-types", - "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", - "sp-runtime-interface-proc-macro 17.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", - "sp-storage 19.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", - "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", - "sp-wasm-interface 20.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-runtime-interface-proc-macro 17.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-storage 19.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-wasm-interface 20.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "static_assertions", ] @@ -8629,7 +8688,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" version = "17.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "Inflector", "expander", @@ -8655,7 +8714,7 @@ dependencies = [ [[package]] name = "sp-session" version = "27.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "parity-scale-codec", "scale-info", @@ -8669,7 +8728,7 @@ dependencies = [ [[package]] name = "sp-staking" version = "26.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", @@ -8682,7 +8741,7 @@ dependencies = [ [[package]] name = "sp-state-machine" version = "0.35.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "hash-db", "log", @@ -8691,7 +8750,7 @@ dependencies = [ "rand", "smallvec", "sp-core", - "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "sp-panic-handler", "sp-trie", "thiserror", @@ -8702,7 +8761,7 @@ dependencies = [ [[package]] name = "sp-statement-store" version = "10.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "aes-gcm", "curve25519-dalek 4.1.3", @@ -8716,9 +8775,9 @@ dependencies = [ "sp-application-crypto", "sp-core", "sp-crypto-hashing", - "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "sp-runtime", - "sp-runtime-interface 24.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-runtime-interface 24.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "thiserror", "x25519-dalek 2.0.1", ] @@ -8726,7 +8785,7 @@ dependencies = [ [[package]] name = "sp-std" version = "14.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" [[package]] name = "sp-std" @@ -8736,13 +8795,13 @@ source = "git+https://github.com/paritytech/polkadot-sdk#c4b3c1c6c6e492c4196e06f [[package]] name = "sp-storage" version = "19.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "impl-serde", "parity-scale-codec", "ref-cast", "serde", - "sp-debug-derive 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-debug-derive 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", ] [[package]] @@ -8760,7 +8819,7 @@ dependencies = [ [[package]] name = "sp-timestamp" version = "26.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "async-trait", "parity-scale-codec", @@ -8772,7 +8831,7 @@ dependencies = [ [[package]] name = "sp-tracing" version = "16.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "parity-scale-codec", "tracing", @@ -8794,7 +8853,7 @@ dependencies = [ [[package]] name = "sp-transaction-pool" version = "26.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "sp-api", "sp-runtime", @@ -8803,7 +8862,7 @@ dependencies = [ [[package]] name = "sp-transaction-storage-proof" version = "26.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "async-trait", "parity-scale-codec", @@ -8817,7 +8876,7 @@ dependencies = [ [[package]] name = "sp-trie" version = "29.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "ahash 0.8.11", "hash-db", @@ -8830,7 +8889,7 @@ dependencies = [ "scale-info", "schnellru", "sp-core", - "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "thiserror", "tracing", "trie-db", @@ -8840,7 +8899,7 @@ dependencies = [ [[package]] name = "sp-version" version = "29.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "impl-serde", "parity-scale-codec", @@ -8849,7 +8908,7 @@ dependencies = [ "serde", "sp-crypto-hashing-proc-macro", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", "sp-version-proc-macro", "thiserror", ] @@ -8857,7 +8916,7 @@ dependencies = [ [[package]] name = "sp-version-proc-macro" version = "13.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "parity-scale-codec", "proc-macro2", @@ -8868,7 +8927,7 @@ dependencies = [ [[package]] name = "sp-wasm-interface" version = "20.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "anyhow", "impl-trait-for-tuples", @@ -8890,7 +8949,7 @@ dependencies = [ [[package]] name = "sp-weights" version = "27.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "bounded-collections", "parity-scale-codec", @@ -8898,7 +8957,7 @@ dependencies = [ "serde", "smallvec", "sp-arithmetic", - "sp-debug-derive 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0)", + "sp-debug-derive 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", ] [[package]] @@ -9037,7 +9096,7 @@ dependencies = [ [[package]] name = "substrate-bip39" version = "0.4.7" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "hmac 0.12.1", "pbkdf2", @@ -9049,7 +9108,7 @@ dependencies = [ [[package]] name = "substrate-build-script-utils" version = "11.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" [[package]] name = "substrate-fixed" @@ -9065,7 +9124,7 @@ dependencies = [ [[package]] name = "substrate-frame-rpc-system" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "frame-system-rpc-runtime-api", "futures", @@ -9084,7 +9143,7 @@ dependencies = [ [[package]] name = "substrate-prometheus-endpoint" version = "0.17.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ "hyper", "log", @@ -9096,15 +9155,24 @@ dependencies = [ [[package]] name = "substrate-wasm-builder" version = "17.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10.0#7049c3c98836b3e9253f6aaa69b6bf3d622e3962" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" dependencies = [ + "array-bytes 6.2.3", "build-helper", "cargo_metadata", "console", "filetime", + "frame-metadata", + "merkleized-metadata", + "parity-scale-codec", "parity-wasm", "polkavm-linker", + "sc-executor", + "sp-core", + "sp-io", "sp-maybe-compressed-blob", + "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-version", "strum 0.26.2", "tempfile", "toml 0.8.14", From fc0ccbd44cc40466baa4437b017c600b293ba636 Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Mon, 15 Jul 2024 12:25:42 -0400 Subject: [PATCH 05/58] add production just target --- justfile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/justfile b/justfile index e33fdf685..f99f3913a 100644 --- a/justfile +++ b/justfile @@ -47,4 +47,8 @@ lint: @echo "Running cargo clippy with automatic fixes on potentially dirty code..." just clippy-fix @echo "Running cargo clippy..." - just clippy \ No newline at end of file + just clippy + +production: + @echo "Running cargo build with metadata-hash generation..." + cargo +{{RUSTV}} build --profile production --features="runtime-benchmarks metadata-hash" From b09b3e6b6c9a233ba9d40559207c6647e1b82cd8 Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Mon, 15 Jul 2024 12:27:59 -0400 Subject: [PATCH 06/58] fmt --- runtime/build.rs | 10 +++++----- runtime/src/lib.rs | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/runtime/build.rs b/runtime/build.rs index 4d65d12a7..c0fa0405b 100644 --- a/runtime/build.rs +++ b/runtime/build.rs @@ -7,13 +7,13 @@ fn main() { .import_memory() .build(); } - #[cfg(all(feature = "std", feature = "metadata-hash"))] - { - substrate_wasm_builder::WasmBuilder::new() + #[cfg(all(feature = "std", feature = "metadata-hash"))] + { + substrate_wasm_builder::WasmBuilder::new() .with_current_project() .export_heap_base() .import_memory() - .enable_metadata_hash("TAO", 9) + .enable_metadata_hash("TAO", 9) .build(); - } + } } diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 3457ecb5f..58c415bc0 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -12,6 +12,7 @@ pub mod check_nonce; mod migrations; use codec::{Decode, Encode, MaxEncodedLen}; +use frame_metadata_hash_extension::CheckMetadataHash; use frame_support::{ dispatch::DispatchResultWithPostInfo, genesis_builder_helper::{build_config, create_default_config}, @@ -23,7 +24,6 @@ use pallet_commitments::CanCommit; use pallet_grandpa::{ fg_primitives, AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList, }; -use frame_metadata_hash_extension::CheckMetadataHash; use pallet_registry::CanRegisterIdentity; use scale_info::TypeInfo; use smallvec::smallvec; @@ -1284,7 +1284,7 @@ pub type SignedExtra = ( pallet_transaction_payment::ChargeTransactionPayment, pallet_subtensor::SubtensorSignedExtension, pallet_commitments::CommitmentsSignedExtension, - frame_metadata_hash_extension::CheckMetadataHash, + frame_metadata_hash_extension::CheckMetadataHash, ); type Migrations = pallet_grandpa::migrations::MigrateV4ToV5; From bddf9774ad41a07470b21091d183a15e014e9136 Mon Sep 17 00:00:00 2001 From: const Date: Mon, 15 Jul 2024 13:17:44 -0500 Subject: [PATCH 07/58] save --- .../src/{ => coinbase}/block_step.rs | 0 pallets/subtensor/src/coinbase/mod.rs | 2 + pallets/subtensor/src/{ => epoch}/epoch.rs | 2 +- pallets/subtensor/src/{ => epoch}/math.rs | 0 pallets/subtensor/src/epoch/mod.rs | 3 + pallets/subtensor/src/lib.rs | 2529 +++-------------- pallets/subtensor/src/macros/config.rs | 175 ++ pallets/subtensor/src/macros/dispatches.rs | 847 ++++++ pallets/subtensor/src/{ => macros}/errors.rs | 0 pallets/subtensor/src/{ => macros}/events.rs | 0 pallets/subtensor/src/macros/genesis.rs | 163 ++ pallets/subtensor/src/macros/hooks.rs | 75 + pallets/subtensor/src/macros/mod.rs | 6 + .../migrations/migrate_create_root_network.rs | 99 + .../migrations/migrate_delete_subnet_21.rs | 127 + .../src/migrations/migrate_delete_subnet_3.rs | 130 + .../migrate_fix_total_coldkey_stake.rs | 73 + .../migrate_populate_owned_hotkeys.rs | 83 + .../migrate_populate_staking_hotkeys.rs | 85 + .../migrate_to_v1_separate_emission.rs | 106 + .../migrate_to_v2_fixed_total_stake.rs | 103 + .../src/migrations/migrate_total_issuance.rs | 84 + ...igrate_transfer_ownership_to_foundation.rs | 87 + pallets/subtensor/src/migrations/mod.rs | 11 + pallets/subtensor/src/root.rs | 2 +- .../src/{ => rpc_info}/delegate_info.rs | 0 pallets/subtensor/src/rpc_info/mod.rs | 5 + .../src/{ => rpc_info}/neuron_info.rs | 0 .../src/{ => rpc_info}/stake_info.rs | 0 .../src/{ => rpc_info}/subnet_info.rs | 0 pallets/subtensor/src/weights.rs | 2 +- pallets/subtensor/tests/math.rs | 2 +- 32 files changed, 2701 insertions(+), 2100 deletions(-) rename pallets/subtensor/src/{ => coinbase}/block_step.rs (100%) create mode 100644 pallets/subtensor/src/coinbase/mod.rs rename pallets/subtensor/src/{ => epoch}/epoch.rs (99%) rename pallets/subtensor/src/{ => epoch}/math.rs (100%) create mode 100644 pallets/subtensor/src/epoch/mod.rs create mode 100644 pallets/subtensor/src/macros/config.rs create mode 100644 pallets/subtensor/src/macros/dispatches.rs rename pallets/subtensor/src/{ => macros}/errors.rs (100%) rename pallets/subtensor/src/{ => macros}/events.rs (100%) create mode 100644 pallets/subtensor/src/macros/genesis.rs create mode 100644 pallets/subtensor/src/macros/hooks.rs create mode 100644 pallets/subtensor/src/macros/mod.rs create mode 100644 pallets/subtensor/src/migrations/migrate_create_root_network.rs create mode 100644 pallets/subtensor/src/migrations/migrate_delete_subnet_21.rs create mode 100644 pallets/subtensor/src/migrations/migrate_delete_subnet_3.rs create mode 100644 pallets/subtensor/src/migrations/migrate_fix_total_coldkey_stake.rs create mode 100644 pallets/subtensor/src/migrations/migrate_populate_owned_hotkeys.rs create mode 100644 pallets/subtensor/src/migrations/migrate_populate_staking_hotkeys.rs create mode 100644 pallets/subtensor/src/migrations/migrate_to_v1_separate_emission.rs create mode 100644 pallets/subtensor/src/migrations/migrate_to_v2_fixed_total_stake.rs create mode 100644 pallets/subtensor/src/migrations/migrate_total_issuance.rs create mode 100644 pallets/subtensor/src/migrations/migrate_transfer_ownership_to_foundation.rs create mode 100644 pallets/subtensor/src/migrations/mod.rs rename pallets/subtensor/src/{ => rpc_info}/delegate_info.rs (100%) create mode 100644 pallets/subtensor/src/rpc_info/mod.rs rename pallets/subtensor/src/{ => rpc_info}/neuron_info.rs (100%) rename pallets/subtensor/src/{ => rpc_info}/stake_info.rs (100%) rename pallets/subtensor/src/{ => rpc_info}/subnet_info.rs (100%) diff --git a/pallets/subtensor/src/block_step.rs b/pallets/subtensor/src/coinbase/block_step.rs similarity index 100% rename from pallets/subtensor/src/block_step.rs rename to pallets/subtensor/src/coinbase/block_step.rs diff --git a/pallets/subtensor/src/coinbase/mod.rs b/pallets/subtensor/src/coinbase/mod.rs new file mode 100644 index 000000000..e86c66b59 --- /dev/null +++ b/pallets/subtensor/src/coinbase/mod.rs @@ -0,0 +1,2 @@ +use super::*; +pub mod block_step; \ No newline at end of file diff --git a/pallets/subtensor/src/epoch.rs b/pallets/subtensor/src/epoch/epoch.rs similarity index 99% rename from pallets/subtensor/src/epoch.rs rename to pallets/subtensor/src/epoch/epoch.rs index 12c407efa..d67eeded0 100644 --- a/pallets/subtensor/src/epoch.rs +++ b/pallets/subtensor/src/epoch/epoch.rs @@ -1,5 +1,5 @@ use super::*; -use crate::math::*; +use crate::epoch::math::*; use frame_support::IterableStorageDoubleMap; use sp_std::vec; use substrate_fixed::types::{I32F32, I64F64, I96F32}; diff --git a/pallets/subtensor/src/math.rs b/pallets/subtensor/src/epoch/math.rs similarity index 100% rename from pallets/subtensor/src/math.rs rename to pallets/subtensor/src/epoch/math.rs diff --git a/pallets/subtensor/src/epoch/mod.rs b/pallets/subtensor/src/epoch/mod.rs new file mode 100644 index 000000000..74f3b1094 --- /dev/null +++ b/pallets/subtensor/src/epoch/mod.rs @@ -0,0 +1,3 @@ +use super::*; +pub mod math; +pub mod epoch; \ No newline at end of file diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index 8d713d76a..528c06229 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -35,11 +35,12 @@ mod benchmarks; // ========================= // ==== Pallet Imports ===== // ========================= -mod block_step; +mod rpc_info; +mod coinbase; mod epoch; -mod errors; -mod events; -pub mod math; +mod macros; +use macros::{events, errors, dispatches, genesis, hooks, config}; + mod registration; mod root; mod serving; @@ -49,18 +50,17 @@ mod uids; mod utils; mod weights; -pub mod delegate_info; -pub mod neuron_info; -pub mod stake_info; -pub mod subnet_info; - // apparently this is stabilized since rust 1.36 extern crate alloc; -pub mod migration; +pub mod migrations; #[deny(missing_docs)] #[import_section(errors::errors)] #[import_section(events::events)] +#[import_section(dispatches::dispatches)] +#[import_section(genesis::genesis)] +#[import_section(hooks::hooks)] +#[import_section(config::config)] #[frame_support::pallet] pub mod pallet { @@ -69,14 +69,13 @@ pub mod pallet { pallet_prelude::{DispatchResult, StorageMap, ValueQuery, *}, traits::{tokens::fungible, UnfilteredDispatchable}, }; + use crate::migrations; use frame_system::pallet_prelude::*; use sp_core::H256; use sp_runtime::traits::TrailingZeroInput; use sp_std::vec; use sp_std::vec::Vec; - use subtensor_macros::freeze_struct; - #[cfg(not(feature = "std"))] use alloc::boxed::Box; #[cfg(feature = "std")] @@ -94,653 +93,13 @@ pub mod pallet { #[pallet::storage_version(STORAGE_VERSION)] pub struct Pallet(_); - /// Configure the pallet by specifying the parameters and types on which it depends. - #[pallet::config] - pub trait Config: frame_system::Config { - /// Because this pallet emits events, it depends on the runtime's definition of an event. - type RuntimeEvent: From> + IsType<::RuntimeEvent>; - - /// A sudo-able call. - type SudoRuntimeCall: Parameter - + UnfilteredDispatchable - + GetDispatchInfo; - - /// Origin checking for council majority - type CouncilOrigin: EnsureOrigin; - - /// Currency type that will be used to place deposits on neurons - type Currency: fungible::Balanced - + fungible::Mutate; - - /// Senate members with members management functions. - type SenateMembers: crate::MemberManagement; - - /// Interface to allow other pallets to control who can register identities - type TriumvirateInterface: crate::CollectiveInterface; - - /// ================================= - /// ==== Initial Value Constants ==== - /// ================================= - - /// Initial currency issuance. - #[pallet::constant] - type InitialIssuance: Get; - /// Initial min allowed weights setting. - #[pallet::constant] - type InitialMinAllowedWeights: Get; - /// Initial Emission Ratio. - #[pallet::constant] - type InitialEmissionValue: Get; - /// Initial max weight limit. - #[pallet::constant] - type InitialMaxWeightsLimit: Get; - /// Tempo for each network. - #[pallet::constant] - type InitialTempo: Get; - /// Initial Difficulty. - #[pallet::constant] - type InitialDifficulty: Get; - /// Initial Max Difficulty. - #[pallet::constant] - type InitialMaxDifficulty: Get; - /// Initial Min Difficulty. - #[pallet::constant] - type InitialMinDifficulty: Get; - /// Initial RAO Recycled. - #[pallet::constant] - type InitialRAORecycledForRegistration: Get; - /// Initial Burn. - #[pallet::constant] - type InitialBurn: Get; - /// Initial Max Burn. - #[pallet::constant] - type InitialMaxBurn: Get; - /// Initial Min Burn. - #[pallet::constant] - type InitialMinBurn: Get; - /// Initial adjustment interval. - #[pallet::constant] - type InitialAdjustmentInterval: Get; - /// Initial bonds moving average. - #[pallet::constant] - type InitialBondsMovingAverage: Get; - /// Initial target registrations per interval. - #[pallet::constant] - type InitialTargetRegistrationsPerInterval: Get; - /// Rho constant. - #[pallet::constant] - type InitialRho: Get; - /// Kappa constant. - #[pallet::constant] - type InitialKappa: Get; - /// Max UID constant. - #[pallet::constant] - type InitialMaxAllowedUids: Get; - /// Initial validator context pruning length. - #[pallet::constant] - type InitialValidatorPruneLen: Get; - /// Initial scaling law power. - #[pallet::constant] - type InitialScalingLawPower: Get; - /// Immunity Period Constant. - #[pallet::constant] - type InitialImmunityPeriod: Get; - /// Activity constant. - #[pallet::constant] - type InitialActivityCutoff: Get; - /// Initial max registrations per block. - #[pallet::constant] - type InitialMaxRegistrationsPerBlock: Get; - /// Initial pruning score for each neuron. - #[pallet::constant] - type InitialPruningScore: Get; - /// Initial maximum allowed validators per network. - #[pallet::constant] - type InitialMaxAllowedValidators: Get; - /// Initial default delegation take. - #[pallet::constant] - type InitialDefaultTake: Get; - /// Initial minimum delegation take. - #[pallet::constant] - type InitialMinTake: Get; - /// Initial weights version key. - #[pallet::constant] - type InitialWeightsVersionKey: Get; - /// Initial serving rate limit. - #[pallet::constant] - type InitialServingRateLimit: Get; - /// Initial transaction rate limit. - #[pallet::constant] - type InitialTxRateLimit: Get; - /// Initial delegate take transaction rate limit. - #[pallet::constant] - type InitialTxDelegateTakeRateLimit: Get; - /// Initial percentage of total stake required to join senate. - #[pallet::constant] - type InitialSenateRequiredStakePercentage: Get; - /// Initial adjustment alpha on burn and pow. - #[pallet::constant] - type InitialAdjustmentAlpha: Get; - /// Initial network immunity period - #[pallet::constant] - type InitialNetworkImmunityPeriod: Get; - /// Initial minimum allowed network UIDs - #[pallet::constant] - type InitialNetworkMinAllowedUids: Get; - /// Initial network minimum burn cost - #[pallet::constant] - type InitialNetworkMinLockCost: Get; - /// Initial network subnet cut. - #[pallet::constant] - type InitialSubnetOwnerCut: Get; - /// Initial lock reduction interval. - #[pallet::constant] - type InitialNetworkLockReductionInterval: Get; - /// Initial max allowed subnets - #[pallet::constant] - type InitialSubnetLimit: Get; - /// Initial network creation rate limit - #[pallet::constant] - type InitialNetworkRateLimit: Get; - /// Initial target stakes per interval issuance. - #[pallet::constant] - type InitialTargetStakesPerInterval: Get; - /// Cost of swapping a hotkey. - #[pallet::constant] - type KeySwapCost: Get; - /// The upper bound for the alpha parameter. Used for Liquid Alpha. - #[pallet::constant] - type AlphaHigh: Get; - /// The lower bound for the alpha parameter. Used for Liquid Alpha. - #[pallet::constant] - type AlphaLow: Get; - /// A flag to indicate if Liquid Alpha is enabled. - #[pallet::constant] - type LiquidAlphaOn: Get; - /// The base difficulty for proof of work for coldkey swaps - #[pallet::constant] - type InitialBaseDifficulty: Get; - } - /// Alias for the account ID. pub type AccountIdOf = ::AccountId; - /// Senate requirements - #[pallet::type_value] - pub fn DefaultSenateRequiredStakePercentage() -> u64 { - T::InitialSenateRequiredStakePercentage::get() - } - - #[pallet::storage] - pub(super) type SenateRequiredStakePercentage = - StorageValue<_, u64, ValueQuery, DefaultSenateRequiredStakePercentage>; - - /// ============================ - /// ==== Staking + Accounts ==== - /// ============================ - - /// Total Rao in circulation. - #[pallet::type_value] - pub fn TotalSupply() -> u64 { - 21_000_000_000_000_000 // Rao => 21_000_000 Tao - } - /// Default total stake. - #[pallet::type_value] - pub fn DefaultDefaultTake() -> u16 { - T::InitialDefaultTake::get() - } - /// Default minimum take. - #[pallet::type_value] - pub fn DefaultMinTake() -> u16 { - T::InitialMinTake::get() - } - /// Default account take. - #[pallet::type_value] - pub fn DefaultAccountTake() -> u64 { - 0 - } - /// Default stakes per interval. - #[pallet::type_value] - pub fn DefaultStakesPerInterval() -> (u64, u64) { - (0, 0) - } - /// Default emission per block. - #[pallet::type_value] - pub fn DefaultBlockEmission() -> u64 { - 1_000_000_000 - } - /// Default allowed delegation. - #[pallet::type_value] - pub fn DefaultAllowsDelegation() -> bool { - false - } - /// Default total issuance. - #[pallet::type_value] - pub fn DefaultTotalIssuance() -> u64 { - T::InitialIssuance::get() - } - /// Default account, derived from zero trailing bytes. - #[pallet::type_value] - pub fn DefaultAccount() -> T::AccountId { - T::AccountId::decode(&mut TrailingZeroInput::zeroes()) - .expect("trailing zeroes always produce a valid account ID; qed") - } - /// Default target stakes per interval. - #[pallet::type_value] - pub fn DefaultTargetStakesPerInterval() -> u64 { - T::InitialTargetStakesPerInterval::get() - } - /// Default stake interval. - #[pallet::type_value] - pub fn DefaultStakeInterval() -> u64 { - 360 - } - - /// Default base difficulty for proof of work for coldkey swaps - #[pallet::type_value] - pub fn DefaultBaseDifficulty() -> u64 { - T::InitialBaseDifficulty::get() - } - - #[pallet::storage] // --- ITEM ( total_stake ) - pub type TotalStake = StorageValue<_, u64, ValueQuery>; - #[pallet::storage] // --- ITEM ( default_take ) - pub type MaxTake = StorageValue<_, u16, ValueQuery, DefaultDefaultTake>; - #[pallet::storage] // --- ITEM ( min_take ) - pub type MinTake = StorageValue<_, u16, ValueQuery, DefaultMinTake>; - #[pallet::storage] // --- ITEM ( global_block_emission ) - pub type BlockEmission = StorageValue<_, u64, ValueQuery, DefaultBlockEmission>; - #[pallet::storage] // --- ITEM ( total_issuance ) - pub type TotalIssuance = StorageValue<_, u64, ValueQuery, DefaultTotalIssuance>; - #[pallet::storage] // --- ITEM (target_stakes_per_interval) - pub type TargetStakesPerInterval = - StorageValue<_, u64, ValueQuery, DefaultTargetStakesPerInterval>; - - #[pallet::storage] // --- ITEM ( base_difficulty ) - pub type BaseDifficulty = StorageValue<_, u64, ValueQuery, DefaultBaseDifficulty>; - #[pallet::storage] // --- ITEM (default_stake_interval) - pub type StakeInterval = StorageValue<_, u64, ValueQuery, DefaultStakeInterval>; - #[pallet::storage] // --- MAP ( hot ) --> stake | Returns the total amount of stake under a hotkey. - pub type TotalHotkeyStake = - StorageMap<_, Identity, T::AccountId, u64, ValueQuery, DefaultAccountTake>; - #[pallet::storage] // --- MAP ( cold ) --> stake | Returns the total amount of stake under a coldkey. - pub type TotalColdkeyStake = - StorageMap<_, Identity, T::AccountId, u64, ValueQuery, DefaultAccountTake>; - #[pallet::storage] - /// MAP (hot, cold) --> stake | Returns a tuple (u64: stakes, u64: block_number) - pub type TotalHotkeyColdkeyStakesThisInterval = StorageDoubleMap< - _, - Identity, - T::AccountId, - Identity, - T::AccountId, - (u64, u64), - ValueQuery, - DefaultStakesPerInterval, - >; - #[pallet::storage] // --- MAP ( hot ) --> cold | Returns the controlling coldkey for a hotkey. - pub type Owner = - StorageMap<_, Blake2_128Concat, T::AccountId, T::AccountId, ValueQuery, DefaultAccount>; - #[pallet::storage] // --- MAP ( cold ) --> Vec | Returns the vector of hotkeys controlled by this coldkey. - pub type OwnedHotkeys = - StorageMap<_, Blake2_128Concat, T::AccountId, Vec, ValueQuery>; - #[pallet::storage] // --- DMAP ( cold ) --> Vec | Maps coldkey to hotkeys that stake to it - pub type StakingHotkeys = - StorageMap<_, Blake2_128Concat, T::AccountId, Vec, ValueQuery>; - #[pallet::storage] // --- MAP ( hot ) --> take | Returns the hotkey delegation take. And signals that this key is open for delegation. - pub type Delegates = - StorageMap<_, Blake2_128Concat, T::AccountId, u16, ValueQuery, DefaultDefaultTake>; - #[pallet::storage] // --- DMAP ( hot, cold ) --> stake | Returns the stake under a coldkey prefixed by hotkey. - pub type Stake = StorageDoubleMap< - _, - Blake2_128Concat, - T::AccountId, - Identity, - T::AccountId, - u64, - ValueQuery, - DefaultAccountTake, - >; - - #[pallet::type_value] - /// Default value for hotkeys. - pub fn EmptyAccounts() -> Vec { - vec![] - } - #[pallet::type_value] - /// Default arbitration period. - /// This value represents the default arbitration period in blocks. - /// The period is set to 18 hours, assuming a block time of 12 seconds. - pub fn DefaultArbitrationPeriod() -> u64 { - 7200 * 3 // 3 days - } - #[pallet::storage] // ---- StorageItem Global Used Work. - pub type ArbitrationPeriod = - StorageValue<_, u64, ValueQuery, DefaultArbitrationPeriod>; - #[pallet::storage] // --- MAP ( cold ) --> Vec | Returns a list of keys to drain to, if there are two, we extend the period. - pub type ColdkeySwapDestinations = StorageMap< - _, - Blake2_128Concat, - T::AccountId, - Vec, - ValueQuery, - EmptyAccounts, - >; - #[pallet::storage] // --- MAP ( cold ) --> u64 | Block when the coldkey will be arbitrated. - pub type ColdkeyArbitrationBlock = - StorageMap<_, Blake2_128Concat, T::AccountId, u64, ValueQuery>; - #[pallet::storage] // --- MAP ( u64 ) --> Vec | Coldkeys to drain on the specific block. - pub type ColdkeysToSwapAtBlock = - StorageMap<_, Identity, u64, Vec, ValueQuery, EmptyAccounts>; - /// -- ITEM (switches liquid alpha on) - #[pallet::type_value] - pub fn DefaultLiquidAlpha() -> bool { - false - } - #[pallet::storage] // --- MAP ( netuid ) --> Whether or not Liquid Alpha is enabled - pub type LiquidAlphaOn = - StorageMap<_, Blake2_128Concat, u16, bool, ValueQuery, DefaultLiquidAlpha>; - - /// ===================================== - /// ==== Difficulty / Registrations ===== - /// ===================================== - - /// Default last adjustment block. - #[pallet::type_value] - pub fn DefaultLastAdjustmentBlock() -> u64 { - 0 - } - /// Default registrations this block. - #[pallet::type_value] - pub fn DefaultRegistrationsThisBlock() -> u16 { - 0 - } - /// Default burn token. - #[pallet::type_value] - pub fn DefaultBurn() -> u64 { - T::InitialBurn::get() - } - /// Default min burn token. - #[pallet::type_value] - pub fn DefaultMinBurn() -> u64 { - T::InitialMinBurn::get() - } - /// Default max burn token. - #[pallet::type_value] - pub fn DefaultMaxBurn() -> u64 { - T::InitialMaxBurn::get() - } - /// Default difficulty value. - #[pallet::type_value] - pub fn DefaultDifficulty() -> u64 { - T::InitialDifficulty::get() - } - /// Default min difficulty value. - #[pallet::type_value] - pub fn DefaultMinDifficulty() -> u64 { - T::InitialMinDifficulty::get() - } - /// Default max difficulty value. - #[pallet::type_value] - pub fn DefaultMaxDifficulty() -> u64 { - T::InitialMaxDifficulty::get() - } - /// Default max registrations per block. - #[pallet::type_value] - pub fn DefaultMaxRegistrationsPerBlock() -> u16 { - T::InitialMaxRegistrationsPerBlock::get() - } - /// Default RAO recycled for registration. - #[pallet::type_value] - pub fn DefaultRAORecycledForRegistration() -> u64 { - T::InitialRAORecycledForRegistration::get() - } - - #[pallet::storage] // ---- StorageItem Global Used Work. - pub type UsedWork = StorageMap<_, Identity, Vec, u64, ValueQuery>; - #[pallet::storage] // --- MAP ( netuid ) --> Burn - pub type Burn = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultBurn>; - #[pallet::storage] // --- MAP ( netuid ) --> Difficulty - pub type Difficulty = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultDifficulty>; - #[pallet::storage] // --- MAP ( netuid ) --> MinBurn - pub type MinBurn = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultMinBurn>; - #[pallet::storage] // --- MAP ( netuid ) --> MaxBurn - pub type MaxBurn = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultMaxBurn>; - #[pallet::storage] // --- MAP ( netuid ) --> MinDifficulty - pub type MinDifficulty = - StorageMap<_, Identity, u16, u64, ValueQuery, DefaultMinDifficulty>; - #[pallet::storage] // --- MAP ( netuid ) --> MaxDifficulty - pub type MaxDifficulty = - StorageMap<_, Identity, u16, u64, ValueQuery, DefaultMaxDifficulty>; - #[pallet::storage] // --- MAP ( netuid ) --> Block at last adjustment. - pub type LastAdjustmentBlock = - StorageMap<_, Identity, u16, u64, ValueQuery, DefaultLastAdjustmentBlock>; - #[pallet::storage] // --- MAP ( netuid ) --> Registrations of this Block. - pub type RegistrationsThisBlock = - StorageMap<_, Identity, u16, u16, ValueQuery, DefaultRegistrationsThisBlock>; - #[pallet::storage] // --- ITEM( global_max_registrations_per_block ) - pub type MaxRegistrationsPerBlock = - StorageMap<_, Identity, u16, u16, ValueQuery, DefaultMaxRegistrationsPerBlock>; - #[pallet::storage] // --- MAP ( netuid, global_RAO_recycled_for_registration ) - pub type RAORecycledForRegistration = - StorageMap<_, Identity, u16, u64, ValueQuery, DefaultRAORecycledForRegistration>; - - /// ============================== - /// ==== Subnetworks Storage ===== - /// ============================== - - /// Default number of networks. - #[pallet::type_value] - pub fn DefaultN() -> u16 { - 0 - } - /// Default value for modality. - #[pallet::type_value] - pub fn DefaultModality() -> u16 { - 0 - } - /// Default value for hotkeys. - #[pallet::type_value] - pub fn DefaultHotkeys() -> Vec { - vec![] - } - /// Default value if network is added. - #[pallet::type_value] - pub fn DefaultNeworksAdded() -> bool { - false - } - /// Default value for network member. - #[pallet::type_value] - pub fn DefaultIsNetworkMember() -> bool { - false - } - /// Default value for registration allowed. - #[pallet::type_value] - pub fn DefaultRegistrationAllowed() -> bool { - false - } - /// Default value for network registered at. - #[pallet::type_value] - pub fn DefaultNetworkRegisteredAt() -> u64 { - 0 - } - /// Default value for network immunity period. - #[pallet::type_value] - pub fn DefaultNetworkImmunityPeriod() -> u64 { - T::InitialNetworkImmunityPeriod::get() - } - /// Default value for network last registered. - #[pallet::type_value] - pub fn DefaultNetworkLastRegistered() -> u64 { - 0 - } - /// Default value for nominator min required stake. - #[pallet::type_value] - pub fn DefaultNominatorMinRequiredStake() -> u64 { - 0 - } - /// Default value for network min allowed UIDs. - #[pallet::type_value] - pub fn DefaultNetworkMinAllowedUids() -> u16 { - T::InitialNetworkMinAllowedUids::get() - } - /// Default value for network min lock cost. - #[pallet::type_value] - pub fn DefaultNetworkMinLockCost() -> u64 { - T::InitialNetworkMinLockCost::get() - } - /// Default value for network lock reduction interval. - #[pallet::type_value] - pub fn DefaultNetworkLockReductionInterval() -> u64 { - T::InitialNetworkLockReductionInterval::get() - } - /// Default value for subnet owner cut. - #[pallet::type_value] - pub fn DefaultSubnetOwnerCut() -> u16 { - T::InitialSubnetOwnerCut::get() - } - /// Default value for subnet limit. - #[pallet::type_value] - pub fn DefaultSubnetLimit() -> u16 { - T::InitialSubnetLimit::get() - } - /// Default value for network rate limit. - #[pallet::type_value] - pub fn DefaultNetworkRateLimit() -> u64 { - if cfg!(feature = "pow-faucet") { - return 0; - } - - T::InitialNetworkRateLimit::get() - } - - #[pallet::storage] // --- ITEM( maximum_number_of_networks ) - pub type SubnetLimit = StorageValue<_, u16, ValueQuery, DefaultSubnetLimit>; - #[pallet::storage] // --- ITEM( total_number_of_existing_networks ) - pub type TotalNetworks = StorageValue<_, u16, ValueQuery>; - #[pallet::storage] // --- MAP ( netuid ) --> subnetwork_n (Number of UIDs in the network). - pub type SubnetworkN = StorageMap<_, Identity, u16, u16, ValueQuery, DefaultN>; - #[pallet::storage] // --- MAP ( netuid ) --> modality TEXT: 0, IMAGE: 1, TENSOR: 2 - pub type NetworkModality = StorageMap<_, Identity, u16, u16, ValueQuery, DefaultModality>; - #[pallet::storage] // --- MAP ( netuid ) --> network_is_added - pub type NetworksAdded = - StorageMap<_, Identity, u16, bool, ValueQuery, DefaultNeworksAdded>; - #[pallet::storage] // --- DMAP ( hotkey, netuid ) --> bool - pub type IsNetworkMember = StorageDoubleMap< - _, - Blake2_128Concat, - T::AccountId, - Identity, - u16, - bool, - ValueQuery, - DefaultIsNetworkMember, - >; - #[pallet::storage] // --- MAP ( netuid ) --> network_registration_allowed - pub type NetworkRegistrationAllowed = - StorageMap<_, Identity, u16, bool, ValueQuery, DefaultRegistrationAllowed>; - #[pallet::storage] // --- MAP ( netuid ) --> network_pow_allowed - pub type NetworkPowRegistrationAllowed = - StorageMap<_, Identity, u16, bool, ValueQuery, DefaultRegistrationAllowed>; - #[pallet::storage] // --- MAP ( netuid ) --> block_created - pub type NetworkRegisteredAt = - StorageMap<_, Identity, u16, u64, ValueQuery, DefaultNetworkRegisteredAt>; - #[pallet::storage] // ITEM( network_immunity_period ) - pub type NetworkImmunityPeriod = - StorageValue<_, u64, ValueQuery, DefaultNetworkImmunityPeriod>; - #[pallet::storage] // ITEM( network_last_registered_block ) - pub type NetworkLastRegistered = - StorageValue<_, u64, ValueQuery, DefaultNetworkLastRegistered>; - #[pallet::storage] // ITEM( network_min_allowed_uids ) - pub type NetworkMinAllowedUids = - StorageValue<_, u16, ValueQuery, DefaultNetworkMinAllowedUids>; - #[pallet::storage] // ITEM( min_network_lock_cost ) - pub type NetworkMinLockCost = StorageValue<_, u64, ValueQuery, DefaultNetworkMinLockCost>; - #[pallet::storage] // ITEM( last_network_lock_cost ) - pub type NetworkLastLockCost = - StorageValue<_, u64, ValueQuery, DefaultNetworkMinLockCost>; - #[pallet::storage] // ITEM( network_lock_reduction_interval ) - pub type NetworkLockReductionInterval = - StorageValue<_, u64, ValueQuery, DefaultNetworkLockReductionInterval>; - #[pallet::storage] // ITEM( subnet_owner_cut ) - pub type SubnetOwnerCut = StorageValue<_, u16, ValueQuery, DefaultSubnetOwnerCut>; - #[pallet::storage] // ITEM( network_rate_limit ) - pub type NetworkRateLimit = StorageValue<_, u64, ValueQuery, DefaultNetworkRateLimit>; - #[pallet::storage] // ITEM( nominator_min_required_stake ) - pub type NominatorMinRequiredStake = - StorageValue<_, u64, ValueQuery, DefaultNominatorMinRequiredStake>; - - /// ============================== - /// ==== Subnetwork Features ===== - /// ============================== - - /// Default value for emission values. - #[pallet::type_value] - pub fn DefaultEmissionValues() -> u64 { - 0 - } - /// Default value for pending emission. - #[pallet::type_value] - pub fn DefaultPendingEmission() -> u64 { - 0 - } - /// Default value for blocks since last step. - #[pallet::type_value] - pub fn DefaultBlocksSinceLastStep() -> u64 { - 0 - } - /// Default value for last mechanism step block. - #[pallet::type_value] - pub fn DefaultLastMechanismStepBlock() -> u64 { - 0 - } - /// Default value for subnet owner. - #[pallet::type_value] - pub fn DefaultSubnetOwner() -> T::AccountId { - T::AccountId::decode(&mut sp_runtime::traits::TrailingZeroInput::zeroes()) - .expect("trailing zeroes always produce a valid account ID; qed") - } - /// Default value for subnet locked. - #[pallet::type_value] - pub fn DefaultSubnetLocked() -> u64 { - 0 - } - /// Default value for network tempo - #[pallet::type_value] - pub fn DefaultTempo() -> u16 { - T::InitialTempo::get() - } - - #[pallet::storage] // --- MAP ( netuid ) --> tempo - pub type Tempo = StorageMap<_, Identity, u16, u16, ValueQuery, DefaultTempo>; - #[pallet::storage] // --- MAP ( netuid ) --> emission_values - pub type EmissionValues = - StorageMap<_, Identity, u16, u64, ValueQuery, DefaultEmissionValues>; - #[pallet::storage] // --- MAP ( netuid ) --> pending_emission - pub type PendingEmission = - StorageMap<_, Identity, u16, u64, ValueQuery, DefaultPendingEmission>; - #[pallet::storage] // --- MAP ( netuid ) --> blocks_since_last_step - pub type BlocksSinceLastStep = - StorageMap<_, Identity, u16, u64, ValueQuery, DefaultBlocksSinceLastStep>; - #[pallet::storage] // --- MAP ( netuid ) --> last_mechanism_step_block - pub type LastMechansimStepBlock = - StorageMap<_, Identity, u16, u64, ValueQuery, DefaultLastMechanismStepBlock>; - #[pallet::storage] // --- MAP ( netuid ) --> subnet_owner - pub type SubnetOwner = - StorageMap<_, Identity, u16, T::AccountId, ValueQuery, DefaultSubnetOwner>; - #[pallet::storage] // --- MAP ( netuid ) --> subnet_locked - pub type SubnetLocked = - StorageMap<_, Identity, u16, u64, ValueQuery, DefaultSubnetLocked>; - - /// ================================= - /// ==== Axon / Promo Endpoints ===== - /// ================================= - /// Struct for Axon. pub type AxonInfoOf = AxonInfo; /// Data structure for Axon information. - #[freeze_struct("3545cfb0cac4c1f5")] #[derive(Encode, Decode, Default, TypeInfo, Clone, PartialEq, Eq, Debug)] pub struct AxonInfo { /// Axon serving block. @@ -764,7 +123,6 @@ pub mod pallet { /// Struct for Prometheus. pub type PrometheusInfoOf = PrometheusInfo; /// Data structure for Prometheus information. - #[freeze_struct("5dde687e63baf0cd")] #[derive(Encode, Decode, Default, TypeInfo, Clone, PartialEq, Eq, Debug)] pub struct PrometheusInfo { /// Prometheus serving block. @@ -779,366 +137,452 @@ pub mod pallet { pub ip_type: u8, } - /// Default value for rate limiting - #[pallet::type_value] - pub fn DefaultTxRateLimit() -> u64 { - T::InitialTxRateLimit::get() - } - /// Default value for delegate take rate limiting - #[pallet::type_value] - pub fn DefaultTxDelegateTakeRateLimit() -> u64 { - T::InitialTxDelegateTakeRateLimit::get() - } - /// Default value for last extrinsic block. - #[pallet::type_value] - pub fn DefaultLastTxBlock() -> u64 { - 0 - } - #[pallet::storage] // --- ITEM ( tx_rate_limit ) - pub(super) type TxRateLimit = StorageValue<_, u64, ValueQuery, DefaultTxRateLimit>; - #[pallet::storage] // --- ITEM ( tx_rate_limit ) - pub(super) type TxDelegateTakeRateLimit = - StorageValue<_, u64, ValueQuery, DefaultTxDelegateTakeRateLimit>; - #[pallet::storage] // --- MAP ( key ) --> last_block - pub type LastTxBlock = - StorageMap<_, Identity, T::AccountId, u64, ValueQuery, DefaultLastTxBlock>; - #[pallet::storage] // --- MAP ( key ) --> last_block - pub(super) type LastTxBlockDelegateTake = - StorageMap<_, Identity, T::AccountId, u64, ValueQuery, DefaultLastTxBlock>; - - /// Default value for serving rate limit. - #[pallet::type_value] - pub fn DefaultServingRateLimit() -> u64 { - T::InitialServingRateLimit::get() - } + /// ============================ + /// ==== Staking + Accounts ==== + /// ============================ - #[pallet::storage] // --- MAP ( netuid ) --> serving_rate_limit - pub type ServingRateLimit = - StorageMap<_, Identity, u16, u64, ValueQuery, DefaultServingRateLimit>; - #[pallet::storage] // --- MAP ( netuid, hotkey ) --> axon_info - pub type Axons = - StorageDoubleMap<_, Identity, u16, Blake2_128Concat, T::AccountId, AxonInfoOf, OptionQuery>; - #[pallet::storage] // --- MAP ( netuid, hotkey ) --> prometheus_info - pub type Prometheus = StorageDoubleMap< - _, - Identity, - u16, - Blake2_128Concat, - T::AccountId, - PrometheusInfoOf, - OptionQuery, - >; + #[pallet::type_value] /// Total Rao in circulation. + pub fn TotalSupply() -> u64 { 21_000_000_000_000_000 } + #[pallet::type_value] /// Default total stake. + pub fn DefaultDefaultTake() -> u16 { T::InitialDefaultTake::get() } + #[pallet::type_value] /// Default minimum take. + pub fn DefaultMinTake() -> u16 { T::InitialMinTake::get() } + #[pallet::type_value] /// Default account take. + pub fn DefaultAccountTake() -> u64 { 0 } + #[pallet::type_value] /// Default stakes per interval. + pub fn DefaultStakesPerInterval() -> (u64, u64) { (0, 0) } + #[pallet::type_value] /// Default emission per block. + pub fn DefaultBlockEmission() -> u64 { 1_000_000_000 } + #[pallet::type_value] /// Default allowed delegation. + pub fn DefaultAllowsDelegation() -> bool { false } + #[pallet::type_value] /// Default total issuance. + pub fn DefaultTotalIssuance() -> u64 { T::InitialIssuance::get() } + #[pallet::type_value] /// Default account, derived from zero trailing bytes. + pub fn DefaultAccount() -> T::AccountId { T::AccountId::decode(&mut TrailingZeroInput::zeroes()).expect("trailing zeroes always produce a valid account ID; qed") } + #[pallet::type_value] /// Default target stakes per interval. + pub fn DefaultTargetStakesPerInterval() -> u64 { T::InitialTargetStakesPerInterval::get() } + #[pallet::type_value] /// Default stake interval. + pub fn DefaultStakeInterval() -> u64 { 360 } + #[pallet::type_value] /// Default account linkage + pub fn DefaultAccountLinkage() -> Vec<(u64, T::AccountId)> { vec![] } + #[pallet::type_value] /// Default account linkage + pub fn DefaultProportion() -> u64 { 0 } + #[pallet::type_value] /// Default accumulated emission for a hotkey + pub fn DefaultAccumulatedEmission() -> u64 { 0 } + #[pallet::type_value] /// Default last adjustment block. + pub fn DefaultLastAdjustmentBlock() -> u64 { 0 } + #[pallet::type_value] /// Default last adjustment block. + pub fn DefaultRegistrationsThisBlock() -> u16 { 0 } + #[pallet::type_value] /// Default registrations this block. + pub fn DefaultBurn() -> u64 { T::InitialBurn::get() } + #[pallet::type_value] /// Default burn token. + pub fn DefaultMinBurn() -> u64 { T::InitialMinBurn::get() } + #[pallet::type_value] /// Default min burn token. + pub fn DefaultMaxBurn() -> u64 { T::InitialMaxBurn::get() } + #[pallet::type_value] /// Default max burn token. + pub fn DefaultDifficulty() -> u64 { T::InitialDifficulty::get() } + #[pallet::type_value] /// Default difficulty value. + pub fn DefaultMinDifficulty() -> u64 { T::InitialMinDifficulty::get() } + #[pallet::type_value] /// Default min difficulty value. + pub fn DefaultMaxDifficulty() -> u64 { T::InitialMaxDifficulty::get() } + #[pallet::type_value] /// Default max difficulty value. + pub fn DefaultMaxRegistrationsPerBlock() -> u16 { T::InitialMaxRegistrationsPerBlock::get() } + #[pallet::type_value] /// Default max registrations per block. + pub fn DefaultRAORecycledForRegistration() -> u64 { T::InitialRAORecycledForRegistration::get() } + #[pallet::type_value] /// Default number of networks. + pub fn DefaultN() -> u16 { 0 } + #[pallet::type_value] /// Default value for modality. + pub fn DefaultModality() -> u16 { 0 } + #[pallet::type_value] /// Default value for hotkeys. + pub fn DefaultHotkeys() -> Vec { vec![] } + #[pallet::type_value] /// Default value if network is added. + pub fn DefaultNeworksAdded() -> bool { false } + #[pallet::type_value] /// Default value for network member. + pub fn DefaultIsNetworkMember() -> bool { false } + #[pallet::type_value] /// Default value for registration allowed. + pub fn DefaultRegistrationAllowed() -> bool { false } + #[pallet::type_value] /// Default value for network registered at. + pub fn DefaultNetworkRegisteredAt() -> u64 { 0 } + #[pallet::type_value] /// Default value for network immunity period. + pub fn DefaultNetworkImmunityPeriod() -> u64 { T::InitialNetworkImmunityPeriod::get() } + #[pallet::type_value] /// Default value for network last registered. + pub fn DefaultNetworkLastRegistered() -> u64 { 0 } + #[pallet::type_value] /// Default value for nominator min required stake. + pub fn DefaultNominatorMinRequiredStake() -> u64 { 0 } + #[pallet::type_value] /// Default value for network min allowed UIDs. + pub fn DefaultNetworkMinAllowedUids() -> u16 { T::InitialNetworkMinAllowedUids::get() } + #[pallet::type_value] /// Default value for network min lock cost. + pub fn DefaultNetworkMinLockCost() -> u64 { T::InitialNetworkMinLockCost::get() } + #[pallet::type_value] /// Default value for network lock reduction interval. + pub fn DefaultNetworkLockReductionInterval() -> u64 { T::InitialNetworkLockReductionInterval::get() } + #[pallet::type_value] /// Default value for subnet owner cut. + pub fn DefaultSubnetOwnerCut() -> u16 { T::InitialSubnetOwnerCut::get() } + #[pallet::type_value] /// Default value for subnet limit. + pub fn DefaultSubnetLimit() -> u16 { T::InitialSubnetLimit::get() } + #[pallet::type_value] /// Default value for network rate limit. + pub fn DefaultNetworkRateLimit() -> u64 { if cfg!(feature = "pow-faucet") { return 0; } T::InitialNetworkRateLimit::get() } + // #[pallet::type_value] /// Default value for network max stake. + // pub fn DefaultNetworkMaxStake() -> u64 { T::InitialNetworkMaxStake::get() } + #[pallet::type_value] /// Default value for emission values. + pub fn DefaultEmissionValues() -> u64 { 0 } + #[pallet::type_value] /// Default value for pending emission. + pub fn DefaultPendingEmission() -> u64 { 0 } + #[pallet::type_value] /// Default value for blocks since last step. + pub fn DefaultBlocksSinceLastStep() -> u64 { 0 } + #[pallet::type_value] /// Default value for last mechanism step block. + pub fn DefaultLastMechanismStepBlock() -> u64 { 0 } + #[pallet::type_value] /// Default value for subnet owner. + pub fn DefaultSubnetOwner() -> T::AccountId { T::AccountId::decode(&mut sp_runtime::traits::TrailingZeroInput::zeroes()).expect("trailing zeroes always produce a valid account ID; qed") } + #[pallet::type_value] /// Default value for subnet locked. + pub fn DefaultSubnetLocked() -> u64 { 0 } + #[pallet::type_value] /// Default value for network tempo + pub fn DefaultTempo() -> u16 { T::InitialTempo::get() } + #[pallet::type_value] /// Default value for weights set rate limit. + pub fn DefaultWeightsSetRateLimit() -> u64 { 100 } + #[pallet::type_value] /// Default block number at registration. + pub fn DefaultBlockAtRegistration() -> u64 { 0 } + #[pallet::type_value] /// Default value for rho parameter. + pub fn DefaultRho() -> u16 { T::InitialRho::get() } + #[pallet::type_value] /// Default value for kappa parameter. + pub fn DefaultKappa() -> u16 { T::InitialKappa::get() } + #[pallet::type_value] /// Default maximum allowed UIDs. + pub fn DefaultMaxAllowedUids() -> u16 { T::InitialMaxAllowedUids::get() } + #[pallet::type_value] /// Default immunity period. + pub fn DefaultImmunityPeriod() -> u16 { T::InitialImmunityPeriod::get() } + #[pallet::type_value] /// Default activity cutoff. + pub fn DefaultActivityCutoff() -> u16 { T::InitialActivityCutoff::get() } + #[pallet::type_value] /// Default maximum weights limit. + pub fn DefaultMaxWeightsLimit() -> u16 { T::InitialMaxWeightsLimit::get() } + #[pallet::type_value] /// Default weights version key. + pub fn DefaultWeightsVersionKey() -> u64 { T::InitialWeightsVersionKey::get() } + #[pallet::type_value] /// Default minimum allowed weights. + pub fn DefaultMinAllowedWeights() -> u16 { T::InitialMinAllowedWeights::get() } + #[pallet::type_value] /// Default maximum allowed validators. + pub fn DefaultMaxAllowedValidators() -> u16 { T::InitialMaxAllowedValidators::get() } + #[pallet::type_value] /// Default adjustment interval. + pub fn DefaultAdjustmentInterval() -> u16 { T::InitialAdjustmentInterval::get() } + #[pallet::type_value] /// Default bonds moving average. + pub fn DefaultBondsMovingAverage() -> u64 { T::InitialBondsMovingAverage::get() } + #[pallet::type_value] /// Default validator prune length. + pub fn DefaultValidatorPruneLen() -> u64 { T::InitialValidatorPruneLen::get() } + #[pallet::type_value] /// Default scaling law power. + pub fn DefaultScalingLawPower() -> u16 { T::InitialScalingLawPower::get() } + #[pallet::type_value] /// Default target registrations per interval. + pub fn DefaultTargetRegistrationsPerInterval() -> u16 { T::InitialTargetRegistrationsPerInterval::get() } + #[pallet::type_value] /// Default adjustment alpha. + pub fn DefaultAdjustmentAlpha() -> u64 { T::InitialAdjustmentAlpha::get() } + #[pallet::type_value] /// Default minimum stake for weights. + pub fn DefaultWeightsMinStake() -> u64 { 0 } + #[pallet::type_value] /// Value definition for vector of u16. + pub fn EmptyU16Vec() -> Vec { vec![] } + #[pallet::type_value] /// Value definition for vector of u64. + pub fn EmptyU64Vec() -> Vec { vec![] } + #[pallet::type_value] /// Value definition for vector of bool. + pub fn EmptyBoolVec() -> Vec { vec![] } + #[pallet::type_value] /// Value definition for bonds with type vector of (u16, u16). + pub fn DefaultBonds() -> Vec<(u16, u16)> { vec![] } + #[pallet::type_value] /// Value definition for weights with vector of (u16, u16). + pub fn DefaultWeights() -> Vec<(u16, u16)> { vec![] } + #[pallet::type_value] /// Default value for key with type T::AccountId derived from trailing zeroes. + pub fn DefaultKey() -> T::AccountId { T::AccountId::decode(&mut sp_runtime::traits::TrailingZeroInput::zeroes()).expect("trailing zeroes always produce a valid account ID; qed") } + #[pallet::type_value] /// Default value for network immunity period. + pub fn DefaultHotkeyEmissionTempo() -> u64 { 7200 } + #[pallet::type_value] /// Default value for rate limiting + pub fn DefaultTxRateLimit() -> u64 { T::InitialTxRateLimit::get() } + #[pallet::type_value] /// Default value for delegate take rate limiting + pub fn DefaultTxDelegateTakeRateLimit() -> u64 { T::InitialTxDelegateTakeRateLimit::get() } + #[pallet::type_value] /// Default value for last extrinsic block. + pub fn DefaultLastTxBlock() -> u64 { 0 } + #[pallet::type_value] /// Default value for serving rate limit. + pub fn DefaultServingRateLimit() -> u64 { T::InitialServingRateLimit::get() } + #[pallet::type_value] /// Default value for weight commit reveal interval. + pub fn DefaultWeightCommitRevealInterval() -> u64 { 1000 } + #[pallet::type_value] /// Default value for weight commit/reveal enabled. + pub fn DefaultCommitRevealWeightsEnabled() -> bool { false } + #[pallet::type_value] /// Senate requirements + pub fn DefaultSenateRequiredStakePercentage() -> u64 { T::InitialSenateRequiredStakePercentage::get() } + #[pallet::type_value] /// -- ITEM (switches liquid alpha on) + pub fn DefaultLiquidAlpha() -> bool {false} + #[pallet::type_value] /// (alpha_low: 0.7, alpha_high: 0.9) + pub fn DefaultAlphaValues() -> (u16, u16) { (45875, 58982) } - /// ======================================= - /// ==== Subnetwork Hyperparam storage ==== - /// ======================================= + #[pallet::storage] + pub(super) type SenateRequiredStakePercentage = StorageValue<_, u64, ValueQuery, DefaultSenateRequiredStakePercentage>; - /// Default weights set rate limit. - #[pallet::type_value] - pub fn DefaultWeightsSetRateLimit() -> u64 { - 100 - } - /// Default block at registration. - #[pallet::type_value] - pub fn DefaultBlockAtRegistration() -> u64 { - 0 - } - /// Default Rho parameter value. - #[pallet::type_value] - pub fn DefaultRho() -> u16 { - T::InitialRho::get() - } - /// Default Kai parameter value. - #[pallet::type_value] - pub fn DefaultKappa() -> u16 { - T::InitialKappa::get() - } - /// Default max allowed uids. - #[pallet::type_value] - pub fn DefaultMaxAllowedUids() -> u16 { - T::InitialMaxAllowedUids::get() - } - /// Default immunity period value. - #[pallet::type_value] - pub fn DefaultImmunityPeriod() -> u16 { - T::InitialImmunityPeriod::get() - } - /// Default activity cutoff value. - #[pallet::type_value] - pub fn DefaultActivityCutoff() -> u16 { - T::InitialActivityCutoff::get() - } - /// Default max weights limit. - #[pallet::type_value] - pub fn DefaultMaxWeightsLimit() -> u16 { - T::InitialMaxWeightsLimit::get() - } - /// Default weights version key. - #[pallet::type_value] - pub fn DefaultWeightsVersionKey() -> u64 { - T::InitialWeightsVersionKey::get() - } - /// Default minimal allowed weights. - #[pallet::type_value] - pub fn DefaultMinAllowedWeights() -> u16 { - T::InitialMinAllowedWeights::get() - } - /// Default max allowed validators. - #[pallet::type_value] - pub fn DefaultMaxAllowedValidators() -> u16 { - T::InitialMaxAllowedValidators::get() - } - /// Default adjustment interval. - #[pallet::type_value] - pub fn DefaultAdjustmentInterval() -> u16 { - T::InitialAdjustmentInterval::get() - } - /// Default bonds moving average. - #[pallet::type_value] - pub fn DefaultBondsMovingAverage() -> u64 { - T::InitialBondsMovingAverage::get() - } - /// Default validator prune length. - #[pallet::type_value] - pub fn DefaultValidatorPruneLen() -> u64 { - T::InitialValidatorPruneLen::get() - } - /// Default scaling law power. - #[pallet::type_value] - pub fn DefaultScalingLawPower() -> u16 { - T::InitialScalingLawPower::get() - } - /// Default target registrations per interval. - #[pallet::type_value] - pub fn DefaultTargetRegistrationsPerInterval() -> u16 { - T::InitialTargetRegistrationsPerInterval::get() - } - /// Default adjustment alpha. - #[pallet::type_value] - pub fn DefaultAdjustmentAlpha() -> u64 { - T::InitialAdjustmentAlpha::get() - } - /// Default weights min stake. - #[pallet::type_value] - pub fn DefaultWeightsMinStake() -> u64 { - 0 - } - /// Provides the default value for the upper bound of the alpha parameter. + /// ============================ + /// ==== Staking Variables ==== + /// ============================ + #[pallet::storage] // --- ITEM ( total_issuance ) + pub type TotalIssuance = StorageValue<_, u64, ValueQuery, DefaultTotalIssuance>; + #[pallet::storage] // --- ITEM ( total_stake ) + pub type TotalStake = StorageValue<_, u64, ValueQuery>; + #[pallet::storage] // --- ITEM ( default_take ) + pub type MaxTake = StorageValue<_, u16, ValueQuery, DefaultDefaultTake>; + #[pallet::storage] // --- ITEM ( min_take ) + pub type MinTake = StorageValue<_, u16, ValueQuery, DefaultMinTake>; + #[pallet::storage] // --- ITEM ( global_block_emission ) + pub type BlockEmission = StorageValue<_, u64, ValueQuery, DefaultBlockEmission>; + #[pallet::storage] // --- ITEM (target_stakes_per_interval) + pub type TargetStakesPerInterval = StorageValue<_, u64, ValueQuery, DefaultTargetStakesPerInterval>; + #[pallet::storage] // --- ITEM (default_stake_interval) + pub type StakeInterval = StorageValue<_, u64, ValueQuery, DefaultStakeInterval>; + #[pallet::storage] // --- MAP ( hot ) --> stake | Returns the total amount of stake under a hotkey. + pub type TotalHotkeyStake = StorageMap<_, Identity, T::AccountId, u64, ValueQuery, DefaultAccountTake>; + #[pallet::storage] // --- MAP ( cold ) --> stake | Returns the total amount of stake under a coldkey. + pub type TotalColdkeyStake = StorageMap<_, Identity, T::AccountId, u64, ValueQuery, DefaultAccountTake>; + #[pallet::storage] /// MAP (hot, cold) --> stake | Returns a tuple (u64: stakes, u64: block_number) + pub type TotalHotkeyColdkeyStakesThisInterval = StorageDoubleMap<_, Identity, T::AccountId, Identity, T::AccountId, (u64, u64), ValueQuery, DefaultStakesPerInterval>; + #[pallet::storage] /// MAP ( hot ) --> cold | Returns the controlling coldkey for a hotkey. + pub type Owner = StorageMap<_, Blake2_128Concat, T::AccountId, T::AccountId, ValueQuery, DefaultAccount>; + #[pallet::storage] /// MAP ( hot ) --> take | Returns the hotkey delegation take. And signals that this key is open for delegation. + pub type Delegates = StorageMap<_, Blake2_128Concat, T::AccountId, u16, ValueQuery, DefaultDefaultTake>; + #[pallet::storage] /// DMAP ( hot, cold ) --> stake | Returns the stake under a coldkey prefixed by hotkey. + pub type Stake = StorageDoubleMap<_, Blake2_128Concat, T::AccountId, Identity, T::AccountId, u64, ValueQuery, DefaultAccountTake>; + #[pallet::storage] /// Map ( hot ) --> last_hotkey_emission_drain | Last block we drained this hotkey's emission. + pub type LastHotkeyEmissionDrain = StorageMap<_, Blake2_128Concat, T::AccountId, u64, ValueQuery, DefaultAccumulatedEmission>; + #[pallet::storage] /// ITEM ( hotkey_emission_tempo ) + pub type HotkeyEmissionTempo = StorageValue<_, u64, ValueQuery, DefaultHotkeyEmissionTempo>; + #[pallet::storage] /// Map ( hot ) --> emission | Accumulated hotkey emission. + pub type PendingdHotkeyEmission = StorageMap<_, Blake2_128Concat, T::AccountId, u64, ValueQuery, DefaultAccumulatedEmission>; + #[pallet::storage] /// Map ( hot, cold ) --> block_number | Last add stake increase. + pub type LastAddStakeIncrease = StorageDoubleMap<_, Blake2_128Concat, T::AccountId, Identity, T::AccountId, u64, ValueQuery, DefaultAccountTake>; + #[pallet::storage] /// DMAP ( parent, netuid ) --> Vec<(proportion,child)> + pub type ChildKeys = StorageDoubleMap<_, Blake2_128Concat, T::AccountId, Identity, u16, Vec<(u64, T::AccountId)>, ValueQuery, DefaultAccountLinkage>; + #[pallet::storage] /// DMAP ( child, netuid ) --> Vec<(proportion,parent)> + pub type ParentKeys = StorageDoubleMap<_, Blake2_128Concat, T::AccountId, Identity, u16, Vec<(u64, T::AccountId)>, ValueQuery, DefaultAccountLinkage>; + #[pallet::storage] // --- DMAP ( cold ) --> Vec | Maps coldkey to hotkeys that stake to it + pub type StakingHotkeys = StorageMap<_, Blake2_128Concat, T::AccountId, Vec, ValueQuery>; + #[pallet::storage] // --- MAP ( cold ) --> Vec | Returns the vector of hotkeys controlled by this coldkey. + pub type OwnedHotkeys = StorageMap<_, Blake2_128Concat, T::AccountId, Vec, ValueQuery>; - #[pallet::type_value] - pub fn DefaultAlphaValues() -> (u16, u16) { - (45875, 58982) // (alpha_low: 0.7, alpha_high: 0.9) - } - #[pallet::storage] // ITEM( weights_min_stake ) - pub type WeightsMinStake = StorageValue<_, u64, ValueQuery, DefaultWeightsMinStake>; - #[pallet::storage] // --- MAP ( netuid ) --> Rho + /// ============================ + /// ==== Global Parameters ===== + /// ============================ + #[pallet::storage] /// --- StorageItem Global Used Work. + pub type UsedWork = StorageMap<_, Identity, Vec, u64, ValueQuery>; + #[pallet::storage] /// --- ITEM( global_max_registrations_per_block ) + pub type MaxRegistrationsPerBlock = StorageMap<_, Identity, u16, u16, ValueQuery, DefaultMaxRegistrationsPerBlock>; + #[pallet::storage] /// --- ITEM( maximum_number_of_networks ) + pub type SubnetLimit = StorageValue<_, u16, ValueQuery, DefaultSubnetLimit>; + #[pallet::storage] /// --- ITEM( total_number_of_existing_networks ) + pub type TotalNetworks = StorageValue<_, u16, ValueQuery>; + #[pallet::storage] /// ITEM( network_immunity_period ) + pub type NetworkImmunityPeriod = StorageValue<_, u64, ValueQuery, DefaultNetworkImmunityPeriod>; + #[pallet::storage] /// ITEM( network_last_registered_block ) + pub type NetworkLastRegistered = StorageValue<_, u64, ValueQuery, DefaultNetworkLastRegistered>; + #[pallet::storage] /// ITEM( network_min_allowed_uids ) + pub type NetworkMinAllowedUids = StorageValue<_, u16, ValueQuery, DefaultNetworkMinAllowedUids>; + #[pallet::storage] /// ITEM( min_network_lock_cost ) + pub type NetworkMinLockCost = StorageValue<_, u64, ValueQuery, DefaultNetworkMinLockCost>; + #[pallet::storage] /// ITEM( last_network_lock_cost ) + pub type NetworkLastLockCost = StorageValue<_, u64, ValueQuery, DefaultNetworkMinLockCost>; + #[pallet::storage] /// ITEM( network_lock_reduction_interval ) + pub type NetworkLockReductionInterval = StorageValue<_, u64, ValueQuery, DefaultNetworkLockReductionInterval>; + #[pallet::storage] /// ITEM( subnet_owner_cut ) + pub type SubnetOwnerCut = StorageValue<_, u16, ValueQuery, DefaultSubnetOwnerCut>; + #[pallet::storage] /// ITEM( network_rate_limit ) + pub type NetworkRateLimit = StorageValue<_, u64, ValueQuery, DefaultNetworkRateLimit>; + #[pallet::storage] /// ITEM( nominator_min_required_stake ) + pub type NominatorMinRequiredStake = StorageValue<_, u64, ValueQuery, DefaultNominatorMinRequiredStake>; + + /// ============================ + /// ==== Subnet Parameters ===== + /// ============================ + #[pallet::storage] /// --- MAP ( netuid ) --> subnetwork_n (Number of UIDs in the network). + pub type SubnetworkN = StorageMap<_, Identity, u16, u16, ValueQuery, DefaultN>; + #[pallet::storage] /// --- MAP ( netuid ) --> modality TEXT: 0, IMAGE: 1, TENSOR: 2 + pub type NetworkModality = StorageMap<_, Identity, u16, u16, ValueQuery, DefaultModality>; + #[pallet::storage] /// --- MAP ( netuid ) --> network_is_added + pub type NetworksAdded = StorageMap<_, Identity, u16, bool, ValueQuery, DefaultNeworksAdded>; + #[pallet::storage] /// --- DMAP ( hotkey, netuid ) --> bool + pub type IsNetworkMember = StorageDoubleMap<_, Blake2_128Concat, T::AccountId, Identity, u16, bool, ValueQuery, DefaultIsNetworkMember>; + #[pallet::storage] /// --- MAP ( netuid ) --> network_registration_allowed + pub type NetworkRegistrationAllowed = StorageMap<_, Identity, u16, bool, ValueQuery, DefaultRegistrationAllowed>; + #[pallet::storage] /// --- MAP ( netuid ) --> network_pow_allowed + pub type NetworkPowRegistrationAllowed = StorageMap<_, Identity, u16, bool, ValueQuery, DefaultRegistrationAllowed>; + #[pallet::storage] /// --- MAP ( netuid ) --> block_created + pub type NetworkRegisteredAt = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultNetworkRegisteredAt>; + #[pallet::storage] /// --- MAP ( netuid ) --> tempo + pub type Tempo = StorageMap<_, Identity, u16, u16, ValueQuery, DefaultTempo>; + #[pallet::storage] /// --- MAP ( netuid ) --> emission_values + pub type EmissionValues = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultEmissionValues>; + #[pallet::storage] /// --- MAP ( netuid ) --> pending_emission + pub type PendingEmission = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultPendingEmission>; + #[pallet::storage] /// --- MAP ( netuid ) --> blocks_since_last_step + pub type BlocksSinceLastStep = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultBlocksSinceLastStep>; + #[pallet::storage] /// --- MAP ( netuid ) --> last_mechanism_step_block + pub type LastMechansimStepBlock = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultLastMechanismStepBlock>; + #[pallet::storage] /// --- MAP ( netuid ) --> subnet_owner + pub type SubnetOwner = StorageMap<_, Identity, u16, T::AccountId, ValueQuery, DefaultSubnetOwner>; + #[pallet::storage] /// --- MAP ( netuid ) --> subnet_locked + pub type SubnetLocked = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultSubnetLocked>; + #[pallet::storage] /// --- MAP ( netuid ) --> serving_rate_limit + pub type ServingRateLimit = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultServingRateLimit>; + #[pallet::storage] /// --- MAP ( netuid ) --> Rho pub type Rho = StorageMap<_, Identity, u16, u16, ValueQuery, DefaultRho>; - #[pallet::storage] // --- MAP ( netuid ) --> Kappa + #[pallet::storage] /// --- MAP ( netuid ) --> Kappa pub type Kappa = StorageMap<_, Identity, u16, u16, ValueQuery, DefaultKappa>; - #[pallet::storage] // --- MAP ( netuid ) --> uid, we use to record uids to prune at next epoch. + #[pallet::storage] /// --- MAP ( netuid ) --> uid, we use to record uids to prune at next epoch. pub type NeuronsToPruneAtNextEpoch = StorageMap<_, Identity, u16, u16, ValueQuery>; - #[pallet::storage] // --- MAP ( netuid ) --> registrations_this_interval + #[pallet::storage] /// --- MAP ( netuid ) --> registrations_this_interval pub type RegistrationsThisInterval = StorageMap<_, Identity, u16, u16, ValueQuery>; - #[pallet::storage] // --- MAP ( netuid ) --> pow_registrations_this_interval - pub type POWRegistrationsThisInterval = - StorageMap<_, Identity, u16, u16, ValueQuery>; - #[pallet::storage] // --- MAP ( netuid ) --> burn_registrations_this_interval - pub type BurnRegistrationsThisInterval = - StorageMap<_, Identity, u16, u16, ValueQuery>; - #[pallet::storage] // --- MAP ( netuid ) --> max_allowed_uids - pub type MaxAllowedUids = - StorageMap<_, Identity, u16, u16, ValueQuery, DefaultMaxAllowedUids>; - #[pallet::storage] // --- MAP ( netuid ) --> immunity_period - pub type ImmunityPeriod = - StorageMap<_, Identity, u16, u16, ValueQuery, DefaultImmunityPeriod>; - #[pallet::storage] // --- MAP ( netuid ) --> activity_cutoff - pub type ActivityCutoff = - StorageMap<_, Identity, u16, u16, ValueQuery, DefaultActivityCutoff>; - #[pallet::storage] // --- MAP ( netuid ) --> max_weight_limit - pub type MaxWeightsLimit = - StorageMap<_, Identity, u16, u16, ValueQuery, DefaultMaxWeightsLimit>; - #[pallet::storage] // --- MAP ( netuid ) --> weights_version_key - pub type WeightsVersionKey = - StorageMap<_, Identity, u16, u64, ValueQuery, DefaultWeightsVersionKey>; - #[pallet::storage] // --- MAP ( netuid ) --> min_allowed_weights - pub type MinAllowedWeights = - StorageMap<_, Identity, u16, u16, ValueQuery, DefaultMinAllowedWeights>; - #[pallet::storage] // --- MAP ( netuid ) --> max_allowed_validators - pub type MaxAllowedValidators = - StorageMap<_, Identity, u16, u16, ValueQuery, DefaultMaxAllowedValidators>; - #[pallet::storage] // --- MAP ( netuid ) --> adjustment_interval - pub type AdjustmentInterval = - StorageMap<_, Identity, u16, u16, ValueQuery, DefaultAdjustmentInterval>; - #[pallet::storage] // --- MAP ( netuid ) --> bonds_moving_average - pub type BondsMovingAverage = - StorageMap<_, Identity, u16, u64, ValueQuery, DefaultBondsMovingAverage>; - #[pallet::storage] // --- MAP ( netuid ) --> weights_set_rate_limit - pub type WeightsSetRateLimit = - StorageMap<_, Identity, u16, u64, ValueQuery, DefaultWeightsSetRateLimit>; - #[pallet::storage] // --- MAP ( netuid ) --> validator_prune_len - pub type ValidatorPruneLen = - StorageMap<_, Identity, u16, u64, ValueQuery, DefaultValidatorPruneLen>; - #[pallet::storage] // --- MAP ( netuid ) --> scaling_law_power - pub type ScalingLawPower = - StorageMap<_, Identity, u16, u16, ValueQuery, DefaultScalingLawPower>; - #[pallet::storage] // --- MAP ( netuid ) --> target_registrations_this_interval - pub type TargetRegistrationsPerInterval = - StorageMap<_, Identity, u16, u16, ValueQuery, DefaultTargetRegistrationsPerInterval>; - #[pallet::storage] // --- DMAP ( netuid, uid ) --> block_at_registration - pub type BlockAtRegistration = StorageDoubleMap< - _, - Identity, - u16, - Identity, - u16, - u64, - ValueQuery, - DefaultBlockAtRegistration, - >; - #[pallet::storage] // --- DMAP ( netuid ) --> adjustment_alpha - pub type AdjustmentAlpha = - StorageMap<_, Identity, u16, u64, ValueQuery, DefaultAdjustmentAlpha>; - - // MAP ( netuid ) --> (alpha_low, alpha_high) - #[pallet::storage] - pub type AlphaValues = - StorageMap<_, Identity, u16, (u16, u16), ValueQuery, DefaultAlphaValues>; - - #[pallet::storage] // --- MAP (netuid, who) --> (hash, weight) | Returns the hash and weight committed by an account for a given netuid. - pub type WeightCommits = StorageDoubleMap< - _, - Twox64Concat, - u16, - Twox64Concat, - T::AccountId, - (H256, u64), - OptionQuery, - >; - - /// Default value for weight commit reveal interval. - #[pallet::type_value] - pub fn DefaultWeightCommitRevealInterval() -> u64 { - 1000 - } - // --- DMAP ( netuid ) --> interval - #[pallet::storage] - pub type WeightCommitRevealInterval = - StorageMap<_, Identity, u16, u64, ValueQuery, DefaultWeightCommitRevealInterval>; + #[pallet::storage] /// --- MAP ( netuid ) --> pow_registrations_this_interval + pub type POWRegistrationsThisInterval = StorageMap<_, Identity, u16, u16, ValueQuery>; + #[pallet::storage] /// --- MAP ( netuid ) --> burn_registrations_this_interval + pub type BurnRegistrationsThisInterval = StorageMap<_, Identity, u16, u16, ValueQuery>; + #[pallet::storage] /// --- MAP ( netuid ) --> max_allowed_uids + pub type MaxAllowedUids = StorageMap<_, Identity, u16, u16, ValueQuery, DefaultMaxAllowedUids>; + #[pallet::storage] /// --- MAP ( netuid ) --> immunity_period + pub type ImmunityPeriod = StorageMap<_, Identity, u16, u16, ValueQuery, DefaultImmunityPeriod>; + #[pallet::storage] /// --- MAP ( netuid ) --> activity_cutoff + pub type ActivityCutoff = StorageMap<_, Identity, u16, u16, ValueQuery, DefaultActivityCutoff>; + #[pallet::storage] /// --- MAP ( netuid ) --> max_weight_limit + pub type MaxWeightsLimit = StorageMap<_, Identity, u16, u16, ValueQuery, DefaultMaxWeightsLimit>; + #[pallet::storage] /// --- MAP ( netuid ) --> weights_version_key + pub type WeightsVersionKey = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultWeightsVersionKey>; + #[pallet::storage] /// --- MAP ( netuid ) --> min_allowed_weights + pub type MinAllowedWeights = StorageMap<_, Identity, u16, u16, ValueQuery, DefaultMinAllowedWeights>; + #[pallet::storage] /// --- MAP ( netuid ) --> max_allowed_validators + pub type MaxAllowedValidators = StorageMap<_, Identity, u16, u16, ValueQuery, DefaultMaxAllowedValidators>; + #[pallet::storage] /// --- MAP ( netuid ) --> adjustment_interval + pub type AdjustmentInterval = StorageMap<_, Identity, u16, u16, ValueQuery, DefaultAdjustmentInterval>; + #[pallet::storage] /// --- MAP ( netuid ) --> bonds_moving_average + pub type BondsMovingAverage = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultBondsMovingAverage>; + #[pallet::storage] /// --- MAP ( netuid ) --> weights_set_rate_limit + pub type WeightsSetRateLimit = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultWeightsSetRateLimit>; + #[pallet::storage] /// --- MAP ( netuid ) --> validator_prune_len + pub type ValidatorPruneLen = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultValidatorPruneLen>; + #[pallet::storage] /// --- MAP ( netuid ) --> scaling_law_power + pub type ScalingLawPower = StorageMap<_, Identity, u16, u16, ValueQuery, DefaultScalingLawPower>; + #[pallet::storage] /// --- MAP ( netuid ) --> target_registrations_this_interval + pub type TargetRegistrationsPerInterval = StorageMap<_, Identity, u16, u16, ValueQuery, DefaultTargetRegistrationsPerInterval>; + #[pallet::storage] /// --- MAP ( netuid ) --> adjustment_alpha + pub type AdjustmentAlpha = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultAdjustmentAlpha>; + #[pallet::storage] /// --- MAP ( netuid ) --> interval + pub type WeightCommitRevealInterval = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultWeightCommitRevealInterval>; + #[pallet::storage] /// --- MAP ( netuid ) --> interval + pub type CommitRevealWeightsEnabled = StorageMap<_, Identity, u16, bool, ValueQuery, DefaultCommitRevealWeightsEnabled>; + #[pallet::storage] /// --- MAP ( netuid ) --> Burn + pub type Burn = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultBurn>; + #[pallet::storage] /// --- MAP ( netuid ) --> Difficulty + pub type Difficulty = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultDifficulty>; + #[pallet::storage] /// --- MAP ( netuid ) --> MinBurn + pub type MinBurn = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultMinBurn>; + #[pallet::storage] /// --- MAP ( netuid ) --> MaxBurn + pub type MaxBurn = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultMaxBurn>; + #[pallet::storage] /// --- MAP ( netuid ) --> MinDifficulty + pub type MinDifficulty = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultMinDifficulty>; + #[pallet::storage] /// --- MAP ( netuid ) --> MaxDifficulty + pub type MaxDifficulty = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultMaxDifficulty>; + #[pallet::storage] /// --- MAP ( netuid ) --> Block at last adjustment. + pub type LastAdjustmentBlock = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultLastAdjustmentBlock>; + #[pallet::storage] /// --- MAP ( netuid ) --> Registrations of this Block. + pub type RegistrationsThisBlock = StorageMap<_, Identity, u16, u16, ValueQuery, DefaultRegistrationsThisBlock>; + #[pallet::storage] /// --- MAP ( netuid ) --> global_RAO_recycled_for_registration + pub type RAORecycledForRegistration = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultRAORecycledForRegistration>; + #[pallet::storage] /// --- ITEM ( tx_rate_limit ) + pub(super) type TxRateLimit = StorageValue<_, u64, ValueQuery, DefaultTxRateLimit>; + #[pallet::storage] /// --- ITEM ( tx_rate_limit ) + pub(super) type TxDelegateTakeRateLimit = StorageValue<_, u64, ValueQuery, DefaultTxDelegateTakeRateLimit>; + #[pallet::storage] /// --- MAP ( netuid ) --> Whether or not Liquid Alpha is enabled + pub type LiquidAlphaOn = StorageMap<_, Blake2_128Concat, u16, bool, ValueQuery, DefaultLiquidAlpha>; + #[pallet::storage] /// MAP ( netuid ) --> (alpha_low, alpha_high) + pub type AlphaValues = StorageMap<_, Identity, u16, (u16, u16), ValueQuery, DefaultAlphaValues>; - /// Default value for weight commit/reveal enabled. - #[pallet::type_value] - pub fn DefaultCommitRevealWeightsEnabled() -> bool { - false - } - // --- DMAP ( netuid ) --> interval - #[pallet::storage] - pub type CommitRevealWeightsEnabled = - StorageMap<_, Identity, u16, bool, ValueQuery, DefaultCommitRevealWeightsEnabled>; /// ======================================= /// ==== Subnetwork Consensus Storage ==== /// ======================================= + #[pallet::storage] /// --- DMAP ( netuid, hotkey ) --> uid + pub(super) type Uids = StorageDoubleMap<_, Identity, u16, Blake2_128Concat, T::AccountId, u16, OptionQuery>; + #[pallet::storage] /// --- DMAP ( netuid, uid ) --> hotkey + pub(super) type Keys = StorageDoubleMap<_, Identity, u16, Identity, u16, T::AccountId, ValueQuery, DefaultKey>; + #[pallet::storage] /// --- DMAP ( netuid ) --> (hotkey, se, ve) + pub(super) type LoadedEmission = StorageMap<_, Identity, u16, Vec<(T::AccountId, u64, u64)>, OptionQuery>; + #[pallet::storage] /// --- DMAP ( netuid ) --> active + pub(super) type Active = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyBoolVec>; + #[pallet::storage] /// --- DMAP ( netuid ) --> rank + pub(super) type Rank = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; + #[pallet::storage] /// --- DMAP ( netuid ) --> trust + pub(super) type Trust = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; + #[pallet::storage] /// --- DMAP ( netuid ) --> consensus + pub(super) type Consensus = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; + #[pallet::storage] /// --- DMAP ( netuid ) --> incentive + pub(super) type Incentive = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; + #[pallet::storage] /// --- DMAP ( netuid ) --> dividends + pub(super) type Dividends = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; + #[pallet::storage] /// --- DMAP ( netuid ) --> emission + pub(super) type Emission = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU64Vec>; + #[pallet::storage] /// --- DMAP ( netuid ) --> last_update + pub(super) type LastUpdate = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU64Vec>; + #[pallet::storage] /// --- DMAP ( netuid ) --> validator_trust + pub(super) type ValidatorTrust = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; + #[pallet::storage] /// --- DMAP ( netuid ) --> pruning_scores + pub(super) type PruningScores = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; + #[pallet::storage] /// --- DMAP ( netuid ) --> validator_permit + pub(super) type ValidatorPermit = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyBoolVec>; + #[pallet::storage] /// --- DMAP ( netuid, uid ) --> weights + pub(super) type Weights = StorageDoubleMap<_, Identity, u16, Identity, u16, Vec<(u16, u16)>, ValueQuery, DefaultWeights>; + #[pallet::storage] /// --- DMAP ( netuid, uid ) --> bonds + pub(super) type Bonds = StorageDoubleMap<_, Identity, u16, Identity, u16, Vec<(u16, u16)>, ValueQuery, DefaultBonds>; + #[pallet::storage] /// --- DMAP ( netuid, uid ) --> block_at_registration + pub type BlockAtRegistration = StorageDoubleMap<_, Identity, u16, Identity, u16, u64, ValueQuery, DefaultBlockAtRegistration>; + #[pallet::storage] /// --- MAP ( netuid, hotkey ) --> axon_info + pub(super) type Axons = StorageDoubleMap<_, Identity, u16, Blake2_128Concat, T::AccountId, AxonInfoOf, OptionQuery>; + #[pallet::storage] /// --- MAP ( netuid, hotkey ) --> prometheus_info + pub(super) type Prometheus = StorageDoubleMap<_, Identity, u16, Blake2_128Concat, T::AccountId, PrometheusInfoOf, OptionQuery>; - /// Value definition for vector of u16. - #[pallet::type_value] - pub fn EmptyU16Vec() -> Vec { - vec![] - } - /// Value definition for vector of u64. - #[pallet::type_value] - pub fn EmptyU64Vec() -> Vec { - vec![] - } - /// Value definition for vector of bool. - #[pallet::type_value] - pub fn EmptyBoolVec() -> Vec { - vec![] - } - /// Value definition for bonds with type vector of (u16, u16). - #[pallet::type_value] - pub fn DefaultBonds() -> Vec<(u16, u16)> { - vec![] - } - /// Value definition for weights with vector of (u16, u16). + /// ================================= + /// ==== Axon / Promo Endpoints ===== + /// ================================= + #[pallet::storage] /// --- MAP ( key ) --> last_block + pub(super) type LastTxBlock = StorageMap<_, Identity, T::AccountId, u64, ValueQuery, DefaultLastTxBlock>; + #[pallet::storage] /// --- MAP ( key ) --> last_block + pub(super) type LastTxBlockDelegateTake = StorageMap<_, Identity, T::AccountId, u64, ValueQuery, DefaultLastTxBlock>; + #[pallet::storage] /// ITEM( weights_min_stake ) + pub type WeightsMinStake = StorageValue<_, u64, ValueQuery, DefaultWeightsMinStake>; + #[pallet::storage] /// --- MAP (netuid, who) --> (hash, weight) | Returns the hash and weight committed by an account for a given netuid. + pub type WeightCommits = StorageDoubleMap<_, Twox64Concat, u16, Twox64Concat, T::AccountId, (H256, u64), OptionQuery>; + + /// =============================== + /// ==== Coldkey Arbitrations ===== + /// =============================== + #[pallet::type_value] /// Default base difficulty for proof of work for coldkey swaps + pub fn DefaultBaseDifficulty() -> u64 { T::InitialBaseDifficulty::get() } + #[pallet::storage] // --- ITEM ( base_difficulty ) + pub type BaseDifficulty = StorageValue<_, u64, ValueQuery, DefaultBaseDifficulty>; #[pallet::type_value] - pub fn DefaultWeights() -> Vec<(u16, u16)> { + /// Default value for hotkeys. + pub fn EmptyAccounts() -> Vec { vec![] } - /// Default value for key with type T::AccountId derived from trailing zeroes. #[pallet::type_value] - pub fn DefaultKey() -> T::AccountId { - T::AccountId::decode(&mut sp_runtime::traits::TrailingZeroInput::zeroes()) - .expect("trailing zeroes always produce a valid account ID; qed") + /// Default arbitration period. + /// This value represents the default arbitration period in blocks. + /// The period is set to 18 hours, assuming a block time of 12 seconds. + pub fn DefaultArbitrationPeriod() -> u64 { + 7200 * 3 // 3 days } - - #[pallet::storage] // --- DMAP ( netuid, hotkey ) --> uid - pub type Uids = - StorageDoubleMap<_, Identity, u16, Blake2_128Concat, T::AccountId, u16, OptionQuery>; - #[pallet::storage] // --- DMAP ( netuid, uid ) --> hotkey - pub type Keys = - StorageDoubleMap<_, Identity, u16, Identity, u16, T::AccountId, ValueQuery, DefaultKey>; - #[pallet::storage] // --- DMAP ( netuid ) --> (hotkey, se, ve) - pub type LoadedEmission = - StorageMap<_, Identity, u16, Vec<(T::AccountId, u64, u64)>, OptionQuery>; - - #[pallet::storage] // --- DMAP ( netuid ) --> active - pub(super) type Active = - StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyBoolVec>; - #[pallet::storage] // --- DMAP ( netuid ) --> rank - pub(super) type Rank = - StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; - #[pallet::storage] // --- DMAP ( netuid ) --> trust - pub(super) type Trust = - StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; - #[pallet::storage] // --- DMAP ( netuid ) --> consensus - pub(super) type Consensus = - StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; - #[pallet::storage] // --- DMAP ( netuid ) --> incentive - pub(super) type Incentive = - StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; - #[pallet::storage] // --- DMAP ( netuid ) --> dividends - pub(super) type Dividends = - StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; - #[pallet::storage] // --- DMAP ( netuid ) --> emission - pub(super) type Emission = - StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU64Vec>; - #[pallet::storage] // --- DMAP ( netuid ) --> last_update - pub(super) type LastUpdate = - StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU64Vec>; - #[pallet::storage] // --- DMAP ( netuid ) --> validator_trust - pub(super) type ValidatorTrust = - StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; - #[pallet::storage] // --- DMAP ( netuid ) --> pruning_scores - pub(super) type PruningScores = - StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; - #[pallet::storage] // --- DMAP ( netuid ) --> validator_permit - pub(super) type ValidatorPermit = - StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyBoolVec>; - - #[pallet::storage] // --- DMAP ( netuid, uid ) --> weights - pub(super) type Weights = StorageDoubleMap< - _, - Identity, - u16, - Identity, - u16, - Vec<(u16, u16)>, - ValueQuery, - DefaultWeights, - >; - #[pallet::storage] // --- DMAP ( netuid, uid ) --> bonds - pub(super) type Bonds = StorageDoubleMap< + #[pallet::storage] // ---- StorageItem Global Used Work. + pub type ArbitrationPeriod = + StorageValue<_, u64, ValueQuery, DefaultArbitrationPeriod>; + #[pallet::storage] // --- MAP ( cold ) --> Vec | Returns a list of keys to drain to, if there are two, we extend the period. + pub type ColdkeySwapDestinations = StorageMap< _, - Identity, - u16, - Identity, - u16, - Vec<(u16, u16)>, + Blake2_128Concat, + T::AccountId, + Vec, ValueQuery, - DefaultBonds, + EmptyAccounts, >; + #[pallet::storage] // --- MAP ( cold ) --> u64 | Block when the coldkey will be arbitrated. + pub type ColdkeyArbitrationBlock = + StorageMap<_, Blake2_128Concat, T::AccountId, u64, ValueQuery>; + #[pallet::storage] // --- MAP ( u64 ) --> Vec | Coldkeys to drain on the specific block. + pub type ColdkeysToSwapAtBlock = + StorageMap<_, Identity, u64, Vec, ValueQuery, EmptyAccounts>; /// ================== /// ==== Genesis ===== @@ -1161,1113 +605,6 @@ pub mod pallet { } } - #[pallet::genesis_build] - impl BuildGenesisConfig for GenesisConfig { - fn build(&self) { - // Set initial total issuance from balances - TotalIssuance::::put(self.balances_issuance); - - // Subnet config values - let netuid: u16 = 3; - let tempo = 99; - let max_uids = 4096; - - // The functions for initializing new networks/setting defaults cannot be run directly from genesis functions like extrinsics would - // --- Set this network uid to alive. - NetworksAdded::::insert(netuid, true); - - // --- Fill tempo memory item. - Tempo::::insert(netuid, tempo); - - // --- Fill modality item. - // Only modality 0 exists (text) - NetworkModality::::insert(netuid, 0); - - // Make network parameters explicit. - if !Tempo::::contains_key(netuid) { - Tempo::::insert(netuid, Tempo::::get(netuid)); - } - if !Kappa::::contains_key(netuid) { - Kappa::::insert(netuid, Kappa::::get(netuid)); - } - if !Difficulty::::contains_key(netuid) { - Difficulty::::insert(netuid, Difficulty::::get(netuid)); - } - if !MaxAllowedUids::::contains_key(netuid) { - MaxAllowedUids::::insert(netuid, MaxAllowedUids::::get(netuid)); - } - if !ImmunityPeriod::::contains_key(netuid) { - ImmunityPeriod::::insert(netuid, ImmunityPeriod::::get(netuid)); - } - if !ActivityCutoff::::contains_key(netuid) { - ActivityCutoff::::insert(netuid, ActivityCutoff::::get(netuid)); - } - if !EmissionValues::::contains_key(netuid) { - EmissionValues::::insert(netuid, EmissionValues::::get(netuid)); - } - if !MaxWeightsLimit::::contains_key(netuid) { - MaxWeightsLimit::::insert(netuid, MaxWeightsLimit::::get(netuid)); - } - if !MinAllowedWeights::::contains_key(netuid) { - MinAllowedWeights::::insert(netuid, MinAllowedWeights::::get(netuid)); - } - if !RegistrationsThisInterval::::contains_key(netuid) { - RegistrationsThisInterval::::insert( - netuid, - RegistrationsThisInterval::::get(netuid), - ); - } - if !POWRegistrationsThisInterval::::contains_key(netuid) { - POWRegistrationsThisInterval::::insert( - netuid, - POWRegistrationsThisInterval::::get(netuid), - ); - } - if !BurnRegistrationsThisInterval::::contains_key(netuid) { - BurnRegistrationsThisInterval::::insert( - netuid, - BurnRegistrationsThisInterval::::get(netuid), - ); - } - - // Set max allowed uids - MaxAllowedUids::::insert(netuid, max_uids); - - let mut next_uid = 0u16; - - for (coldkey, hotkeys) in self.stakes.iter() { - for (hotkey, stake_uid) in hotkeys.iter() { - let (stake, uid) = stake_uid; - - // Expand Yuma Consensus with new position. - Rank::::mutate(netuid, |v| v.push(0)); - Trust::::mutate(netuid, |v| v.push(0)); - Active::::mutate(netuid, |v| v.push(true)); - Emission::::mutate(netuid, |v| v.push(0)); - Consensus::::mutate(netuid, |v| v.push(0)); - Incentive::::mutate(netuid, |v| v.push(0)); - Dividends::::mutate(netuid, |v| v.push(0)); - LastUpdate::::mutate(netuid, |v| v.push(0)); - PruningScores::::mutate(netuid, |v| v.push(0)); - ValidatorTrust::::mutate(netuid, |v| v.push(0)); - ValidatorPermit::::mutate(netuid, |v| v.push(false)); - - // Insert account information. - Keys::::insert(netuid, uid, hotkey.clone()); // Make hotkey - uid association. - Uids::::insert(netuid, hotkey.clone(), uid); // Make uid - hotkey association. - BlockAtRegistration::::insert(netuid, uid, 0); // Fill block at registration. - IsNetworkMember::::insert(hotkey.clone(), netuid, true); // Fill network is member. - - // Fill stake information. - Owner::::insert(hotkey.clone(), coldkey.clone()); - - // Update OwnedHotkeys map - let mut hotkeys = OwnedHotkeys::::get(coldkey); - if !hotkeys.contains(hotkey) { - hotkeys.push(hotkey.clone()); - OwnedHotkeys::::insert(coldkey, hotkeys); - } - - TotalHotkeyStake::::insert(hotkey.clone(), stake); - TotalColdkeyStake::::insert( - coldkey.clone(), - TotalColdkeyStake::::get(coldkey).saturating_add(*stake), - ); - - // Update total issuance value - TotalIssuance::::put(TotalIssuance::::get().saturating_add(*stake)); - - Stake::::insert(hotkey.clone(), coldkey.clone(), stake); - - // Update StakingHotkeys map - let mut staking_hotkeys = StakingHotkeys::::get(coldkey); - if !staking_hotkeys.contains(hotkey) { - staking_hotkeys.push(hotkey.clone()); - StakingHotkeys::::insert(coldkey, staking_hotkeys); - } - - next_uid = next_uid.checked_add(1).expect( - "should not have total number of hotkey accounts larger than u16::MAX", - ); - } - } - - // Set correct length for Subnet neurons - SubnetworkN::::insert(netuid, next_uid); - - // --- Increase total network count. - TotalNetworks::::mutate(|n| { - *n = n.checked_add(1).expect( - "should not have total number of networks larger than u16::MAX in genesis", - ) - }); - - // Get the root network uid. - let root_netuid: u16 = 0; - - // Set the root network as added. - NetworksAdded::::insert(root_netuid, true); - - // Increment the number of total networks. - TotalNetworks::::mutate(|n| { - *n = n.checked_add(1).expect( - "should not have total number of networks larger than u16::MAX in genesis", - ) - }); - // Set the number of validators to 1. - SubnetworkN::::insert(root_netuid, 0); - - // Set the maximum number to the number of senate members. - MaxAllowedUids::::insert(root_netuid, 64u16); - - // Set the maximum number to the number of validators to all members. - MaxAllowedValidators::::insert(root_netuid, 64u16); - - // Set the min allowed weights to zero, no weights restrictions. - MinAllowedWeights::::insert(root_netuid, 0); - - // Set the max weight limit to infinity, no weight restrictions. - MaxWeightsLimit::::insert(root_netuid, u16::MAX); - - // Add default root tempo. - Tempo::::insert(root_netuid, 100); - - // Set the root network as open. - NetworkRegistrationAllowed::::insert(root_netuid, true); - - // Set target registrations for validators as 1 per block. - TargetRegistrationsPerInterval::::insert(root_netuid, 1); - } - } - - // ================ - // ==== Hooks ===== - // ================ - - #[pallet::hooks] - impl Hooks> for Pallet { - fn on_idle(_n: BlockNumberFor, _remaining_weight: Weight) -> Weight { - Weight::zero() - } - - fn on_initialize(_block_number: BlockNumberFor) -> Weight { - let mut total_weight = Weight::zero(); - - // Create a Weight::MAX value to pass to swap_coldkeys_this_block - let max_weight = Weight::MAX; - - // Perform coldkey swapping - let swap_weight = match Self::swap_coldkeys_this_block(&max_weight) { - Ok(weight_used) => weight_used, - Err(e) => { - log::error!("Error while swapping coldkeys: {:?}", e); - Weight::zero() - } - }; - total_weight = total_weight.saturating_add(swap_weight); - - // Perform block step - let block_step_result = Self::block_step(); - match block_step_result { - Ok(_) => { - log::debug!("Successfully ran block step."); - total_weight = total_weight.saturating_add( - Weight::from_parts(110_634_229_000_u64, 0) - .saturating_add(T::DbWeight::get().reads(8304_u64)) - .saturating_add(T::DbWeight::get().writes(110_u64)), - ); - } - Err(e) => { - log::error!("Error while stepping block: {:?}", e); - total_weight = total_weight.saturating_add( - Weight::from_parts(110_634_229_000_u64, 0) - .saturating_add(T::DbWeight::get().reads(8304_u64)) - .saturating_add(T::DbWeight::get().writes(110_u64)), - ); - } - } - - total_weight - } - - fn on_runtime_upgrade() -> frame_support::weights::Weight { - // --- Migrate storage - use crate::migration; - let mut weight = frame_support::weights::Weight::from_parts(0, 0); - - // Hex encoded foundation coldkey - let hex = hex_literal::hex![ - "feabaafee293d3b76dae304e2f9d885f77d2b17adab9e17e921b321eccd61c77" - ]; - weight = weight - // Initializes storage version (to 1) - .saturating_add(migration::migrate_to_v1_separate_emission::()) - // Storage version v1 -> v2 - .saturating_add(migration::migrate_to_v2_fixed_total_stake::()) - // Doesn't check storage version. TODO: Remove after upgrade - .saturating_add(migration::migrate_create_root_network::()) - // Storage version v2 -> v3 - .saturating_add(migration::migrate_transfer_ownership_to_foundation::( - hex, - )) - // Storage version v3 -> v4 - .saturating_add(migration::migrate_delete_subnet_21::()) - // Storage version v4 -> v5 - .saturating_add(migration::migrate_delete_subnet_3::()) - // Doesn't check storage version. TODO: Remove after upgrade - .saturating_add(migration::migration5_total_issuance::(false)) - // Populate OwnedHotkeys map for coldkey swap. Doesn't update storage vesion. - .saturating_add(migration::migrate_populate_owned::()) - // Populate StakingHotkeys map for coldkey swap. Doesn't update storage vesion. - .saturating_add(migration::migrate_populate_staking_hotkeys::()) - // Fix total coldkey stake. - .saturating_add(migration::migrate_fix_total_coldkey_stake::()); - - weight - } - } - - /// Dispatchable functions allow users to interact with the pallet and invoke state changes. - /// These functions materialize as "extrinsics", which are often compared to transactions. - /// Dispatchable functions must be annotated with a weight and must return a DispatchResult. - #[pallet::call] - impl Pallet { - /// --- Sets the caller weights for the incentive mechanism. The call can be - /// made from the hotkey account so is potentially insecure, however, the damage - /// of changing weights is minimal if caught early. This function includes all the - /// checks that the passed weights meet the requirements. Stored as u16s they represent - /// rational values in the range [0,1] which sum to 1 and can be interpreted as - /// probabilities. The specific weights determine how inflation propagates outward - /// from this peer. - /// - /// Note: The 16 bit integers weights should represent 1.0 as the max u16. - /// However, the function normalizes all integers to u16_max anyway. This means that if the sum of all - /// elements is larger or smaller than the amount of elements * u16_max, all elements - /// will be corrected for this deviation. - /// - /// # Args: - /// * `origin`: (Origin): - /// - The caller, a hotkey who wishes to set their weights. - /// - /// * `netuid` (u16): - /// - The network uid we are setting these weights on. - /// - /// * `dests` (Vec): - /// - The edge endpoint for the weight, i.e. j for w_ij. - /// - /// * 'weights' (Vec): - /// - The u16 integer encoded weights. Interpreted as rational - /// values in the range [0,1]. They must sum to in32::MAX. - /// - /// * 'version_key' ( u64 ): - /// - The network version key to check if the validator is up to date. - /// - /// # Event: - /// * WeightsSet; - /// - On successfully setting the weights on chain. - /// - /// # Raises: - /// * 'SubNetworkDoesNotExist': - /// - Attempting to set weights on a non-existent network. - /// - /// * 'NotRegistered': - /// - Attempting to set weights from a non registered account. - /// - /// * 'WeightVecNotEqualSize': - /// - Attempting to set weights with uids not of same length. - /// - /// * 'DuplicateUids': - /// - Attempting to set weights with duplicate uids. - /// - /// * 'UidsLengthExceedUidsInSubNet': - /// - Attempting to set weights above the max allowed uids. - /// - /// * 'UidVecContainInvalidOne': - /// - Attempting to set weights with invalid uids. - /// - /// * 'WeightVecLengthIsLow': - /// - Attempting to set weights with fewer weights than min. - /// - /// * 'MaxWeightExceeded': - /// - Attempting to set weights with max value exceeding limit. - #[pallet::call_index(0)] - #[pallet::weight((Weight::from_parts(22_060_000_000, 0) - .saturating_add(T::DbWeight::get().reads(4106)) - .saturating_add(T::DbWeight::get().writes(2)), DispatchClass::Normal, Pays::No))] - pub fn set_weights( - origin: OriginFor, - netuid: u16, - dests: Vec, - weights: Vec, - version_key: u64, - ) -> DispatchResult { - if !Self::get_commit_reveal_weights_enabled(netuid) { - return Self::do_set_weights(origin, netuid, dests, weights, version_key); - } - - Err(Error::::CommitRevealEnabled.into()) - } - - /// ---- Used to commit a hash of your weight values to later be revealed. - /// - /// # Args: - /// * `origin`: (`::RuntimeOrigin`): - /// - The signature of the committing hotkey. - /// - /// * `netuid` (`u16`): - /// - The u16 network identifier. - /// - /// * `commit_hash` (`H256`): - /// - The hash representing the committed weights. - /// - /// # Raises: - /// * `WeightsCommitNotAllowed`: - /// - Attempting to commit when it is not allowed. - /// - #[pallet::call_index(96)] - #[pallet::weight((Weight::from_parts(46_000_000, 0) - .saturating_add(T::DbWeight::get().reads(1)) - .saturating_add(T::DbWeight::get().writes(1)), DispatchClass::Normal, Pays::No))] - pub fn commit_weights( - origin: T::RuntimeOrigin, - netuid: u16, - commit_hash: H256, - ) -> DispatchResult { - Self::do_commit_weights(origin, netuid, commit_hash) - } - - /// ---- Used to reveal the weights for a previously committed hash. - /// - /// # Args: - /// * `origin`: (`::RuntimeOrigin`): - /// - The signature of the revealing hotkey. - /// - /// * `netuid` (`u16`): - /// - The u16 network identifier. - /// - /// * `uids` (`Vec`): - /// - The uids for the weights being revealed. - /// - /// * `values` (`Vec`): - /// - The values of the weights being revealed. - /// - /// * `salt` (`Vec`): - /// - The random salt to protect from brute-force guessing attack in case of small weight changes bit-wise. - /// - /// * `version_key` (`u64`): - /// - The network version key. - /// - /// # Raises: - /// * `NoWeightsCommitFound`: - /// - Attempting to reveal weights without an existing commit. - /// - /// * `InvalidRevealCommitHashNotMatchTempo`: - /// - Attempting to reveal weights outside the valid tempo. - /// - /// * `InvalidRevealCommitHashNotMatch`: - /// - The revealed hash does not match the committed hash. - /// - #[pallet::call_index(97)] - #[pallet::weight((Weight::from_parts(103_000_000, 0) - .saturating_add(T::DbWeight::get().reads(11)) - .saturating_add(T::DbWeight::get().writes(3)), DispatchClass::Normal, Pays::No))] - pub fn reveal_weights( - origin: T::RuntimeOrigin, - netuid: u16, - uids: Vec, - values: Vec, - salt: Vec, - version_key: u64, - ) -> DispatchResult { - Self::do_reveal_weights(origin, netuid, uids, values, salt, version_key) - } - - /// # Args: - /// * `origin`: (Origin): - /// - The caller, a hotkey who wishes to set their weights. - /// - /// * `netuid` (u16): - /// - The network uid we are setting these weights on. - /// - /// * `hotkey` (T::AccountId): - /// - The hotkey associated with the operation and the calling coldkey. - /// - /// * `dests` (Vec): - /// - The edge endpoint for the weight, i.e. j for w_ij. - /// - /// * 'weights' (Vec): - /// - The u16 integer encoded weights. Interpreted as rational - /// values in the range [0,1]. They must sum to in32::MAX. - /// - /// * 'version_key' ( u64 ): - /// - The network version key to check if the validator is up to date. - /// - /// # Event: - /// - /// * WeightsSet; - /// - On successfully setting the weights on chain. - /// - /// # Raises: - /// - /// * NonAssociatedColdKey; - /// - Attempting to set weights on a non-associated cold key. - /// - /// * 'SubNetworkDoesNotExist': - /// - Attempting to set weights on a non-existent network. - /// - /// * 'NotRootSubnet': - /// - Attempting to set weights on a subnet that is not the root network. - /// - /// * 'WeightVecNotEqualSize': - /// - Attempting to set weights with uids not of same length. - /// - /// * 'UidVecContainInvalidOne': - /// - Attempting to set weights with invalid uids. - /// - /// * 'NotRegistered': - /// - Attempting to set weights from a non registered account. - /// - /// * 'WeightVecLengthIsLow': - /// - Attempting to set weights with fewer weights than min. - /// - /// * 'IncorrectWeightVersionKey': - /// - Attempting to set weights with the incorrect network version key. - /// - /// * 'SettingWeightsTooFast': - /// - Attempting to set weights too fast. - /// - /// * 'WeightVecLengthIsLow': - /// - Attempting to set weights with fewer weights than min. - /// - /// * 'MaxWeightExceeded': - /// - Attempting to set weights with max value exceeding limit. - /// - #[pallet::call_index(8)] - #[pallet::weight((Weight::from_parts(10_151_000_000, 0) - .saturating_add(T::DbWeight::get().reads(4104)) - .saturating_add(T::DbWeight::get().writes(2)), DispatchClass::Normal, Pays::No))] - pub fn set_root_weights( - origin: OriginFor, - netuid: u16, - hotkey: T::AccountId, - dests: Vec, - weights: Vec, - version_key: u64, - ) -> DispatchResult { - Self::do_set_root_weights(origin, netuid, hotkey, dests, weights, version_key) - } - - /// --- Sets the key as a delegate. - /// - /// # Args: - /// * 'origin': (Origin): - /// - The signature of the caller's coldkey. - /// - /// * 'hotkey' (T::AccountId): - /// - The hotkey we are delegating (must be owned by the coldkey.) - /// - /// * 'take' (u64): - /// - The stake proportion that this hotkey takes from delegations. - /// - /// # Event: - /// * DelegateAdded; - /// - On successfully setting a hotkey as a delegate. - /// - /// # Raises: - /// * 'NotRegistered': - /// - The hotkey we are delegating is not registered on the network. - /// - /// * 'NonAssociatedColdKey': - /// - The hotkey we are delegating is not owned by the calling coldket. - /// - #[pallet::call_index(1)] - #[pallet::weight((Weight::from_parts(79_000_000, 0) - .saturating_add(T::DbWeight::get().reads(6)) - .saturating_add(T::DbWeight::get().writes(3)), DispatchClass::Normal, Pays::No))] - pub fn become_delegate(origin: OriginFor, hotkey: T::AccountId) -> DispatchResult { - Self::do_become_delegate(origin, hotkey, Self::get_default_take()) - } - - /// --- Allows delegates to decrease its take value. - /// - /// # Args: - /// * 'origin': (::Origin): - /// - The signature of the caller's coldkey. - /// - /// * 'hotkey' (T::AccountId): - /// - The hotkey we are delegating (must be owned by the coldkey.) - /// - /// * 'netuid' (u16): - /// - Subnet ID to decrease take for - /// - /// * 'take' (u16): - /// - The new stake proportion that this hotkey takes from delegations. - /// The new value can be between 0 and 11_796 and should be strictly - /// lower than the previous value. It T is the new value (rational number), - /// the the parameter is calculated as [65535 * T]. For example, 1% would be - /// [0.01 * 65535] = [655.35] = 655 - /// - /// # Event: - /// * TakeDecreased; - /// - On successfully setting a decreased take for this hotkey. - /// - /// # Raises: - /// * 'NotRegistered': - /// - The hotkey we are delegating is not registered on the network. - /// - /// * 'NonAssociatedColdKey': - /// - The hotkey we are delegating is not owned by the calling coldkey. - /// - /// * 'DelegateTakeTooLow': - /// - The delegate is setting a take which is not lower than the previous. - /// - #[pallet::call_index(65)] - #[pallet::weight((0, DispatchClass::Normal, Pays::No))] - pub fn decrease_take( - origin: OriginFor, - hotkey: T::AccountId, - take: u16, - ) -> DispatchResult { - Self::do_decrease_take(origin, hotkey, take) - } - - /// --- Allows delegates to increase its take value. This call is rate-limited. - /// - /// # Args: - /// * 'origin': (::Origin): - /// - The signature of the caller's coldkey. - /// - /// * 'hotkey' (T::AccountId): - /// - The hotkey we are delegating (must be owned by the coldkey.) - /// - /// * 'take' (u16): - /// - The new stake proportion that this hotkey takes from delegations. - /// The new value can be between 0 and 11_796 and should be strictly - /// greater than the previous value. T is the new value (rational number), - /// the the parameter is calculated as [65535 * T]. For example, 1% would be - /// [0.01 * 65535] = [655.35] = 655 - /// - /// # Event: - /// * TakeIncreased; - /// - On successfully setting a increased take for this hotkey. - /// - /// # Raises: - /// * 'NotRegistered': - /// - The hotkey we are delegating is not registered on the network. - /// - /// * 'NonAssociatedColdKey': - /// - The hotkey we are delegating is not owned by the calling coldkey. - /// - /// * 'DelegateTakeTooHigh': - /// - The delegate is setting a take which is not greater than the previous. - /// - #[pallet::call_index(66)] - #[pallet::weight((0, DispatchClass::Normal, Pays::No))] - pub fn increase_take( - origin: OriginFor, - hotkey: T::AccountId, - take: u16, - ) -> DispatchResult { - Self::do_increase_take(origin, hotkey, take) - } - - /// --- Adds stake to a hotkey. The call is made from the - /// coldkey account linked in the hotkey. - /// Only the associated coldkey is allowed to make staking and - /// unstaking requests. This protects the neuron against - /// attacks on its hotkey running in production code. - /// - /// # Args: - /// * 'origin': (Origin): - /// - The signature of the caller's coldkey. - /// - /// * 'hotkey' (T::AccountId): - /// - The associated hotkey account. - /// - /// * 'amount_staked' (u64): - /// - The amount of stake to be added to the hotkey staking account. - /// - /// # Event: - /// * StakeAdded; - /// - On the successfully adding stake to a global account. - /// - /// # Raises: - /// * 'NotEnoughBalanceToStake': - /// - Not enough balance on the coldkey to add onto the global account. - /// - /// * 'NonAssociatedColdKey': - /// - The calling coldkey is not associated with this hotkey. - /// - /// * 'BalanceWithdrawalError': - /// - Errors stemming from transaction pallet. - /// - #[pallet::call_index(2)] - #[pallet::weight((Weight::from_parts(124_000_000, 0) - .saturating_add(T::DbWeight::get().reads(10)) - .saturating_add(T::DbWeight::get().writes(7)), DispatchClass::Normal, Pays::No))] - pub fn add_stake( - origin: OriginFor, - hotkey: T::AccountId, - amount_staked: u64, - ) -> DispatchResult { - Self::do_add_stake(origin, hotkey, amount_staked) - } - - /// Remove stake from the staking account. The call must be made - /// from the coldkey account attached to the neuron metadata. Only this key - /// has permission to make staking and unstaking requests. - /// - /// # Args: - /// * 'origin': (Origin): - /// - The signature of the caller's coldkey. - /// - /// * 'hotkey' (T::AccountId): - /// - The associated hotkey account. - /// - /// * 'amount_unstaked' (u64): - /// - The amount of stake to be added to the hotkey staking account. - /// - /// # Event: - /// * StakeRemoved; - /// - On the successfully removing stake from the hotkey account. - /// - /// # Raises: - /// * 'NotRegistered': - /// - Thrown if the account we are attempting to unstake from is non existent. - /// - /// * 'NonAssociatedColdKey': - /// - Thrown if the coldkey does not own the hotkey we are unstaking from. - /// - /// * 'NotEnoughStakeToWithdraw': - /// - Thrown if there is not enough stake on the hotkey to withdwraw this amount. - /// - #[pallet::call_index(3)] - #[pallet::weight((Weight::from_parts(111_000_000, 0) - .saturating_add(Weight::from_parts(0, 43991)) - .saturating_add(T::DbWeight::get().reads(10)) - .saturating_add(T::DbWeight::get().writes(7)), DispatchClass::Normal, Pays::No))] - pub fn remove_stake( - origin: OriginFor, - hotkey: T::AccountId, - amount_unstaked: u64, - ) -> DispatchResult { - Self::do_remove_stake(origin, hotkey, amount_unstaked) - } - - /// Serves or updates axon /promethteus information for the neuron associated with the caller. If the caller is - /// already registered the metadata is updated. If the caller is not registered this call throws NotRegistered. - /// - /// # Args: - /// * 'origin': (Origin): - /// - The signature of the caller. - /// - /// * 'netuid' (u16): - /// - The u16 network identifier. - /// - /// * 'version' (u64): - /// - The bittensor version identifier. - /// - /// * 'ip' (u64): - /// - The endpoint ip information as a u128 encoded integer. - /// - /// * 'port' (u16): - /// - The endpoint port information as a u16 encoded integer. - /// - /// * 'ip_type' (u8): - /// - The endpoint ip version as a u8, 4 or 6. - /// - /// * 'protocol' (u8): - /// - UDP:1 or TCP:0 - /// - /// * 'placeholder1' (u8): - /// - Placeholder for further extra params. - /// - /// * 'placeholder2' (u8): - /// - Placeholder for further extra params. - /// - /// # Event: - /// * AxonServed; - /// - On successfully serving the axon info. - /// - /// # Raises: - /// * 'SubNetworkDoesNotExist': - /// - Attempting to set weights on a non-existent network. - /// - /// * 'NotRegistered': - /// - Attempting to set weights from a non registered account. - /// - /// * 'InvalidIpType': - /// - The ip type is not 4 or 6. - /// - /// * 'InvalidIpAddress': - /// - The numerically encoded ip address does not resolve to a proper ip. - /// - /// * 'ServingRateLimitExceeded': - /// - Attempting to set prometheus information withing the rate limit min. - /// - #[pallet::call_index(4)] - #[pallet::weight((Weight::from_parts(46_000_000, 0) - .saturating_add(T::DbWeight::get().reads(4)) - .saturating_add(T::DbWeight::get().writes(1)), DispatchClass::Normal, Pays::No))] - pub fn serve_axon( - origin: OriginFor, - netuid: u16, - version: u32, - ip: u128, - port: u16, - ip_type: u8, - protocol: u8, - placeholder1: u8, - placeholder2: u8, - ) -> DispatchResult { - Self::do_serve_axon( - origin, - netuid, - version, - ip, - port, - ip_type, - protocol, - placeholder1, - placeholder2, - ) - } - - /// ---- Set prometheus information for the neuron. - /// # Args: - /// * 'origin': (Origin): - /// - The signature of the calling hotkey. - /// - /// * 'netuid' (u16): - /// - The u16 network identifier. - /// - /// * 'version' (u16): - /// - The bittensor version identifier. - /// - /// * 'ip' (u128): - /// - The prometheus ip information as a u128 encoded integer. - /// - /// * 'port' (u16): - /// - The prometheus port information as a u16 encoded integer. - /// - /// * 'ip_type' (u8): - /// - The ip type v4 or v6. - /// - #[pallet::call_index(5)] - #[pallet::weight((Weight::from_parts(45_000_000, 0) - .saturating_add(T::DbWeight::get().reads(4)) - .saturating_add(T::DbWeight::get().writes(1)), DispatchClass::Normal, Pays::No))] - pub fn serve_prometheus( - origin: OriginFor, - netuid: u16, - version: u32, - ip: u128, - port: u16, - ip_type: u8, - ) -> DispatchResult { - Self::do_serve_prometheus(origin, netuid, version, ip, port, ip_type) - } - - /// ---- Registers a new neuron to the subnetwork. - /// - /// # Args: - /// * 'origin': (Origin): - /// - The signature of the calling hotkey. - /// - /// * 'netuid' (u16): - /// - The u16 network identifier. - /// - /// * 'block_number' ( u64 ): - /// - Block hash used to prove work done. - /// - /// * 'nonce' ( u64 ): - /// - Positive integer nonce used in POW. - /// - /// * 'work' ( Vec ): - /// - Vector encoded bytes representing work done. - /// - /// * 'hotkey' ( T::AccountId ): - /// - Hotkey to be registered to the network. - /// - /// * 'coldkey' ( T::AccountId ): - /// - Associated coldkey account. - /// - /// # Event: - /// * NeuronRegistered; - /// - On successfully registering a uid to a neuron slot on a subnetwork. - /// - /// # Raises: - /// * 'SubNetworkDoesNotExist': - /// - Attempting to register to a non existent network. - /// - /// * 'TooManyRegistrationsThisBlock': - /// - This registration exceeds the total allowed on this network this block. - /// - /// * 'HotKeyAlreadyRegisteredInSubNet': - /// - The hotkey is already registered on this network. - /// - /// * 'InvalidWorkBlock': - /// - The work has been performed on a stale, future, or non existent block. - /// - /// * 'InvalidDifficulty': - /// - The work does not match the difficulty. - /// - /// * 'InvalidSeal': - /// - The seal is incorrect. - /// - #[pallet::call_index(6)] - #[pallet::weight((Weight::from_parts(192_000_000, 0) - .saturating_add(T::DbWeight::get().reads(24)) - .saturating_add(T::DbWeight::get().writes(22)), DispatchClass::Normal, Pays::No))] - pub fn register( - origin: OriginFor, - netuid: u16, - block_number: u64, - nonce: u64, - work: Vec, - hotkey: T::AccountId, - coldkey: T::AccountId, - ) -> DispatchResult { - Self::do_registration(origin, netuid, block_number, nonce, work, hotkey, coldkey) - } - - /// Register the hotkey to root network - #[pallet::call_index(62)] - #[pallet::weight((Weight::from_parts(164_000_000, 0) - .saturating_add(T::DbWeight::get().reads(23)) - .saturating_add(T::DbWeight::get().writes(20)), DispatchClass::Normal, Pays::No))] - pub fn root_register(origin: OriginFor, hotkey: T::AccountId) -> DispatchResult { - Self::do_root_register(origin, hotkey) - } - - /// Attempt to adjust the senate membership to include a hotkey - #[pallet::call_index(63)] - #[pallet::weight((Weight::from_parts(0, 0) - .saturating_add(T::DbWeight::get().reads(0)) - .saturating_add(T::DbWeight::get().writes(0)), DispatchClass::Normal, Pays::Yes))] - pub fn adjust_senate(origin: OriginFor, hotkey: T::AccountId) -> DispatchResult { - Self::do_adjust_senate(origin, hotkey) - } - - /// User register a new subnetwork via burning token - #[pallet::call_index(7)] - #[pallet::weight((Weight::from_parts(177_000_000, 0) - .saturating_add(T::DbWeight::get().reads(26)) - .saturating_add(T::DbWeight::get().writes(24)), DispatchClass::Normal, Pays::No))] - pub fn burned_register( - origin: OriginFor, - netuid: u16, - hotkey: T::AccountId, - ) -> DispatchResult { - Self::do_burned_registration(origin, netuid, hotkey) - } - - /// The extrinsic for user to change its hotkey - ///#[pallet::call_index(70)] - ///#[pallet::weight((Weight::from_parts(1_940_000_000, 0) - ///.saturating_add(T::DbWeight::get().reads(272)) - ///.saturating_add(T::DbWeight::get().writes(527)), DispatchClass::Operational, Pays::No))] - ///pub fn swap_hotkey( - /// origin: OriginFor, - /// hotkey: T::AccountId, - /// new_hotkey: T::AccountId, - ///) -> DispatchResultWithPostInfo { - /// Self::do_swap_hotkey(origin, &hotkey, &new_hotkey) - ///} - - /// The extrinsic for user to change the coldkey associated with their account. - /// - /// # Arguments - /// - /// * `origin` - The origin of the call, must be signed by the old coldkey. - /// * `old_coldkey` - The current coldkey associated with the account. - /// * `new_coldkey` - The new coldkey to be associated with the account. - /// - /// # Returns - /// - /// Returns a `DispatchResultWithPostInfo` indicating success or failure of the operation. - /// - /// # Weight - /// - /// Weight is calculated based on the number of database reads and writes. - #[pallet::call_index(71)] - #[pallet::weight((Weight::from_parts(1_940_000_000, 0) - .saturating_add(T::DbWeight::get().reads(272)) - .saturating_add(T::DbWeight::get().writes(527)), DispatchClass::Operational, Pays::No))] - pub fn swap_coldkey( - origin: OriginFor, - new_coldkey: T::AccountId, - ) -> DispatchResultWithPostInfo { - Self::do_swap_coldkey(origin, &new_coldkey) - } - /// Unstakes all tokens associated with a hotkey and transfers them to a new coldkey. - /// - /// # Arguments - /// - /// * `origin` - The origin of the call, must be signed by the current coldkey. - /// * `hotkey` - The hotkey associated with the stakes to be unstaked. - /// * `new_coldkey` - The new coldkey to receive the unstaked tokens. - /// - /// # Returns - /// - /// Returns a `DispatchResult` indicating success or failure of the operation. - /// - /// # Weight - /// - /// Weight is calculated based on the number of database reads and writes. - #[cfg(test)] - #[pallet::call_index(72)] - #[pallet::weight((Weight::from_parts(21_000_000, 0) - .saturating_add(T::DbWeight::get().reads(3)) - .saturating_add(T::DbWeight::get().writes(3)), DispatchClass::Operational, Pays::No))] - pub fn schedule_coldkey_swap( - origin: OriginFor, - new_coldkey: T::AccountId, - work: Vec, - block_number: u64, - nonce: u64, - ) -> DispatchResult { - // Attain the calling coldkey from the origin. - let old_coldkey: T::AccountId = ensure_signed(origin)?; - Self::do_schedule_coldkey_swap(&old_coldkey, &new_coldkey, work, block_number, nonce) - } - - // ---- SUDO ONLY FUNCTIONS ------------------------------------------------------------ - - // ================================== - // ==== Parameter Sudo calls ======== - // ================================== - // Each function sets the corresponding hyper paramter on the specified network - // Args: - // * 'origin': (Origin): - // - The caller, must be sudo. - // - // * `netuid` (u16): - // - The network identifier. - // - // * `hyperparameter value` (u16): - // - The value of the hyper parameter. - // - - /// Authenticates a council proposal and dispatches a function call with `Root` origin. - /// - /// The dispatch origin for this call must be a council majority. - /// - /// ## Complexity - /// - O(1). - #[pallet::call_index(51)] - #[pallet::weight((Weight::from_parts(0, 0), DispatchClass::Operational, Pays::No))] - pub fn sudo( - origin: OriginFor, - call: Box, - ) -> DispatchResultWithPostInfo { - // This is a public call, so we ensure that the origin is a council majority. - T::CouncilOrigin::ensure_origin(origin)?; - - let result = call.dispatch_bypass_filter(frame_system::RawOrigin::Root.into()); - let error = result.map(|_| ()).map_err(|e| e.error); - Self::deposit_event(Event::Sudid(error)); - - return result; - } - - /// Authenticates a council proposal and dispatches a function call with `Root` origin. - /// This function does not check the weight of the call, and instead allows the - /// user to specify the weight of the call. - /// - /// The dispatch origin for this call must be a council majority. - /// - /// ## Complexity - /// - O(1). - #[allow(deprecated)] - #[pallet::call_index(52)] - #[pallet::weight((*weight, call.get_dispatch_info().class, Pays::No))] - pub fn sudo_unchecked_weight( - origin: OriginFor, - call: Box, - weight: Weight, - ) -> DispatchResultWithPostInfo { - // We dont need to check the weight witness, suppress warning. - // See https://github.com/paritytech/polkadot-sdk/pull/1818. - let _ = weight; - - // This is a public call, so we ensure that the origin is a council majority. - T::CouncilOrigin::ensure_origin(origin)?; - - let result = call.dispatch_bypass_filter(frame_system::RawOrigin::Root.into()); - let error = result.map(|_| ()).map_err(|e| e.error); - Self::deposit_event(Event::Sudid(error)); - - return result; - } - - /// User vote on a proposal - #[pallet::call_index(55)] - #[pallet::weight((Weight::from_parts(0, 0) - .saturating_add(Weight::from_parts(0, 0)) - .saturating_add(T::DbWeight::get().reads(0)) - .saturating_add(T::DbWeight::get().writes(0)), DispatchClass::Operational))] - pub fn vote( - origin: OriginFor, - hotkey: T::AccountId, - proposal: T::Hash, - #[pallet::compact] index: u32, - approve: bool, - ) -> DispatchResultWithPostInfo { - Self::do_vote_root(origin, &hotkey, proposal, index, approve) - } - - /// User register a new subnetwork - #[pallet::call_index(59)] - #[pallet::weight((Weight::from_parts(157_000_000, 0) - .saturating_add(T::DbWeight::get().reads(16)) - .saturating_add(T::DbWeight::get().writes(30)), DispatchClass::Operational, Pays::No))] - pub fn register_network(origin: OriginFor) -> DispatchResult { - Self::user_add_network(origin) - } - - /// Facility extrinsic for user to get taken from faucet - /// It is only available when pow-faucet feature enabled - /// Just deployed in testnet and devnet for testing purpose - #[pallet::call_index(60)] - #[pallet::weight((Weight::from_parts(91_000_000, 0) - .saturating_add(T::DbWeight::get().reads(27)) - .saturating_add(T::DbWeight::get().writes(22)), DispatchClass::Normal, Pays::No))] - pub fn faucet( - origin: OriginFor, - block_number: u64, - nonce: u64, - work: Vec, - ) -> DispatchResult { - if cfg!(feature = "pow-faucet") { - return Self::do_faucet(origin, block_number, nonce, work); - } - - Err(Error::::FaucetDisabled.into()) - } - - /// Remove a user's subnetwork - /// The caller must be the owner of the network - #[pallet::call_index(61)] - #[pallet::weight((Weight::from_parts(119_000_000, 0) - .saturating_add(T::DbWeight::get().reads(6)) - .saturating_add(T::DbWeight::get().writes(31)), DispatchClass::Operational, Pays::No))] - pub fn dissolve_network(origin: OriginFor, netuid: u16) -> DispatchResult { - Self::user_remove_network(origin, netuid) - } - - /// Sets values for liquid alpha - #[pallet::call_index(64)] - #[pallet::weight((0, DispatchClass::Operational, Pays::No))] - pub fn sudo_hotfix_swap_coldkey_delegates( - _origin: OriginFor, - _old_coldkey: T::AccountId, - _new_coldkey: T::AccountId, - ) -> DispatchResult { - Ok(()) - } - } - // ---- Subtensor helper functions. impl Pallet { /// Returns the transaction priority for setting weights. diff --git a/pallets/subtensor/src/macros/config.rs b/pallets/subtensor/src/macros/config.rs new file mode 100644 index 000000000..e54cd222f --- /dev/null +++ b/pallets/subtensor/src/macros/config.rs @@ -0,0 +1,175 @@ +use frame_support::pallet_macros::pallet_section; + +/// A [`pallet_section`] that defines the errors for a pallet. +/// This can later be imported into the pallet using [`import_section`]. +#[pallet_section] +mod config { + + /// Configure the pallet by specifying the parameters and types on which it depends. + #[pallet::config] + pub trait Config: frame_system::Config { + /// Because this pallet emits events, it depends on the runtime's definition of an event. + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + + /// A sudo-able call. + type SudoRuntimeCall: Parameter + + UnfilteredDispatchable + + GetDispatchInfo; + + /// Origin checking for council majority + type CouncilOrigin: EnsureOrigin; + + /// Currency type that will be used to place deposits on neurons + type Currency: fungible::Balanced + + fungible::Mutate; + + /// Senate members with members management functions. + type SenateMembers: crate::MemberManagement; + + /// Interface to allow other pallets to control who can register identities + type TriumvirateInterface: crate::CollectiveInterface; + + /// ================================= + /// ==== Initial Value Constants ==== + /// ================================= + + /// Initial currency issuance. + #[pallet::constant] + type InitialIssuance: Get; + /// Initial min allowed weights setting. + #[pallet::constant] + type InitialMinAllowedWeights: Get; + /// Initial Emission Ratio. + #[pallet::constant] + type InitialEmissionValue: Get; + /// Initial max weight limit. + #[pallet::constant] + type InitialMaxWeightsLimit: Get; + /// Tempo for each network. + #[pallet::constant] + type InitialTempo: Get; + /// Initial Difficulty. + #[pallet::constant] + type InitialDifficulty: Get; + /// Initial Max Difficulty. + #[pallet::constant] + type InitialMaxDifficulty: Get; + /// Initial Min Difficulty. + #[pallet::constant] + type InitialMinDifficulty: Get; + /// Initial RAO Recycled. + #[pallet::constant] + type InitialRAORecycledForRegistration: Get; + /// Initial Burn. + #[pallet::constant] + type InitialBurn: Get; + /// Initial Max Burn. + #[pallet::constant] + type InitialMaxBurn: Get; + /// Initial Min Burn. + #[pallet::constant] + type InitialMinBurn: Get; + /// Initial adjustment interval. + #[pallet::constant] + type InitialAdjustmentInterval: Get; + /// Initial bonds moving average. + #[pallet::constant] + type InitialBondsMovingAverage: Get; + /// Initial target registrations per interval. + #[pallet::constant] + type InitialTargetRegistrationsPerInterval: Get; + /// Rho constant. + #[pallet::constant] + type InitialRho: Get; + /// Kappa constant. + #[pallet::constant] + type InitialKappa: Get; + /// Max UID constant. + #[pallet::constant] + type InitialMaxAllowedUids: Get; + /// Initial validator context pruning length. + #[pallet::constant] + type InitialValidatorPruneLen: Get; + /// Initial scaling law power. + #[pallet::constant] + type InitialScalingLawPower: Get; + /// Immunity Period Constant. + #[pallet::constant] + type InitialImmunityPeriod: Get; + /// Activity constant. + #[pallet::constant] + type InitialActivityCutoff: Get; + /// Initial max registrations per block. + #[pallet::constant] + type InitialMaxRegistrationsPerBlock: Get; + /// Initial pruning score for each neuron. + #[pallet::constant] + type InitialPruningScore: Get; + /// Initial maximum allowed validators per network. + #[pallet::constant] + type InitialMaxAllowedValidators: Get; + /// Initial default delegation take. + #[pallet::constant] + type InitialDefaultTake: Get; + /// Initial minimum delegation take. + #[pallet::constant] + type InitialMinTake: Get; + /// Initial weights version key. + #[pallet::constant] + type InitialWeightsVersionKey: Get; + /// Initial serving rate limit. + #[pallet::constant] + type InitialServingRateLimit: Get; + /// Initial transaction rate limit. + #[pallet::constant] + type InitialTxRateLimit: Get; + /// Initial delegate take transaction rate limit. + #[pallet::constant] + type InitialTxDelegateTakeRateLimit: Get; + /// Initial percentage of total stake required to join senate. + #[pallet::constant] + type InitialSenateRequiredStakePercentage: Get; + /// Initial adjustment alpha on burn and pow. + #[pallet::constant] + type InitialAdjustmentAlpha: Get; + /// Initial network immunity period + #[pallet::constant] + type InitialNetworkImmunityPeriod: Get; + /// Initial minimum allowed network UIDs + #[pallet::constant] + type InitialNetworkMinAllowedUids: Get; + /// Initial network minimum burn cost + #[pallet::constant] + type InitialNetworkMinLockCost: Get; + /// Initial network subnet cut. + #[pallet::constant] + type InitialSubnetOwnerCut: Get; + /// Initial lock reduction interval. + #[pallet::constant] + type InitialNetworkLockReductionInterval: Get; + /// Initial max allowed subnets + #[pallet::constant] + type InitialSubnetLimit: Get; + /// Initial network creation rate limit + #[pallet::constant] + type InitialNetworkRateLimit: Get; + /// Initial target stakes per interval issuance. + #[pallet::constant] + type InitialTargetStakesPerInterval: Get; + /// Cost of swapping a hotkey. + #[pallet::constant] + type KeySwapCost: Get; + /// The upper bound for the alpha parameter. Used for Liquid Alpha. + #[pallet::constant] + type AlphaHigh: Get; + /// The lower bound for the alpha parameter. Used for Liquid Alpha. + #[pallet::constant] + type AlphaLow: Get; + /// A flag to indicate if Liquid Alpha is enabled. + #[pallet::constant] + type LiquidAlphaOn: Get; + /// The base difficulty for proof of work for coldkey swaps + #[pallet::constant] + type InitialBaseDifficulty: Get; + } +} \ No newline at end of file diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs new file mode 100644 index 000000000..62b02f6a4 --- /dev/null +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -0,0 +1,847 @@ +use frame_support::pallet_macros::pallet_section; + +/// A [`pallet_section`] that defines the errors for a pallet. +/// This can later be imported into the pallet using [`import_section`]. +#[pallet_section] +mod dispatches { + /// Dispatchable functions allow users to interact with the pallet and invoke state changes. + /// These functions materialize as "extrinsics", which are often compared to transactions. + /// Dispatchable functions must be annotated with a weight and must return a DispatchResult. + #[pallet::call] + impl Pallet { + /// --- Sets the caller weights for the incentive mechanism. The call can be + /// made from the hotkey account so is potentially insecure, however, the damage + /// of changing weights is minimal if caught early. This function includes all the + /// checks that the passed weights meet the requirements. Stored as u16s they represent + /// rational values in the range [0,1] which sum to 1 and can be interpreted as + /// probabilities. The specific weights determine how inflation propagates outward + /// from this peer. + /// + /// Note: The 16 bit integers weights should represent 1.0 as the max u16. + /// However, the function normalizes all integers to u16_max anyway. This means that if the sum of all + /// elements is larger or smaller than the amount of elements * u16_max, all elements + /// will be corrected for this deviation. + /// + /// # Args: + /// * `origin`: (Origin): + /// - The caller, a hotkey who wishes to set their weights. + /// + /// * `netuid` (u16): + /// - The network uid we are setting these weights on. + /// + /// * `dests` (Vec): + /// - The edge endpoint for the weight, i.e. j for w_ij. + /// + /// * 'weights' (Vec): + /// - The u16 integer encoded weights. Interpreted as rational + /// values in the range [0,1]. They must sum to in32::MAX. + /// + /// * 'version_key' ( u64 ): + /// - The network version key to check if the validator is up to date. + /// + /// # Event: + /// * WeightsSet; + /// - On successfully setting the weights on chain. + /// + /// # Raises: + /// * 'SubNetworkDoesNotExist': + /// - Attempting to set weights on a non-existent network. + /// + /// * 'NotRegistered': + /// - Attempting to set weights from a non registered account. + /// + /// * 'WeightVecNotEqualSize': + /// - Attempting to set weights with uids not of same length. + /// + /// * 'DuplicateUids': + /// - Attempting to set weights with duplicate uids. + /// + /// * 'UidsLengthExceedUidsInSubNet': + /// - Attempting to set weights above the max allowed uids. + /// + /// * 'UidVecContainInvalidOne': + /// - Attempting to set weights with invalid uids. + /// + /// * 'WeightVecLengthIsLow': + /// - Attempting to set weights with fewer weights than min. + /// + /// * 'MaxWeightExceeded': + /// - Attempting to set weights with max value exceeding limit. + #[pallet::call_index(0)] + #[pallet::weight((Weight::from_parts(22_060_000_000, 0) + .saturating_add(T::DbWeight::get().reads(4106)) + .saturating_add(T::DbWeight::get().writes(2)), DispatchClass::Normal, Pays::No))] + pub fn set_weights( + origin: OriginFor, + netuid: u16, + dests: Vec, + weights: Vec, + version_key: u64, + ) -> DispatchResult { + if !Self::get_commit_reveal_weights_enabled(netuid) { + return Self::do_set_weights(origin, netuid, dests, weights, version_key); + } + + Err(Error::::CommitRevealEnabled.into()) + } + + /// ---- Used to commit a hash of your weight values to later be revealed. + /// + /// # Args: + /// * `origin`: (`::RuntimeOrigin`): + /// - The signature of the committing hotkey. + /// + /// * `netuid` (`u16`): + /// - The u16 network identifier. + /// + /// * `commit_hash` (`H256`): + /// - The hash representing the committed weights. + /// + /// # Raises: + /// * `WeightsCommitNotAllowed`: + /// - Attempting to commit when it is not allowed. + /// + #[pallet::call_index(96)] + #[pallet::weight((Weight::from_parts(46_000_000, 0) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)), DispatchClass::Normal, Pays::No))] + pub fn commit_weights( + origin: T::RuntimeOrigin, + netuid: u16, + commit_hash: H256, + ) -> DispatchResult { + Self::do_commit_weights(origin, netuid, commit_hash) + } + + /// ---- Used to reveal the weights for a previously committed hash. + /// + /// # Args: + /// * `origin`: (`::RuntimeOrigin`): + /// - The signature of the revealing hotkey. + /// + /// * `netuid` (`u16`): + /// - The u16 network identifier. + /// + /// * `uids` (`Vec`): + /// - The uids for the weights being revealed. + /// + /// * `values` (`Vec`): + /// - The values of the weights being revealed. + /// + /// * `salt` (`Vec`): + /// - The random salt to protect from brute-force guessing attack in case of small weight changes bit-wise. + /// + /// * `version_key` (`u64`): + /// - The network version key. + /// + /// # Raises: + /// * `NoWeightsCommitFound`: + /// - Attempting to reveal weights without an existing commit. + /// + /// * `InvalidRevealCommitHashNotMatchTempo`: + /// - Attempting to reveal weights outside the valid tempo. + /// + /// * `InvalidRevealCommitHashNotMatch`: + /// - The revealed hash does not match the committed hash. + /// + #[pallet::call_index(97)] + #[pallet::weight((Weight::from_parts(103_000_000, 0) + .saturating_add(T::DbWeight::get().reads(11)) + .saturating_add(T::DbWeight::get().writes(3)), DispatchClass::Normal, Pays::No))] + pub fn reveal_weights( + origin: T::RuntimeOrigin, + netuid: u16, + uids: Vec, + values: Vec, + salt: Vec, + version_key: u64, + ) -> DispatchResult { + Self::do_reveal_weights(origin, netuid, uids, values, salt, version_key) + } + + /// # Args: + /// * `origin`: (Origin): + /// - The caller, a hotkey who wishes to set their weights. + /// + /// * `netuid` (u16): + /// - The network uid we are setting these weights on. + /// + /// * `hotkey` (T::AccountId): + /// - The hotkey associated with the operation and the calling coldkey. + /// + /// * `dests` (Vec): + /// - The edge endpoint for the weight, i.e. j for w_ij. + /// + /// * 'weights' (Vec): + /// - The u16 integer encoded weights. Interpreted as rational + /// values in the range [0,1]. They must sum to in32::MAX. + /// + /// * 'version_key' ( u64 ): + /// - The network version key to check if the validator is up to date. + /// + /// # Event: + /// + /// * WeightsSet; + /// - On successfully setting the weights on chain. + /// + /// # Raises: + /// + /// * NonAssociatedColdKey; + /// - Attempting to set weights on a non-associated cold key. + /// + /// * 'SubNetworkDoesNotExist': + /// - Attempting to set weights on a non-existent network. + /// + /// * 'NotRootSubnet': + /// - Attempting to set weights on a subnet that is not the root network. + /// + /// * 'WeightVecNotEqualSize': + /// - Attempting to set weights with uids not of same length. + /// + /// * 'UidVecContainInvalidOne': + /// - Attempting to set weights with invalid uids. + /// + /// * 'NotRegistered': + /// - Attempting to set weights from a non registered account. + /// + /// * 'WeightVecLengthIsLow': + /// - Attempting to set weights with fewer weights than min. + /// + /// * 'IncorrectWeightVersionKey': + /// - Attempting to set weights with the incorrect network version key. + /// + /// * 'SettingWeightsTooFast': + /// - Attempting to set weights too fast. + /// + /// * 'WeightVecLengthIsLow': + /// - Attempting to set weights with fewer weights than min. + /// + /// * 'MaxWeightExceeded': + /// - Attempting to set weights with max value exceeding limit. + /// + #[pallet::call_index(8)] + #[pallet::weight((Weight::from_parts(10_151_000_000, 0) + .saturating_add(T::DbWeight::get().reads(4104)) + .saturating_add(T::DbWeight::get().writes(2)), DispatchClass::Normal, Pays::No))] + pub fn set_root_weights( + origin: OriginFor, + netuid: u16, + hotkey: T::AccountId, + dests: Vec, + weights: Vec, + version_key: u64, + ) -> DispatchResult { + Self::do_set_root_weights(origin, netuid, hotkey, dests, weights, version_key) + } + + /// --- Sets the key as a delegate. + /// + /// # Args: + /// * 'origin': (Origin): + /// - The signature of the caller's coldkey. + /// + /// * 'hotkey' (T::AccountId): + /// - The hotkey we are delegating (must be owned by the coldkey.) + /// + /// * 'take' (u64): + /// - The stake proportion that this hotkey takes from delegations. + /// + /// # Event: + /// * DelegateAdded; + /// - On successfully setting a hotkey as a delegate. + /// + /// # Raises: + /// * 'NotRegistered': + /// - The hotkey we are delegating is not registered on the network. + /// + /// * 'NonAssociatedColdKey': + /// - The hotkey we are delegating is not owned by the calling coldket. + /// + #[pallet::call_index(1)] + #[pallet::weight((Weight::from_parts(79_000_000, 0) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(3)), DispatchClass::Normal, Pays::No))] + pub fn become_delegate(origin: OriginFor, hotkey: T::AccountId) -> DispatchResult { + Self::do_become_delegate(origin, hotkey, Self::get_default_take()) + } + + /// --- Allows delegates to decrease its take value. + /// + /// # Args: + /// * 'origin': (::Origin): + /// - The signature of the caller's coldkey. + /// + /// * 'hotkey' (T::AccountId): + /// - The hotkey we are delegating (must be owned by the coldkey.) + /// + /// * 'netuid' (u16): + /// - Subnet ID to decrease take for + /// + /// * 'take' (u16): + /// - The new stake proportion that this hotkey takes from delegations. + /// The new value can be between 0 and 11_796 and should be strictly + /// lower than the previous value. It T is the new value (rational number), + /// the the parameter is calculated as [65535 * T]. For example, 1% would be + /// [0.01 * 65535] = [655.35] = 655 + /// + /// # Event: + /// * TakeDecreased; + /// - On successfully setting a decreased take for this hotkey. + /// + /// # Raises: + /// * 'NotRegistered': + /// - The hotkey we are delegating is not registered on the network. + /// + /// * 'NonAssociatedColdKey': + /// - The hotkey we are delegating is not owned by the calling coldkey. + /// + /// * 'DelegateTakeTooLow': + /// - The delegate is setting a take which is not lower than the previous. + /// + #[pallet::call_index(65)] + #[pallet::weight((0, DispatchClass::Normal, Pays::No))] + pub fn decrease_take( + origin: OriginFor, + hotkey: T::AccountId, + take: u16, + ) -> DispatchResult { + Self::do_decrease_take(origin, hotkey, take) + } + + /// --- Allows delegates to increase its take value. This call is rate-limited. + /// + /// # Args: + /// * 'origin': (::Origin): + /// - The signature of the caller's coldkey. + /// + /// * 'hotkey' (T::AccountId): + /// - The hotkey we are delegating (must be owned by the coldkey.) + /// + /// * 'take' (u16): + /// - The new stake proportion that this hotkey takes from delegations. + /// The new value can be between 0 and 11_796 and should be strictly + /// greater than the previous value. T is the new value (rational number), + /// the the parameter is calculated as [65535 * T]. For example, 1% would be + /// [0.01 * 65535] = [655.35] = 655 + /// + /// # Event: + /// * TakeIncreased; + /// - On successfully setting a increased take for this hotkey. + /// + /// # Raises: + /// * 'NotRegistered': + /// - The hotkey we are delegating is not registered on the network. + /// + /// * 'NonAssociatedColdKey': + /// - The hotkey we are delegating is not owned by the calling coldkey. + /// + /// * 'DelegateTakeTooHigh': + /// - The delegate is setting a take which is not greater than the previous. + /// + #[pallet::call_index(66)] + #[pallet::weight((0, DispatchClass::Normal, Pays::No))] + pub fn increase_take( + origin: OriginFor, + hotkey: T::AccountId, + take: u16, + ) -> DispatchResult { + Self::do_increase_take(origin, hotkey, take) + } + + /// --- Adds stake to a hotkey. The call is made from the + /// coldkey account linked in the hotkey. + /// Only the associated coldkey is allowed to make staking and + /// unstaking requests. This protects the neuron against + /// attacks on its hotkey running in production code. + /// + /// # Args: + /// * 'origin': (Origin): + /// - The signature of the caller's coldkey. + /// + /// * 'hotkey' (T::AccountId): + /// - The associated hotkey account. + /// + /// * 'amount_staked' (u64): + /// - The amount of stake to be added to the hotkey staking account. + /// + /// # Event: + /// * StakeAdded; + /// - On the successfully adding stake to a global account. + /// + /// # Raises: + /// * 'NotEnoughBalanceToStake': + /// - Not enough balance on the coldkey to add onto the global account. + /// + /// * 'NonAssociatedColdKey': + /// - The calling coldkey is not associated with this hotkey. + /// + /// * 'BalanceWithdrawalError': + /// - Errors stemming from transaction pallet. + /// + #[pallet::call_index(2)] + #[pallet::weight((Weight::from_parts(124_000_000, 0) + .saturating_add(T::DbWeight::get().reads(10)) + .saturating_add(T::DbWeight::get().writes(7)), DispatchClass::Normal, Pays::No))] + pub fn add_stake( + origin: OriginFor, + hotkey: T::AccountId, + amount_staked: u64, + ) -> DispatchResult { + Self::do_add_stake(origin, hotkey, amount_staked) + } + + /// Remove stake from the staking account. The call must be made + /// from the coldkey account attached to the neuron metadata. Only this key + /// has permission to make staking and unstaking requests. + /// + /// # Args: + /// * 'origin': (Origin): + /// - The signature of the caller's coldkey. + /// + /// * 'hotkey' (T::AccountId): + /// - The associated hotkey account. + /// + /// * 'amount_unstaked' (u64): + /// - The amount of stake to be added to the hotkey staking account. + /// + /// # Event: + /// * StakeRemoved; + /// - On the successfully removing stake from the hotkey account. + /// + /// # Raises: + /// * 'NotRegistered': + /// - Thrown if the account we are attempting to unstake from is non existent. + /// + /// * 'NonAssociatedColdKey': + /// - Thrown if the coldkey does not own the hotkey we are unstaking from. + /// + /// * 'NotEnoughStakeToWithdraw': + /// - Thrown if there is not enough stake on the hotkey to withdwraw this amount. + /// + #[pallet::call_index(3)] + #[pallet::weight((Weight::from_parts(111_000_000, 0) + .saturating_add(Weight::from_parts(0, 43991)) + .saturating_add(T::DbWeight::get().reads(10)) + .saturating_add(T::DbWeight::get().writes(7)), DispatchClass::Normal, Pays::No))] + pub fn remove_stake( + origin: OriginFor, + hotkey: T::AccountId, + amount_unstaked: u64, + ) -> DispatchResult { + Self::do_remove_stake(origin, hotkey, amount_unstaked) + } + + /// Serves or updates axon /promethteus information for the neuron associated with the caller. If the caller is + /// already registered the metadata is updated. If the caller is not registered this call throws NotRegistered. + /// + /// # Args: + /// * 'origin': (Origin): + /// - The signature of the caller. + /// + /// * 'netuid' (u16): + /// - The u16 network identifier. + /// + /// * 'version' (u64): + /// - The bittensor version identifier. + /// + /// * 'ip' (u64): + /// - The endpoint ip information as a u128 encoded integer. + /// + /// * 'port' (u16): + /// - The endpoint port information as a u16 encoded integer. + /// + /// * 'ip_type' (u8): + /// - The endpoint ip version as a u8, 4 or 6. + /// + /// * 'protocol' (u8): + /// - UDP:1 or TCP:0 + /// + /// * 'placeholder1' (u8): + /// - Placeholder for further extra params. + /// + /// * 'placeholder2' (u8): + /// - Placeholder for further extra params. + /// + /// # Event: + /// * AxonServed; + /// - On successfully serving the axon info. + /// + /// # Raises: + /// * 'SubNetworkDoesNotExist': + /// - Attempting to set weights on a non-existent network. + /// + /// * 'NotRegistered': + /// - Attempting to set weights from a non registered account. + /// + /// * 'InvalidIpType': + /// - The ip type is not 4 or 6. + /// + /// * 'InvalidIpAddress': + /// - The numerically encoded ip address does not resolve to a proper ip. + /// + /// * 'ServingRateLimitExceeded': + /// - Attempting to set prometheus information withing the rate limit min. + /// + #[pallet::call_index(4)] + #[pallet::weight((Weight::from_parts(46_000_000, 0) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(1)), DispatchClass::Normal, Pays::No))] + pub fn serve_axon( + origin: OriginFor, + netuid: u16, + version: u32, + ip: u128, + port: u16, + ip_type: u8, + protocol: u8, + placeholder1: u8, + placeholder2: u8, + ) -> DispatchResult { + Self::do_serve_axon( + origin, + netuid, + version, + ip, + port, + ip_type, + protocol, + placeholder1, + placeholder2, + ) + } + + /// ---- Set prometheus information for the neuron. + /// # Args: + /// * 'origin': (Origin): + /// - The signature of the calling hotkey. + /// + /// * 'netuid' (u16): + /// - The u16 network identifier. + /// + /// * 'version' (u16): + /// - The bittensor version identifier. + /// + /// * 'ip' (u128): + /// - The prometheus ip information as a u128 encoded integer. + /// + /// * 'port' (u16): + /// - The prometheus port information as a u16 encoded integer. + /// + /// * 'ip_type' (u8): + /// - The ip type v4 or v6. + /// + #[pallet::call_index(5)] + #[pallet::weight((Weight::from_parts(45_000_000, 0) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(1)), DispatchClass::Normal, Pays::No))] + pub fn serve_prometheus( + origin: OriginFor, + netuid: u16, + version: u32, + ip: u128, + port: u16, + ip_type: u8, + ) -> DispatchResult { + Self::do_serve_prometheus(origin, netuid, version, ip, port, ip_type) + } + + /// ---- Registers a new neuron to the subnetwork. + /// + /// # Args: + /// * 'origin': (Origin): + /// - The signature of the calling hotkey. + /// + /// * 'netuid' (u16): + /// - The u16 network identifier. + /// + /// * 'block_number' ( u64 ): + /// - Block hash used to prove work done. + /// + /// * 'nonce' ( u64 ): + /// - Positive integer nonce used in POW. + /// + /// * 'work' ( Vec ): + /// - Vector encoded bytes representing work done. + /// + /// * 'hotkey' ( T::AccountId ): + /// - Hotkey to be registered to the network. + /// + /// * 'coldkey' ( T::AccountId ): + /// - Associated coldkey account. + /// + /// # Event: + /// * NeuronRegistered; + /// - On successfully registering a uid to a neuron slot on a subnetwork. + /// + /// # Raises: + /// * 'SubNetworkDoesNotExist': + /// - Attempting to register to a non existent network. + /// + /// * 'TooManyRegistrationsThisBlock': + /// - This registration exceeds the total allowed on this network this block. + /// + /// * 'HotKeyAlreadyRegisteredInSubNet': + /// - The hotkey is already registered on this network. + /// + /// * 'InvalidWorkBlock': + /// - The work has been performed on a stale, future, or non existent block. + /// + /// * 'InvalidDifficulty': + /// - The work does not match the difficulty. + /// + /// * 'InvalidSeal': + /// - The seal is incorrect. + /// + #[pallet::call_index(6)] + #[pallet::weight((Weight::from_parts(192_000_000, 0) + .saturating_add(T::DbWeight::get().reads(24)) + .saturating_add(T::DbWeight::get().writes(22)), DispatchClass::Normal, Pays::No))] + pub fn register( + origin: OriginFor, + netuid: u16, + block_number: u64, + nonce: u64, + work: Vec, + hotkey: T::AccountId, + coldkey: T::AccountId, + ) -> DispatchResult { + Self::do_registration(origin, netuid, block_number, nonce, work, hotkey, coldkey) + } + + /// Register the hotkey to root network + #[pallet::call_index(62)] + #[pallet::weight((Weight::from_parts(164_000_000, 0) + .saturating_add(T::DbWeight::get().reads(23)) + .saturating_add(T::DbWeight::get().writes(20)), DispatchClass::Normal, Pays::No))] + pub fn root_register(origin: OriginFor, hotkey: T::AccountId) -> DispatchResult { + Self::do_root_register(origin, hotkey) + } + + /// Attempt to adjust the senate membership to include a hotkey + #[pallet::call_index(63)] + #[pallet::weight((Weight::from_parts(0, 0) + .saturating_add(T::DbWeight::get().reads(0)) + .saturating_add(T::DbWeight::get().writes(0)), DispatchClass::Normal, Pays::Yes))] + pub fn adjust_senate(origin: OriginFor, hotkey: T::AccountId) -> DispatchResult { + Self::do_adjust_senate(origin, hotkey) + } + + /// User register a new subnetwork via burning token + #[pallet::call_index(7)] + #[pallet::weight((Weight::from_parts(177_000_000, 0) + .saturating_add(T::DbWeight::get().reads(26)) + .saturating_add(T::DbWeight::get().writes(24)), DispatchClass::Normal, Pays::No))] + pub fn burned_register( + origin: OriginFor, + netuid: u16, + hotkey: T::AccountId, + ) -> DispatchResult { + Self::do_burned_registration(origin, netuid, hotkey) + } + + /// The extrinsic for user to change its hotkey + ///#[pallet::call_index(70)] + ///#[pallet::weight((Weight::from_parts(1_940_000_000, 0) + ///.saturating_add(T::DbWeight::get().reads(272)) + ///.saturating_add(T::DbWeight::get().writes(527)), DispatchClass::Operational, Pays::No))] + ///pub fn swap_hotkey( + /// origin: OriginFor, + /// hotkey: T::AccountId, + /// new_hotkey: T::AccountId, + ///) -> DispatchResultWithPostInfo { + /// Self::do_swap_hotkey(origin, &hotkey, &new_hotkey) + ///} + + /// The extrinsic for user to change the coldkey associated with their account. + /// + /// # Arguments + /// + /// * `origin` - The origin of the call, must be signed by the old coldkey. + /// * `old_coldkey` - The current coldkey associated with the account. + /// * `new_coldkey` - The new coldkey to be associated with the account. + /// + /// # Returns + /// + /// Returns a `DispatchResultWithPostInfo` indicating success or failure of the operation. + /// + /// # Weight + /// + /// Weight is calculated based on the number of database reads and writes. + #[pallet::call_index(71)] + #[pallet::weight((Weight::from_parts(1_940_000_000, 0) + .saturating_add(T::DbWeight::get().reads(272)) + .saturating_add(T::DbWeight::get().writes(527)), DispatchClass::Operational, Pays::No))] + pub fn swap_coldkey( + origin: OriginFor, + new_coldkey: T::AccountId, + ) -> DispatchResultWithPostInfo { + Self::do_swap_coldkey(origin, &new_coldkey) + } + /// Unstakes all tokens associated with a hotkey and transfers them to a new coldkey. + /// + /// # Arguments + /// + /// * `origin` - The origin of the call, must be signed by the current coldkey. + /// * `hotkey` - The hotkey associated with the stakes to be unstaked. + /// * `new_coldkey` - The new coldkey to receive the unstaked tokens. + /// + /// # Returns + /// + /// Returns a `DispatchResult` indicating success or failure of the operation. + /// + /// # Weight + /// + /// Weight is calculated based on the number of database reads and writes. + #[cfg(test)] + #[pallet::call_index(72)] + #[pallet::weight((Weight::from_parts(21_000_000, 0) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)), DispatchClass::Operational, Pays::No))] + pub fn schedule_coldkey_swap( + origin: OriginFor, + new_coldkey: T::AccountId, + work: Vec, + block_number: u64, + nonce: u64, + ) -> DispatchResult { + // Attain the calling coldkey from the origin. + let old_coldkey: T::AccountId = ensure_signed(origin)?; + Self::do_schedule_coldkey_swap(&old_coldkey, &new_coldkey, work, block_number, nonce) + } + + // ---- SUDO ONLY FUNCTIONS ------------------------------------------------------------ + + // ================================== + // ==== Parameter Sudo calls ======== + // ================================== + // Each function sets the corresponding hyper paramter on the specified network + // Args: + // * 'origin': (Origin): + // - The caller, must be sudo. + // + // * `netuid` (u16): + // - The network identifier. + // + // * `hyperparameter value` (u16): + // - The value of the hyper parameter. + // + + /// Authenticates a council proposal and dispatches a function call with `Root` origin. + /// + /// The dispatch origin for this call must be a council majority. + /// + /// ## Complexity + /// - O(1). + #[pallet::call_index(51)] + #[pallet::weight((Weight::from_parts(0, 0), DispatchClass::Operational, Pays::No))] + pub fn sudo( + origin: OriginFor, + call: Box, + ) -> DispatchResultWithPostInfo { + // This is a public call, so we ensure that the origin is a council majority. + T::CouncilOrigin::ensure_origin(origin)?; + + let result = call.dispatch_bypass_filter(frame_system::RawOrigin::Root.into()); + let error = result.map(|_| ()).map_err(|e| e.error); + Self::deposit_event(Event::Sudid(error)); + + return result; + } + + /// Authenticates a council proposal and dispatches a function call with `Root` origin. + /// This function does not check the weight of the call, and instead allows the + /// user to specify the weight of the call. + /// + /// The dispatch origin for this call must be a council majority. + /// + /// ## Complexity + /// - O(1). + #[allow(deprecated)] + #[pallet::call_index(52)] + #[pallet::weight((*weight, call.get_dispatch_info().class, Pays::No))] + pub fn sudo_unchecked_weight( + origin: OriginFor, + call: Box, + weight: Weight, + ) -> DispatchResultWithPostInfo { + // We dont need to check the weight witness, suppress warning. + // See https://github.com/paritytech/polkadot-sdk/pull/1818. + let _ = weight; + + // This is a public call, so we ensure that the origin is a council majority. + T::CouncilOrigin::ensure_origin(origin)?; + + let result = call.dispatch_bypass_filter(frame_system::RawOrigin::Root.into()); + let error = result.map(|_| ()).map_err(|e| e.error); + Self::deposit_event(Event::Sudid(error)); + + return result; + } + + /// User vote on a proposal + #[pallet::call_index(55)] + #[pallet::weight((Weight::from_parts(0, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().reads(0)) + .saturating_add(T::DbWeight::get().writes(0)), DispatchClass::Operational))] + pub fn vote( + origin: OriginFor, + hotkey: T::AccountId, + proposal: T::Hash, + #[pallet::compact] index: u32, + approve: bool, + ) -> DispatchResultWithPostInfo { + Self::do_vote_root(origin, &hotkey, proposal, index, approve) + } + + /// User register a new subnetwork + #[pallet::call_index(59)] + #[pallet::weight((Weight::from_parts(157_000_000, 0) + .saturating_add(T::DbWeight::get().reads(16)) + .saturating_add(T::DbWeight::get().writes(30)), DispatchClass::Operational, Pays::No))] + pub fn register_network(origin: OriginFor) -> DispatchResult { + Self::user_add_network(origin) + } + + /// Facility extrinsic for user to get taken from faucet + /// It is only available when pow-faucet feature enabled + /// Just deployed in testnet and devnet for testing purpose + #[pallet::call_index(60)] + #[pallet::weight((Weight::from_parts(91_000_000, 0) + .saturating_add(T::DbWeight::get().reads(27)) + .saturating_add(T::DbWeight::get().writes(22)), DispatchClass::Normal, Pays::No))] + pub fn faucet( + origin: OriginFor, + block_number: u64, + nonce: u64, + work: Vec, + ) -> DispatchResult { + if cfg!(feature = "pow-faucet") { + return Self::do_faucet(origin, block_number, nonce, work); + } + + Err(Error::::FaucetDisabled.into()) + } + + /// Remove a user's subnetwork + /// The caller must be the owner of the network + #[pallet::call_index(61)] + #[pallet::weight((Weight::from_parts(119_000_000, 0) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(31)), DispatchClass::Operational, Pays::No))] + pub fn dissolve_network(origin: OriginFor, netuid: u16) -> DispatchResult { + Self::user_remove_network(origin, netuid) + } + + /// Sets values for liquid alpha + #[pallet::call_index(64)] + #[pallet::weight((0, DispatchClass::Operational, Pays::No))] + pub fn sudo_hotfix_swap_coldkey_delegates( + _origin: OriginFor, + _old_coldkey: T::AccountId, + _new_coldkey: T::AccountId, + ) -> DispatchResult { + Ok(()) + } + } +} \ No newline at end of file diff --git a/pallets/subtensor/src/errors.rs b/pallets/subtensor/src/macros/errors.rs similarity index 100% rename from pallets/subtensor/src/errors.rs rename to pallets/subtensor/src/macros/errors.rs diff --git a/pallets/subtensor/src/events.rs b/pallets/subtensor/src/macros/events.rs similarity index 100% rename from pallets/subtensor/src/events.rs rename to pallets/subtensor/src/macros/events.rs diff --git a/pallets/subtensor/src/macros/genesis.rs b/pallets/subtensor/src/macros/genesis.rs new file mode 100644 index 000000000..5fbf613d6 --- /dev/null +++ b/pallets/subtensor/src/macros/genesis.rs @@ -0,0 +1,163 @@ +use frame_support::pallet_macros::pallet_section; + +/// A [`pallet_section`] that defines the errors for a pallet. +/// This can later be imported into the pallet using [`import_section`]. +#[pallet_section] +mod genesis { + + #[pallet::genesis_build] + impl BuildGenesisConfig for GenesisConfig { + fn build(&self) { + // Set initial total issuance from balances + TotalIssuance::::put(self.balances_issuance); + + // Subnet config values + let netuid: u16 = 3; + let tempo = 99; + let max_uids = 4096; + + // The functions for initializing new networks/setting defaults cannot be run directly from genesis functions like extrinsics would + // --- Set this network uid to alive. + NetworksAdded::::insert(netuid, true); + + // --- Fill tempo memory item. + Tempo::::insert(netuid, tempo); + + // --- Fill modality item. + // Only modality 0 exists (text) + NetworkModality::::insert(netuid, 0); + + // Make network parameters explicit. + if !Tempo::::contains_key(netuid) { + Tempo::::insert(netuid, Tempo::::get(netuid)); + } + if !Kappa::::contains_key(netuid) { + Kappa::::insert(netuid, Kappa::::get(netuid)); + } + if !Difficulty::::contains_key(netuid) { + Difficulty::::insert(netuid, Difficulty::::get(netuid)); + } + if !MaxAllowedUids::::contains_key(netuid) { + MaxAllowedUids::::insert(netuid, MaxAllowedUids::::get(netuid)); + } + if !ImmunityPeriod::::contains_key(netuid) { + ImmunityPeriod::::insert(netuid, ImmunityPeriod::::get(netuid)); + } + if !ActivityCutoff::::contains_key(netuid) { + ActivityCutoff::::insert(netuid, ActivityCutoff::::get(netuid)); + } + if !EmissionValues::::contains_key(netuid) { + EmissionValues::::insert(netuid, EmissionValues::::get(netuid)); + } + if !MaxWeightsLimit::::contains_key(netuid) { + MaxWeightsLimit::::insert(netuid, MaxWeightsLimit::::get(netuid)); + } + if !MinAllowedWeights::::contains_key(netuid) { + MinAllowedWeights::::insert(netuid, MinAllowedWeights::::get(netuid)); + } + if !RegistrationsThisInterval::::contains_key(netuid) { + RegistrationsThisInterval::::insert( + netuid, + RegistrationsThisInterval::::get(netuid), + ); + } + if !POWRegistrationsThisInterval::::contains_key(netuid) { + POWRegistrationsThisInterval::::insert( + netuid, + POWRegistrationsThisInterval::::get(netuid), + ); + } + if !BurnRegistrationsThisInterval::::contains_key(netuid) { + BurnRegistrationsThisInterval::::insert( + netuid, + BurnRegistrationsThisInterval::::get(netuid), + ); + } + + // Set max allowed uids + MaxAllowedUids::::insert(netuid, max_uids); + + let mut next_uid = 0; + + for (coldkey, hotkeys) in self.stakes.iter() { + for (hotkey, stake_uid) in hotkeys.iter() { + let (stake, uid) = stake_uid; + + // Expand Yuma Consensus with new position. + Rank::::mutate(netuid, |v| v.push(0)); + Trust::::mutate(netuid, |v| v.push(0)); + Active::::mutate(netuid, |v| v.push(true)); + Emission::::mutate(netuid, |v| v.push(0)); + Consensus::::mutate(netuid, |v| v.push(0)); + Incentive::::mutate(netuid, |v| v.push(0)); + Dividends::::mutate(netuid, |v| v.push(0)); + LastUpdate::::mutate(netuid, |v| v.push(0)); + PruningScores::::mutate(netuid, |v| v.push(0)); + ValidatorTrust::::mutate(netuid, |v| v.push(0)); + ValidatorPermit::::mutate(netuid, |v| v.push(false)); + + // Insert account information. + Keys::::insert(netuid, uid, hotkey.clone()); // Make hotkey - uid association. + Uids::::insert(netuid, hotkey.clone(), uid); // Make uid - hotkey association. + BlockAtRegistration::::insert(netuid, uid, 0); // Fill block at registration. + IsNetworkMember::::insert(hotkey.clone(), netuid, true); // Fill network is member. + + // Fill stake information. + Owner::::insert(hotkey.clone(), coldkey.clone()); + + TotalHotkeyStake::::insert(hotkey.clone(), stake); + TotalColdkeyStake::::insert( + coldkey.clone(), + TotalColdkeyStake::::get(coldkey).saturating_add(*stake), + ); + + // Update total issuance value + TotalIssuance::::put(TotalIssuance::::get().saturating_add(*stake)); + + Stake::::insert(hotkey.clone(), coldkey.clone(), stake); + + next_uid += 1; + } + } + + // Set correct length for Subnet neurons + SubnetworkN::::insert(netuid, next_uid); + + // --- Increase total network count. + TotalNetworks::::mutate(|n| *n += 1); + + // Get the root network uid. + let root_netuid: u16 = 0; + + // Set the root network as added. + NetworksAdded::::insert(root_netuid, true); + + // Increment the number of total networks. + TotalNetworks::::mutate(|n| *n += 1); + // Set the number of validators to 1. + SubnetworkN::::insert(root_netuid, 0); + + // Set the maximum number to the number of senate members. + MaxAllowedUids::::insert(root_netuid, 64u16); + + // Set the maximum number to the number of validators to all members. + MaxAllowedValidators::::insert(root_netuid, 64u16); + + // Set the min allowed weights to zero, no weights restrictions. + MinAllowedWeights::::insert(root_netuid, 0); + + // Set the max weight limit to infitiy, no weight restrictions. + MaxWeightsLimit::::insert(root_netuid, u16::MAX); + + // Add default root tempo. + Tempo::::insert(root_netuid, 100); + + // Set the root network as open. + NetworkRegistrationAllowed::::insert(root_netuid, true); + + // Set target registrations for validators as 1 per block. + TargetRegistrationsPerInterval::::insert(root_netuid, 1); + } + } + +} \ No newline at end of file diff --git a/pallets/subtensor/src/macros/hooks.rs b/pallets/subtensor/src/macros/hooks.rs new file mode 100644 index 000000000..baa9de21a --- /dev/null +++ b/pallets/subtensor/src/macros/hooks.rs @@ -0,0 +1,75 @@ +use frame_support::pallet_macros::pallet_section; + +/// A [`pallet_section`] that defines the events for a pallet. +/// This can later be imported into the pallet using [`import_section`]. +#[pallet_section] +mod hooks { + // ================ + // ==== Hooks ===== + // ================ + #[pallet::hooks] + impl Hooks> for Pallet { + // ---- Called on the initialization of this pallet. (the order of on_finalize calls is determined in the runtime) + // + // # Args: + // * 'n': (BlockNumberFor): + // - The number of the block we are initializing. + fn on_initialize(_block_number: BlockNumberFor) -> Weight { + let block_step_result = Self::block_step(); + match block_step_result { + Ok(_) => { + // --- If the block step was successful, return the weight. + log::info!("Successfully ran block step."); + Weight::from_parts(110_634_229_000_u64, 0) + .saturating_add(T::DbWeight::get().reads(8304_u64)) + .saturating_add(T::DbWeight::get().writes(110_u64)) + } + Err(e) => { + // --- If the block step was unsuccessful, return the weight anyway. + log::error!("Error while stepping block: {:?}", e); + Weight::from_parts(110_634_229_000_u64, 0) + .saturating_add(T::DbWeight::get().reads(8304_u64)) + .saturating_add(T::DbWeight::get().writes(110_u64)) + } + } + } + + fn on_runtime_upgrade() -> frame_support::weights::Weight { + // --- Migrate storage + let mut weight = frame_support::weights::Weight::from_parts(0, 0); + + // Hex encoded foundation coldkey + let hex = hex_literal::hex![ + "feabaafee293d3b76dae304e2f9d885f77d2b17adab9e17e921b321eccd61c77" + ]; + weight = weight + // Initializes storage version (to 1) + .saturating_add(migrations::migrate_to_v1_separate_emission::migrate_to_v1_separate_emission::()) + // Storage version v1 -> v2 + .saturating_add(migrations::migrate_to_v2_fixed_total_stake::migrate_to_v2_fixed_total_stake::()) + // Doesn't check storage version. TODO: Remove after upgrade + .saturating_add(migrations::migrate_create_root_network::migrate_create_root_network::()) + // Storage version v2 -> v3 + .saturating_add(migrations::migrate_transfer_ownership_to_foundation::migrate_transfer_ownership_to_foundation::( + hex, + )) + // Storage version v3 -> v4 + .saturating_add(migrations::migrate_delete_subnet_21::migrate_delete_subnet_21::()) + // Storage version v4 -> v5 + .saturating_add(migrations::migrate_delete_subnet_3::migrate_delete_subnet_3::()) + // Doesn't check storage version. TODO: Remove after upgrade + // Storage version v5 -> v6 + .saturating_add(migrations::migrate_total_issuance::migration5_total_issuance::(false)) + // Populate OwnedHotkeys map for coldkey swap. Doesn't update storage vesion. + // Storage version v6 -> v7 + .saturating_add(migrations::migrate_populate_owned_hotkeys::migrate_populate_owned::()) + // Populate StakingHotkeys map for coldkey swap. Doesn't update storage vesion. + // Storage version v7 -> v8 + .saturating_add(migrations::migrate_populate_staking_hotkeys::migrate_populate_staking_hotkeys::()) + // Fix total coldkey stake. + // Storage version v8 -> v9 + .saturating_add(migrations::migrate_fix_total_coldkey_stake::migrate_fix_total_coldkey_stake::()); + weight + } + } +} \ No newline at end of file diff --git a/pallets/subtensor/src/macros/mod.rs b/pallets/subtensor/src/macros/mod.rs new file mode 100644 index 000000000..d64983d52 --- /dev/null +++ b/pallets/subtensor/src/macros/mod.rs @@ -0,0 +1,6 @@ +pub mod events; +pub mod errors; +pub mod dispatches; +pub mod genesis; +pub mod hooks; +pub mod config; \ No newline at end of file diff --git a/pallets/subtensor/src/migrations/migrate_create_root_network.rs b/pallets/subtensor/src/migrations/migrate_create_root_network.rs new file mode 100644 index 000000000..ff858ec6a --- /dev/null +++ b/pallets/subtensor/src/migrations/migrate_create_root_network.rs @@ -0,0 +1,99 @@ +use super::*; +use frame_support::{ + pallet_prelude::{Identity, OptionQuery}, + storage_alias, + traits::{Get, DefensiveResult}, + weights::Weight, +}; +use sp_std::vec::Vec; + +// TODO (camfairchild): TEST MIGRATION + +/// Module containing deprecated storage format for LoadedEmission +pub mod deprecated_loaded_emission_format { + use super::*; + + #[storage_alias] + pub(super) type LoadedEmission = + StorageMap, Identity, u16, Vec<(AccountIdOf, u64)>, OptionQuery>; +} + +/// Migrates the storage to create the root network +/// +/// This function performs the following steps: +/// 1. Checks if the root network already exists +/// 2. If not, creates the root network with default settings +/// 3. Removes all existing senate members +/// +/// # Arguments +/// +/// * `T` - The Config trait of the pallet +/// +/// # Returns +/// +/// * `Weight` - The computational weight of this operation +/// +/// # Example +/// +/// ``` +/// let weight = migrate_create_root_network::(); +/// ``` +pub fn migrate_create_root_network() -> Weight { + // Define the root network UID + let root_netuid: u16 = 0; + + // Initialize weight counter + let mut weight = T::DbWeight::get().reads(1); + + // Check if root network already exists + if NetworksAdded::::get(root_netuid) { + // Return early if root network already exists + return weight; + } + + // Set the root network as added + NetworksAdded::::insert(root_netuid, true); + + // Increment the total number of networks + TotalNetworks::::mutate(|n| *n += 1); + + // Set the maximum number of UIDs to the number of senate members + MaxAllowedUids::::insert(root_netuid, 64); + + // Set the maximum number of validators to all members + MaxAllowedValidators::::insert(root_netuid, 64); + + // Set the minimum allowed weights to zero (no weight restrictions) + MinAllowedWeights::::insert(root_netuid, 0); + + // Set the maximum weight limit to u16::MAX (no weight restrictions) + MaxWeightsLimit::::insert(root_netuid, u16::MAX); + + // Set default root tempo + Tempo::::insert(root_netuid, 100); + + // Set the root network as open for registration + NetworkRegistrationAllowed::::insert(root_netuid, true); + + // Set target registrations for validators as 1 per block + TargetRegistrationsPerInterval::::insert(root_netuid, 1); + + // TODO: Consider if WeightsSetRateLimit should be set + // WeightsSetRateLimit::::insert(root_netuid, 7200); + + // Accrue weight for database writes + weight.saturating_accrue(T::DbWeight::get().writes(8)); + + // Remove all existing senate members + for hotkey_i in T::SenateMembers::members().iter() { + // Remove votes associated with the member + T::TriumvirateInterface::remove_votes(hotkey_i).defensive_ok(); + // Remove the member from the senate + T::SenateMembers::remove_member(hotkey_i).defensive_ok(); + + // Accrue weight for database operations + weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2)); + } + + weight +} \ No newline at end of file diff --git a/pallets/subtensor/src/migrations/migrate_delete_subnet_21.rs b/pallets/subtensor/src/migrations/migrate_delete_subnet_21.rs new file mode 100644 index 000000000..df6a2ae34 --- /dev/null +++ b/pallets/subtensor/src/migrations/migrate_delete_subnet_21.rs @@ -0,0 +1,127 @@ +use super::*; +use frame_support::{ + pallet_prelude::*, storage_alias, + traits::{Get, GetStorageVersion, StorageVersion}, + weights::Weight, +}; +use log::info; +use sp_std::vec::Vec; + +/// Constant for logging purposes +const LOG_TARGET: &str = "migrate_delete_subnet_21"; + +/// Module containing deprecated storage format +pub mod deprecated_loaded_emission_format { + use super::*; + + #[storage_alias] + pub(super) type LoadedEmission = + StorageMap, Identity, u16, Vec<(AccountIdOf, u64)>, OptionQuery>; +} + +/// Migrates the storage to delete subnet 21 +/// +/// This function performs the following steps: +/// 1. Checks if the migration is necessary +/// 2. Removes all storage related to subnet 21 +/// 3. Updates the storage version +/// +/// # Arguments +/// +/// * `T` - The Config trait of the pallet +/// +/// # Returns +/// +/// * `Weight` - The computational weight of this operation +/// +/// # Example +/// +/// ``` +/// let weight = migrate_delete_subnet_21::(); +/// ``` +pub fn migrate_delete_subnet_21() -> Weight { + let new_storage_version = 4; + + // Setup migration weight + let mut weight = T::DbWeight::get().reads(1); + + // Grab current version + let onchain_version = Pallet::::on_chain_storage_version(); + + // Only runs if we haven't already updated version past above new_storage_version and subnet 21 exists. + if onchain_version < new_storage_version && Pallet::::if_subnet_exist(21) { + info!(target: LOG_TARGET, ">>> Removing subnet 21 {:?}", onchain_version); + + let netuid = 21; + + // We do this all manually as we don't want to call code related to giving subnet owner back their locked token cost. + // Remove network count + SubnetworkN::::remove(netuid); + + // Remove network modality storage + NetworkModality::::remove(netuid); + + // Remove netuid from added networks + NetworksAdded::::remove(netuid); + + // Decrement the network counter + TotalNetworks::::mutate(|n| *n -= 1); + + // Remove network registration time + NetworkRegisteredAt::::remove(netuid); + + weight.saturating_accrue(T::DbWeight::get().writes(5)); + + // Remove incentive mechanism memory + let _ = Uids::::clear_prefix(netuid, u32::MAX, None); + let _ = Keys::::clear_prefix(netuid, u32::MAX, None); + let _ = Bonds::::clear_prefix(netuid, u32::MAX, None); + let _ = Weights::::clear_prefix(netuid, u32::MAX, None); + + weight.saturating_accrue(T::DbWeight::get().writes(4)); + + // Remove various network-related parameters + Rank::::remove(netuid); + Trust::::remove(netuid); + Active::::remove(netuid); + Emission::::remove(netuid); + Incentive::::remove(netuid); + Consensus::::remove(netuid); + Dividends::::remove(netuid); + PruningScores::::remove(netuid); + LastUpdate::::remove(netuid); + ValidatorPermit::::remove(netuid); + ValidatorTrust::::remove(netuid); + + weight.saturating_accrue(T::DbWeight::get().writes(11)); + + // Erase network parameters + Tempo::::remove(netuid); + Kappa::::remove(netuid); + Difficulty::::remove(netuid); + MaxAllowedUids::::remove(netuid); + ImmunityPeriod::::remove(netuid); + ActivityCutoff::::remove(netuid); + EmissionValues::::remove(netuid); + MaxWeightsLimit::::remove(netuid); + MinAllowedWeights::::remove(netuid); + RegistrationsThisInterval::::remove(netuid); + POWRegistrationsThisInterval::::remove(netuid); + BurnRegistrationsThisInterval::::remove(netuid); + + weight.saturating_accrue(T::DbWeight::get().writes(12)); + + // Update storage version + StorageVersion::new(new_storage_version).put::>(); + weight.saturating_accrue(T::DbWeight::get().writes(1)); + + weight + } else { + info!(target: LOG_TARGET, "Migration to v4 already done or subnet 21 doesn't exist!"); + Weight::zero() + } +} + +// TODO: Add unit tests for this migration +// TODO: Consider adding error handling for storage operations +// TODO: Verify that all relevant storage items for subnet 21 are removed \ No newline at end of file diff --git a/pallets/subtensor/src/migrations/migrate_delete_subnet_3.rs b/pallets/subtensor/src/migrations/migrate_delete_subnet_3.rs new file mode 100644 index 000000000..04df54269 --- /dev/null +++ b/pallets/subtensor/src/migrations/migrate_delete_subnet_3.rs @@ -0,0 +1,130 @@ +use super::*; +use frame_support::{ + pallet_prelude::*, storage_alias, + traits::{Get, GetStorageVersion, StorageVersion}, + weights::Weight, +}; +use log::info; +use sp_std::vec::Vec; + +/// Constant for logging purposes +const LOG_TARGET: &str = "migrate_delete_subnet_3"; + +/// Module containing deprecated storage format +pub mod deprecated_loaded_emission_format { + use super::*; + + #[storage_alias] + pub(super) type LoadedEmission = + StorageMap, Identity, u16, Vec<(AccountIdOf, u64)>, OptionQuery>; +} + +/// Migrates the storage to delete subnet 3 +/// +/// This function performs the following steps: +/// 1. Checks if the migration is necessary +/// 2. Removes all storage related to subnet 3 +/// 3. Updates the storage version +/// +/// # Arguments +/// +/// * `T` - The Config trait of the pallet +/// +/// # Returns +/// +/// * `Weight` - The computational weight of this operation +/// +/// # Example +/// +/// ``` +/// let weight = migrate_delete_subnet_3::(); +/// ``` +pub fn migrate_delete_subnet_3() -> Weight { + let new_storage_version = 5; + + // Initialize weight counter + let mut weight = T::DbWeight::get().reads(1); + + // Get current on-chain storage version + let onchain_version = Pallet::::on_chain_storage_version(); + + // Only proceed if current version is less than the new version and subnet 3 exists + if onchain_version < new_storage_version && Pallet::::if_subnet_exist(3) { + info!( + target: LOG_TARGET, + "Removing subnet 3. Current version: {:?}", + onchain_version + ); + + let netuid = 3; + + // Remove network count + SubnetworkN::::remove(netuid); + + // Remove network modality storage + NetworkModality::::remove(netuid); + + // Remove netuid from added networks + NetworksAdded::::remove(netuid); + + // Decrement the network counter + TotalNetworks::::mutate(|n| *n -= 1); + + // Remove network registration time + NetworkRegisteredAt::::remove(netuid); + + weight.saturating_accrue(T::DbWeight::get().writes(5)); + + // Remove incentive mechanism memory + let _ = Uids::::clear_prefix(netuid, u32::MAX, None); + let _ = Keys::::clear_prefix(netuid, u32::MAX, None); + let _ = Bonds::::clear_prefix(netuid, u32::MAX, None); + let _ = Weights::::clear_prefix(netuid, u32::MAX, None); + + weight.saturating_accrue(T::DbWeight::get().writes(4)); + + // Remove various network-related parameters + Rank::::remove(netuid); + Trust::::remove(netuid); + Active::::remove(netuid); + Emission::::remove(netuid); + Incentive::::remove(netuid); + Consensus::::remove(netuid); + Dividends::::remove(netuid); + PruningScores::::remove(netuid); + LastUpdate::::remove(netuid); + ValidatorPermit::::remove(netuid); + ValidatorTrust::::remove(netuid); + + weight.saturating_accrue(T::DbWeight::get().writes(11)); + + // Erase network parameters + Tempo::::remove(netuid); + Kappa::::remove(netuid); + Difficulty::::remove(netuid); + MaxAllowedUids::::remove(netuid); + ImmunityPeriod::::remove(netuid); + ActivityCutoff::::remove(netuid); + EmissionValues::::remove(netuid); + MaxWeightsLimit::::remove(netuid); + MinAllowedWeights::::remove(netuid); + RegistrationsThisInterval::::remove(netuid); + POWRegistrationsThisInterval::::remove(netuid); + BurnRegistrationsThisInterval::::remove(netuid); + + weight.saturating_accrue(T::DbWeight::get().writes(12)); + + // Update storage version + StorageVersion::new(new_storage_version).put::>(); + weight.saturating_accrue(T::DbWeight::get().writes(1)); + + weight + } else { + info!(target: LOG_TARGET, "Migration to v5 already completed or subnet 3 doesn't exist"); + Weight::zero() + } +} + +// TODO: Add unit tests for this migration +// TODO: Consider adding error handling for storage operations +// TODO: Verify that all relevant storage items for subnet 3 are removed \ No newline at end of file diff --git a/pallets/subtensor/src/migrations/migrate_fix_total_coldkey_stake.rs b/pallets/subtensor/src/migrations/migrate_fix_total_coldkey_stake.rs new file mode 100644 index 000000000..20c47e29c --- /dev/null +++ b/pallets/subtensor/src/migrations/migrate_fix_total_coldkey_stake.rs @@ -0,0 +1,73 @@ +use super::*; +use frame_support::{ + pallet_prelude::{Identity, OptionQuery}, + storage_alias, + traits::{Get, GetStorageVersion, StorageVersion}, + weights::Weight, +}; +use sp_std::vec::Vec; + +// TODO (camfairchild): TEST MIGRATION +pub mod deprecated_loaded_emission_format { + use super::*; + + #[storage_alias] + pub(super) type LoadedEmission = + StorageMap, Identity, u16, Vec<(AccountIdOf, u64)>, OptionQuery>; +} + +/// Migrates and fixes the total coldkey stake. +/// +/// This function iterates through all staking hotkeys, calculates the total stake for each coldkey, +/// and updates the `TotalColdkeyStake` storage accordingly. The migration is only performed if the +/// on-chain storage version is 6. +/// +/// # Returns +/// The weight of the migration process. +pub fn do_migrate_fix_total_coldkey_stake() -> Weight { + // Initialize the weight with one read operation. + let mut weight = T::DbWeight::get().reads(1); + + // Iterate through all staking hotkeys. + for (coldkey, hotkey_vec) in StakingHotkeys::::iter() { + // Init the zero value. + let mut coldkey_stake_sum: u64 = 0; + weight = weight.saturating_add(T::DbWeight::get().reads(1)); + + // Calculate the total stake for the current coldkey. + for hotkey in hotkey_vec { + // Cant fail on retrieval. + coldkey_stake_sum = + coldkey_stake_sum.saturating_add(Stake::::get(hotkey, coldkey.clone())); + weight = weight.saturating_add(T::DbWeight::get().reads(1)); + } + // Update the `TotalColdkeyStake` storage with the calculated stake sum. + // Cant fail on insert. + TotalColdkeyStake::::insert(coldkey.clone(), coldkey_stake_sum); + weight = weight.saturating_add(T::DbWeight::get().writes(1)); + } + weight +} +// Public migrate function to be called by Lib.rs on upgrade. +pub fn migrate_fix_total_coldkey_stake() -> Weight { + let current_storage_version: u16 = 7; + let next_storage_version: u16 = 8; + + // Initialize the weight with one read operation. + let mut weight = T::DbWeight::get().reads(1); + + // Grab the current on-chain storage version. + // Cant fail on retrieval. + let onchain_version = Pallet::::on_chain_storage_version(); + + // Only run this migration on storage version 6. + if onchain_version == current_storage_version { + weight = weight.saturating_add(do_migrate_fix_total_coldkey_stake::()); + // Cant fail on insert. + StorageVersion::new(next_storage_version).put::>(); + weight.saturating_accrue(T::DbWeight::get().writes(1)); + } + + // Return the migration weight. + weight +} diff --git a/pallets/subtensor/src/migrations/migrate_populate_owned_hotkeys.rs b/pallets/subtensor/src/migrations/migrate_populate_owned_hotkeys.rs new file mode 100644 index 000000000..23cf90d33 --- /dev/null +++ b/pallets/subtensor/src/migrations/migrate_populate_owned_hotkeys.rs @@ -0,0 +1,83 @@ +use super::*; +use frame_support::{ + pallet_prelude::{Identity, OptionQuery}, + storage_alias, + traits::{Get}, + weights::Weight, +}; +use log::info; +use sp_std::vec::Vec; + +const LOG_TARGET_1: &str = "migrate_populate_owned"; + +/// Module containing deprecated storage format for LoadedEmission +pub mod deprecated_loaded_emission_format { + use super::*; + + #[storage_alias] + pub(super) type LoadedEmission = + StorageMap, Identity, u16, Vec<(AccountIdOf, u64)>, OptionQuery>; +} + + +/// Migrate the OwnedHotkeys map to the new storage format +pub fn migrate_populate_owned() -> Weight { + // Setup migration weight + let mut weight = T::DbWeight::get().reads(1); + let migration_name = "Populate OwnedHotkeys map"; + + // Check if this migration is needed (if OwnedHotkeys map is empty) + let migrate = OwnedHotkeys::::iter().next().is_none(); + + // Only runs if the migration is needed + if migrate { + info!(target: LOG_TARGET_1, ">>> Starting Migration: {}", migration_name); + + let mut longest_hotkey_vector: usize = 0; + let mut longest_coldkey: Option = None; + let mut keys_touched: u64 = 0; + let mut storage_reads: u64 = 0; + let mut storage_writes: u64 = 0; + + // Iterate through all Owner entries + Owner::::iter().for_each(|(hotkey, coldkey)| { + storage_reads = storage_reads.saturating_add(1); // Read from Owner storage + let mut hotkeys = OwnedHotkeys::::get(&coldkey); + storage_reads = storage_reads.saturating_add(1); // Read from OwnedHotkeys storage + + // Add the hotkey if it's not already in the vector + if !hotkeys.contains(&hotkey) { + hotkeys.push(hotkey); + keys_touched = keys_touched.saturating_add(1); + + // Update longest hotkey vector info + if longest_hotkey_vector < hotkeys.len() { + longest_hotkey_vector = hotkeys.len(); + longest_coldkey = Some(coldkey.clone()); + } + + // Update the OwnedHotkeys storage + OwnedHotkeys::::insert(&coldkey, hotkeys); + storage_writes = storage_writes.saturating_add(1); // Write to OwnedHotkeys storage + } + + // Accrue weight for reads and writes + weight = weight.saturating_add(T::DbWeight::get().reads_writes(2, 1)); + }); + + // Log migration results + info!( + target: LOG_TARGET_1, + "Migration {} finished. Keys touched: {}, Longest hotkey vector: {}, Storage reads: {}, Storage writes: {}", + migration_name, keys_touched, longest_hotkey_vector, storage_reads, storage_writes + ); + if let Some(c) = longest_coldkey { + info!(target: LOG_TARGET_1, "Longest hotkey vector is controlled by: {:?}", c); + } + + weight + } else { + info!(target: LOG_TARGET_1, "Migration {} already done!", migration_name); + Weight::zero() + } +} \ No newline at end of file diff --git a/pallets/subtensor/src/migrations/migrate_populate_staking_hotkeys.rs b/pallets/subtensor/src/migrations/migrate_populate_staking_hotkeys.rs new file mode 100644 index 000000000..2c0988bbd --- /dev/null +++ b/pallets/subtensor/src/migrations/migrate_populate_staking_hotkeys.rs @@ -0,0 +1,85 @@ + +use super::*; +use frame_support::{ + pallet_prelude::{Identity, OptionQuery}, + storage_alias, + traits::{Get}, + weights::Weight, +}; +use log::info; +use sp_std::vec::Vec; +const LOG_TARGET_1: &str = "migrate_populate_owned"; + +/// Module containing deprecated storage format for LoadedEmission +pub mod deprecated_loaded_emission_format { + use super::*; + + #[storage_alias] + pub(super) type LoadedEmission = + StorageMap, Identity, u16, Vec<(AccountIdOf, u64)>, OptionQuery>; +} + + +/// Populate the StakingHotkeys map from Stake map +pub fn migrate_populate_staking_hotkeys() -> Weight { + // Setup migration weight + let mut weight = T::DbWeight::get().reads(1); + let migration_name = "Populate StakingHotkeys map"; + + // Check if this migration is needed (if StakingHotkeys map is empty) + let migrate = StakingHotkeys::::iter().next().is_none(); + + // Only runs if the migration is needed + if migrate { + info!(target: LOG_TARGET_1, ">>> Starting Migration: {}", migration_name); + + let mut longest_hotkey_vector: usize = 0; + let mut longest_coldkey: Option = None; + let mut keys_touched: u64 = 0; + let mut storage_reads: u64 = 0; + let mut storage_writes: u64 = 0; + + // Iterate through all Owner entries + Stake::::iter().for_each(|(hotkey, coldkey, stake)| { + storage_reads = storage_reads.saturating_add(1); // Read from Owner storage + if stake > 0 { + let mut hotkeys = StakingHotkeys::::get(&coldkey); + storage_reads = storage_reads.saturating_add(1); // Read from StakingHotkeys storage + + // Add the hotkey if it's not already in the vector + if !hotkeys.contains(&hotkey) { + hotkeys.push(hotkey); + keys_touched = keys_touched.saturating_add(1); + + // Update longest hotkey vector info + if longest_hotkey_vector < hotkeys.len() { + longest_hotkey_vector = hotkeys.len(); + longest_coldkey = Some(coldkey.clone()); + } + + // Update the StakingHotkeys storage + StakingHotkeys::::insert(&coldkey, hotkeys); + storage_writes = storage_writes.saturating_add(1); // Write to StakingHotkeys storage + } + + // Accrue weight for reads and writes + weight = weight.saturating_add(T::DbWeight::get().reads_writes(2, 1)); + } + }); + + // Log migration results + info!( + target: LOG_TARGET_1, + "Migration {} finished. Keys touched: {}, Longest hotkey vector: {}, Storage reads: {}, Storage writes: {}", + migration_name, keys_touched, longest_hotkey_vector, storage_reads, storage_writes + ); + if let Some(c) = longest_coldkey { + info!(target: LOG_TARGET_1, "Longest hotkey vector is controlled by: {:?}", c); + } + + weight + } else { + info!(target: LOG_TARGET_1, "Migration {} already done!", migration_name); + Weight::zero() + } +} diff --git a/pallets/subtensor/src/migrations/migrate_to_v1_separate_emission.rs b/pallets/subtensor/src/migrations/migrate_to_v1_separate_emission.rs new file mode 100644 index 000000000..4512801fd --- /dev/null +++ b/pallets/subtensor/src/migrations/migrate_to_v1_separate_emission.rs @@ -0,0 +1,106 @@ +use super::*; +use frame_support::{ + pallet_prelude::*, storage_alias, + traits::{Get, GetStorageVersion, StorageVersion}, + weights::Weight, +}; +use log::{info, warn}; +use sp_std::vec::Vec; + +/// Constant for logging purposes +const LOG_TARGET: &str = "loadedemissionmigration"; +const LOG_TARGET_1: &str = "fixtotalstakestorage"; + +/// Module containing deprecated storage format +pub mod deprecated_loaded_emission_format { + use super::*; + + type AccountIdOf = ::AccountId; + + #[storage_alias] + pub(super) type LoadedEmission = + StorageMap, Identity, u16, Vec<(AccountIdOf, u64)>, OptionQuery>; +} + +/// Migrates the LoadedEmission storage to a new format +/// +/// # Arguments +/// +/// * `T` - The runtime configuration trait +/// +/// # Returns +/// +/// * `Weight` - The computational weight of this operation +/// +/// # Example +/// +/// ``` +/// let weight = migrate_to_v1_separate_emission::(); +/// ``` +pub fn migrate_to_v1_separate_emission() -> Weight { + use deprecated_loaded_emission_format as old; + + // Initialize weight counter + let mut weight = T::DbWeight::get().reads_writes(1, 0); + + // Get current on-chain storage version + let onchain_version = Pallet::::on_chain_storage_version(); + + // Only proceed if current version is less than 1 + if onchain_version < 1 { + info!( + target: LOG_TARGET, + ">>> Updating the LoadedEmission to a new format {:?}", onchain_version + ); + + // Collect all network IDs (netuids) from old LoadedEmission storage + let curr_loaded_emission: Vec = old::LoadedEmission::::iter_keys().collect(); + + // Remove any undecodable entries + for netuid in curr_loaded_emission { + weight.saturating_accrue(T::DbWeight::get().reads(1)); + if old::LoadedEmission::::try_get(netuid).is_err() { + weight.saturating_accrue(T::DbWeight::get().writes(1)); + old::LoadedEmission::::remove(netuid); + warn!( + "Was unable to decode old loaded_emission for netuid {}", + netuid + ); + } + } + + // Translate old storage values to new format + LoadedEmission::::translate::, u64)>, _>( + |netuid: u16, + netuid_emissions: Vec<(AccountIdOf, u64)>| + -> Option, u64, u64)>> { + info!(target: LOG_TARGET, " Do migration of netuid: {:?}...", netuid); + + // Convert old format (server, validator_emission) to new format (server, server_emission, validator_emission) + // Assume all loaded emission is validator emissions + let new_netuid_emissions = netuid_emissions + .into_iter() + .map(|(server, validator_emission)| (server, 0_u64, validator_emission)) + .collect(); + + // Update weight for read and write operations + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); + + Some(new_netuid_emissions) + }, + ); + + // Update storage version to 1 + StorageVersion::new(1).put::>(); + weight.saturating_accrue(T::DbWeight::get().writes(1)); + + weight + } else { + info!(target: LOG_TARGET_1, "Migration to v1 already completed!"); + Weight::zero() + } +} + +// TODO: Add unit tests for this migration +// TODO: Consider adding error handling for edge cases +// TODO: Verify that all possible states of the old format are handled correctly \ No newline at end of file diff --git a/pallets/subtensor/src/migrations/migrate_to_v2_fixed_total_stake.rs b/pallets/subtensor/src/migrations/migrate_to_v2_fixed_total_stake.rs new file mode 100644 index 000000000..da0811521 --- /dev/null +++ b/pallets/subtensor/src/migrations/migrate_to_v2_fixed_total_stake.rs @@ -0,0 +1,103 @@ +use super::*; +use frame_support::{ + pallet_prelude::*, storage_alias, + traits::{Get, GetStorageVersion, StorageVersion}, + weights::Weight, +}; +use log::info; +use sp_std::vec::Vec; + +/// Constant for logging purposes +const LOG_TARGET: &str = "fix_total_stake_storage"; + +/// Module containing deprecated storage format +pub mod deprecated_loaded_emission_format { + use super::*; + + #[storage_alias] + pub(super) type LoadedEmission = + StorageMap, Identity, u16, Vec<(AccountIdOf, u64)>, OptionQuery>; +} + +/// Migrates the storage to fix TotalStake and TotalColdkeyStake +/// +/// This function performs the following steps: +/// 1. Resets TotalStake to 0 +/// 2. Resets all TotalColdkeyStake entries to 0 +/// 3. Recalculates TotalStake and TotalColdkeyStake based on the Stake map +/// +/// # Arguments +/// +/// * `T` - The Config trait of the pallet +/// +/// # Returns +/// +/// * `Weight` - The computational weight of this operation +/// +/// # Example +/// +/// ``` +/// let weight = migrate_to_v2_fixed_total_stake::(); +/// ``` +pub fn migrate_to_v2_fixed_total_stake() -> Weight { + let new_storage_version = 2; + + // Initialize weight counter + let mut weight = T::DbWeight::get().reads(1); + + // Get current on-chain storage version + let onchain_version = Pallet::::on_chain_storage_version(); + + // Only proceed if current version is less than the new version + if onchain_version < new_storage_version { + info!( + target: LOG_TARGET, + "Fixing the TotalStake and TotalColdkeyStake storage. Current version: {:?}", + onchain_version + ); + + // Reset TotalStake to 0 + TotalStake::::put(0); + weight.saturating_accrue(T::DbWeight::get().writes(1)); + + // Reset all TotalColdkeyStake entries to 0 + let total_coldkey_stake_keys = TotalColdkeyStake::::iter_keys().collect::>(); + for coldkey in total_coldkey_stake_keys { + weight.saturating_accrue(T::DbWeight::get().reads(1)); + TotalColdkeyStake::::insert(coldkey, 0); + weight.saturating_accrue(T::DbWeight::get().writes(1)); + } + + // Recalculate TotalStake and TotalColdkeyStake based on the Stake map + for (_, coldkey, stake) in Stake::::iter() { + weight.saturating_accrue(T::DbWeight::get().reads(1)); + + // Update TotalColdkeyStake + let mut total_coldkey_stake = TotalColdkeyStake::::get(coldkey.clone()); + weight.saturating_accrue(T::DbWeight::get().reads(1)); + total_coldkey_stake = total_coldkey_stake.saturating_add(stake); + TotalColdkeyStake::::insert(coldkey, total_coldkey_stake); + weight.saturating_accrue(T::DbWeight::get().writes(1)); + + // Update TotalStake + let mut total_stake = TotalStake::::get(); + weight.saturating_accrue(T::DbWeight::get().reads(1)); + total_stake = total_stake.saturating_add(stake); + TotalStake::::put(total_stake); + weight.saturating_accrue(T::DbWeight::get().writes(1)); + } + + // Update storage version to prevent re-running this migration + StorageVersion::new(new_storage_version).put::>(); + weight.saturating_accrue(T::DbWeight::get().writes(1)); + + weight + } else { + info!(target: LOG_TARGET, "Migration to v2 already completed"); + Weight::zero() + } +} + +// TODO: Add unit tests for this migration function +// TODO: Consider adding error handling for potential arithmetic overflow +// TODO: Optimize the iteration over Stake map if possible to reduce database reads \ No newline at end of file diff --git a/pallets/subtensor/src/migrations/migrate_total_issuance.rs b/pallets/subtensor/src/migrations/migrate_total_issuance.rs new file mode 100644 index 000000000..50d679ba0 --- /dev/null +++ b/pallets/subtensor/src/migrations/migrate_total_issuance.rs @@ -0,0 +1,84 @@ +use super::*; +use frame_support::{ + pallet_prelude::Identity, + storage_alias, + traits::{fungible::Inspect, Get, GetStorageVersion, StorageVersion}, + weights::Weight, +}; +use sp_std::vec::Vec; +use frame_support::pallet_prelude::OptionQuery; + +// TODO: Implement comprehensive tests for this migration + +/// Module containing deprecated storage format for LoadedEmission +pub mod deprecated_loaded_emission_format { + use super::*; + + #[storage_alias] + pub(super) type LoadedEmission = + StorageMap, Identity, u16, Vec<(AccountIdOf, u64)>, OptionQuery>; +} + +/// Performs migration to update the total issuance based on the sum of stakes and total balances. +/// +/// This migration is applicable only if the current storage version is 5, after which it updates the storage version to 6. +/// +/// # Arguments +/// +/// * `test` - A boolean flag to force migration execution for testing purposes. +/// +/// # Returns +/// +/// * `Weight` - The computational weight of this operation. +/// +/// # Example +/// +/// ``` +/// let weight = migration5_total_issuance::(false); +/// ``` +pub fn migration5_total_issuance(test: bool) -> Weight { + // Initialize migration weight with the cost of reading the storage version + let mut weight = T::DbWeight::get().reads(1); + + // Execute migration if the current storage version is 5 or if in test mode + if Pallet::::on_chain_storage_version() == StorageVersion::new(5) || test { + // Calculate the sum of all stake values + let stake_sum: u64 = Stake::::iter().fold(0, |acc, (_, _, stake)| acc.saturating_add(stake)); + // Add weight for reading all stake entries + weight = weight.saturating_add(T::DbWeight::get().reads(Stake::::iter().count() as u64)); + + // Calculate the sum of all locked subnet values + let locked_sum: u64 = SubnetLocked::::iter().fold(0, |acc, (_, locked)| acc.saturating_add(locked)); + // Add weight for reading all subnet locked entries + weight = weight.saturating_add(T::DbWeight::get().reads(SubnetLocked::::iter().count() as u64)); + + // Retrieve the total balance sum + let total_balance = T::Currency::total_issuance(); + // Add weight for reading total issuance + weight = weight.saturating_add(T::DbWeight::get().reads(1)); + + // Attempt to convert total balance to u64 + match TryInto::::try_into(total_balance) { + Ok(total_balance_sum) => { + // Compute the total issuance value + let total_issuance_value: u64 = stake_sum.saturating_add(total_balance_sum).saturating_add(locked_sum); + + // Update the total issuance in storage + TotalIssuance::::put(total_issuance_value); + + // Update the storage version to 6 + StorageVersion::new(6).put::>(); + + // Add weight for writing total issuance and storage version + weight = weight.saturating_add(T::DbWeight::get().writes(2)); + } + Err(_) => { + // TODO: Implement proper error handling for conversion failure + log::error!("Failed to convert total balance to u64, migration aborted"); + } + } + } + + // Return the computed weight of the migration process + weight +} \ No newline at end of file diff --git a/pallets/subtensor/src/migrations/migrate_transfer_ownership_to_foundation.rs b/pallets/subtensor/src/migrations/migrate_transfer_ownership_to_foundation.rs new file mode 100644 index 000000000..6a160c128 --- /dev/null +++ b/pallets/subtensor/src/migrations/migrate_transfer_ownership_to_foundation.rs @@ -0,0 +1,87 @@ +use super::*; +use frame_support::{ + pallet_prelude::{Identity, OptionQuery}, + storage_alias, + traits::{GetStorageVersion, StorageVersion}, + weights::Weight, +}; +use log::info; +use sp_core::Get; +use sp_std::vec::Vec; + +/// Constant for logging purposes +const LOG_TARGET: &str = "migrate_transfer_ownership"; + +/// Module containing deprecated storage format +pub mod deprecated_loaded_emission_format { + use super::*; + + #[storage_alias] + pub(super) type LoadedEmission = + StorageMap, Identity, u16, Vec<(AccountIdOf, u64)>, OptionQuery>; +} + +/// Migrates subnet ownership to the foundation and updates related storage +/// +/// # Arguments +/// +/// * `coldkey` - 32-byte array representing the foundation's coldkey +/// +/// # Returns +/// +/// * `Weight` - The computational weight of this operation +/// +/// # Example +/// +/// ``` +/// let foundation_coldkey = [0u8; 32]; // Replace with actual foundation coldkey +/// let weight = migrate_transfer_ownership_to_foundation::(foundation_coldkey); +/// ``` +pub fn migrate_transfer_ownership_to_foundation(coldkey: [u8; 32]) -> Weight { + let new_storage_version = 3; + + // Initialize weight counter + let mut weight = T::DbWeight::get().reads(1); + + // Get current on-chain storage version + let onchain_version = Pallet::::on_chain_storage_version(); + + // Only proceed if current version is less than the new version + if onchain_version < new_storage_version { + info!( + target: LOG_TARGET, + "Migrating subnet 1 and 11 to foundation control. Current version: {:?}", + onchain_version + ); + + // Decode the foundation's coldkey into an AccountId + // TODO: Consider error handling for decoding failure + let coldkey_account: T::AccountId = T::AccountId::decode(&mut &coldkey[..]) + .expect("coldkey should be a valid 32-byte array"); + info!(target: LOG_TARGET, "Foundation coldkey: {:?}", coldkey_account); + + // Get the current block number + let current_block = Pallet::::get_current_block_as_u64(); + weight.saturating_accrue(T::DbWeight::get().reads(1)); + + // Transfer ownership of subnets 1 and 11 to the foundation + SubnetOwner::::insert(1, coldkey_account.clone()); + SubnetOwner::::insert(11, coldkey_account); + + // Set the registration time for subnet 1 to extend immunity period + NetworkRegisteredAt::::insert(1, current_block.saturating_add(13 * 7200)); + // Set the registration time for subnet 11 to the current block + NetworkRegisteredAt::::insert(11, current_block); + + weight.saturating_accrue(T::DbWeight::get().writes(4)); + + // Update the storage version to prevent re-running this migration + StorageVersion::new(new_storage_version).put::>(); + weight.saturating_accrue(T::DbWeight::get().writes(1)); + + weight + } else { + info!(target: LOG_TARGET, "Migration to v3 already completed"); + Weight::zero() + } +} \ No newline at end of file diff --git a/pallets/subtensor/src/migrations/mod.rs b/pallets/subtensor/src/migrations/mod.rs new file mode 100644 index 000000000..cdc512d63 --- /dev/null +++ b/pallets/subtensor/src/migrations/mod.rs @@ -0,0 +1,11 @@ +use super::*; +pub mod migrate_delete_subnet_21; +pub mod migrate_create_root_network; +pub mod migrate_delete_subnet_3; +pub mod migrate_to_v1_separate_emission; +pub mod migrate_to_v2_fixed_total_stake; +pub mod migrate_transfer_ownership_to_foundation; +pub mod migrate_total_issuance; +pub mod migrate_populate_owned_hotkeys; +pub mod migrate_populate_staking_hotkeys; +pub mod migrate_fix_total_coldkey_stake; \ No newline at end of file diff --git a/pallets/subtensor/src/root.rs b/pallets/subtensor/src/root.rs index a973b8d7d..9cc38cab6 100644 --- a/pallets/subtensor/src/root.rs +++ b/pallets/subtensor/src/root.rs @@ -16,7 +16,7 @@ // DEALINGS IN THE SOFTWARE. use super::*; -use crate::math::*; +use crate::epoch::math::*; use frame_support::dispatch::Pays; use frame_support::storage::{IterableStorageDoubleMap, IterableStorageMap}; use frame_support::traits::Get; diff --git a/pallets/subtensor/src/delegate_info.rs b/pallets/subtensor/src/rpc_info/delegate_info.rs similarity index 100% rename from pallets/subtensor/src/delegate_info.rs rename to pallets/subtensor/src/rpc_info/delegate_info.rs diff --git a/pallets/subtensor/src/rpc_info/mod.rs b/pallets/subtensor/src/rpc_info/mod.rs new file mode 100644 index 000000000..70dc816cc --- /dev/null +++ b/pallets/subtensor/src/rpc_info/mod.rs @@ -0,0 +1,5 @@ +use super::*; +pub mod neuron_info; +pub mod stake_info; +pub mod subnet_info; +pub mod delegate_info; \ No newline at end of file diff --git a/pallets/subtensor/src/neuron_info.rs b/pallets/subtensor/src/rpc_info/neuron_info.rs similarity index 100% rename from pallets/subtensor/src/neuron_info.rs rename to pallets/subtensor/src/rpc_info/neuron_info.rs diff --git a/pallets/subtensor/src/stake_info.rs b/pallets/subtensor/src/rpc_info/stake_info.rs similarity index 100% rename from pallets/subtensor/src/stake_info.rs rename to pallets/subtensor/src/rpc_info/stake_info.rs diff --git a/pallets/subtensor/src/subnet_info.rs b/pallets/subtensor/src/rpc_info/subnet_info.rs similarity index 100% rename from pallets/subtensor/src/subnet_info.rs rename to pallets/subtensor/src/rpc_info/subnet_info.rs diff --git a/pallets/subtensor/src/weights.rs b/pallets/subtensor/src/weights.rs index 1866f8e62..67b1d485e 100644 --- a/pallets/subtensor/src/weights.rs +++ b/pallets/subtensor/src/weights.rs @@ -1,5 +1,5 @@ use super::*; -use crate::math::*; +use crate::epoch::math::*; use sp_core::H256; use sp_runtime::traits::{BlakeTwo256, Hash}; use sp_std::vec; diff --git a/pallets/subtensor/tests/math.rs b/pallets/subtensor/tests/math.rs index 35b383f68..7f70e89f6 100644 --- a/pallets/subtensor/tests/math.rs +++ b/pallets/subtensor/tests/math.rs @@ -5,7 +5,7 @@ )] use substrate_fixed::types::{I32F32, I64F64}; -use pallet_subtensor::math::*; +use pallet_subtensor::epoch::math::*; use rand::{seq::SliceRandom, thread_rng, Rng}; use substrate_fixed::{ transcendental::exp, From f7ade4d02dfae2caf84e64f6aefaa962e01e272c Mon Sep 17 00:00:00 2001 From: const Date: Mon, 15 Jul 2024 14:00:10 -0500 Subject: [PATCH 08/58] clean tests --- pallets/admin-utils/tests/mock.rs | 2 - pallets/admin-utils/tests/tests.rs | 4 +- pallets/subtensor/src/lib.rs | 114 +- pallets/subtensor/src/macros/config.rs | 3 - pallets/subtensor/src/macros/dispatches.rs | 15 +- pallets/subtensor/src/macros/hooks.rs | 2 +- pallets/subtensor/src/migration.rs | 2 +- .../migrations/migrate_create_root_network.rs | 2 +- .../migrations/migrate_delete_subnet_21.rs | 2 +- .../src/migrations/migrate_delete_subnet_3.rs | 2 +- .../migrate_to_v1_separate_emission.rs | 2 +- .../migrate_to_v2_fixed_total_stake.rs | 2 +- .../src/migrations/migrate_total_issuance.rs | 6 +- ...igrate_transfer_ownership_to_foundation.rs | 2 +- pallets/subtensor/src/registration.rs | 4 - pallets/subtensor/src/root.rs | 23 +- pallets/subtensor/src/staking.rs | 20 - pallets/subtensor/src/swap.rs | 1055 ------------- pallets/subtensor/src/swap/mod.rs | 3 + pallets/subtensor/src/swap/swap_coldkey.rs | 391 +++++ pallets/subtensor/src/swap/swap_hotkey.rs | 438 ++++++ pallets/subtensor/tests/epoch.rs | 6 +- pallets/subtensor/tests/migration.rs | 38 +- pallets/subtensor/tests/mock.rs | 2 - pallets/subtensor/tests/root.rs | 20 +- pallets/subtensor/tests/senate.rs | 18 +- pallets/subtensor/tests/staking.rs | 1337 +---------------- pallets/subtensor/tests/swap.rs | 100 +- runtime/src/lib.rs | 2 - 29 files changed, 975 insertions(+), 2642 deletions(-) delete mode 100644 pallets/subtensor/src/swap.rs create mode 100644 pallets/subtensor/src/swap/mod.rs create mode 100644 pallets/subtensor/src/swap/swap_coldkey.rs create mode 100644 pallets/subtensor/src/swap/swap_hotkey.rs diff --git a/pallets/admin-utils/tests/mock.rs b/pallets/admin-utils/tests/mock.rs index dbf88bdfa..dee8e742f 100644 --- a/pallets/admin-utils/tests/mock.rs +++ b/pallets/admin-utils/tests/mock.rs @@ -114,7 +114,6 @@ parameter_types! { pub const InitialAlphaHigh: u16 = 58982; // Represents 0.9 as per the production default pub const InitialAlphaLow: u16 = 45875; // Represents 0.7 as per the production default pub const InitialLiquidAlphaOn: bool = false; // Default value for LiquidAlphaOn - pub const InitialBaseDifficulty: u64 = 10_000; // Base difficulty } impl pallet_subtensor::Config for Test { @@ -170,7 +169,6 @@ impl pallet_subtensor::Config for Test { type AlphaHigh = InitialAlphaHigh; type AlphaLow = InitialAlphaLow; type LiquidAlphaOn = InitialLiquidAlphaOn; - type InitialBaseDifficulty = InitialBaseDifficulty; } #[derive_impl(frame_system::config_preludes::TestDefaultConfig)] diff --git a/pallets/admin-utils/tests/tests.rs b/pallets/admin-utils/tests/tests.rs index 9df59978f..6e78a1ed6 100644 --- a/pallets/admin-utils/tests/tests.rs +++ b/pallets/admin-utils/tests/tests.rs @@ -6,7 +6,7 @@ use frame_support::{ use frame_system::Config; use pallet_admin_utils::Error; use pallet_subtensor::Error as SubtensorError; -use pallet_subtensor::{migration, Event}; +use pallet_subtensor::{migrations, Event}; use sp_core::U256; mod mock; @@ -1232,7 +1232,7 @@ fn test_sudo_get_set_alpha() { // Enable Liquid Alpha and setup SubtensorModule::set_liquid_alpha_enabled(netuid, true); - migration::migrate_create_root_network::(); + migrations::migrate_create_root_network::migrate_create_root_network::(); SubtensorModule::add_balance_to_coldkey_account(&coldkey, 1_000_000_000_000_000); assert_ok!(SubtensorModule::root_register(signer.clone(), hotkey,)); assert_ok!(SubtensorModule::add_stake(signer.clone(), hotkey, 1000)); diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index 528c06229..329cebcdc 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -37,7 +37,8 @@ mod benchmarks; // ========================= mod rpc_info; mod coinbase; -mod epoch; +pub mod epoch; +pub mod swap; mod macros; use macros::{events, errors, dispatches, genesis, hooks, config}; @@ -45,7 +46,6 @@ mod registration; mod root; mod serving; mod staking; -mod swap; mod uids; mod utils; mod weights; @@ -308,7 +308,7 @@ pub mod pallet { pub fn DefaultAlphaValues() -> (u16, u16) { (45875, 58982) } #[pallet::storage] - pub(super) type SenateRequiredStakePercentage = StorageValue<_, u64, ValueQuery, DefaultSenateRequiredStakePercentage>; + pub type SenateRequiredStakePercentage = StorageValue<_, u64, ValueQuery, DefaultSenateRequiredStakePercentage>; /// ============================ /// ==== Staking Variables ==== @@ -483,9 +483,9 @@ pub mod pallet { #[pallet::storage] /// --- MAP ( netuid ) --> global_RAO_recycled_for_registration pub type RAORecycledForRegistration = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultRAORecycledForRegistration>; #[pallet::storage] /// --- ITEM ( tx_rate_limit ) - pub(super) type TxRateLimit = StorageValue<_, u64, ValueQuery, DefaultTxRateLimit>; + pub type TxRateLimit = StorageValue<_, u64, ValueQuery, DefaultTxRateLimit>; #[pallet::storage] /// --- ITEM ( tx_rate_limit ) - pub(super) type TxDelegateTakeRateLimit = StorageValue<_, u64, ValueQuery, DefaultTxDelegateTakeRateLimit>; + pub type TxDelegateTakeRateLimit = StorageValue<_, u64, ValueQuery, DefaultTxDelegateTakeRateLimit>; #[pallet::storage] /// --- MAP ( netuid ) --> Whether or not Liquid Alpha is enabled pub type LiquidAlphaOn = StorageMap<_, Blake2_128Concat, u16, bool, ValueQuery, DefaultLiquidAlpha>; #[pallet::storage] /// MAP ( netuid ) --> (alpha_low, alpha_high) @@ -496,94 +496,55 @@ pub mod pallet { /// ==== Subnetwork Consensus Storage ==== /// ======================================= #[pallet::storage] /// --- DMAP ( netuid, hotkey ) --> uid - pub(super) type Uids = StorageDoubleMap<_, Identity, u16, Blake2_128Concat, T::AccountId, u16, OptionQuery>; + pub type Uids = StorageDoubleMap<_, Identity, u16, Blake2_128Concat, T::AccountId, u16, OptionQuery>; #[pallet::storage] /// --- DMAP ( netuid, uid ) --> hotkey - pub(super) type Keys = StorageDoubleMap<_, Identity, u16, Identity, u16, T::AccountId, ValueQuery, DefaultKey>; + pub type Keys = StorageDoubleMap<_, Identity, u16, Identity, u16, T::AccountId, ValueQuery, DefaultKey>; #[pallet::storage] /// --- DMAP ( netuid ) --> (hotkey, se, ve) - pub(super) type LoadedEmission = StorageMap<_, Identity, u16, Vec<(T::AccountId, u64, u64)>, OptionQuery>; + pub type LoadedEmission = StorageMap<_, Identity, u16, Vec<(T::AccountId, u64, u64)>, OptionQuery>; #[pallet::storage] /// --- DMAP ( netuid ) --> active - pub(super) type Active = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyBoolVec>; + pub type Active = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyBoolVec>; #[pallet::storage] /// --- DMAP ( netuid ) --> rank - pub(super) type Rank = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; + pub type Rank = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; #[pallet::storage] /// --- DMAP ( netuid ) --> trust - pub(super) type Trust = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; + pub type Trust = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; #[pallet::storage] /// --- DMAP ( netuid ) --> consensus - pub(super) type Consensus = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; + pub type Consensus = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; #[pallet::storage] /// --- DMAP ( netuid ) --> incentive - pub(super) type Incentive = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; + pub type Incentive = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; #[pallet::storage] /// --- DMAP ( netuid ) --> dividends - pub(super) type Dividends = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; + pub type Dividends = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; #[pallet::storage] /// --- DMAP ( netuid ) --> emission - pub(super) type Emission = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU64Vec>; + pub type Emission = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU64Vec>; #[pallet::storage] /// --- DMAP ( netuid ) --> last_update - pub(super) type LastUpdate = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU64Vec>; + pub type LastUpdate = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU64Vec>; #[pallet::storage] /// --- DMAP ( netuid ) --> validator_trust - pub(super) type ValidatorTrust = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; + pub type ValidatorTrust = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; #[pallet::storage] /// --- DMAP ( netuid ) --> pruning_scores - pub(super) type PruningScores = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; + pub type PruningScores = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; #[pallet::storage] /// --- DMAP ( netuid ) --> validator_permit - pub(super) type ValidatorPermit = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyBoolVec>; + pub type ValidatorPermit = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyBoolVec>; #[pallet::storage] /// --- DMAP ( netuid, uid ) --> weights - pub(super) type Weights = StorageDoubleMap<_, Identity, u16, Identity, u16, Vec<(u16, u16)>, ValueQuery, DefaultWeights>; + pub type Weights = StorageDoubleMap<_, Identity, u16, Identity, u16, Vec<(u16, u16)>, ValueQuery, DefaultWeights>; #[pallet::storage] /// --- DMAP ( netuid, uid ) --> bonds - pub(super) type Bonds = StorageDoubleMap<_, Identity, u16, Identity, u16, Vec<(u16, u16)>, ValueQuery, DefaultBonds>; + pub type Bonds = StorageDoubleMap<_, Identity, u16, Identity, u16, Vec<(u16, u16)>, ValueQuery, DefaultBonds>; #[pallet::storage] /// --- DMAP ( netuid, uid ) --> block_at_registration pub type BlockAtRegistration = StorageDoubleMap<_, Identity, u16, Identity, u16, u64, ValueQuery, DefaultBlockAtRegistration>; #[pallet::storage] /// --- MAP ( netuid, hotkey ) --> axon_info - pub(super) type Axons = StorageDoubleMap<_, Identity, u16, Blake2_128Concat, T::AccountId, AxonInfoOf, OptionQuery>; + pub type Axons = StorageDoubleMap<_, Identity, u16, Blake2_128Concat, T::AccountId, AxonInfoOf, OptionQuery>; #[pallet::storage] /// --- MAP ( netuid, hotkey ) --> prometheus_info - pub(super) type Prometheus = StorageDoubleMap<_, Identity, u16, Blake2_128Concat, T::AccountId, PrometheusInfoOf, OptionQuery>; + pub type Prometheus = StorageDoubleMap<_, Identity, u16, Blake2_128Concat, T::AccountId, PrometheusInfoOf, OptionQuery>; /// ================================= /// ==== Axon / Promo Endpoints ===== /// ================================= #[pallet::storage] /// --- MAP ( key ) --> last_block - pub(super) type LastTxBlock = StorageMap<_, Identity, T::AccountId, u64, ValueQuery, DefaultLastTxBlock>; + pub type LastTxBlock = StorageMap<_, Identity, T::AccountId, u64, ValueQuery, DefaultLastTxBlock>; #[pallet::storage] /// --- MAP ( key ) --> last_block - pub(super) type LastTxBlockDelegateTake = StorageMap<_, Identity, T::AccountId, u64, ValueQuery, DefaultLastTxBlock>; + pub type LastTxBlockDelegateTake = StorageMap<_, Identity, T::AccountId, u64, ValueQuery, DefaultLastTxBlock>; #[pallet::storage] /// ITEM( weights_min_stake ) pub type WeightsMinStake = StorageValue<_, u64, ValueQuery, DefaultWeightsMinStake>; #[pallet::storage] /// --- MAP (netuid, who) --> (hash, weight) | Returns the hash and weight committed by an account for a given netuid. pub type WeightCommits = StorageDoubleMap<_, Twox64Concat, u16, Twox64Concat, T::AccountId, (H256, u64), OptionQuery>; - - /// =============================== - /// ==== Coldkey Arbitrations ===== - /// =============================== - #[pallet::type_value] /// Default base difficulty for proof of work for coldkey swaps - pub fn DefaultBaseDifficulty() -> u64 { T::InitialBaseDifficulty::get() } - #[pallet::storage] // --- ITEM ( base_difficulty ) - pub type BaseDifficulty = StorageValue<_, u64, ValueQuery, DefaultBaseDifficulty>; - #[pallet::type_value] - /// Default value for hotkeys. - pub fn EmptyAccounts() -> Vec { - vec![] - } - #[pallet::type_value] - /// Default arbitration period. - /// This value represents the default arbitration period in blocks. - /// The period is set to 18 hours, assuming a block time of 12 seconds. - pub fn DefaultArbitrationPeriod() -> u64 { - 7200 * 3 // 3 days - } - #[pallet::storage] // ---- StorageItem Global Used Work. - pub type ArbitrationPeriod = - StorageValue<_, u64, ValueQuery, DefaultArbitrationPeriod>; - #[pallet::storage] // --- MAP ( cold ) --> Vec | Returns a list of keys to drain to, if there are two, we extend the period. - pub type ColdkeySwapDestinations = StorageMap< - _, - Blake2_128Concat, - T::AccountId, - Vec, - ValueQuery, - EmptyAccounts, - >; - #[pallet::storage] // --- MAP ( cold ) --> u64 | Block when the coldkey will be arbitrated. - pub type ColdkeyArbitrationBlock = - StorageMap<_, Blake2_128Concat, T::AccountId, u64, ValueQuery>; - #[pallet::storage] // --- MAP ( u64 ) --> Vec | Coldkeys to drain on the specific block. - pub type ColdkeysToSwapAtBlock = - StorageMap<_, Identity, u64, Vec, ValueQuery, EmptyAccounts>; - /// ================== /// ==== Genesis ===== /// ================== @@ -736,19 +697,6 @@ where _info: &DispatchInfoOf, _len: usize, ) -> TransactionValidity { - // Check if the call is one of the balance transfer types we want to reject - if let Some(balances_call) = call.is_sub_type() { - match balances_call { - BalancesCall::transfer_allow_death { .. } - | BalancesCall::transfer_keep_alive { .. } - | BalancesCall::transfer_all { .. } => { - if Pallet::::coldkey_in_arbitration(who) { - return Err(TransactionValidityError::Invalid(InvalidTransaction::Call)); - } - } - _ => {} // Other Balances calls are allowed - } - } match call.is_sub_type() { Some(Call::commit_weights { netuid, .. }) => { if Self::check_weights_min_stake(who) { @@ -826,14 +774,10 @@ where ..Default::default() }), Some(Call::dissolve_network { .. }) => { - if Pallet::::coldkey_in_arbitration(who) { - Err(TransactionValidityError::Invalid(InvalidTransaction::Call)) - } else { - Ok(ValidTransaction { - priority: Self::get_priority_vanilla(), - ..Default::default() - }) - } + Ok(ValidTransaction { + priority: Self::get_priority_vanilla(), + ..Default::default() + }) } _ => Ok(ValidTransaction { priority: Self::get_priority_vanilla(), diff --git a/pallets/subtensor/src/macros/config.rs b/pallets/subtensor/src/macros/config.rs index e54cd222f..4e3cf5d2a 100644 --- a/pallets/subtensor/src/macros/config.rs +++ b/pallets/subtensor/src/macros/config.rs @@ -168,8 +168,5 @@ mod config { /// A flag to indicate if Liquid Alpha is enabled. #[pallet::constant] type LiquidAlphaOn: Get; - /// The base difficulty for proof of work for coldkey swaps - #[pallet::constant] - type InitialBaseDifficulty: Get; } } \ No newline at end of file diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 62b02f6a4..6d4c588e9 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -677,6 +677,7 @@ mod dispatches { ) -> DispatchResultWithPostInfo { Self::do_swap_coldkey(origin, &new_coldkey) } + /// Unstakes all tokens associated with a hotkey and transfers them to a new coldkey. /// /// # Arguments @@ -698,15 +699,13 @@ mod dispatches { .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)), DispatchClass::Operational, Pays::No))] pub fn schedule_coldkey_swap( - origin: OriginFor, - new_coldkey: T::AccountId, - work: Vec, - block_number: u64, - nonce: u64, + _origin: OriginFor, + _new_coldkey: T::AccountId, + _work: Vec, + _block_number: u64, + _nonce: u64, ) -> DispatchResult { - // Attain the calling coldkey from the origin. - let old_coldkey: T::AccountId = ensure_signed(origin)?; - Self::do_schedule_coldkey_swap(&old_coldkey, &new_coldkey, work, block_number, nonce) + Ok(()) } // ---- SUDO ONLY FUNCTIONS ------------------------------------------------------------ diff --git a/pallets/subtensor/src/macros/hooks.rs b/pallets/subtensor/src/macros/hooks.rs index baa9de21a..7e612fb4e 100644 --- a/pallets/subtensor/src/macros/hooks.rs +++ b/pallets/subtensor/src/macros/hooks.rs @@ -59,7 +59,7 @@ mod hooks { .saturating_add(migrations::migrate_delete_subnet_3::migrate_delete_subnet_3::()) // Doesn't check storage version. TODO: Remove after upgrade // Storage version v5 -> v6 - .saturating_add(migrations::migrate_total_issuance::migration5_total_issuance::(false)) + .saturating_add(migrations::migrate_total_issuance::migrate_total_issuance::(false)) // Populate OwnedHotkeys map for coldkey swap. Doesn't update storage vesion. // Storage version v6 -> v7 .saturating_add(migrations::migrate_populate_owned_hotkeys::migrate_populate_owned::()) diff --git a/pallets/subtensor/src/migration.rs b/pallets/subtensor/src/migration.rs index 72a86ea4e..cd99f0128 100644 --- a/pallets/subtensor/src/migration.rs +++ b/pallets/subtensor/src/migration.rs @@ -85,7 +85,7 @@ pub fn migrate_fix_total_coldkey_stake() -> Weight { /// /// # Returns /// Weight of the migration process. -pub fn migration5_total_issuance(test: bool) -> Weight { +pub fn migrate_total_issuance(test: bool) -> Weight { let mut weight = T::DbWeight::get().reads(1); // Initialize migration weight // Execute migration if the current storage version is 5 diff --git a/pallets/subtensor/src/migrations/migrate_create_root_network.rs b/pallets/subtensor/src/migrations/migrate_create_root_network.rs index ff858ec6a..20ee82f0a 100644 --- a/pallets/subtensor/src/migrations/migrate_create_root_network.rs +++ b/pallets/subtensor/src/migrations/migrate_create_root_network.rs @@ -35,7 +35,7 @@ pub mod deprecated_loaded_emission_format { /// /// # Example /// -/// ``` +/// ```ignore /// let weight = migrate_create_root_network::(); /// ``` pub fn migrate_create_root_network() -> Weight { diff --git a/pallets/subtensor/src/migrations/migrate_delete_subnet_21.rs b/pallets/subtensor/src/migrations/migrate_delete_subnet_21.rs index df6a2ae34..23fbe122f 100644 --- a/pallets/subtensor/src/migrations/migrate_delete_subnet_21.rs +++ b/pallets/subtensor/src/migrations/migrate_delete_subnet_21.rs @@ -36,7 +36,7 @@ pub mod deprecated_loaded_emission_format { /// /// # Example /// -/// ``` +/// ```ignore /// let weight = migrate_delete_subnet_21::(); /// ``` pub fn migrate_delete_subnet_21() -> Weight { diff --git a/pallets/subtensor/src/migrations/migrate_delete_subnet_3.rs b/pallets/subtensor/src/migrations/migrate_delete_subnet_3.rs index 04df54269..257752c19 100644 --- a/pallets/subtensor/src/migrations/migrate_delete_subnet_3.rs +++ b/pallets/subtensor/src/migrations/migrate_delete_subnet_3.rs @@ -36,7 +36,7 @@ pub mod deprecated_loaded_emission_format { /// /// # Example /// -/// ``` +/// ```ignore /// let weight = migrate_delete_subnet_3::(); /// ``` pub fn migrate_delete_subnet_3() -> Weight { diff --git a/pallets/subtensor/src/migrations/migrate_to_v1_separate_emission.rs b/pallets/subtensor/src/migrations/migrate_to_v1_separate_emission.rs index 4512801fd..5db04f0bc 100644 --- a/pallets/subtensor/src/migrations/migrate_to_v1_separate_emission.rs +++ b/pallets/subtensor/src/migrations/migrate_to_v1_separate_emission.rs @@ -34,7 +34,7 @@ pub mod deprecated_loaded_emission_format { /// /// # Example /// -/// ``` +/// ```ignore /// let weight = migrate_to_v1_separate_emission::(); /// ``` pub fn migrate_to_v1_separate_emission() -> Weight { diff --git a/pallets/subtensor/src/migrations/migrate_to_v2_fixed_total_stake.rs b/pallets/subtensor/src/migrations/migrate_to_v2_fixed_total_stake.rs index da0811521..ef9fe8880 100644 --- a/pallets/subtensor/src/migrations/migrate_to_v2_fixed_total_stake.rs +++ b/pallets/subtensor/src/migrations/migrate_to_v2_fixed_total_stake.rs @@ -36,7 +36,7 @@ pub mod deprecated_loaded_emission_format { /// /// # Example /// -/// ``` +/// ```ignore /// let weight = migrate_to_v2_fixed_total_stake::(); /// ``` pub fn migrate_to_v2_fixed_total_stake() -> Weight { diff --git a/pallets/subtensor/src/migrations/migrate_total_issuance.rs b/pallets/subtensor/src/migrations/migrate_total_issuance.rs index 50d679ba0..187967da3 100644 --- a/pallets/subtensor/src/migrations/migrate_total_issuance.rs +++ b/pallets/subtensor/src/migrations/migrate_total_issuance.rs @@ -33,10 +33,10 @@ pub mod deprecated_loaded_emission_format { /// /// # Example /// +/// ```ignore +/// let weight = migrate_total_issuance::(false); /// ``` -/// let weight = migration5_total_issuance::(false); -/// ``` -pub fn migration5_total_issuance(test: bool) -> Weight { +pub fn migrate_total_issuance(test: bool) -> Weight { // Initialize migration weight with the cost of reading the storage version let mut weight = T::DbWeight::get().reads(1); diff --git a/pallets/subtensor/src/migrations/migrate_transfer_ownership_to_foundation.rs b/pallets/subtensor/src/migrations/migrate_transfer_ownership_to_foundation.rs index 6a160c128..0ca4a7fa5 100644 --- a/pallets/subtensor/src/migrations/migrate_transfer_ownership_to_foundation.rs +++ b/pallets/subtensor/src/migrations/migrate_transfer_ownership_to_foundation.rs @@ -33,7 +33,7 @@ pub mod deprecated_loaded_emission_format { /// /// # Example /// -/// ``` +/// ```ignore /// let foundation_coldkey = [0u8; 32]; // Replace with actual foundation coldkey /// let weight = migrate_transfer_ownership_to_foundation::(foundation_coldkey); /// ``` diff --git a/pallets/subtensor/src/registration.rs b/pallets/subtensor/src/registration.rs index 6b73f2fc3..4688bcbb5 100644 --- a/pallets/subtensor/src/registration.rs +++ b/pallets/subtensor/src/registration.rs @@ -41,10 +41,6 @@ impl Pallet { ) -> DispatchResult { // --- 1. Check that the caller has signed the transaction. (the coldkey of the pairing) let coldkey = ensure_signed(origin)?; - ensure!( - !Self::coldkey_in_arbitration(&coldkey), - Error::::ColdkeyIsInArbitration - ); log::info!( "do_registration( coldkey:{:?} netuid:{:?} hotkey:{:?} )", coldkey, diff --git a/pallets/subtensor/src/root.rs b/pallets/subtensor/src/root.rs index 9cc38cab6..b3ac32f55 100644 --- a/pallets/subtensor/src/root.rs +++ b/pallets/subtensor/src/root.rs @@ -483,10 +483,6 @@ impl Pallet { // --- 1. Ensure that the call originates from a signed source and retrieve the caller's account ID (coldkey). let coldkey = ensure_signed(origin)?; - ensure!( - !Self::coldkey_in_arbitration(&coldkey), - Error::::ColdkeyIsInArbitration - ); log::info!( "do_root_register( coldkey: {:?}, hotkey: {:?} )", coldkey, @@ -734,10 +730,6 @@ impl Pallet { ) -> dispatch::DispatchResult { // Check the caller's signature. This is the coldkey of a registered account. let coldkey = ensure_signed(origin)?; - ensure!( - !Self::coldkey_in_arbitration(&coldkey), - Error::::ColdkeyIsInArbitration - ); log::info!( "do_set_root_weights( origin:{:?} netuid:{:?}, uids:{:?}, values:{:?})", coldkey, @@ -859,10 +851,6 @@ impl Pallet { ) -> DispatchResultWithPostInfo { // --- 1. Ensure that the caller has signed with their coldkey. let coldkey = ensure_signed(origin.clone())?; - ensure!( - !Self::coldkey_in_arbitration(&coldkey), - Error::::ColdkeyIsInArbitration - ); // --- 2. Ensure that the calling coldkey owns the associated hotkey. ensure!( @@ -916,10 +904,7 @@ impl Pallet { pub fn user_add_network(origin: T::RuntimeOrigin) -> dispatch::DispatchResult { // --- 0. Ensure the caller is a signed user. let coldkey = ensure_signed(origin)?; - ensure!( - !Self::coldkey_in_arbitration(&coldkey), - Error::::ColdkeyIsInArbitration - ); + // --- 1. Rate limit for network registrations. let current_block = Self::get_current_block_as_u64(); @@ -1008,11 +993,7 @@ impl Pallet { pub fn user_remove_network(origin: T::RuntimeOrigin, netuid: u16) -> dispatch::DispatchResult { // --- 1. Ensure the function caller is a signed user. let coldkey = ensure_signed(origin)?; - ensure!( - !Self::coldkey_in_arbitration(&coldkey), - Error::::ColdkeyIsInArbitration - ); - + // --- 2. Ensure this subnet exists. ensure!( Self::if_subnet_exist(netuid), diff --git a/pallets/subtensor/src/staking.rs b/pallets/subtensor/src/staking.rs index 199234a30..2707d90ef 100644 --- a/pallets/subtensor/src/staking.rs +++ b/pallets/subtensor/src/staking.rs @@ -44,10 +44,6 @@ impl Pallet { ) -> dispatch::DispatchResult { // --- 1. We check the coldkey signuture. let coldkey = ensure_signed(origin)?; - ensure!( - !Self::coldkey_in_arbitration(&coldkey), - Error::::ColdkeyIsInArbitration - ); log::info!( "do_become_delegate( origin:{:?} hotkey:{:?}, take:{:?} )", coldkey, @@ -137,10 +133,6 @@ impl Pallet { hotkey, take ); - ensure!( - !Self::coldkey_in_arbitration(&coldkey), - Error::::ColdkeyIsInArbitration - ); // --- 2. Ensure we are delegating a known key. // Ensure that the coldkey is the owner. @@ -213,10 +205,6 @@ impl Pallet { hotkey, take ); - ensure!( - !Self::coldkey_in_arbitration(&coldkey), - Error::::ColdkeyIsInArbitration - ); // --- 2. Ensure we are delegating a known key. // Ensure that the coldkey is the owner. @@ -302,10 +290,6 @@ impl Pallet { hotkey, stake_to_be_added ); - ensure!( - !Self::coldkey_in_arbitration(&coldkey), - Error::::ColdkeyIsInArbitration - ); // Ensure the callers coldkey has enough stake to perform the transaction. ensure!( @@ -418,10 +402,6 @@ impl Pallet { hotkey, stake_to_be_removed ); - ensure!( - !Self::coldkey_in_arbitration(&coldkey), - Error::::ColdkeyIsInArbitration - ); // Ensure that the hotkey account exists this is only possible through registration. ensure!( diff --git a/pallets/subtensor/src/swap.rs b/pallets/subtensor/src/swap.rs deleted file mode 100644 index 8e4ca5cc9..000000000 --- a/pallets/subtensor/src/swap.rs +++ /dev/null @@ -1,1055 +0,0 @@ -use super::*; -use crate::MIN_BALANCE_TO_PERFORM_COLDKEY_SWAP; -use frame_support::traits::fungible::Mutate; -use frame_support::traits::tokens::Preservation; -use frame_support::{storage::IterableStorageDoubleMap, weights::Weight}; -use sp_core::{Get, U256}; - -impl Pallet { - /// Swaps the hotkey of a coldkey account. - /// - /// # Arguments - /// - /// * `origin` - The origin of the transaction, and also the coldkey account. - /// * `old_hotkey` - The old hotkey to be swapped. - /// * `new_hotkey` - The new hotkey to replace the old one. - /// - /// # Returns - /// - /// * `DispatchResultWithPostInfo` - The result of the dispatch. - /// - /// # Errors - /// - /// * `NonAssociatedColdKey` - If the coldkey does not own the old hotkey. - /// * `HotKeySetTxRateLimitExceeded` - If the transaction rate limit is exceeded. - /// * `NewHotKeyIsSameWithOld` - If the new hotkey is the same as the old hotkey. - /// * `HotKeyAlreadyRegisteredInSubNet` - If the new hotkey is already registered in the subnet. - /// * `NotEnoughBalanceToPaySwapHotKey` - If there is not enough balance to pay for the swap. - pub fn do_swap_hotkey( - origin: T::RuntimeOrigin, - old_hotkey: &T::AccountId, - new_hotkey: &T::AccountId, - ) -> DispatchResultWithPostInfo { - let coldkey = ensure_signed(origin)?; - - ensure!( - !Self::coldkey_in_arbitration(&coldkey), - Error::::ColdkeyIsInArbitration - ); - - let mut weight = T::DbWeight::get().reads(2); - - ensure!(old_hotkey != new_hotkey, Error::::NewHotKeyIsSameWithOld); - ensure!( - !Self::is_hotkey_registered_on_any_network(new_hotkey), - Error::::HotKeyAlreadyRegisteredInSubNet - ); - - weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 0)); - ensure!( - Self::coldkey_owns_hotkey(&coldkey, old_hotkey), - Error::::NonAssociatedColdKey - ); - - let block: u64 = Self::get_current_block_as_u64(); - ensure!( - !Self::exceeds_tx_rate_limit(Self::get_last_tx_block(&coldkey), block), - Error::::HotKeySetTxRateLimitExceeded - ); - - weight.saturating_accrue( - T::DbWeight::get().reads((TotalNetworks::::get().saturating_add(1u16)) as u64), - ); - - let swap_cost = Self::get_key_swap_cost(); - log::debug!("Swap cost: {:?}", swap_cost); - - ensure!( - Self::can_remove_balance_from_coldkey_account(&coldkey, swap_cost), - Error::::NotEnoughBalanceToPaySwapHotKey - ); - let actual_burn_amount = Self::remove_balance_from_coldkey_account(&coldkey, swap_cost)?; - Self::burn_tokens(actual_burn_amount); - - Self::swap_owner(old_hotkey, new_hotkey, &coldkey, &mut weight); - Self::swap_total_hotkey_stake(old_hotkey, new_hotkey, &mut weight); - Self::swap_delegates(old_hotkey, new_hotkey, &mut weight); - Self::swap_stake(old_hotkey, new_hotkey, &mut weight); - - // Store the value of is_network_member for the old key - let netuid_is_member: Vec = Self::get_netuid_is_member(old_hotkey, &mut weight); - - Self::swap_is_network_member(old_hotkey, new_hotkey, &netuid_is_member, &mut weight); - Self::swap_axons(old_hotkey, new_hotkey, &netuid_is_member, &mut weight); - Self::swap_keys(old_hotkey, new_hotkey, &netuid_is_member, &mut weight); - Self::swap_loaded_emission(old_hotkey, new_hotkey, &netuid_is_member, &mut weight); - Self::swap_uids(old_hotkey, new_hotkey, &netuid_is_member, &mut weight); - Self::swap_prometheus(old_hotkey, new_hotkey, &netuid_is_member, &mut weight); - Self::swap_senate_member(old_hotkey, new_hotkey, &mut weight)?; - - Self::swap_total_hotkey_coldkey_stakes_this_interval(old_hotkey, new_hotkey, &mut weight); - - Self::set_last_tx_block(&coldkey, block); - weight.saturating_accrue(T::DbWeight::get().writes(1)); - - Self::deposit_event(Event::HotkeySwapped { - coldkey, - old_hotkey: old_hotkey.clone(), - new_hotkey: new_hotkey.clone(), - }); - - Ok(Some(weight).into()) - } - - /// Swaps the coldkey associated with a set of hotkeys from an old coldkey to a new coldkey. - /// - /// # Arguments - /// - /// * `origin` - The origin of the call, which must be signed by the old coldkey. - /// * `old_coldkey` - The account ID of the old coldkey. - /// * `new_coldkey` - The account ID of the new coldkey. - /// - /// # Returns - /// - /// Returns a `DispatchResultWithPostInfo` indicating success or failure, along with the weight consumed. - /// - /// # Errors - /// - /// This function will return an error if: - /// - The caller is not the old coldkey. - /// - The new coldkey is the same as the old coldkey. - /// - The new coldkey is already associated with other hotkeys. - /// - The transaction rate limit for coldkey swaps has been exceeded. - /// - There's not enough balance to pay for the swap. - /// - /// # Events - /// - /// Emits a `ColdkeySwapped` event when successful. - /// - /// # Weight - /// - /// Weight is tracked and updated throughout the function execution. - pub fn do_swap_coldkey( - origin: T::RuntimeOrigin, - new_coldkey: &T::AccountId, - ) -> DispatchResultWithPostInfo { - let old_coldkey = ensure_signed(origin)?; - ensure!( - !Self::coldkey_in_arbitration(&old_coldkey), - Error::::ColdkeyIsInArbitration - ); - - let mut weight: Weight = T::DbWeight::get().reads(2); - - // Check that the coldkey is a new key (does not exist elsewhere.) - ensure!( - !Self::coldkey_has_associated_hotkeys(new_coldkey), - Error::::ColdKeyAlreadyAssociated - ); - // Check that the new coldkey is not a hotkey. - ensure!( - !Self::hotkey_account_exists(new_coldkey), - Error::::ColdKeyAlreadyAssociated - ); - - // Calculate and charge the swap fee - let swap_cost = Self::get_key_swap_cost(); - log::debug!("Coldkey swap cost: {:?}", swap_cost); - - ensure!( - Self::can_remove_balance_from_coldkey_account(&old_coldkey, swap_cost), - Error::::NotEnoughBalanceToPaySwapColdKey - ); - let actual_burn_amount = - Self::remove_balance_from_coldkey_account(&old_coldkey, swap_cost)?; - Self::burn_tokens(actual_burn_amount); - - weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); - - // Actually do the swap. - weight = weight.saturating_add( - Self::perform_swap_coldkey(&old_coldkey, new_coldkey) - .map_err(|_| Error::::ColdkeySwapError)?, - ); - - Self::set_last_tx_block(new_coldkey, Self::get_current_block_as_u64()); - weight.saturating_accrue(T::DbWeight::get().writes(1)); - - Self::deposit_event(Event::ColdkeySwapped { - old_coldkey: old_coldkey.clone(), - new_coldkey: new_coldkey.clone(), - }); - - Ok(Some(weight).into()) - } - - /// Checks if a coldkey is currently in arbitration. - /// - /// # Arguments - /// - /// * `coldkey` - The account ID of the coldkey to check. - /// - /// # Returns - /// - /// * `bool` - True if the coldkey is in arbitration, false otherwise. - /// - /// # Notes - /// - /// This function compares the arbitration block number of the coldkey with the current block number. - pub fn coldkey_in_arbitration(coldkey: &T::AccountId) -> bool { - ColdkeyArbitrationBlock::::get(coldkey) > Self::get_current_block_as_u64() - } - - /// Returns the remaining arbitration period for a given coldkey. - /// - /// # Arguments - /// - /// * `coldkey` - The account ID of the coldkey to check. - /// - /// # Returns - /// - /// * `u64` - The remaining arbitration period in blocks. - /// - /// - /// # Notes - /// - /// This function calculates the remaining arbitration period by subtracting the current block number - /// from the arbitration block number of the coldkey. - pub fn get_remaining_arbitration_period(coldkey: &T::AccountId) -> u64 { - let current_block: u64 = Self::get_current_block_as_u64(); - let arbitration_block: u64 = ColdkeyArbitrationBlock::::get(coldkey); - if arbitration_block > current_block { - arbitration_block.saturating_sub(current_block) - } else { - 0 - } - } - - pub fn meets_min_allowed_coldkey_balance(coldkey: &T::AccountId) -> bool { - let all_staked_keys: Vec = StakingHotkeys::::get(coldkey); - let mut total_staking_balance: u64 = 0; - for hotkey in all_staked_keys { - total_staking_balance = total_staking_balance - .saturating_add(Self::get_stake_for_coldkey_and_hotkey(coldkey, &hotkey)); - } - total_staking_balance = - total_staking_balance.saturating_add(Self::get_coldkey_balance(coldkey)); - total_staking_balance >= MIN_BALANCE_TO_PERFORM_COLDKEY_SWAP - } - - /// Schedules a coldkey swap to a new coldkey with arbitration. - /// - /// # Arguments - /// - /// * `old_coldkey` - The account ID of the old coldkey. - /// * `new_coldkey` - The account ID of the new coldkey. - /// * `work` - The proof of work submitted by the caller. - /// * `block_number` - The block number at which the work was performed. - /// * `nonce` - The nonce used for the proof of work. - /// - /// # Returns - /// - /// * `DispatchResult` - The result of the dispatch. - /// - /// # Errors - /// - - /// - `SameColdkey`: The old coldkey is the same as the new coldkey. - /// - `DuplicateColdkey`: The new coldkey is already in the list of destination coldkeys. - /// - `MaxColdkeyDestinationsReached`: There are already the maximum allowed destination coldkeys for the old coldkey. - /// - `InsufficientBalanceToPerformColdkeySwap`: The old coldkey doesn't have the minimum required TAO balance. - /// - `InvalidDifficulty`: The proof of work is invalid or doesn't meet the required difficulty. - /// - /// # Notes - /// - /// This function ensures that the new coldkey is not already in the list of destination coldkeys. - /// It also checks for a minimum TAO balance and verifies the proof of work. - /// The difficulty of the proof of work increases exponentially with each subsequent call. - pub fn do_schedule_coldkey_swap( - old_coldkey: &T::AccountId, - new_coldkey: &T::AccountId, - work: Vec, - block_number: u64, - nonce: u64, - ) -> DispatchResult { - ensure!(old_coldkey != new_coldkey, Error::::SameColdkey); - - // Check if the old_coldkey is a subnet owner for any network - let is_subnet_owner = (0..=TotalNetworks::::get()) - .any(|netuid| SubnetOwner::::get(netuid) == *old_coldkey); - - // Check if the old_coldkey has more than 500 TAO delegated - let total_delegated = Self::get_total_delegated_stake(old_coldkey); - let has_sufficient_delegation = total_delegated > 500_000_000_000; // 500 TAO in RAO - - // Only check the minimum balance if the old_coldkey is not a subnet owner - // and doesn't have sufficient delegation - if !(is_subnet_owner || has_sufficient_delegation) { - ensure!( - Self::meets_min_allowed_coldkey_balance(old_coldkey), - Error::::InsufficientBalanceToPerformColdkeySwap - ); - } - - // Get current destination coldkeys - let mut destination_coldkeys: Vec = - ColdkeySwapDestinations::::get(old_coldkey.clone()); - - // Calculate difficulty based on the number of existing destination coldkeys - let difficulty = Self::calculate_pow_difficulty(destination_coldkeys.len() as u32); - let work_hash = Self::vec_to_hash(work.clone()); - ensure!( - Self::hash_meets_difficulty(&work_hash, difficulty), - Error::::InvalidDifficulty - ); - - // Verify work is the product of the nonce, the block number, and coldkey - let seal = Self::create_seal_hash(block_number, nonce, old_coldkey); - ensure!(seal == work_hash, Error::::InvalidSeal); - - // Check if the new coldkey is already in the swap wallets list - ensure!( - !destination_coldkeys.contains(new_coldkey), - Error::::DuplicateColdkey - ); - - // If the destinations keys are empty or have less than the maximum allowed, we will add the new coldkey to the list - const MAX_COLDKEY_DESTINATIONS: usize = 10; - - if destination_coldkeys.len() < MAX_COLDKEY_DESTINATIONS { - destination_coldkeys.push(new_coldkey.clone()); - ColdkeySwapDestinations::::insert(old_coldkey.clone(), destination_coldkeys.clone()); - } else { - return Err(Error::::MaxColdkeyDestinationsReached.into()); - } - - // It is the first time we have seen this key - if destination_coldkeys.len() == 1_usize { - // Set the arbitration block for this coldkey - let arbitration_block: u64 = - Self::get_current_block_as_u64().saturating_add(ArbitrationPeriod::::get()); - ColdkeyArbitrationBlock::::insert(old_coldkey.clone(), arbitration_block); - - // Update the list of coldkeys to arbitrate on this block - let mut key_to_arbitrate_on_this_block: Vec = - ColdkeysToSwapAtBlock::::get(arbitration_block); - if !key_to_arbitrate_on_this_block.contains(old_coldkey) { - key_to_arbitrate_on_this_block.push(old_coldkey.clone()); - } - ColdkeysToSwapAtBlock::::insert(arbitration_block, key_to_arbitrate_on_this_block); - } - - // Emit an event indicating that a coldkey swap has been scheduled - Self::deposit_event(Event::ColdkeySwapScheduled { - old_coldkey: old_coldkey.clone(), - new_coldkey: new_coldkey.clone(), - arbitration_block: ColdkeyArbitrationBlock::::get(old_coldkey), - }); - - Ok(()) - } - - /// Calculate the proof of work difficulty based on the number of swap attempts - #[allow(clippy::arithmetic_side_effects)] - pub fn calculate_pow_difficulty(swap_attempts: u32) -> U256 { - let base_difficulty: U256 = U256::from(BaseDifficulty::::get()); // Base difficulty - base_difficulty.saturating_mul(U256::from(2).pow(U256::from(swap_attempts))) - } - - /// Arbitrates coldkeys that are scheduled to be swapped on this block. - /// - /// This function retrieves the list of coldkeys scheduled to be swapped on the current block, - /// and processes each coldkey by either extending the arbitration period or performing the swap - /// to the new coldkey. - /// - /// # Returns - /// - /// * `Weight` - The total weight consumed by this operation - pub fn swap_coldkeys_this_block(_weight_limit: &Weight) -> Result { - let mut weight_used = frame_support::weights::Weight::from_parts(0, 0); - - let current_block: u64 = Self::get_current_block_as_u64(); - log::debug!("Swapping coldkeys for block: {:?}", current_block); - - let source_coldkeys: Vec = ColdkeysToSwapAtBlock::::get(current_block); - ColdkeysToSwapAtBlock::::remove(current_block); - weight_used = weight_used.saturating_add(T::DbWeight::get().reads_writes(1, 1)); - - let mut keys_swapped = 0u64; - for coldkey_i in source_coldkeys.iter() { - // TODO: need a sane way to terminate early without locking users in. - // we should update the swap time - // if weight_used.ref_time() > weight_limit.ref_time() { - // log::warn!("Could not finish swapping all coldkeys this block due to weight limit, breaking after swapping {} keys.", keys_swapped); - // break; - // } - - let destinations_coldkeys: Vec = - ColdkeySwapDestinations::::get(coldkey_i); - weight_used = weight_used.saturating_add(T::DbWeight::get().reads(1)); - - if destinations_coldkeys.len() > 1 { - // Do not remove ColdkeySwapDestinations if there are multiple destinations - ColdkeyArbitrationBlock::::insert(coldkey_i.clone(), u64::MAX); - Self::deposit_event(Event::ArbitrationPeriodExtended { - coldkey: coldkey_i.clone(), - }); - } else if let Some(new_coldkey) = destinations_coldkeys.first() { - // Only remove ColdkeySwapDestinations if there's a single destination - ColdkeySwapDestinations::::remove(&coldkey_i); - weight_used = weight_used.saturating_add(T::DbWeight::get().writes(1)); - Self::perform_swap_coldkey(coldkey_i, new_coldkey).map(|weight| { - weight_used = weight_used.saturating_add(weight); - keys_swapped = keys_swapped.saturating_add(1); - })?; - } - } - - Ok(weight_used) - } - - pub fn perform_swap_coldkey( - old_coldkey: &T::AccountId, - new_coldkey: &T::AccountId, - ) -> Result { - log::info!( - "Performing swap for coldkey: {:?} to {:?}", - old_coldkey, - new_coldkey - ); - // Init the weight. - let mut weight = frame_support::weights::Weight::from_parts(0, 0); - - // Swap coldkey references in storage maps - // NOTE The order of these calls is important - Self::swap_stake_for_coldkey(old_coldkey, new_coldkey, &mut weight); - Self::swap_total_hotkey_coldkey_stakes_this_interval_for_coldkey( - old_coldkey, - new_coldkey, - &mut weight, - ); - Self::swap_subnet_owner_for_coldkey(old_coldkey, new_coldkey, &mut weight); - - // Transfer any remaining balance from old_coldkey to new_coldkey - let remaining_balance = Self::get_coldkey_balance(old_coldkey); - if remaining_balance > 0 { - if let Err(e) = Self::kill_coldkey_account(old_coldkey, remaining_balance) { - return Err(e.into()); - } - Self::add_balance_to_coldkey_account(new_coldkey, remaining_balance); - } - - // Swap the coldkey. - let total_balance: u64 = Self::get_coldkey_balance(old_coldkey); - if total_balance > 0 { - // Attempt to transfer the entire total balance to new_coldkey. - T::Currency::transfer( - old_coldkey, - new_coldkey, - total_balance, - Preservation::Expendable, - )?; - } - - Ok(weight) - } - - /// Retrieves the network membership status for a given hotkey. - /// - /// # Arguments - /// - /// * `old_hotkey` - The hotkey to check for network membership. - /// - /// # Returns - /// - /// * `Vec` - A vector of network IDs where the hotkey is a member. - pub fn get_netuid_is_member(old_hotkey: &T::AccountId, weight: &mut Weight) -> Vec { - let netuid_is_member: Vec = - as IterableStorageDoubleMap<_, _, _>>::iter_prefix(old_hotkey) - .map(|(netuid, _)| netuid) - .collect(); - weight.saturating_accrue(T::DbWeight::get().reads(netuid_is_member.len() as u64)); - netuid_is_member - } - - /// Swaps the owner of the hotkey. - /// - /// # Arguments - /// - /// * `old_hotkey` - The old hotkey. - /// * `new_hotkey` - The new hotkey. - /// * `coldkey` - The coldkey owning the hotkey. - /// * `weight` - The weight of the transaction. - /// - pub fn swap_owner( - old_hotkey: &T::AccountId, - new_hotkey: &T::AccountId, - coldkey: &T::AccountId, - weight: &mut Weight, - ) { - Owner::::remove(old_hotkey); - Owner::::insert(new_hotkey, coldkey.clone()); - - // Update OwnedHotkeys map - let mut hotkeys = OwnedHotkeys::::get(coldkey); - if !hotkeys.contains(new_hotkey) { - hotkeys.push(new_hotkey.clone()); - } - hotkeys.retain(|hk| *hk != *old_hotkey); - OwnedHotkeys::::insert(coldkey, hotkeys); - - weight.saturating_accrue(T::DbWeight::get().writes(2)); - } - - /// Swaps the total stake of the hotkey. - /// - /// # Arguments - /// - /// * `old_hotkey` - The old hotkey. - /// * `new_hotkey` - The new hotkey. - /// * `weight` - The weight of the transaction. - /// - /// # Weight Calculation - /// - /// * Reads: 1 if the old hotkey exists, otherwise 1 for the failed read. - /// * Writes: 2 if the old hotkey exists (one for removal and one for insertion). - pub fn swap_total_hotkey_stake( - old_hotkey: &T::AccountId, - new_hotkey: &T::AccountId, - weight: &mut Weight, - ) { - if let Ok(total_hotkey_stake) = TotalHotkeyStake::::try_get(old_hotkey) { - TotalHotkeyStake::::remove(old_hotkey); - TotalHotkeyStake::::insert(new_hotkey, total_hotkey_stake); - weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); - } else { - weight.saturating_accrue(T::DbWeight::get().reads(1)); - } - } - - /// Swaps the delegates of the hotkey. - /// - /// # Arguments - /// - /// * `old_hotkey` - The old hotkey. - /// * `new_hotkey` - The new hotkey. - /// * `weight` - The weight of the transaction. - /// - /// # Weight Calculation - /// - /// * Reads: 1 if the old hotkey exists, otherwise 1 for the failed read. - /// * Writes: 2 if the old hotkey exists (one for removal and one for insertion). - pub fn swap_delegates( - old_hotkey: &T::AccountId, - new_hotkey: &T::AccountId, - weight: &mut Weight, - ) { - if let Ok(delegate_take) = Delegates::::try_get(old_hotkey) { - Delegates::::remove(old_hotkey); - Delegates::::insert(new_hotkey, delegate_take); - weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); - } else { - weight.saturating_accrue(T::DbWeight::get().reads(1)); - } - } - - /// Swaps the stake of the hotkey. - /// - /// # Arguments - /// - /// * `old_hotkey` - The old hotkey. - /// * `new_hotkey` - The new hotkey. - /// * `weight` - The weight of the transaction. - pub fn swap_stake(old_hotkey: &T::AccountId, new_hotkey: &T::AccountId, weight: &mut Weight) { - let mut writes: u64 = 0; - let stakes: Vec<(T::AccountId, u64)> = Stake::::iter_prefix(old_hotkey).collect(); - let stake_count = stakes.len() as u32; - - for (coldkey, stake_amount) in stakes { - Stake::::insert(new_hotkey, &coldkey, stake_amount); - writes = writes.saturating_add(1u64); // One write for insert - - // Update StakingHotkeys map - let mut staking_hotkeys = StakingHotkeys::::get(&coldkey); - if !staking_hotkeys.contains(new_hotkey) { - staking_hotkeys.push(new_hotkey.clone()); - writes = writes.saturating_add(1u64); // One write for insert - } - if let Some(pos) = staking_hotkeys.iter().position(|x| x == old_hotkey) { - staking_hotkeys.remove(pos); - writes = writes.saturating_add(1u64); // One write for remove - } - StakingHotkeys::::insert(coldkey.clone(), staking_hotkeys); - writes = writes.saturating_add(1u64); // One write for insert - } - - // Clear the prefix for the old hotkey after transferring all stakes - let _ = Stake::::clear_prefix(old_hotkey, stake_count, None); - writes = writes.saturating_add(1); // One write for insert; // One write for clear_prefix - - // TODO: Remove all entries for old hotkey from StakingHotkeys map - - weight.saturating_accrue(T::DbWeight::get().writes(writes)); - } - - /// Swaps the network membership status of the hotkey. - /// - /// # Arguments - /// - /// * `old_hotkey` - The old hotkey. - /// * `new_hotkey` - The new hotkey. - /// * `netuid_is_member` - A vector of network IDs where the hotkey is a member. - /// * `weight` - The weight of the transaction. - pub fn swap_is_network_member( - old_hotkey: &T::AccountId, - new_hotkey: &T::AccountId, - netuid_is_member: &[u16], - weight: &mut Weight, - ) { - let _ = IsNetworkMember::::clear_prefix(old_hotkey, netuid_is_member.len() as u32, None); - weight.saturating_accrue(T::DbWeight::get().writes(netuid_is_member.len() as u64)); - for netuid in netuid_is_member.iter() { - IsNetworkMember::::insert(new_hotkey, netuid, true); - weight.saturating_accrue(T::DbWeight::get().writes(1)); - } - } - - /// Swaps the axons of the hotkey. - /// - /// # Arguments - /// - /// * `old_hotkey` - The old hotkey. - /// * `new_hotkey` - The new hotkey. - /// * `netuid_is_member` - A vector of network IDs where the hotkey is a member. - /// * `weight` - The weight of the transaction. - /// - /// # Weight Calculation - /// - /// * Reads: 1 for each network ID if the old hotkey exists in that network. - /// * Writes: 2 for each network ID if the old hotkey exists in that network (one for removal and one for insertion). - pub fn swap_axons( - old_hotkey: &T::AccountId, - new_hotkey: &T::AccountId, - netuid_is_member: &[u16], - weight: &mut Weight, - ) { - for netuid in netuid_is_member.iter() { - if let Ok(axon_info) = Axons::::try_get(netuid, old_hotkey) { - Axons::::remove(netuid, old_hotkey); - Axons::::insert(netuid, new_hotkey, axon_info); - weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); - } else { - weight.saturating_accrue(T::DbWeight::get().reads(1)); - } - } - } - - /// Swaps the references in the keys storage map of the hotkey. - /// - /// # Arguments - /// - /// * `old_hotkey` - The old hotkey. - /// * `new_hotkey` - The new hotkey. - /// * `netuid_is_member` - A vector of network IDs where the hotkey is a member. - /// * `weight` - The weight of the transaction. - pub fn swap_keys( - old_hotkey: &T::AccountId, - new_hotkey: &T::AccountId, - netuid_is_member: &[u16], - weight: &mut Weight, - ) { - let mut writes: u64 = 0; - for netuid in netuid_is_member { - let keys: Vec<(u16, T::AccountId)> = Keys::::iter_prefix(netuid).collect(); - for (uid, key) in keys { - if key == *old_hotkey { - log::info!("old hotkey found: {:?}", old_hotkey); - Keys::::insert(netuid, uid, new_hotkey.clone()); - } - writes = writes.saturating_add(2u64); - } - } - log::info!("writes: {:?}", writes); - weight.saturating_accrue(T::DbWeight::get().writes(writes)); - } - - /// Swaps the loaded emission of the hotkey. - /// - /// # Arguments - /// - /// * `old_hotkey` - The old hotkey. - /// * `new_hotkey` - The new hotkey. - /// * `netuid_is_member` - A vector of network IDs where the hotkey is a member. - /// * `weight` - The weight of the transaction. - /// - pub fn swap_loaded_emission( - old_hotkey: &T::AccountId, - new_hotkey: &T::AccountId, - netuid_is_member: &[u16], - weight: &mut Weight, - ) { - for netuid in netuid_is_member { - if let Some(mut emissions) = LoadedEmission::::get(netuid) { - for emission in emissions.iter_mut() { - if emission.0 == *old_hotkey { - emission.0 = new_hotkey.clone(); - } - } - LoadedEmission::::insert(netuid, emissions); - } - } - weight.saturating_accrue(T::DbWeight::get().writes(netuid_is_member.len() as u64)); - } - - /// Swaps the UIDs of the hotkey. - /// - /// # Arguments - /// - /// * `old_hotkey` - The old hotkey. - /// * `new_hotkey` - The new hotkey. - /// * `netuid_is_member` - A vector of network IDs where the hotkey is a member. - /// * `weight` - The weight of the transaction. - /// - pub fn swap_uids( - old_hotkey: &T::AccountId, - new_hotkey: &T::AccountId, - netuid_is_member: &[u16], - weight: &mut Weight, - ) { - for netuid in netuid_is_member.iter() { - if let Ok(uid) = Uids::::try_get(netuid, old_hotkey) { - Uids::::remove(netuid, old_hotkey); - Uids::::insert(netuid, new_hotkey, uid); - weight.saturating_accrue(T::DbWeight::get().writes(2)); - } - } - } - - /// Swaps the Prometheus data of the hotkey. - /// - /// # Arguments - /// - /// * `old_hotkey` - The old hotkey. - /// * `new_hotkey` - The new hotkey. - /// * `netuid_is_member` - A vector of network IDs where the hotkey is a member. - /// * `weight` - The weight of the transaction. - /// - /// # Weight Calculation - /// - /// * Reads: 1 for each network ID if the old hotkey exists in that network. - /// * Writes: 2 for each network ID if the old hotkey exists in that network (one for removal and one for insertion). - pub fn swap_prometheus( - old_hotkey: &T::AccountId, - new_hotkey: &T::AccountId, - netuid_is_member: &[u16], - weight: &mut Weight, - ) { - for netuid in netuid_is_member.iter() { - if let Ok(prometheus_info) = Prometheus::::try_get(netuid, old_hotkey) { - Prometheus::::remove(netuid, old_hotkey); - Prometheus::::insert(netuid, new_hotkey, prometheus_info); - weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); - } else { - weight.saturating_accrue(T::DbWeight::get().reads(1)); - } - } - } - - /// Swaps the total hotkey-coldkey stakes for the current interval. - /// - /// # Arguments - /// - /// * `old_hotkey` - The old hotkey. - /// * `new_hotkey` - The new hotkey. - /// * `weight` - The weight of the transaction. - /// - pub fn swap_total_hotkey_coldkey_stakes_this_interval( - old_hotkey: &T::AccountId, - new_hotkey: &T::AccountId, - weight: &mut Weight, - ) { - let stakes: Vec<(T::AccountId, (u64, u64))> = - TotalHotkeyColdkeyStakesThisInterval::::iter_prefix(old_hotkey).collect(); - log::info!("Stakes to swap: {:?}", stakes); - for (coldkey, stake) in stakes { - log::info!( - "Swapping stake for coldkey: {:?}, stake: {:?}", - coldkey, - stake - ); - TotalHotkeyColdkeyStakesThisInterval::::insert(new_hotkey, &coldkey, stake); - TotalHotkeyColdkeyStakesThisInterval::::remove(old_hotkey, &coldkey); - weight.saturating_accrue(T::DbWeight::get().writes(2)); // One write for insert and one for remove - } - } - - /// Swaps the total stake associated with a coldkey from the old coldkey to the new coldkey. - /// - /// # Arguments - /// - /// * `old_coldkey` - The AccountId of the old coldkey. - /// * `new_coldkey` - The AccountId of the new coldkey. - /// * `weight` - Mutable reference to the weight of the transaction. - /// - /// # Effects - /// - /// * Removes the total stake from the old coldkey. - /// * Inserts the total stake for the new coldkey. - /// * Updates the transaction weight. - pub fn swap_total_coldkey_stake( - old_coldkey: &T::AccountId, - new_coldkey: &T::AccountId, - weight: &mut Weight, - ) { - let stake = TotalColdkeyStake::::get(old_coldkey); - TotalColdkeyStake::::remove(old_coldkey); - TotalColdkeyStake::::insert(new_coldkey, stake); - weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); - } - - /// Swaps the stake associated with a coldkey from the old coldkey to the new coldkey. - /// - /// # Arguments - /// - /// * `old_coldkey` - The AccountId of the old coldkey. - /// * `new_coldkey` - The AccountId of the new coldkey. - /// * `weight` - Mutable reference to the weight of the transaction. - /// - /// # Effects - /// - /// * Transfers all stakes from the old coldkey to the new coldkey. - /// * Updates the ownership of hotkeys. - /// * Updates the total stake for both old and new coldkeys. - /// * Updates the transaction weight. - /// - - pub fn swap_stake_for_coldkey( - old_coldkey: &T::AccountId, - new_coldkey: &T::AccountId, - weight: &mut Weight, - ) { - // Retrieve the list of hotkeys owned by the old coldkey - let old_owned_hotkeys: Vec = OwnedHotkeys::::get(old_coldkey); - - // Initialize the total transferred stake to zero - let mut total_transferred_stake: u64 = 0u64; - - // Log the total stake of old and new coldkeys before the swap - log::info!( - "Before swap - Old coldkey total stake: {}", - TotalColdkeyStake::::get(old_coldkey) - ); - log::info!( - "Before swap - New coldkey total stake: {}", - TotalColdkeyStake::::get(new_coldkey) - ); - - // Iterate over each hotkey owned by the old coldkey - for hotkey in old_owned_hotkeys.iter() { - // Retrieve and remove the stake associated with the hotkey and old coldkey - let stake: u64 = Stake::::take(hotkey, old_coldkey); - log::info!("Transferring stake for hotkey {:?}: {}", hotkey, stake); - if stake > 0 { - // Insert the stake for the hotkey and new coldkey - let old_stake = Stake::::get(hotkey, new_coldkey); - Stake::::insert(hotkey, new_coldkey, stake.saturating_add(old_stake)); - total_transferred_stake = total_transferred_stake.saturating_add(stake); - - // Update the owner of the hotkey to the new coldkey - Owner::::insert(hotkey, new_coldkey); - - // Update the transaction weight - weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2)); - } - } - log::info!( - "Starting transfer of delegated stakes for old coldkey: {:?}", - old_coldkey - ); - - for staking_hotkey in StakingHotkeys::::get(old_coldkey) { - log::info!("Processing staking hotkey: {:?}", staking_hotkey); - if Stake::::contains_key(staking_hotkey.clone(), old_coldkey) { - let hotkey = &staking_hotkey; - // Retrieve and remove the stake associated with the hotkey and old coldkey - let stake: u64 = Stake::::get(hotkey, old_coldkey); - Stake::::remove(hotkey, old_coldkey); - log::info!( - "Transferring delegated stake for hotkey {:?}: {}", - hotkey, - stake - ); - if stake > 0 { - // Insert the stake for the hotkey and new coldkey - let old_stake = Stake::::get(hotkey, new_coldkey); - Stake::::insert(hotkey, new_coldkey, stake.saturating_add(old_stake)); - total_transferred_stake = total_transferred_stake.saturating_add(stake); - log::info!( - "Updated stake for hotkey {:?} under new coldkey {:?}: {}", - hotkey, - new_coldkey, - stake.saturating_add(old_stake) - ); - - // Update the transaction weight - weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 1)); - } - } else { - log::info!( - "No stake found for staking hotkey {:?} under old coldkey {:?}", - staking_hotkey, - old_coldkey - ); - weight.saturating_accrue(T::DbWeight::get().reads(1)); - } - } - - log::info!( - "Completed transfer of delegated stakes for old coldkey: {:?}", - old_coldkey - ); - - // Log the total transferred stake - log::info!("Total transferred stake: {}", total_transferred_stake); - - // Update the total stake for both old and new coldkeys if any stake was transferred - if total_transferred_stake > 0 { - let old_coldkey_stake: u64 = TotalColdkeyStake::::take(old_coldkey); // Remove it here. - let new_coldkey_stake: u64 = TotalColdkeyStake::::get(new_coldkey); - - TotalColdkeyStake::::insert(old_coldkey, 0); - TotalColdkeyStake::::insert( - new_coldkey, - new_coldkey_stake.saturating_add(old_coldkey_stake), - ); - - log::info!("Updated old coldkey stake from {} to 0", old_coldkey_stake); - log::info!( - "Updated new coldkey stake from {} to {}", - new_coldkey_stake, - new_coldkey_stake.saturating_add(old_coldkey_stake) - ); - - // Update the transaction weight - weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2)); - } - - // Update the list of owned hotkeys for both old and new coldkeys - - let mut new_owned_hotkeys = OwnedHotkeys::::get(new_coldkey); - for hotkey in old_owned_hotkeys { - if !new_owned_hotkeys.contains(&hotkey) { - new_owned_hotkeys.push(hotkey); - } - } - - OwnedHotkeys::::insert(new_coldkey, new_owned_hotkeys); - OwnedHotkeys::::remove(old_coldkey); - weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); - - // Update the staking hotkeys for both old and new coldkeys - let staking_hotkeys: Vec = StakingHotkeys::::get(old_coldkey); - - let mut existing_staking_hotkeys = StakingHotkeys::::get(new_coldkey); - for hotkey in staking_hotkeys { - if !existing_staking_hotkeys.contains(&hotkey) { - existing_staking_hotkeys.push(hotkey); - } - } - - StakingHotkeys::::remove(old_coldkey); - StakingHotkeys::::insert(new_coldkey, existing_staking_hotkeys); - weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); - - // Log the total stake of old and new coldkeys after the swap - log::info!( - "After swap - Old coldkey total stake: {}", - TotalColdkeyStake::::get(old_coldkey) - ); - log::info!( - "After swap - New coldkey total stake: {}", - TotalColdkeyStake::::get(new_coldkey) - ); - } - - /// Swaps the total hotkey-coldkey stakes for the current interval from the old coldkey to the new coldkey. - /// - /// # Arguments - /// - /// * `old_coldkey` - The AccountId of the old coldkey. - /// * `new_coldkey` - The AccountId of the new coldkey. - /// * `weight` - Mutable reference to the weight of the transaction. - /// - /// # Effects - /// - /// * Removes all total hotkey-coldkey stakes for the current interval associated with the old coldkey. - /// * Inserts all total hotkey-coldkey stakes for the current interval for the new coldkey. - /// * Updates the transaction weight. - pub fn swap_total_hotkey_coldkey_stakes_this_interval_for_coldkey( - old_coldkey: &T::AccountId, - new_coldkey: &T::AccountId, - weight: &mut Weight, - ) { - weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 0)); - for hotkey in OwnedHotkeys::::get(old_coldkey).iter() { - let (stake, block) = - TotalHotkeyColdkeyStakesThisInterval::::get(&hotkey, old_coldkey); - TotalHotkeyColdkeyStakesThisInterval::::remove(&hotkey, old_coldkey); - TotalHotkeyColdkeyStakesThisInterval::::insert(&hotkey, new_coldkey, (stake, block)); - weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2)); - } - } - - /// Checks if a coldkey has any associated hotkeys. - /// - /// # Arguments - /// - /// * `coldkey` - The AccountId of the coldkey to check. - /// - /// # Returns - /// - /// * `bool` - True if the coldkey has any associated hotkeys, false otherwise. - pub fn coldkey_has_associated_hotkeys(coldkey: &T::AccountId) -> bool { - !StakingHotkeys::::get(coldkey).is_empty() - } - - /// Swaps the subnet owner from the old coldkey to the new coldkey for all networks where the old coldkey is the owner. - /// - /// # Arguments - /// - /// * `old_coldkey` - The AccountId of the old coldkey. - /// * `new_coldkey` - The AccountId of the new coldkey. - /// * `weight` - Mutable reference to the weight of the transaction. - /// - /// # Effects - /// - /// * Updates the subnet owner to the new coldkey for all networks where the old coldkey was the owner. - /// * Updates the transaction weight. - pub fn swap_subnet_owner_for_coldkey( - old_coldkey: &T::AccountId, - new_coldkey: &T::AccountId, - weight: &mut Weight, - ) { - for netuid in 0..=TotalNetworks::::get() { - let subnet_owner = SubnetOwner::::get(netuid); - if subnet_owner == *old_coldkey { - SubnetOwner::::insert(netuid, new_coldkey.clone()); - weight.saturating_accrue(T::DbWeight::get().writes(1)); - } - } - weight.saturating_accrue(T::DbWeight::get().reads(TotalNetworks::::get() as u64)); - } - - pub fn swap_senate_member( - old_hotkey: &T::AccountId, - new_hotkey: &T::AccountId, - weight: &mut Weight, - ) -> DispatchResult { - weight.saturating_accrue(T::DbWeight::get().reads(1)); - if T::SenateMembers::is_member(old_hotkey) { - T::SenateMembers::swap_member(old_hotkey, new_hotkey).map_err(|e| e.error)?; - weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); - } - Ok(()) - } -} diff --git a/pallets/subtensor/src/swap/mod.rs b/pallets/subtensor/src/swap/mod.rs new file mode 100644 index 000000000..0e71b1b1d --- /dev/null +++ b/pallets/subtensor/src/swap/mod.rs @@ -0,0 +1,3 @@ +use super::*; +pub mod swap_coldkey; +pub mod swap_hotkey; \ No newline at end of file diff --git a/pallets/subtensor/src/swap/swap_coldkey.rs b/pallets/subtensor/src/swap/swap_coldkey.rs new file mode 100644 index 000000000..83bad5134 --- /dev/null +++ b/pallets/subtensor/src/swap/swap_coldkey.rs @@ -0,0 +1,391 @@ +use super::*; +use frame_support::traits::fungible::Mutate; +use frame_support::traits::tokens::Preservation; +use frame_support::{storage::IterableStorageDoubleMap, weights::Weight}; +use sp_core::Get; + +impl Pallet { + + + /// Swaps the coldkey associated with a set of hotkeys from an old coldkey to a new coldkey. + /// + /// # Arguments + /// + /// * `origin` - The origin of the call, which must be signed by the old coldkey. + /// * `old_coldkey` - The account ID of the old coldkey. + /// * `new_coldkey` - The account ID of the new coldkey. + /// + /// # Returns + /// + /// Returns a `DispatchResultWithPostInfo` indicating success or failure, along with the weight consumed. + /// + /// # Errors + /// + /// This function will return an error if: + /// - The caller is not the old coldkey. + /// - The new coldkey is the same as the old coldkey. + /// - The new coldkey is already associated with other hotkeys. + /// - The transaction rate limit for coldkey swaps has been exceeded. + /// - There's not enough balance to pay for the swap. + /// + /// # Events + /// + /// Emits a `ColdkeySwapped` event when successful. + /// + /// # Weight + /// + /// Weight is tracked and updated throughout the function execution. + pub fn do_swap_coldkey( + origin: T::RuntimeOrigin, + new_coldkey: &T::AccountId, + ) -> DispatchResultWithPostInfo { + let old_coldkey = ensure_signed(origin)?; + let mut weight: Weight = T::DbWeight::get().reads(2); + + // Check that the coldkey is a new key (does not exist elsewhere.) + ensure!( + !Self::coldkey_has_associated_hotkeys(new_coldkey), + Error::::ColdKeyAlreadyAssociated + ); + // Check that the new coldkey is not a hotkey. + ensure!( + !Self::hotkey_account_exists(new_coldkey), + Error::::ColdKeyAlreadyAssociated + ); + + // Calculate and charge the swap fee + let swap_cost = Self::get_key_swap_cost(); + log::debug!("Coldkey swap cost: {:?}", swap_cost); + + ensure!( + Self::can_remove_balance_from_coldkey_account(&old_coldkey, swap_cost), + Error::::NotEnoughBalanceToPaySwapColdKey + ); + let actual_burn_amount = + Self::remove_balance_from_coldkey_account(&old_coldkey, swap_cost)?; + Self::burn_tokens(actual_burn_amount); + + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); + + // Actually do the swap. + weight = weight.saturating_add( + Self::perform_swap_coldkey(&old_coldkey, new_coldkey) + .map_err(|_| Error::::ColdkeySwapError)?, + ); + + Self::set_last_tx_block(new_coldkey, Self::get_current_block_as_u64()); + weight.saturating_accrue(T::DbWeight::get().writes(1)); + + Self::deposit_event(Event::ColdkeySwapped { + old_coldkey: old_coldkey.clone(), + new_coldkey: new_coldkey.clone(), + }); + + Ok(Some(weight).into()) + } + + pub fn perform_swap_coldkey( + old_coldkey: &T::AccountId, + new_coldkey: &T::AccountId, + ) -> Result { + log::info!( + "Performing swap for coldkey: {:?} to {:?}", + old_coldkey, + new_coldkey + ); + // Init the weight. + let mut weight = frame_support::weights::Weight::from_parts(0, 0); + + // Swap coldkey references in storage maps + // NOTE The order of these calls is important + Self::swap_stake_for_coldkey(old_coldkey, new_coldkey, &mut weight); + Self::swap_total_hotkey_coldkey_stakes_this_interval_for_coldkey( + old_coldkey, + new_coldkey, + &mut weight, + ); + Self::swap_subnet_owner_for_coldkey(old_coldkey, new_coldkey, &mut weight); + + // Transfer any remaining balance from old_coldkey to new_coldkey + let remaining_balance = Self::get_coldkey_balance(old_coldkey); + if remaining_balance > 0 { + if let Err(e) = Self::kill_coldkey_account(old_coldkey, remaining_balance) { + return Err(e.into()); + } + Self::add_balance_to_coldkey_account(new_coldkey, remaining_balance); + } + + // Swap the coldkey. + let total_balance: u64 = Self::get_coldkey_balance(old_coldkey); + if total_balance > 0 { + // Attempt to transfer the entire total balance to new_coldkey. + T::Currency::transfer( + old_coldkey, + new_coldkey, + total_balance, + Preservation::Expendable, + )?; + } + + Ok(weight) + } + + + /// Swaps the total stake associated with a coldkey from the old coldkey to the new coldkey. + /// + /// # Arguments + /// + /// * `old_coldkey` - The AccountId of the old coldkey. + /// * `new_coldkey` - The AccountId of the new coldkey. + /// * `weight` - Mutable reference to the weight of the transaction. + /// + /// # Effects + /// + /// * Removes the total stake from the old coldkey. + /// * Inserts the total stake for the new coldkey. + /// * Updates the transaction weight. + pub fn swap_total_coldkey_stake( + old_coldkey: &T::AccountId, + new_coldkey: &T::AccountId, + weight: &mut Weight, + ) { + let stake = TotalColdkeyStake::::get(old_coldkey); + TotalColdkeyStake::::remove(old_coldkey); + TotalColdkeyStake::::insert(new_coldkey, stake); + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); + } + + /// Swaps the stake associated with a coldkey from the old coldkey to the new coldkey. + /// + /// # Arguments + /// + /// * `old_coldkey` - The AccountId of the old coldkey. + /// * `new_coldkey` - The AccountId of the new coldkey. + /// * `weight` - Mutable reference to the weight of the transaction. + /// + /// # Effects + /// + /// * Transfers all stakes from the old coldkey to the new coldkey. + /// * Updates the ownership of hotkeys. + /// * Updates the total stake for both old and new coldkeys. + /// * Updates the transaction weight. + /// + + pub fn swap_stake_for_coldkey( + old_coldkey: &T::AccountId, + new_coldkey: &T::AccountId, + weight: &mut Weight, + ) { + // Retrieve the list of hotkeys owned by the old coldkey + let old_owned_hotkeys: Vec = OwnedHotkeys::::get(old_coldkey); + + // Initialize the total transferred stake to zero + let mut total_transferred_stake: u64 = 0u64; + + // Log the total stake of old and new coldkeys before the swap + log::info!( + "Before swap - Old coldkey total stake: {}", + TotalColdkeyStake::::get(old_coldkey) + ); + log::info!( + "Before swap - New coldkey total stake: {}", + TotalColdkeyStake::::get(new_coldkey) + ); + + // Iterate over each hotkey owned by the old coldkey + for hotkey in old_owned_hotkeys.iter() { + // Retrieve and remove the stake associated with the hotkey and old coldkey + let stake: u64 = Stake::::take(hotkey, old_coldkey); + log::info!("Transferring stake for hotkey {:?}: {}", hotkey, stake); + if stake > 0 { + // Insert the stake for the hotkey and new coldkey + let old_stake = Stake::::get(hotkey, new_coldkey); + Stake::::insert(hotkey, new_coldkey, stake.saturating_add(old_stake)); + total_transferred_stake = total_transferred_stake.saturating_add(stake); + + // Update the owner of the hotkey to the new coldkey + Owner::::insert(hotkey, new_coldkey); + + // Update the transaction weight + weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2)); + } + } + log::info!( + "Starting transfer of delegated stakes for old coldkey: {:?}", + old_coldkey + ); + + for staking_hotkey in StakingHotkeys::::get(old_coldkey) { + log::info!("Processing staking hotkey: {:?}", staking_hotkey); + if Stake::::contains_key(staking_hotkey.clone(), old_coldkey) { + let hotkey = &staking_hotkey; + // Retrieve and remove the stake associated with the hotkey and old coldkey + let stake: u64 = Stake::::get(hotkey, old_coldkey); + Stake::::remove(hotkey, old_coldkey); + log::info!( + "Transferring delegated stake for hotkey {:?}: {}", + hotkey, + stake + ); + if stake > 0 { + // Insert the stake for the hotkey and new coldkey + let old_stake = Stake::::get(hotkey, new_coldkey); + Stake::::insert(hotkey, new_coldkey, stake.saturating_add(old_stake)); + total_transferred_stake = total_transferred_stake.saturating_add(stake); + log::info!( + "Updated stake for hotkey {:?} under new coldkey {:?}: {}", + hotkey, + new_coldkey, + stake.saturating_add(old_stake) + ); + + // Update the transaction weight + weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 1)); + } + } else { + log::info!( + "No stake found for staking hotkey {:?} under old coldkey {:?}", + staking_hotkey, + old_coldkey + ); + weight.saturating_accrue(T::DbWeight::get().reads(1)); + } + } + + log::info!( + "Completed transfer of delegated stakes for old coldkey: {:?}", + old_coldkey + ); + + // Log the total transferred stake + log::info!("Total transferred stake: {}", total_transferred_stake); + + // Update the total stake for both old and new coldkeys if any stake was transferred + if total_transferred_stake > 0 { + let old_coldkey_stake: u64 = TotalColdkeyStake::::take(old_coldkey); // Remove it here. + let new_coldkey_stake: u64 = TotalColdkeyStake::::get(new_coldkey); + + TotalColdkeyStake::::insert(old_coldkey, 0); + TotalColdkeyStake::::insert( + new_coldkey, + new_coldkey_stake.saturating_add(old_coldkey_stake), + ); + + log::info!("Updated old coldkey stake from {} to 0", old_coldkey_stake); + log::info!( + "Updated new coldkey stake from {} to {}", + new_coldkey_stake, + new_coldkey_stake.saturating_add(old_coldkey_stake) + ); + + // Update the transaction weight + weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2)); + } + + // Update the list of owned hotkeys for both old and new coldkeys + + let mut new_owned_hotkeys = OwnedHotkeys::::get(new_coldkey); + for hotkey in old_owned_hotkeys { + if !new_owned_hotkeys.contains(&hotkey) { + new_owned_hotkeys.push(hotkey); + } + } + + OwnedHotkeys::::insert(new_coldkey, new_owned_hotkeys); + OwnedHotkeys::::remove(old_coldkey); + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); + + // Update the staking hotkeys for both old and new coldkeys + let staking_hotkeys: Vec = StakingHotkeys::::get(old_coldkey); + + let mut existing_staking_hotkeys = StakingHotkeys::::get(new_coldkey); + for hotkey in staking_hotkeys { + if !existing_staking_hotkeys.contains(&hotkey) { + existing_staking_hotkeys.push(hotkey); + } + } + + StakingHotkeys::::remove(old_coldkey); + StakingHotkeys::::insert(new_coldkey, existing_staking_hotkeys); + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); + + // Log the total stake of old and new coldkeys after the swap + log::info!( + "After swap - Old coldkey total stake: {}", + TotalColdkeyStake::::get(old_coldkey) + ); + log::info!( + "After swap - New coldkey total stake: {}", + TotalColdkeyStake::::get(new_coldkey) + ); + } + + /// Swaps the total hotkey-coldkey stakes for the current interval from the old coldkey to the new coldkey. + /// + /// # Arguments + /// + /// * `old_coldkey` - The AccountId of the old coldkey. + /// * `new_coldkey` - The AccountId of the new coldkey. + /// * `weight` - Mutable reference to the weight of the transaction. + /// + /// # Effects + /// + /// * Removes all total hotkey-coldkey stakes for the current interval associated with the old coldkey. + /// * Inserts all total hotkey-coldkey stakes for the current interval for the new coldkey. + /// * Updates the transaction weight. + pub fn swap_total_hotkey_coldkey_stakes_this_interval_for_coldkey( + old_coldkey: &T::AccountId, + new_coldkey: &T::AccountId, + weight: &mut Weight, + ) { + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 0)); + for hotkey in OwnedHotkeys::::get(old_coldkey).iter() { + let (stake, block) = + TotalHotkeyColdkeyStakesThisInterval::::get(&hotkey, old_coldkey); + TotalHotkeyColdkeyStakesThisInterval::::remove(&hotkey, old_coldkey); + TotalHotkeyColdkeyStakesThisInterval::::insert(&hotkey, new_coldkey, (stake, block)); + weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2)); + } + } + + /// Checks if a coldkey has any associated hotkeys. + /// + /// # Arguments + /// + /// * `coldkey` - The AccountId of the coldkey to check. + /// + /// # Returns + /// + /// * `bool` - True if the coldkey has any associated hotkeys, false otherwise. + pub fn coldkey_has_associated_hotkeys(coldkey: &T::AccountId) -> bool { + !StakingHotkeys::::get(coldkey).is_empty() + } + + /// Swaps the subnet owner from the old coldkey to the new coldkey for all networks where the old coldkey is the owner. + /// + /// # Arguments + /// + /// * `old_coldkey` - The AccountId of the old coldkey. + /// * `new_coldkey` - The AccountId of the new coldkey. + /// * `weight` - Mutable reference to the weight of the transaction. + /// + /// # Effects + /// + /// * Updates the subnet owner to the new coldkey for all networks where the old coldkey was the owner. + /// * Updates the transaction weight. + pub fn swap_subnet_owner_for_coldkey( + old_coldkey: &T::AccountId, + new_coldkey: &T::AccountId, + weight: &mut Weight, + ) { + for netuid in 0..=TotalNetworks::::get() { + let subnet_owner = SubnetOwner::::get(netuid); + if subnet_owner == *old_coldkey { + SubnetOwner::::insert(netuid, new_coldkey.clone()); + weight.saturating_accrue(T::DbWeight::get().writes(1)); + } + } + weight.saturating_accrue(T::DbWeight::get().reads(TotalNetworks::::get() as u64)); + } + +} diff --git a/pallets/subtensor/src/swap/swap_hotkey.rs b/pallets/subtensor/src/swap/swap_hotkey.rs new file mode 100644 index 000000000..2755f1c4c --- /dev/null +++ b/pallets/subtensor/src/swap/swap_hotkey.rs @@ -0,0 +1,438 @@ +use super::*; +use frame_support::{storage::IterableStorageDoubleMap, weights::Weight}; +use sp_core::Get; + +impl Pallet { + /// Swaps the hotkey of a coldkey account. + /// + /// # Arguments + /// + /// * `origin` - The origin of the transaction, and also the coldkey account. + /// * `old_hotkey` - The old hotkey to be swapped. + /// * `new_hotkey` - The new hotkey to replace the old one. + /// + /// # Returns + /// + /// * `DispatchResultWithPostInfo` - The result of the dispatch. + /// + /// # Errors + /// + /// * `NonAssociatedColdKey` - If the coldkey does not own the old hotkey. + /// * `HotKeySetTxRateLimitExceeded` - If the transaction rate limit is exceeded. + /// * `NewHotKeyIsSameWithOld` - If the new hotkey is the same as the old hotkey. + /// * `HotKeyAlreadyRegisteredInSubNet` - If the new hotkey is already registered in the subnet. + /// * `NotEnoughBalanceToPaySwapHotKey` - If there is not enough balance to pay for the swap. + pub fn do_swap_hotkey( + origin: T::RuntimeOrigin, + old_hotkey: &T::AccountId, + new_hotkey: &T::AccountId, + ) -> DispatchResultWithPostInfo { + let coldkey = ensure_signed(origin)?; + + let mut weight = T::DbWeight::get().reads(2); + + ensure!(old_hotkey != new_hotkey, Error::::NewHotKeyIsSameWithOld); + ensure!( + !Self::is_hotkey_registered_on_any_network(new_hotkey), + Error::::HotKeyAlreadyRegisteredInSubNet + ); + + weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 0)); + ensure!( + Self::coldkey_owns_hotkey(&coldkey, old_hotkey), + Error::::NonAssociatedColdKey + ); + + let block: u64 = Self::get_current_block_as_u64(); + ensure!( + !Self::exceeds_tx_rate_limit(Self::get_last_tx_block(&coldkey), block), + Error::::HotKeySetTxRateLimitExceeded + ); + + weight.saturating_accrue( + T::DbWeight::get().reads((TotalNetworks::::get().saturating_add(1u16)) as u64), + ); + + let swap_cost = Self::get_key_swap_cost(); + log::debug!("Swap cost: {:?}", swap_cost); + + ensure!( + Self::can_remove_balance_from_coldkey_account(&coldkey, swap_cost), + Error::::NotEnoughBalanceToPaySwapHotKey + ); + let actual_burn_amount = Self::remove_balance_from_coldkey_account(&coldkey, swap_cost)?; + Self::burn_tokens(actual_burn_amount); + + Self::swap_owner(old_hotkey, new_hotkey, &coldkey, &mut weight); + Self::swap_total_hotkey_stake(old_hotkey, new_hotkey, &mut weight); + Self::swap_delegates(old_hotkey, new_hotkey, &mut weight); + Self::swap_stake(old_hotkey, new_hotkey, &mut weight); + + // Store the value of is_network_member for the old key + let netuid_is_member: Vec = Self::get_netuid_is_member(old_hotkey, &mut weight); + + Self::swap_is_network_member(old_hotkey, new_hotkey, &netuid_is_member, &mut weight); + Self::swap_axons(old_hotkey, new_hotkey, &netuid_is_member, &mut weight); + Self::swap_keys(old_hotkey, new_hotkey, &netuid_is_member, &mut weight); + Self::swap_loaded_emission(old_hotkey, new_hotkey, &netuid_is_member, &mut weight); + Self::swap_uids(old_hotkey, new_hotkey, &netuid_is_member, &mut weight); + Self::swap_prometheus(old_hotkey, new_hotkey, &netuid_is_member, &mut weight); + Self::swap_senate_member(old_hotkey, new_hotkey, &mut weight)?; + + Self::swap_total_hotkey_coldkey_stakes_this_interval(old_hotkey, new_hotkey, &mut weight); + + Self::set_last_tx_block(&coldkey, block); + weight.saturating_accrue(T::DbWeight::get().writes(1)); + + Self::deposit_event(Event::HotkeySwapped { + coldkey, + old_hotkey: old_hotkey.clone(), + new_hotkey: new_hotkey.clone(), + }); + + Ok(Some(weight).into()) + } + + /// Retrieves the network membership status for a given hotkey. + /// + /// # Arguments + /// + /// * `old_hotkey` - The hotkey to check for network membership. + /// + /// # Returns + /// + /// * `Vec` - A vector of network IDs where the hotkey is a member. + pub fn get_netuid_is_member(old_hotkey: &T::AccountId, weight: &mut Weight) -> Vec { + let netuid_is_member: Vec = + as IterableStorageDoubleMap<_, _, _>>::iter_prefix(old_hotkey) + .map(|(netuid, _)| netuid) + .collect(); + weight.saturating_accrue(T::DbWeight::get().reads(netuid_is_member.len() as u64)); + netuid_is_member + } + + /// Swaps the owner of the hotkey. + /// + /// # Arguments + /// + /// * `old_hotkey` - The old hotkey. + /// * `new_hotkey` - The new hotkey. + /// * `coldkey` - The coldkey owning the hotkey. + /// * `weight` - The weight of the transaction. + /// + pub fn swap_owner( + old_hotkey: &T::AccountId, + new_hotkey: &T::AccountId, + coldkey: &T::AccountId, + weight: &mut Weight, + ) { + Owner::::remove(old_hotkey); + Owner::::insert(new_hotkey, coldkey.clone()); + + // Update OwnedHotkeys map + let mut hotkeys = OwnedHotkeys::::get(coldkey); + if !hotkeys.contains(new_hotkey) { + hotkeys.push(new_hotkey.clone()); + } + hotkeys.retain(|hk| *hk != *old_hotkey); + OwnedHotkeys::::insert(coldkey, hotkeys); + + weight.saturating_accrue(T::DbWeight::get().writes(2)); + } + + /// Swaps the total stake of the hotkey. + /// + /// # Arguments + /// + /// * `old_hotkey` - The old hotkey. + /// * `new_hotkey` - The new hotkey. + /// * `weight` - The weight of the transaction. + /// + /// # Weight Calculation + /// + /// * Reads: 1 if the old hotkey exists, otherwise 1 for the failed read. + /// * Writes: 2 if the old hotkey exists (one for removal and one for insertion). + pub fn swap_total_hotkey_stake( + old_hotkey: &T::AccountId, + new_hotkey: &T::AccountId, + weight: &mut Weight, + ) { + if let Ok(total_hotkey_stake) = TotalHotkeyStake::::try_get(old_hotkey) { + TotalHotkeyStake::::remove(old_hotkey); + TotalHotkeyStake::::insert(new_hotkey, total_hotkey_stake); + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); + } else { + weight.saturating_accrue(T::DbWeight::get().reads(1)); + } + } + + /// Swaps the delegates of the hotkey. + /// + /// # Arguments + /// + /// * `old_hotkey` - The old hotkey. + /// * `new_hotkey` - The new hotkey. + /// * `weight` - The weight of the transaction. + /// + /// # Weight Calculation + /// + /// * Reads: 1 if the old hotkey exists, otherwise 1 for the failed read. + /// * Writes: 2 if the old hotkey exists (one for removal and one for insertion). + pub fn swap_delegates( + old_hotkey: &T::AccountId, + new_hotkey: &T::AccountId, + weight: &mut Weight, + ) { + if let Ok(delegate_take) = Delegates::::try_get(old_hotkey) { + Delegates::::remove(old_hotkey); + Delegates::::insert(new_hotkey, delegate_take); + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); + } else { + weight.saturating_accrue(T::DbWeight::get().reads(1)); + } + } + + /// Swaps the stake of the hotkey. + /// + /// # Arguments + /// + /// * `old_hotkey` - The old hotkey. + /// * `new_hotkey` - The new hotkey. + /// * `weight` - The weight of the transaction. + pub fn swap_stake(old_hotkey: &T::AccountId, new_hotkey: &T::AccountId, weight: &mut Weight) { + let mut writes: u64 = 0; + let stakes: Vec<(T::AccountId, u64)> = Stake::::iter_prefix(old_hotkey).collect(); + let stake_count = stakes.len() as u32; + + for (coldkey, stake_amount) in stakes { + Stake::::insert(new_hotkey, &coldkey, stake_amount); + writes = writes.saturating_add(1u64); // One write for insert + + // Update StakingHotkeys map + let mut staking_hotkeys = StakingHotkeys::::get(&coldkey); + if !staking_hotkeys.contains(new_hotkey) { + staking_hotkeys.push(new_hotkey.clone()); + writes = writes.saturating_add(1u64); // One write for insert + } + if let Some(pos) = staking_hotkeys.iter().position(|x| x == old_hotkey) { + staking_hotkeys.remove(pos); + writes = writes.saturating_add(1u64); // One write for remove + } + StakingHotkeys::::insert(coldkey.clone(), staking_hotkeys); + writes = writes.saturating_add(1u64); // One write for insert + } + + // Clear the prefix for the old hotkey after transferring all stakes + let _ = Stake::::clear_prefix(old_hotkey, stake_count, None); + writes = writes.saturating_add(1); // One write for insert; // One write for clear_prefix + + // TODO: Remove all entries for old hotkey from StakingHotkeys map + + weight.saturating_accrue(T::DbWeight::get().writes(writes)); + } + + /// Swaps the network membership status of the hotkey. + /// + /// # Arguments + /// + /// * `old_hotkey` - The old hotkey. + /// * `new_hotkey` - The new hotkey. + /// * `netuid_is_member` - A vector of network IDs where the hotkey is a member. + /// * `weight` - The weight of the transaction. + pub fn swap_is_network_member( + old_hotkey: &T::AccountId, + new_hotkey: &T::AccountId, + netuid_is_member: &[u16], + weight: &mut Weight, + ) { + let _ = IsNetworkMember::::clear_prefix(old_hotkey, netuid_is_member.len() as u32, None); + weight.saturating_accrue(T::DbWeight::get().writes(netuid_is_member.len() as u64)); + for netuid in netuid_is_member.iter() { + IsNetworkMember::::insert(new_hotkey, netuid, true); + weight.saturating_accrue(T::DbWeight::get().writes(1)); + } + } + + /// Swaps the axons of the hotkey. + /// + /// # Arguments + /// + /// * `old_hotkey` - The old hotkey. + /// * `new_hotkey` - The new hotkey. + /// * `netuid_is_member` - A vector of network IDs where the hotkey is a member. + /// * `weight` - The weight of the transaction. + /// + /// # Weight Calculation + /// + /// * Reads: 1 for each network ID if the old hotkey exists in that network. + /// * Writes: 2 for each network ID if the old hotkey exists in that network (one for removal and one for insertion). + pub fn swap_axons( + old_hotkey: &T::AccountId, + new_hotkey: &T::AccountId, + netuid_is_member: &[u16], + weight: &mut Weight, + ) { + for netuid in netuid_is_member.iter() { + if let Ok(axon_info) = Axons::::try_get(netuid, old_hotkey) { + Axons::::remove(netuid, old_hotkey); + Axons::::insert(netuid, new_hotkey, axon_info); + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); + } else { + weight.saturating_accrue(T::DbWeight::get().reads(1)); + } + } + } + + /// Swaps the references in the keys storage map of the hotkey. + /// + /// # Arguments + /// + /// * `old_hotkey` - The old hotkey. + /// * `new_hotkey` - The new hotkey. + /// * `netuid_is_member` - A vector of network IDs where the hotkey is a member. + /// * `weight` - The weight of the transaction. + pub fn swap_keys( + old_hotkey: &T::AccountId, + new_hotkey: &T::AccountId, + netuid_is_member: &[u16], + weight: &mut Weight, + ) { + let mut writes: u64 = 0; + for netuid in netuid_is_member { + let keys: Vec<(u16, T::AccountId)> = Keys::::iter_prefix(netuid).collect(); + for (uid, key) in keys { + if key == *old_hotkey { + log::info!("old hotkey found: {:?}", old_hotkey); + Keys::::insert(netuid, uid, new_hotkey.clone()); + } + writes = writes.saturating_add(2u64); + } + } + log::info!("writes: {:?}", writes); + weight.saturating_accrue(T::DbWeight::get().writes(writes)); + } + + /// Swaps the loaded emission of the hotkey. + /// + /// # Arguments + /// + /// * `old_hotkey` - The old hotkey. + /// * `new_hotkey` - The new hotkey. + /// * `netuid_is_member` - A vector of network IDs where the hotkey is a member. + /// * `weight` - The weight of the transaction. + /// + pub fn swap_loaded_emission( + old_hotkey: &T::AccountId, + new_hotkey: &T::AccountId, + netuid_is_member: &[u16], + weight: &mut Weight, + ) { + for netuid in netuid_is_member { + if let Some(mut emissions) = LoadedEmission::::get(netuid) { + for emission in emissions.iter_mut() { + if emission.0 == *old_hotkey { + emission.0 = new_hotkey.clone(); + } + } + LoadedEmission::::insert(netuid, emissions); + } + } + weight.saturating_accrue(T::DbWeight::get().writes(netuid_is_member.len() as u64)); + } + + /// Swaps the UIDs of the hotkey. + /// + /// # Arguments + /// + /// * `old_hotkey` - The old hotkey. + /// * `new_hotkey` - The new hotkey. + /// * `netuid_is_member` - A vector of network IDs where the hotkey is a member. + /// * `weight` - The weight of the transaction. + /// + pub fn swap_uids( + old_hotkey: &T::AccountId, + new_hotkey: &T::AccountId, + netuid_is_member: &[u16], + weight: &mut Weight, + ) { + for netuid in netuid_is_member.iter() { + if let Ok(uid) = Uids::::try_get(netuid, old_hotkey) { + Uids::::remove(netuid, old_hotkey); + Uids::::insert(netuid, new_hotkey, uid); + weight.saturating_accrue(T::DbWeight::get().writes(2)); + } + } + } + + /// Swaps the Prometheus data of the hotkey. + /// + /// # Arguments + /// + /// * `old_hotkey` - The old hotkey. + /// * `new_hotkey` - The new hotkey. + /// * `netuid_is_member` - A vector of network IDs where the hotkey is a member. + /// * `weight` - The weight of the transaction. + /// + /// # Weight Calculation + /// + /// * Reads: 1 for each network ID if the old hotkey exists in that network. + /// * Writes: 2 for each network ID if the old hotkey exists in that network (one for removal and one for insertion). + pub fn swap_prometheus( + old_hotkey: &T::AccountId, + new_hotkey: &T::AccountId, + netuid_is_member: &[u16], + weight: &mut Weight, + ) { + for netuid in netuid_is_member.iter() { + if let Ok(prometheus_info) = Prometheus::::try_get(netuid, old_hotkey) { + Prometheus::::remove(netuid, old_hotkey); + Prometheus::::insert(netuid, new_hotkey, prometheus_info); + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); + } else { + weight.saturating_accrue(T::DbWeight::get().reads(1)); + } + } + } + + /// Swaps the total hotkey-coldkey stakes for the current interval. + /// + /// # Arguments + /// + /// * `old_hotkey` - The old hotkey. + /// * `new_hotkey` - The new hotkey. + /// * `weight` - The weight of the transaction. + /// + pub fn swap_total_hotkey_coldkey_stakes_this_interval( + old_hotkey: &T::AccountId, + new_hotkey: &T::AccountId, + weight: &mut Weight, + ) { + let stakes: Vec<(T::AccountId, (u64, u64))> = + TotalHotkeyColdkeyStakesThisInterval::::iter_prefix(old_hotkey).collect(); + log::info!("Stakes to swap: {:?}", stakes); + for (coldkey, stake) in stakes { + log::info!( + "Swapping stake for coldkey: {:?}, stake: {:?}", + coldkey, + stake + ); + TotalHotkeyColdkeyStakesThisInterval::::insert(new_hotkey, &coldkey, stake); + TotalHotkeyColdkeyStakesThisInterval::::remove(old_hotkey, &coldkey); + weight.saturating_accrue(T::DbWeight::get().writes(2)); // One write for insert and one for remove + } + } + + + pub fn swap_senate_member( + old_hotkey: &T::AccountId, + new_hotkey: &T::AccountId, + weight: &mut Weight, + ) -> DispatchResult { + weight.saturating_accrue(T::DbWeight::get().reads(1)); + if T::SenateMembers::is_member(old_hotkey) { + T::SenateMembers::swap_member(old_hotkey, new_hotkey).map_err(|e| e.error)?; + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); + } + Ok(()) + } +} diff --git a/pallets/subtensor/tests/epoch.rs b/pallets/subtensor/tests/epoch.rs index 676b3cd35..526a58b4e 100644 --- a/pallets/subtensor/tests/epoch.rs +++ b/pallets/subtensor/tests/epoch.rs @@ -7,7 +7,7 @@ use crate::mock::*; use frame_support::{assert_err, assert_ok}; use frame_system::Config; -use pallet_subtensor::math::safe_exp; +use pallet_subtensor::epoch::math::safe_exp; use pallet_subtensor::*; use rand::{distributions::Uniform, rngs::StdRng, seq::SliceRandom, thread_rng, Rng, SeedableRng}; use sp_core::U256; @@ -1496,7 +1496,7 @@ fn test_set_alpha_disabled() { // Enable Liquid Alpha and setup SubtensorModule::set_liquid_alpha_enabled(netuid, true); - migration::migrate_create_root_network::(); + migrations::migrate_create_root_network::migrate_create_root_network::(); SubtensorModule::add_balance_to_coldkey_account(&coldkey, 1_000_000_000_000_000); assert_ok!(SubtensorModule::root_register(signer.clone(), hotkey,)); assert_ok!(SubtensorModule::add_stake(signer.clone(), hotkey, 1000)); @@ -2574,7 +2574,7 @@ fn test_get_set_alpha() { // Enable Liquid Alpha and setup SubtensorModule::set_liquid_alpha_enabled(netuid, true); - migration::migrate_create_root_network::(); + migrations::migrate_create_root_network::migrate_create_root_network::(); SubtensorModule::add_balance_to_coldkey_account(&coldkey, 1_000_000_000_000_000); assert_ok!(SubtensorModule::root_register(signer.clone(), hotkey,)); assert_ok!(SubtensorModule::add_stake(signer.clone(), hotkey, 1000)); diff --git a/pallets/subtensor/tests/migration.rs b/pallets/subtensor/tests/migration.rs index 360568235..6d79d4794 100644 --- a/pallets/subtensor/tests/migration.rs +++ b/pallets/subtensor/tests/migration.rs @@ -67,7 +67,7 @@ fn test_migration_fix_total_stake_maps() { assert_ne!(SubtensorModule::get_total_stake(), total_stake_amount); // Run the migration to fix the total stake maps - pallet_subtensor::migration::migrate_to_v2_fixed_total_stake::(); + pallet_subtensor::migrations::migrate_to_v2_fixed_total_stake::migrate_to_v2_fixed_total_stake::(); // Verify that the total stake is now correct assert_eq!(SubtensorModule::get_total_stake(), total_stake_amount); @@ -107,19 +107,19 @@ fn test_migration_fix_total_stake_maps() { #[test] // To run this test with cargo, use the following command: -// cargo test --package pallet-subtensor --test migration test_migration5_total_issuance -fn test_migration5_total_issuance() { +// cargo test --package pallet-subtensor --test migration test_migrate_total_issuance +fn test_migrate_total_issuance() { new_test_ext(1).execute_with(|| { // Run the migration to check total issuance. let test: bool = true; assert_eq!(SubtensorModule::get_total_issuance(), 0); - pallet_subtensor::migration::migration5_total_issuance::(test); + pallet_subtensor::migrations::migrate_total_issuance::migrate_total_issuance::(test); assert_eq!(SubtensorModule::get_total_issuance(), 0); SubtensorModule::add_balance_to_coldkey_account(&U256::from(1), 10000); assert_eq!(SubtensorModule::get_total_issuance(), 0); - pallet_subtensor::migration::migration5_total_issuance::(test); + pallet_subtensor::migrations::migrate_total_issuance::migrate_total_issuance::(test); assert_eq!(SubtensorModule::get_total_issuance(), 10000); SubtensorModule::increase_stake_on_coldkey_hotkey_account( @@ -128,7 +128,7 @@ fn test_migration5_total_issuance() { 30000, ); assert_eq!(SubtensorModule::get_total_issuance(), 10000); - pallet_subtensor::migration::migration5_total_issuance::(test); + pallet_subtensor::migrations::migrate_total_issuance::migrate_total_issuance::(test); assert_eq!(SubtensorModule::get_total_issuance(), 10000 + 30000); }) } @@ -152,7 +152,7 @@ fn test_total_issuance_global() { )); SubtensorModule::set_max_allowed_uids(netuid, 1); // Set the maximum allowed unique identifiers for the network to 1. assert_eq!(SubtensorModule::get_total_issuance(), 0); // initial is zero. - pallet_subtensor::migration::migration5_total_issuance::(true); // Pick up lock. + pallet_subtensor::migrations::migrate_total_issuance::migrate_total_issuance::(true); // Pick up lock. assert_eq!(SubtensorModule::get_total_issuance(), lockcost); // Verify the total issuance is updated to 20000 after migration. assert!(SubtensorModule::if_subnet_exist(netuid)); @@ -162,7 +162,7 @@ fn test_total_issuance_global() { let _coldkey_account_id_1 = U256::from(1); // Define a coldkey account ID for further operations. assert_eq!(SubtensorModule::get_total_issuance(), lockcost); // Ensure the total issuance starts at 0 before the migration. SubtensorModule::add_balance_to_coldkey_account(&coldkey, account_balance); // Add a balance of 20000 to the coldkey account. - pallet_subtensor::migration::migration5_total_issuance::(true); // Execute the migration to update total issuance. + pallet_subtensor::migrations::migrate_total_issuance::migrate_total_issuance::(true); // Execute the migration to update total issuance. assert_eq!( SubtensorModule::get_total_issuance(), account_balance + lockcost @@ -185,7 +185,7 @@ fn test_total_issuance_global() { SubtensorModule::get_total_issuance(), account_balance + lockcost - burn_cost ); // Verify the total issuance is reduced to 10000 after burning. - pallet_subtensor::migration::migration5_total_issuance::(true); // Execute the migration to update total issuance. + pallet_subtensor::migrations::migrate_total_issuance::migrate_total_issuance::(true); // Execute the migration to update total issuance. assert_eq!( SubtensorModule::get_total_issuance(), account_balance + lockcost - burn_cost @@ -202,7 +202,7 @@ fn test_total_issuance_global() { SubtensorModule::get_total_issuance(), account_balance + lockcost - burn_cost ); // Same - pallet_subtensor::migration::migration5_total_issuance::(true); // Fix issuance + pallet_subtensor::migrations::migrate_total_issuance::migrate_total_issuance::(true); // Fix issuance assert_eq!( SubtensorModule::get_total_issuance(), account_balance + lockcost - burn_cost + new_stake @@ -222,7 +222,7 @@ fn test_total_issuance_global() { SubtensorModule::get_total_issuance(), account_balance + lockcost - burn_cost + new_stake + emission ); // Verify the total issuance reflects the staked amount and emission value that has been put through the epoch. - pallet_subtensor::migration::migration5_total_issuance::(true); // Test migration does not change amount. + pallet_subtensor::migrations::migrate_total_issuance::migrate_total_issuance::(true); // Test migration does not change amount. assert_eq!( SubtensorModule::get_total_issuance(), account_balance + lockcost - burn_cost + new_stake + emission @@ -244,7 +244,7 @@ fn test_migration_transfer_nets_to_foundation() { // Run the migration to transfer ownership let hex = hex_literal::hex!["feabaafee293d3b76dae304e2f9d885f77d2b17adab9e17e921b321eccd61c77"]; - pallet_subtensor::migration::migrate_transfer_ownership_to_foundation::(hex); + pallet_subtensor::migrations::migrate_transfer_ownership_to_foundation::migrate_transfer_ownership_to_foundation::(hex); log::info!("new owner: {:?}", SubtensorModule::get_subnet_owner(1)); }) @@ -258,7 +258,7 @@ fn test_migration_delete_subnet_3() { assert!(SubtensorModule::if_subnet_exist(3)); // Run the migration to transfer ownership - pallet_subtensor::migration::migrate_delete_subnet_3::(); + pallet_subtensor::migrations::migrate_delete_subnet_3::migrate_delete_subnet_3::(); assert!(!SubtensorModule::if_subnet_exist(3)); }) @@ -272,7 +272,7 @@ fn test_migration_delete_subnet_21() { assert!(SubtensorModule::if_subnet_exist(21)); // Run the migration to transfer ownership - pallet_subtensor::migration::migrate_delete_subnet_21::(); + pallet_subtensor::migrations::migrate_delete_subnet_21::migrate_delete_subnet_21::(); assert!(!SubtensorModule::if_subnet_exist(21)); }) @@ -288,7 +288,7 @@ fn test_migrate_fix_total_coldkey_stake() { Stake::::insert(U256::from(1), U256::from(0), 10000); Stake::::insert(U256::from(2), U256::from(0), 10000); Stake::::insert(U256::from(3), U256::from(0), 10000); - pallet_subtensor::migration::do_migrate_fix_total_coldkey_stake::(); + pallet_subtensor::migrations::migrate_fix_total_coldkey_stake::do_migrate_fix_total_coldkey_stake::(); assert_eq!(TotalColdkeyStake::::get(coldkey), 30000); }) } @@ -303,7 +303,7 @@ fn test_migrate_fix_total_coldkey_stake_value_already_in_total() { Stake::::insert(U256::from(1), U256::from(0), 10000); Stake::::insert(U256::from(2), U256::from(0), 10000); Stake::::insert(U256::from(3), U256::from(0), 10000); - pallet_subtensor::migration::do_migrate_fix_total_coldkey_stake::(); + pallet_subtensor::migrations::migrate_fix_total_coldkey_stake::do_migrate_fix_total_coldkey_stake::(); assert_eq!(TotalColdkeyStake::::get(coldkey), 30000); }) } @@ -317,7 +317,7 @@ fn test_migrate_fix_total_coldkey_stake_no_entry() { Stake::::insert(U256::from(1), U256::from(0), 10000); Stake::::insert(U256::from(2), U256::from(0), 10000); Stake::::insert(U256::from(3), U256::from(0), 10000); - pallet_subtensor::migration::do_migrate_fix_total_coldkey_stake::(); + pallet_subtensor::migrations::migrate_fix_total_coldkey_stake::do_migrate_fix_total_coldkey_stake::(); assert_eq!(TotalColdkeyStake::::get(coldkey), 30000); }) } @@ -329,7 +329,7 @@ fn test_migrate_fix_total_coldkey_stake_no_entry_in_hotkeys() { let coldkey = U256::from(0); TotalColdkeyStake::::insert(coldkey, 100000000); StakingHotkeys::::insert(coldkey, vec![U256::from(1), U256::from(2), U256::from(3)]); - pallet_subtensor::migration::do_migrate_fix_total_coldkey_stake::(); + pallet_subtensor::migrations::migrate_fix_total_coldkey_stake::do_migrate_fix_total_coldkey_stake::(); assert_eq!(TotalColdkeyStake::::get(coldkey), 0); }) } @@ -343,7 +343,7 @@ fn test_migrate_fix_total_coldkey_stake_one_hotkey_stake_missing() { StakingHotkeys::::insert(coldkey, vec![U256::from(1), U256::from(2), U256::from(3)]); Stake::::insert(U256::from(1), U256::from(0), 10000); Stake::::insert(U256::from(2), U256::from(0), 10000); - pallet_subtensor::migration::do_migrate_fix_total_coldkey_stake::(); + pallet_subtensor::migrations::migrate_fix_total_coldkey_stake::do_migrate_fix_total_coldkey_stake::(); assert_eq!(TotalColdkeyStake::::get(coldkey), 20000); }) } diff --git a/pallets/subtensor/tests/mock.rs b/pallets/subtensor/tests/mock.rs index fc784f46f..71e1d593b 100644 --- a/pallets/subtensor/tests/mock.rs +++ b/pallets/subtensor/tests/mock.rs @@ -168,7 +168,6 @@ parameter_types! { pub const InitialAlphaHigh: u16 = 58982; // Represents 0.9 as per the production default pub const InitialAlphaLow: u16 = 45875; // Represents 0.7 as per the production default pub const InitialLiquidAlphaOn: bool = false; // Default value for LiquidAlphaOn - pub const SubtensorInitialBaseDifficulty: u64 = 10_000; // Base difficulty } // Configure collective pallet for council @@ -379,7 +378,6 @@ impl pallet_subtensor::Config for Test { type AlphaHigh = InitialAlphaHigh; type AlphaLow = InitialAlphaLow; type LiquidAlphaOn = InitialLiquidAlphaOn; - type InitialBaseDifficulty = SubtensorInitialBaseDifficulty; } impl pallet_utility::Config for Test { diff --git a/pallets/subtensor/tests/root.rs b/pallets/subtensor/tests/root.rs index 7c6622670..d4e8448a1 100644 --- a/pallets/subtensor/tests/root.rs +++ b/pallets/subtensor/tests/root.rs @@ -4,7 +4,7 @@ use crate::mock::*; use frame_support::{assert_err, assert_ok}; use frame_system::Config; use frame_system::{EventRecord, Phase}; -use pallet_subtensor::migration; +use pallet_subtensor::migrations; use pallet_subtensor::Error; use sp_core::{Get, H256, U256}; @@ -22,7 +22,7 @@ fn record(event: RuntimeEvent) -> EventRecord { #[test] fn test_root_register_network_exist() { new_test_ext(1).execute_with(|| { - migration::migrate_create_root_network::(); + migrations::migrate_create_root_network::migrate_create_root_network::(); let hotkey_account_id: U256 = U256::from(1); let coldkey_account_id = U256::from(667); assert_ok!(SubtensorModule::root_register( @@ -63,7 +63,7 @@ fn test_set_weights_not_root_error() { #[test] fn test_root_register_normal_on_root_fails() { new_test_ext(1).execute_with(|| { - migration::migrate_create_root_network::(); + migrations::migrate_create_root_network::migrate_create_root_network::(); // Test fails because normal registrations are not allowed // on the root network. let root_netuid: u16 = 0; @@ -107,7 +107,7 @@ fn test_root_register_normal_on_root_fails() { #[test] fn test_root_register_stake_based_pruning_works() { new_test_ext(1).execute_with(|| { - migration::migrate_create_root_network::(); + migrations::migrate_create_root_network::migrate_create_root_network::(); // Add two networks. let root_netuid: u16 = 0; let other_netuid: u16 = 1; @@ -196,7 +196,7 @@ fn test_root_register_stake_based_pruning_works() { fn test_root_set_weights() { new_test_ext(1).execute_with(|| { System::set_block_number(0); - migration::migrate_create_root_network::(); + migrations::migrate_create_root_network::migrate_create_root_network::(); let n: usize = 10; let root_netuid: u16 = 0; @@ -338,7 +338,7 @@ fn test_root_set_weights() { fn test_root_set_weights_out_of_order_netuids() { new_test_ext(1).execute_with(|| { System::set_block_number(0); - migration::migrate_create_root_network::(); + migrations::migrate_create_root_network::migrate_create_root_network::(); let n: usize = 10; let root_netuid: u16 = 0; @@ -458,7 +458,7 @@ fn test_root_set_weights_out_of_order_netuids() { fn test_root_subnet_creation_deletion() { new_test_ext(1).execute_with(|| { System::set_block_number(0); - migration::migrate_create_root_network::(); + migrations::migrate_create_root_network::migrate_create_root_network::(); // Owner of subnets. let owner: U256 = U256::from(0); @@ -538,7 +538,7 @@ fn test_root_subnet_creation_deletion() { fn test_network_pruning() { new_test_ext(1).execute_with(|| { System::set_block_number(0); - migration::migrate_create_root_network::(); + migrations::migrate_create_root_network::migrate_create_root_network::(); assert_eq!(SubtensorModule::get_total_issuance(), 0); @@ -630,7 +630,7 @@ fn test_network_pruning() { #[test] fn test_network_prune_results() { new_test_ext(1).execute_with(|| { - migration::migrate_create_root_network::(); + migrations::migrate_create_root_network::migrate_create_root_network::(); SubtensorModule::set_network_immunity_period(3); SubtensorModule::set_network_min_lock(0); @@ -671,7 +671,7 @@ fn test_network_prune_results() { #[test] fn test_weights_after_network_pruning() { new_test_ext(1).execute_with(|| { - migration::migrate_create_root_network::(); + migrations::migrate_create_root_network::migrate_create_root_network::(); assert_eq!(SubtensorModule::get_total_issuance(), 0); diff --git a/pallets/subtensor/tests/senate.rs b/pallets/subtensor/tests/senate.rs index bcec1a63a..e1f33db5e 100644 --- a/pallets/subtensor/tests/senate.rs +++ b/pallets/subtensor/tests/senate.rs @@ -15,7 +15,7 @@ use sp_runtime::{ use frame_system::pallet_prelude::*; use frame_system::Config; use pallet_collective::Event as CollectiveEvent; -use pallet_subtensor::migration; +use pallet_subtensor::migrations; use pallet_subtensor::Error; pub fn new_test_ext() -> sp_io::TestExternalities { @@ -57,7 +57,7 @@ fn record(event: RuntimeEvent) -> EventRecord { #[test] fn test_senate_join_works() { new_test_ext().execute_with(|| { - migration::migrate_create_root_network::(); + migrations::migrate_create_root_network::migrate_create_root_network::(); let netuid: u16 = 1; let tempo: u16 = 13; @@ -125,7 +125,7 @@ fn test_senate_join_works() { #[test] fn test_senate_vote_works() { new_test_ext().execute_with(|| { - migration::migrate_create_root_network::(); + migrations::migrate_create_root_network::migrate_create_root_network::(); let netuid: u16 = 1; let tempo: u16 = 13; @@ -233,7 +233,7 @@ fn test_senate_vote_works() { #[test] fn test_senate_vote_not_member() { new_test_ext().execute_with(|| { - migration::migrate_create_root_network::(); + migrations::migrate_create_root_network::migrate_create_root_network::(); let netuid: u16 = 1; let tempo: u16 = 13; @@ -294,7 +294,7 @@ fn test_senate_vote_not_member() { #[test] fn test_senate_leave_works() { new_test_ext().execute_with(|| { - migration::migrate_create_root_network::(); + migrations::migrate_create_root_network::migrate_create_root_network::(); let netuid: u16 = 1; let tempo: u16 = 13; @@ -362,7 +362,7 @@ fn test_senate_leave_works() { #[test] fn test_senate_leave_vote_removal() { new_test_ext().execute_with(|| { - migration::migrate_create_root_network::(); + migrations::migrate_create_root_network::migrate_create_root_network::(); let netuid: u16 = 1; let tempo: u16 = 13; @@ -501,7 +501,7 @@ fn test_senate_leave_vote_removal() { #[test] fn test_senate_not_leave_when_stake_removed() { new_test_ext().execute_with(|| { - migration::migrate_create_root_network::(); + migrations::migrate_create_root_network::migrate_create_root_network::(); let netuid: u16 = 1; let tempo: u16 = 13; @@ -582,7 +582,7 @@ fn test_senate_not_leave_when_stake_removed() { fn test_senate_join_current_delegate() { // Test that a current delegate can join the senate new_test_ext().execute_with(|| { - migration::migrate_create_root_network::(); + migrations::migrate_create_root_network::migrate_create_root_network::(); let netuid: u16 = 1; let tempo: u16 = 13; @@ -656,7 +656,7 @@ fn test_senate_join_current_delegate() { fn test_adjust_senate_events() { // Test the events emitted after adjusting the senate successfully new_test_ext().execute_with(|| { - migration::migrate_create_root_network::(); + migrations::migrate_create_root_network::migrate_create_root_network::(); let netuid: u16 = 1; let tempo: u16 = 13; diff --git a/pallets/subtensor/tests/staking.rs b/pallets/subtensor/tests/staking.rs index 5db439e5b..a923a7010 100644 --- a/pallets/subtensor/tests/staking.rs +++ b/pallets/subtensor/tests/staking.rs @@ -1,21 +1,14 @@ #![allow(clippy::unwrap_used)] #![allow(clippy::arithmetic_side_effects)] -use frame_support::pallet_prelude::{ - InvalidTransaction, TransactionValidity, TransactionValidityError, -}; -use frame_support::traits::{OnFinalize, OnIdle, OnInitialize}; -use frame_support::weights::Weight; use frame_support::{assert_err, assert_noop, assert_ok, traits::Currency}; use frame_system::Config; mod mock; use frame_support::dispatch::{DispatchClass, DispatchInfo, GetDispatchInfo, Pays}; use frame_support::sp_runtime::DispatchError; use mock::*; -use pallet_balances::Call as BalancesCall; use pallet_subtensor::*; use sp_core::{H256, U256}; -use sp_runtime::traits::SignedExtension; /*********************************************************** staking::add_stake() tests @@ -3136,1067 +3129,6 @@ fn test_rate_limits_enforced_on_increase_take() { }); } -// Helper function to set up a test environment -fn setup_test_environment() -> (AccountId, AccountId, AccountId) { - let current_coldkey = U256::from(1); - let hotkey = U256::from(2); - let new_coldkey = U256::from(3); - // Register the neuron to a new network - let netuid = 1; - add_network(netuid, 0, 0); - - // Register the hotkey and associate it with the current coldkey - register_ok_neuron(1, hotkey, current_coldkey, 0); - - // Add some balance to the hotkey - SubtensorModule::add_balance_to_coldkey_account(¤t_coldkey, 1000); - - // Stake some amount - assert_ok!(SubtensorModule::add_stake( - RuntimeOrigin::signed(current_coldkey), - hotkey, - 500 - )); - - (current_coldkey, hotkey, new_coldkey) -} - -/// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test staking -- test_arbitrated_coldkey_swap_success --exact --nocapture -#[test] -fn test_arbitrated_coldkey_swap_success() { - new_test_ext(1).execute_with(|| { - let (current_coldkey, hotkey, new_coldkey) = setup_test_environment(); - - let current_block = SubtensorModule::get_current_block_as_u64(); - let (work, nonce) = generate_valid_pow( - ¤t_coldkey, - current_block, - U256::from(BaseDifficulty::::get()), - ); - SubtensorModule::add_balance_to_coldkey_account( - ¤t_coldkey, - MIN_BALANCE_TO_PERFORM_COLDKEY_SWAP, - ); - assert_ok!(SubtensorModule::do_schedule_coldkey_swap( - ¤t_coldkey.clone(), - &new_coldkey, - work.to_fixed_bytes().to_vec(), - current_block, - nonce - )); - - // Check that ColdkeySwapDestinations is populated correctly - assert_eq!( - pallet_subtensor::ColdkeySwapDestinations::::get(current_coldkey), - vec![new_coldkey] - ); - - // Check that drain block is set correctly - let drain_block: u64 = 7200 * 3 + 1; - - log::info!( - "ColdkeysToSwapAtBlock before scheduling: {:?}", - pallet_subtensor::ColdkeysToSwapAtBlock::::get(drain_block) - ); - - assert_eq!( - pallet_subtensor::ColdkeysToSwapAtBlock::::get(drain_block), - vec![current_coldkey] - ); - log::info!("Drain block set correctly: {:?}", drain_block); - log::info!( - "Drain block {:?}", - pallet_subtensor::ColdkeysToSwapAtBlock::::get(drain_block) - ); - - // Make 5400 blocks pass - run_to_block(drain_block); - - // Run unstaking - SubtensorModule::swap_coldkeys_this_block(&BlockWeights::get().max_block).unwrap(); - log::info!( - "Arbitrated coldkeys for block: {:?}", - SubtensorModule::get_current_block_as_u64() - ); - - // Check the hotkey stake. - assert_eq!(SubtensorModule::get_total_stake_for_hotkey(&hotkey), 500); - - // Get the owner of the hotkey now new key. - assert_eq!( - SubtensorModule::get_owning_coldkey_for_hotkey(&hotkey), - new_coldkey - ); - - // Check that the balance has been transferred to the new coldkey - assert_eq!( - SubtensorModule::get_coldkey_balance(&new_coldkey), - MIN_BALANCE_TO_PERFORM_COLDKEY_SWAP + 500 - ); // The new key as the 500 - }); -} - -/// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test staking -- test_arbitrated_coldkey_swap_same_coldkey --exact --nocapture -#[test] -fn test_arbitrated_coldkey_swap_same_coldkey() { - new_test_ext(1).execute_with(|| { - let (current_coldkey, _hotkey, _) = setup_test_environment(); - - let current_block = SubtensorModule::get_current_block_as_u64(); - let (work, nonce) = generate_valid_pow( - ¤t_coldkey, - current_block, - U256::from(BaseDifficulty::::get()), - ); - - assert_noop!( - SubtensorModule::do_schedule_coldkey_swap( - ¤t_coldkey.clone(), - ¤t_coldkey, - work.to_fixed_bytes().to_vec(), - current_block, - nonce - ), - Error::::SameColdkey - ); - }); -} - -/// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test staking -- test_arbitrated_coldkey_swap_no_balance --exact --nocapture -#[test] -fn test_arbitrated_coldkey_swap_no_balance() { - new_test_ext(1).execute_with(|| { - // Create accounts manually - let current_coldkey: AccountId = U256::from(1); - let hotkey: AccountId = U256::from(2); - let new_coldkey: AccountId = U256::from(3); - - add_network(1, 0, 0); - - // Register the hotkey and associate it with the current coldkey - register_ok_neuron(1, hotkey, current_coldkey, 0); - - // Print initial balances - log::info!( - "Initial current_coldkey balance: {:?}", - Balances::total_balance(¤t_coldkey) - ); - log::info!( - "Initial hotkey balance: {:?}", - Balances::total_balance(&hotkey) - ); - log::info!( - "Initial new_coldkey balance: {:?}", - Balances::total_balance(&new_coldkey) - ); - - // Ensure there's no balance in any of the accounts - assert_eq!(Balances::total_balance(¤t_coldkey), 0); - assert_eq!(Balances::total_balance(&hotkey), 0); - assert_eq!(Balances::total_balance(&new_coldkey), 0); - - // Generate valid PoW - let current_block = SubtensorModule::get_current_block_as_u64(); - let (work, nonce) = generate_valid_pow( - ¤t_coldkey, - current_block, - U256::from(BaseDifficulty::::get()), - ); - - // Try to schedule coldkey swap - let result = SubtensorModule::do_schedule_coldkey_swap( - ¤t_coldkey.clone(), - &new_coldkey, - work.to_fixed_bytes().to_vec(), - current_block, - nonce, - ); - - // Print the result - log::info!("Result of arbitrated_coldkey_swap: {:?}", result); - - // Verify that the operation failed due to insufficient balance - assert_noop!( - result, - Error::::InsufficientBalanceToPerformColdkeySwap - ); - - // Print final balances - log::info!( - "Final current_coldkey balance: {:?}", - Balances::total_balance(¤t_coldkey) - ); - log::info!( - "Final hotkey balance: {:?}", - Balances::total_balance(&hotkey) - ); - log::info!( - "Final new_coldkey balance: {:?}", - Balances::total_balance(&new_coldkey) - ); - - // Verify that no balance was transferred - assert_eq!(Balances::total_balance(¤t_coldkey), 0); - assert_eq!(Balances::total_balance(&hotkey), 0); - assert_eq!(Balances::total_balance(&new_coldkey), 0); - }); -} - -// To run this test, use the following command: -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test staking -- test_arbitrated_coldkey_swap_with_no_stake --exact --nocapture -#[test] -fn test_arbitrated_coldkey_swap_with_no_stake() { - new_test_ext(1).execute_with(|| { - // Create accounts manually - let current_coldkey: AccountId = U256::from(1); - let hotkey: AccountId = U256::from(2); - let new_coldkey: AccountId = U256::from(3); - - add_network(1, 0, 0); - - // Register the hotkey and associate it with the current coldkey - register_ok_neuron(1, hotkey, current_coldkey, 0); - - // Add balance to the current coldkey without staking - Balances::make_free_balance_be(¤t_coldkey, MIN_BALANCE_TO_PERFORM_COLDKEY_SWAP); - - // Print initial balances - log::info!( - "Initial current_coldkey balance: {:?}", - Balances::total_balance(¤t_coldkey) - ); - log::info!( - "Initial hotkey balance: {:?}", - Balances::total_balance(&hotkey) - ); - log::info!( - "Initial new_coldkey balance: {:?}", - Balances::total_balance(&new_coldkey) - ); - - // Ensure initial balances are correct - assert_eq!( - Balances::total_balance(¤t_coldkey), - MIN_BALANCE_TO_PERFORM_COLDKEY_SWAP - ); - assert_eq!(Balances::total_balance(&hotkey), 0); - assert_eq!(Balances::total_balance(&new_coldkey), 0); - - let current_block = SubtensorModule::get_current_block_as_u64(); - let (work, nonce) = generate_valid_pow( - ¤t_coldkey, - current_block, - U256::from(BaseDifficulty::::get()), - ); - - // Schedule coldkey swap - assert_ok!(SubtensorModule::do_schedule_coldkey_swap( - ¤t_coldkey.clone(), - &new_coldkey, - work.to_fixed_bytes().to_vec(), - current_block, - nonce - )); - - // Make 5400 blocks pass, simulating on_idle for each block - let drain_block: u64 = 7200 * 3 + 1; - for _ in 0..drain_block { - next_block(); - SubtensorModule::on_idle(System::block_number(), Weight::MAX); - } - - // Print final balances - log::info!( - "Final current_coldkey balance: {:?}", - Balances::total_balance(¤t_coldkey) - ); - log::info!( - "Final hotkey balance: {:?}", - Balances::total_balance(&hotkey) - ); - log::info!( - "Final new_coldkey balance: {:?}", - Balances::total_balance(&new_coldkey) - ); - - // Check that the balance has been transferred to the new coldkey - assert_eq!( - Balances::total_balance(&new_coldkey), - MIN_BALANCE_TO_PERFORM_COLDKEY_SWAP - ); - assert_eq!(Balances::total_balance(¤t_coldkey), 0); - }); -} - -// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test staking -- test_arbitrated_coldkey_swap_with_multiple_stakes --exact --nocapture -#[test] -fn test_arbitrated_coldkey_swap_with_multiple_stakes() { - new_test_ext(1).execute_with(|| { - let (current_coldkey, hotkey, new_coldkey) = setup_test_environment(); - - SubtensorModule::set_target_stakes_per_interval(10); - SubtensorModule::add_balance_to_coldkey_account( - ¤t_coldkey, - MIN_BALANCE_TO_PERFORM_COLDKEY_SWAP, - ); - - // Add more stake - assert_ok!(SubtensorModule::add_stake( - RuntimeOrigin::signed(current_coldkey), - hotkey, - 300 - )); - - let current_block = SubtensorModule::get_current_block_as_u64(); - let (work, nonce) = generate_valid_pow( - ¤t_coldkey, - current_block, - U256::from(BaseDifficulty::::get()), - ); - - assert_ok!(SubtensorModule::do_schedule_coldkey_swap( - ¤t_coldkey.clone(), - &new_coldkey, - work.to_fixed_bytes().to_vec(), - current_block, - nonce - )); - - // Make 5400 blocks pass, simulating on_idle for each block - let drain_block: u64 = 7200 * 3 + 1; - for _ in 0..drain_block { - next_block(); - SubtensorModule::on_idle(System::block_number(), Weight::MAX); - } - - // Check that all stake has been removed - assert_eq!(SubtensorModule::get_total_stake_for_hotkey(&hotkey), 800); - - // Owner has changed - assert_eq!( - SubtensorModule::get_owning_coldkey_for_hotkey(&hotkey), - new_coldkey - ); - - // Check that the full balance has been transferred to the new coldkey - assert_eq!( - SubtensorModule::get_coldkey_balance(&new_coldkey), - MIN_BALANCE_TO_PERFORM_COLDKEY_SWAP + 200 - ); - - // Check that the full balance has been transferred to the new coldkey - assert_eq!(SubtensorModule::get_coldkey_balance(¤t_coldkey), 0); - }); -} -// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test staking -- test_arbitrated_coldkey_swap_multiple_arbitrations --exact --nocapture -#[test] -fn test_arbitrated_coldkey_swap_multiple_arbitrations() { - new_test_ext(1).execute_with(|| { - // Set a very low base difficulty for testing - BaseDifficulty::::put(1); - - // Create coldkey with three choices. - let coldkey: AccountId = U256::from(1); - let new_coldkey1: AccountId = U256::from(2); - let new_coldkey2: AccountId = U256::from(3); - let new_coldkey3: AccountId = U256::from(4); - let hotkey: AccountId = U256::from(5); - - // Setup network state. - add_network(1, 0, 0); - SubtensorModule::add_balance_to_coldkey_account( - &coldkey, - MIN_BALANCE_TO_PERFORM_COLDKEY_SWAP, - ); - ArbitrationPeriod::::put(5); // Set arbitration period to 5 blocks - register_ok_neuron(1, hotkey, coldkey, 0); - - let current_block = SubtensorModule::get_current_block_as_u64(); - - // Generate valid PoW for each swap attempt - let (work1, nonce1) = generate_valid_pow(&coldkey, current_block, U256::from(1)); - let (work2, nonce2) = generate_valid_pow(&coldkey, current_block, U256::from(2)); - let (work3, nonce3) = generate_valid_pow(&coldkey, current_block, U256::from(4)); - - // Schedule three swaps - assert_ok!(SubtensorModule::do_schedule_coldkey_swap( - &coldkey.clone(), - &new_coldkey1, - work1.to_fixed_bytes().to_vec(), - current_block, - nonce1 - )); - assert_ok!(SubtensorModule::do_schedule_coldkey_swap( - &coldkey.clone(), - &new_coldkey2, - work2.to_fixed_bytes().to_vec(), - current_block, - nonce2 - )); - assert_ok!(SubtensorModule::do_schedule_coldkey_swap( - &coldkey.clone(), - &new_coldkey3, - work3.to_fixed_bytes().to_vec(), - current_block, - nonce3 - )); - - // All three keys are added in swap destinations. - assert_eq!( - pallet_subtensor::ColdkeySwapDestinations::::get(coldkey), - vec![new_coldkey1, new_coldkey2, new_coldkey3] - ); - - // Simulate the passage of blocks and on_idle calls - for i in 0..(7200 * 3 + 1) { - next_block(); - SubtensorModule::on_idle(System::block_number(), Weight::MAX); - - log::info!( - "Block {}: Coldkey in arbitration: {}, Swap destinations: {:?}", - i + 1, - SubtensorModule::coldkey_in_arbitration(&coldkey), - pallet_subtensor::ColdkeySwapDestinations::::get(coldkey) - ); - } - - // Check that the swap destinations remain unchanged due to multiple (>2) swap calls - assert_eq!( - pallet_subtensor::ColdkeySwapDestinations::::get(coldkey), - vec![new_coldkey1, new_coldkey2, new_coldkey3], - "ColdkeySwapDestinations should remain unchanged with more than two swap calls" - ); - - // Key remains in arbitration due to multiple (>2) swap calls - assert!( - SubtensorModule::coldkey_in_arbitration(&coldkey), - "Coldkey should remain in arbitration with more than two swap calls" - ); - - // Check that no balance has been transferred - assert_eq!( - SubtensorModule::get_coldkey_balance(&coldkey), - MIN_BALANCE_TO_PERFORM_COLDKEY_SWAP, - "Original coldkey balance should remain unchanged" - ); - assert_eq!( - SubtensorModule::get_coldkey_balance(&new_coldkey1), - 0, - "New coldkey1 should not receive any balance" - ); - assert_eq!( - SubtensorModule::get_coldkey_balance(&new_coldkey2), - 0, - "New coldkey2 should not receive any balance" - ); - assert_eq!( - SubtensorModule::get_coldkey_balance(&new_coldkey3), - 0, - "New coldkey3 should not receive any balance" - ); - }); -} - -// TODO: Verify that we never want more than 2 destinations for a coldkey -#[test] -fn test_arbitrated_coldkey_swap_existing_destination() { - new_test_ext(1).execute_with(|| { - let (current_coldkey, _hotkey, new_coldkey) = setup_test_environment(); - let another_coldkey = U256::from(4); - let third_coldkey = U256::from(5); - - let current_block = SubtensorModule::get_current_block_as_u64(); - - SubtensorModule::add_balance_to_coldkey_account( - ¤t_coldkey, - MIN_BALANCE_TO_PERFORM_COLDKEY_SWAP, - ); - - // First swap attempt (0 existing destinations) - let difficulty1 = SubtensorModule::calculate_pow_difficulty(0); - let (work1, nonce1) = generate_valid_pow(¤t_coldkey, current_block, difficulty1); - - // Schedule a swap to new_coldkey - assert_ok!(SubtensorModule::do_schedule_coldkey_swap( - ¤t_coldkey, - &new_coldkey, - work1.to_fixed_bytes().to_vec(), - current_block, - nonce1 - )); - - // Second swap attempt (1 existing destination) - let difficulty2 = SubtensorModule::calculate_pow_difficulty(1); - let (work2, nonce2) = generate_valid_pow(¤t_coldkey, current_block, difficulty2); - - // Attempt to schedule a swap to the same new_coldkey again - assert_noop!( - SubtensorModule::do_schedule_coldkey_swap( - ¤t_coldkey.clone(), - &new_coldkey, - work2.to_fixed_bytes().to_vec(), - current_block, - nonce2 - ), - Error::::DuplicateColdkey - ); - - // Schedule a swap to another_coldkey (still 1 existing destination) - assert_ok!(SubtensorModule::do_schedule_coldkey_swap( - ¤t_coldkey.clone(), - &another_coldkey, - work2.to_fixed_bytes().to_vec(), - current_block, - nonce2 - )); - - // Third swap attempt (2 existing destinations) - let difficulty3 = SubtensorModule::calculate_pow_difficulty(2); - let (work3, nonce3) = generate_valid_pow(¤t_coldkey, current_block, difficulty3); - - // Attempt to schedule a third swap - assert_ok!(SubtensorModule::do_schedule_coldkey_swap( - ¤t_coldkey.clone(), - &third_coldkey, - work3.to_fixed_bytes().to_vec(), - current_block, - nonce3 - )); - }); -} - -#[test] -fn test_arbitration_period_extension() { - new_test_ext(1).execute_with(|| { - let (current_coldkey, _hotkey, new_coldkey) = setup_test_environment(); - let another_coldkey = U256::from(4); - - let current_block = SubtensorModule::get_current_block_as_u64(); - let (work1, nonce1) = generate_valid_pow( - ¤t_coldkey, - current_block, - U256::from(BaseDifficulty::::get()), - ); - let (work2, nonce2) = - generate_valid_pow(¤t_coldkey, current_block, U256::from(20_000_000u64)); - SubtensorModule::add_balance_to_coldkey_account( - ¤t_coldkey, - MIN_BALANCE_TO_PERFORM_COLDKEY_SWAP, - ); - - // Schedule a swap to new_coldkey - assert_ok!(SubtensorModule::do_schedule_coldkey_swap( - ¤t_coldkey.clone(), - &new_coldkey, - work1.to_fixed_bytes().to_vec(), - current_block, - nonce1 - )); - - // Schedule a swap to another_coldkey - assert_ok!(SubtensorModule::do_schedule_coldkey_swap( - ¤t_coldkey.clone(), - &another_coldkey, - work2.to_fixed_bytes().to_vec(), - current_block, - nonce2 - )); - - // Check that the arbitration period is extended - let arbitration_block = - SubtensorModule::get_current_block_as_u64() + ArbitrationPeriod::::get(); - assert_eq!( - pallet_subtensor::ColdkeyArbitrationBlock::::get(current_coldkey), - arbitration_block - ); - }); -} - -#[test] -fn test_concurrent_arbitrated_coldkey_swaps() { - new_test_ext(1).execute_with(|| { - // Manually create accounts - let coldkey1: AccountId = U256::from(1); - let hotkey1: AccountId = U256::from(2); - let new_coldkey1: AccountId = U256::from(3); - - let coldkey2: AccountId = U256::from(4); - let hotkey2: AccountId = U256::from(5); - let new_coldkey2: AccountId = U256::from(6); - - // Add networks - let netuid1: u16 = 1; - let netuid2: u16 = 2; - add_network(netuid1, 13, 0); - add_network(netuid2, 13, 0); - - // Register neurons in different networks - register_ok_neuron(netuid1, hotkey1, coldkey1, 0); - register_ok_neuron(netuid2, hotkey2, coldkey2, 0); - - // Add balance to coldkeys - SubtensorModule::add_balance_to_coldkey_account( - &coldkey1, - MIN_BALANCE_TO_PERFORM_COLDKEY_SWAP, - ); - SubtensorModule::add_balance_to_coldkey_account( - &coldkey2, - MIN_BALANCE_TO_PERFORM_COLDKEY_SWAP, - ); - - let current_block = SubtensorModule::get_current_block_as_u64(); - let (work1, nonce1) = generate_valid_pow( - &coldkey1, - current_block, - U256::from(BaseDifficulty::::get()), - ); - let (work2, nonce2) = generate_valid_pow( - &coldkey2, - current_block, - U256::from(BaseDifficulty::::get()), - ); - // Schedule swaps for both coldkeys - assert_ok!(SubtensorModule::do_schedule_coldkey_swap( - &coldkey1.clone(), - &new_coldkey1, - work1.to_fixed_bytes().to_vec(), - current_block, - nonce1 - )); - assert_ok!(SubtensorModule::do_schedule_coldkey_swap( - &coldkey2.clone(), - &new_coldkey2, - work2.to_fixed_bytes().to_vec(), - current_block, - nonce2 - )); - // Make 5400 blocks pass - let drain_block: u64 = 7200 * 3 + 1; - run_to_block(drain_block); - - // Run arbitration - SubtensorModule::swap_coldkeys_this_block(&BlockWeights::get().max_block).unwrap(); - - // Check that the balances have been transferred correctly - assert_eq!( - SubtensorModule::get_coldkey_balance(&new_coldkey1), - MIN_BALANCE_TO_PERFORM_COLDKEY_SWAP - ); - assert_eq!( - SubtensorModule::get_coldkey_balance(&new_coldkey2), - MIN_BALANCE_TO_PERFORM_COLDKEY_SWAP - ); - }); -} - -// #[test] -// fn test_get_remaining_arbitration_period() { -// new_test_ext(1).execute_with(|| { -// let coldkey_account_id = U256::from(12345); // arbitrary coldkey -// let new_coldkey_account_id = U256::from(54321); // arbitrary new coldkey - -// let current_block = SubtensorModule::get_current_block_as_u64(); -// let (work, nonce) = generate_valid_pow( -// &coldkey_account_id, -// current_block, -// U256::from(BaseDifficulty::::get()), -// ); - -// SubtensorModule::add_balance_to_coldkey_account( -// &coldkey_account_id, -// MIN_BALANCE_TO_PERFORM_COLDKEY_SWAP, -// ); - -// // Schedule a coldkey swap to set the arbitration block -// assert_ok!(SubtensorModule::do_schedule_coldkey_swap( -// &coldkey_account_id.clone(), -// &new_coldkey_account_id, -// work.to_fixed_bytes().to_vec(), -// current_block, -// nonce -// )); - -// // Get the current block number and arbitration period -// let current_block: u64 = SubtensorModule::get_current_block_as_u64(); -// let arbitration_period: u64 = ArbitrationPeriod::::get(); -// log::info!("arbitration_period: {:?}", arbitration_period); -// let arbitration_block: u64 = current_block + arbitration_period; -// log::info!("arbitration_block: {:?}", arbitration_block); - -// // Check if the remaining arbitration period is correct -// let remaining_period = -// SubtensorModule::get_remaining_arbitration_period(&coldkey_account_id); -// assert_eq!(remaining_period, arbitration_period); - -// // Move the current block forward and check again -// step_block(50); -// let remaining_period = -// SubtensorModule::get_remaining_arbitration_period(&coldkey_account_id); -// assert_eq!(remaining_period, arbitration_period - 50); - -// // Move the current block beyond the arbitration block and check again -// step_block((arbitration_period as u16) - 50 + 1); -// let remaining_period = -// SubtensorModule::get_remaining_arbitration_period(&coldkey_account_id); -// assert_eq!(remaining_period, 0); -// }); -// } - -#[test] -fn test_transfer_coldkey_in_arbitration() { - new_test_ext(1).execute_with(|| { - let coldkey_account_id = U256::from(1); - let recipient_account_id = U256::from(2); - let new_coldkey_account_id = U256::from(3); - - // Add balance to coldkey - SubtensorModule::add_balance_to_coldkey_account( - &coldkey_account_id, - MIN_BALANCE_TO_PERFORM_COLDKEY_SWAP, - ); - - let current_block = SubtensorModule::get_current_block_as_u64(); - let (work, nonce) = generate_valid_pow( - &coldkey_account_id, - current_block, - U256::from(BaseDifficulty::::get()), - ); - - // Schedule a coldkey swap to put the coldkey in arbitration - assert_ok!(SubtensorModule::do_schedule_coldkey_swap( - &coldkey_account_id.clone(), - &new_coldkey_account_id, - work.to_fixed_bytes().to_vec(), - current_block, - nonce - )); - - // Try to transfer balance - let call = RuntimeCall::Balances(BalancesCall::transfer_allow_death { - dest: recipient_account_id, - value: 1000, - }); - - assert_eq!( - validate_transaction(&coldkey_account_id, &call), - Err(TransactionValidityError::Invalid(InvalidTransaction::Call)) - ); - }); -} - -#[test] -fn test_add_stake_coldkey_in_arbitration() { - new_test_ext(1).execute_with(|| { - let hotkey_account_id = U256::from(561337); - let coldkey_account_id = U256::from(61337); - let new_coldkey_account_id = U256::from(71337); - let netuid: u16 = 1; - let start_nonce: u64 = 0; - let tempo: u16 = 13; - - add_network(netuid, tempo, 0); - register_ok_neuron(netuid, hotkey_account_id, coldkey_account_id, start_nonce); - SubtensorModule::add_balance_to_coldkey_account( - &coldkey_account_id, - MIN_BALANCE_TO_PERFORM_COLDKEY_SWAP, - ); - - let current_block = SubtensorModule::get_current_block_as_u64(); - let (work, nonce) = generate_valid_pow( - &coldkey_account_id, - current_block, - U256::from(BaseDifficulty::::get()), - ); - - // Schedule a coldkey swap to put the coldkey in arbitration - assert_ok!(SubtensorModule::do_schedule_coldkey_swap( - &coldkey_account_id.clone(), - &new_coldkey_account_id, - work.to_fixed_bytes().to_vec(), - current_block, - nonce - )); - let call = RuntimeCall::SubtensorModule(crate::Call::add_stake { - hotkey: hotkey_account_id, - amount_staked: 1000, - }); - - // This should now be Ok - assert!(validate_transaction(&coldkey_account_id, &call).is_ok()); - }) -} - -#[test] -fn test_remove_stake_coldkey_in_arbitration() { - new_test_ext(1).execute_with(|| { - let hotkey_account_id = U256::from(561337); - let coldkey_account_id = U256::from(61337); - let new_coldkey_account_id = U256::from(71337); - let netuid: u16 = 1; - let start_nonce: u64 = 0; - let tempo: u16 = 13; - - add_network(netuid, tempo, 0); - register_ok_neuron(netuid, hotkey_account_id, coldkey_account_id, start_nonce); - SubtensorModule::add_balance_to_coldkey_account( - &coldkey_account_id, - MIN_BALANCE_TO_PERFORM_COLDKEY_SWAP, - ); - SubtensorModule::increase_stake_on_hotkey_account(&hotkey_account_id, 1000); - - let current_block = SubtensorModule::get_current_block_as_u64(); - let (work, nonce) = generate_valid_pow( - &coldkey_account_id, - current_block, - U256::from(BaseDifficulty::::get()), - ); - - // Schedule a coldkey swap to put the coldkey in arbitration - assert_ok!(SubtensorModule::do_schedule_coldkey_swap( - &coldkey_account_id.clone(), - &new_coldkey_account_id, - work.to_fixed_bytes().to_vec(), - current_block, - nonce - )); - - let call = RuntimeCall::SubtensorModule(crate::Call::remove_stake { - hotkey: hotkey_account_id, - amount_unstaked: 500, - }); - - // This should now be Ok - assert!(validate_transaction(&coldkey_account_id, &call).is_ok()); - }); -} - -#[test] -fn test_transfer_coldkey_not_in_arbitration() { - new_test_ext(1).execute_with(|| { - let coldkey_account_id = U256::from(61337); - let recipient_account_id = U256::from(71337); - - SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, 60000); - - let call = RuntimeCall::Balances(BalancesCall::transfer_allow_death { - dest: recipient_account_id, - value: 1000, - }); - - // This should be Ok - assert!(validate_transaction(&coldkey_account_id, &call).is_ok()); - }); -} - -fn validate_transaction(who: &AccountId, call: &RuntimeCall) -> TransactionValidity { - SubtensorSignedExtension::::new().validate(who, call, &DispatchInfo::default(), 0) -} - -// Helper function to generate valid PoW -fn generate_valid_pow(coldkey: &U256, block_number: u64, difficulty: U256) -> (H256, u64) { - let mut nonce: u64 = 0; - loop { - let work = SubtensorModule::create_seal_hash(block_number, nonce, coldkey); - if SubtensorModule::hash_meets_difficulty(&work, difficulty) { - return (work, nonce); - } - nonce += 1; - } -} - -// Helper function to advance to the next block and run hooks -fn next_block() { - let current_block = System::block_number(); - System::on_finalize(current_block); - System::set_block_number(current_block + 1); - System::on_initialize(System::block_number()); - SubtensorModule::on_initialize(System::block_number()); -} - -// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test staking -- test_coldkey_meets_enough --exact --nocapture -#[test] -fn test_coldkey_meets_enough() { - new_test_ext(1).execute_with(|| { - let coldkey = U256::from(1); - let new_coldkey = U256::from(2); - let hotkey = U256::from(2); - let netuid = 1u16; - add_network(netuid, 13, 0); - register_ok_neuron(netuid, hotkey, coldkey, 0); - let current_block = SubtensorModule::get_current_block_as_u64(); - let (work1, nonce1) = generate_valid_pow( - &coldkey, - current_block, - U256::from(BaseDifficulty::::get()), - ); - assert_err!( - SubtensorModule::do_schedule_coldkey_swap( - &coldkey.clone(), - &new_coldkey, - work1.to_fixed_bytes().to_vec(), - current_block, - nonce1 - ), - Error::::InsufficientBalanceToPerformColdkeySwap - ); - SubtensorModule::add_balance_to_coldkey_account( - &coldkey, - MIN_BALANCE_TO_PERFORM_COLDKEY_SWAP, - ); - assert_ok!(SubtensorModule::do_schedule_coldkey_swap( - &coldkey.clone(), - &new_coldkey, - work1.to_fixed_bytes().to_vec(), - current_block, - nonce1 - )); - }); -} - -#[test] -fn test_comprehensive_coldkey_swap_scenarios() { - new_test_ext(1).execute_with(|| { - // Set arbitration period to 5 blocks - ArbitrationPeriod::::put(5); - - let subnet_owner1 = U256::from(1); - let subnet_owner2 = U256::from(2); - let regular_user = U256::from(3); - let new_coldkey1 = U256::from(4); - let new_coldkey2 = U256::from(5); - let new_coldkey3 = U256::from(6); - let netuid1 = 1; - let netuid2 = 2; - - // Add networks and register subnet owners - add_network(netuid1, 13, 0); - add_network(netuid2, 13, 0); - SubnetOwner::::insert(netuid1, subnet_owner1); - SubnetOwner::::insert(netuid2, subnet_owner2); - - // Add balance to subnet owners and regular user - SubtensorModule::add_balance_to_coldkey_account( - &subnet_owner1, - MIN_BALANCE_TO_PERFORM_COLDKEY_SWAP, - ); - SubtensorModule::add_balance_to_coldkey_account( - &subnet_owner2, - MIN_BALANCE_TO_PERFORM_COLDKEY_SWAP, - ); - SubtensorModule::add_balance_to_coldkey_account( - ®ular_user, - MIN_BALANCE_TO_PERFORM_COLDKEY_SWAP * 2, - ); - - // Set a very low base difficulty for testing - BaseDifficulty::::put(1); - - let current_block = SubtensorModule::get_current_block_as_u64(); - - // Schedule swaps for subnet owners and regular user - let (work1, nonce1) = generate_valid_pow(&subnet_owner1, current_block, U256::from(BaseDifficulty::::get())); - let (work2, nonce2) = generate_valid_pow(&subnet_owner2, current_block, U256::from(BaseDifficulty::::get())); - let (work3, nonce3) = generate_valid_pow(®ular_user, current_block, U256::from(BaseDifficulty::::get())); - - assert_ok!(SubtensorModule::do_schedule_coldkey_swap( - &subnet_owner1, - &new_coldkey1, - work1.to_fixed_bytes().to_vec(), - current_block, - nonce1 - )); - - assert_ok!(SubtensorModule::do_schedule_coldkey_swap( - &subnet_owner2, - &new_coldkey2, - work2.to_fixed_bytes().to_vec(), - current_block, - nonce2 - )); - - assert_ok!(SubtensorModule::do_schedule_coldkey_swap( - ®ular_user, - &new_coldkey3, - work3.to_fixed_bytes().to_vec(), - current_block, - nonce3 - )); - - // Check if swaps were scheduled correctly - assert_eq!( - ColdkeySwapDestinations::::get(subnet_owner1), - vec![new_coldkey1] - ); - assert_eq!( - ColdkeySwapDestinations::::get(subnet_owner2), - vec![new_coldkey2] - ); - assert_eq!( - ColdkeySwapDestinations::::get(regular_user), - vec![new_coldkey3] - ); - - // Run through the arbitration period plus one block - for i in 0..6 { - next_block(); - SubtensorModule::on_idle(System::block_number(), Weight::MAX); - - log::info!( - "Block {}: Coldkey in arbitration: {}, Swap destinations: {:?}", - i + 1, - SubtensorModule::coldkey_in_arbitration(&subnet_owner1), - ColdkeySwapDestinations::::get(subnet_owner1) - ); - - // Test edge case: try to schedule another swap during arbitration - if i == 2 { - let (work4, nonce4) = generate_valid_pow( - &subnet_owner1, - current_block + i as u64, - U256::from(4) * U256::from(BaseDifficulty::::get()), - ); - assert_ok!(SubtensorModule::do_schedule_coldkey_swap( - &subnet_owner1, - &new_coldkey2, - work4.to_fixed_bytes().to_vec(), - current_block + i as u64, - nonce4 - )); - // This should add new_coldkey2 to subnet_owner1's destinations - assert_eq!( - ColdkeySwapDestinations::::get(subnet_owner1), - vec![new_coldkey1, new_coldkey2] - ); - } - } - - // Check if swaps have been executed - log::info!( - "After arbitration period - Swap destinations for subnet_owner1: {:?}", - ColdkeySwapDestinations::::get(subnet_owner1) - ); - assert_eq!( - ColdkeySwapDestinations::::get(subnet_owner1), - vec![new_coldkey1, new_coldkey2], - "ColdkeySwapDestinations for subnet_owner1 should still contain two destinations after arbitration period" - ); - assert!(ColdkeySwapDestinations::::get(subnet_owner2).is_empty()); - assert!(ColdkeySwapDestinations::::get(regular_user).is_empty()); - - // Verify that subnet ownerships have NOT been transferred for subnet_owner1 - assert_eq!(SubnetOwner::::get(netuid1), subnet_owner1); - // But subnet_owner2's ownership should have been transferred - assert_eq!(SubnetOwner::::get(netuid2), new_coldkey2); - - // Verify regular user's balance has been transferred - assert_eq!( - SubtensorModule::get_coldkey_balance(&new_coldkey3), - MIN_BALANCE_TO_PERFORM_COLDKEY_SWAP * 2 - ); - assert_eq!(SubtensorModule::get_coldkey_balance(®ular_user), 0); - }); -} - #[test] fn test_get_total_delegated_stake_after_unstaking() { new_test_ext(1).execute_with(|| { @@ -4451,271 +3383,4 @@ fn test_get_total_delegated_stake_exclude_owner_stake() { expected_delegated_stake, actual_delegated_stake ); }); -} - -#[test] -fn test_do_schedule_coldkey_swap_subnet_owner_skips_min_balance() { - new_test_ext(1).execute_with(|| { - let netuid = 1u16; - let subnet_owner = U256::from(1); - let new_coldkey = U256::from(2); - let hotkey = U256::from(3); - let current_block = 0u64; - - add_network(netuid, 0, 0); - register_ok_neuron(netuid, hotkey, subnet_owner, 0); - - // Make subnet_owner the owner of the subnet - SubnetOwner::::insert(netuid, subnet_owner); - - // Ensure subnet_owner has less than minimum balance - assert!( - SubtensorModule::get_coldkey_balance(&subnet_owner) - < MIN_BALANCE_TO_PERFORM_COLDKEY_SWAP - ); - - // Generate valid PoW - let difficulty = U256::from(4) * U256::from(BaseDifficulty::::get()); - let (work, nonce) = generate_valid_pow(&subnet_owner, current_block, difficulty); - - // Debug prints - println!("Subnet owner: {:?}", subnet_owner); - println!("New coldkey: {:?}", new_coldkey); - println!("Current block: {}", current_block); - println!("Difficulty: {:?}", difficulty); - println!("Work: {:?}", work); - println!("Nonce: {}", nonce); - - // Verify the PoW - let seal = SubtensorModule::create_seal_hash(current_block, nonce, &subnet_owner); - println!("Calculated seal: {:?}", seal); - println!("Work matches seal: {}", work == seal); - println!( - "Seal meets difficulty: {}", - SubtensorModule::hash_meets_difficulty(&seal, difficulty) - ); - - // Attempt to schedule coldkey swap - let result = SubtensorModule::do_schedule_coldkey_swap( - &subnet_owner, - &new_coldkey, - work.to_fixed_bytes().to_vec(), - current_block, - nonce, - ); - - // Print the result - println!("Swap result: {:?}", result); - - assert_ok!(result); - - // Verify that the swap was scheduled - assert_eq!( - ColdkeySwapDestinations::::get(subnet_owner), - vec![new_coldkey] - ); - }); -} - -#[test] -fn test_do_schedule_coldkey_swap_delegate_with_500_tao_skips_min_balance() { - new_test_ext(1).execute_with(|| { - let netuid = 1u16; - let delegate_coldkey = U256::from(1); - let delegate_hotkey = U256::from(2); - let new_coldkey = U256::from(3); - let delegator = U256::from(4); - let current_block = 0u64; - - add_network(netuid, 0, 0); - register_ok_neuron(netuid, delegate_hotkey, delegate_coldkey, 0); - - // Make delegate a delegate - assert_ok!(SubtensorModule::become_delegate( - RuntimeOrigin::signed(delegate_coldkey), - delegate_hotkey - )); - - // Add more than 500 TAO of stake to the delegate's hotkey - let stake_amount = 501_000_000_000; // 501 TAO in RAO - SubtensorModule::add_balance_to_coldkey_account(&delegator, stake_amount); - assert_ok!(SubtensorModule::add_stake( - RuntimeOrigin::signed(delegator), - delegate_hotkey, - stake_amount - )); - - // Debug prints - println!( - "Delegator balance: {}", - SubtensorModule::get_coldkey_balance(&delegator) - ); - println!( - "Delegate coldkey balance: {}", - SubtensorModule::get_coldkey_balance(&delegate_coldkey) - ); - println!("Stake amount: {}", stake_amount); - println!( - "Delegate hotkey total stake: {}", - SubtensorModule::get_total_stake_for_hotkey(&delegate_hotkey) - ); - println!( - "Delegate coldkey delegated stake: {}", - SubtensorModule::get_total_delegated_stake(&delegate_coldkey) - ); - - // Ensure delegate's coldkey has less than minimum balance - assert!( - SubtensorModule::get_coldkey_balance(&delegate_coldkey) - < MIN_BALANCE_TO_PERFORM_COLDKEY_SWAP, - "Delegate coldkey balance should be less than minimum required" - ); - - // Ensure the delegate's hotkey has more than 500 TAO delegated - assert!( - SubtensorModule::get_total_delegated_stake(&delegate_coldkey) >= 500_000_000_000, - "Delegate hotkey should have at least 500 TAO delegated" - ); - - // Generate valid PoW - let (work, nonce) = generate_valid_pow( - &delegate_coldkey, - current_block, - U256::from(4) * U256::from(BaseDifficulty::::get()), - ); - - // Debug prints - println!("Work: {:?}", work); - println!("Nonce: {}", nonce); - - // Attempt to schedule coldkey swap - let result = SubtensorModule::do_schedule_coldkey_swap( - &delegate_coldkey, - &new_coldkey, - work.to_fixed_bytes().to_vec(), - current_block, - nonce, - ); - - // Print the result - println!("Swap result: {:?}", result); - - assert_ok!(result); - - // Verify that the swap was scheduled - assert_eq!( - ColdkeySwapDestinations::::get(delegate_coldkey), - vec![new_coldkey] - ); - - // Additional debug prints after swap - println!( - "Coldkey swap destinations: {:?}", - ColdkeySwapDestinations::::get(delegate_coldkey) - ); - println!( - "Is coldkey in arbitration: {}", - SubtensorModule::coldkey_in_arbitration(&delegate_coldkey) - ); - }); -} - -#[test] -fn test_do_schedule_coldkey_swap_regular_user_fails_min_balance() { - new_test_ext(1).execute_with(|| { - let netuid = 1u16; - let regular_user = U256::from(1); - let new_coldkey = U256::from(2); - let hotkey = U256::from(3); - let current_block = 0u64; - let nonce = 0u64; - - add_network(netuid, 0, 0); - register_ok_neuron(netuid, hotkey, regular_user, 0); - - // Ensure regular_user has less than minimum balance - assert!( - SubtensorModule::get_coldkey_balance(®ular_user) - < MIN_BALANCE_TO_PERFORM_COLDKEY_SWAP - ); - - let (work, _) = generate_valid_pow( - ®ular_user, - current_block, - U256::from(4) * U256::from(BaseDifficulty::::get()), - ); - - // Attempt to schedule coldkey swap - assert_noop!( - SubtensorModule::do_schedule_coldkey_swap( - ®ular_user, - &new_coldkey, - work.to_fixed_bytes().to_vec(), - current_block, - nonce - ), - Error::::InsufficientBalanceToPerformColdkeySwap - ); - - // Verify that the swap was not scheduled - assert!(ColdkeySwapDestinations::::get(regular_user).is_empty()); - }); -} - -#[test] -fn test_do_schedule_coldkey_swap_regular_user_passes_min_balance() { - new_test_ext(1).execute_with(|| { - let netuid = 1u16; - let regular_user = U256::from(1); - let new_coldkey = U256::from(2); - let hotkey = U256::from(3); - let current_block = 0u64; - - add_network(netuid, 0, 0); - register_ok_neuron(netuid, hotkey, regular_user, 0); - - // Ensure regular_user has more than minimum balance - SubtensorModule::add_balance_to_coldkey_account( - ®ular_user, - MIN_BALANCE_TO_PERFORM_COLDKEY_SWAP + 1, - ); - assert!( - SubtensorModule::get_coldkey_balance(®ular_user) - > MIN_BALANCE_TO_PERFORM_COLDKEY_SWAP - ); - - // Generate valid PoW - let (work, nonce) = generate_valid_pow( - ®ular_user, - current_block, - U256::from(4) * U256::from(BaseDifficulty::::get()), - ); - - // Debug prints - println!("Regular user: {:?}", regular_user); - println!("New coldkey: {:?}", new_coldkey); - println!("Current block: {}", current_block); - println!("Work: {:?}", work); - println!("Nonce: {}", nonce); - - // Attempt to schedule coldkey swap - let result = SubtensorModule::do_schedule_coldkey_swap( - ®ular_user, - &new_coldkey, - work.to_fixed_bytes().to_vec(), - current_block, - nonce, - ); - - // Print the result - println!("Swap result: {:?}", result); - - assert_ok!(result); - - // Verify that the swap was scheduled - assert_eq!( - ColdkeySwapDestinations::::get(regular_user), - vec![new_coldkey] - ); - }); -} +} \ No newline at end of file diff --git a/pallets/subtensor/tests/swap.rs b/pallets/subtensor/tests/swap.rs index 21c3a983a..1d05b1c51 100644 --- a/pallets/subtensor/tests/swap.rs +++ b/pallets/subtensor/tests/swap.rs @@ -4,9 +4,9 @@ use codec::Encode; use frame_support::weights::Weight; use frame_support::{assert_err, assert_noop, assert_ok}; use frame_system::{Config, RawOrigin}; +use pallet_subtensor::*; mod mock; use mock::*; -use pallet_subtensor::*; use sp_core::U256; #[test] @@ -65,31 +65,31 @@ fn test_do_swap_hotkey_ok() { // UIDs for netuid in SubtensorModule::get_netuid_is_member(&old_hotkey, &mut weight) { assert_eq!( - Uids::::get(netuid, new_hotkey), - Uids::::get(netuid, old_hotkey) + pallet_subtensor::Uids::::get(netuid, new_hotkey), + pallet_subtensor::Uids::::get(netuid, old_hotkey) ); } // Prometheus for netuid in SubtensorModule::get_netuid_is_member(&old_hotkey, &mut weight) { assert_eq!( - Prometheus::::get(netuid, new_hotkey), - Prometheus::::get(netuid, old_hotkey) + pallet_subtensor::Prometheus::::get(netuid, new_hotkey), + pallet_subtensor::Prometheus::::get(netuid, old_hotkey) ); } // LoadedEmission for netuid in SubtensorModule::get_netuid_is_member(&old_hotkey, &mut weight) { assert_eq!( - LoadedEmission::::get(netuid).unwrap(), - LoadedEmission::::get(netuid).unwrap() + pallet_subtensor::LoadedEmission::::get(netuid).unwrap(), + pallet_subtensor::LoadedEmission::::get(netuid).unwrap() ); } // IsNetworkMember for netuid in SubtensorModule::get_netuid_is_member(&old_hotkey, &mut weight) { - assert!(IsNetworkMember::::contains_key(new_hotkey, netuid)); - assert!(!IsNetworkMember::::contains_key(old_hotkey, netuid)); + assert!(pallet_subtensor::IsNetworkMember::::contains_key(new_hotkey, netuid)); + assert!(!pallet_subtensor::IsNetworkMember::::contains_key(old_hotkey, netuid)); } // Owner @@ -97,34 +97,34 @@ fn test_do_swap_hotkey_ok() { // TotalHotkeyStake assert_eq!( - TotalHotkeyStake::::get(new_hotkey), - TotalHotkeyStake::::get(old_hotkey) + pallet_subtensor::TotalHotkeyStake::::get(new_hotkey), + pallet_subtensor::TotalHotkeyStake::::get(old_hotkey) ); // Delegates assert_eq!( - Delegates::::get(new_hotkey), - Delegates::::get(old_hotkey) + pallet_subtensor::Delegates::::get(new_hotkey), + pallet_subtensor::Delegates::::get(old_hotkey) ); // LastTxBlock assert_eq!( - LastTxBlock::::get(new_hotkey), - LastTxBlock::::get(old_hotkey) + pallet_subtensor::LastTxBlock::::get(new_hotkey), + pallet_subtensor::LastTxBlock::::get(old_hotkey) ); // Axons for netuid in SubtensorModule::get_netuid_is_member(&old_hotkey, &mut weight) { assert_eq!( - Axons::::get(netuid, new_hotkey), - Axons::::get(netuid, old_hotkey) + pallet_subtensor::Axons::::get(netuid, new_hotkey), + pallet_subtensor::Axons::::get(netuid, old_hotkey) ); } // TotalHotkeyColdkeyStakesThisInterval assert_eq!( - TotalHotkeyColdkeyStakesThisInterval::::get(new_hotkey, coldkey), - TotalHotkeyColdkeyStakesThisInterval::::get(old_hotkey, coldkey) + pallet_subtensor::TotalHotkeyColdkeyStakesThisInterval::::get(new_hotkey, coldkey), + pallet_subtensor::TotalHotkeyColdkeyStakesThisInterval::::get(old_hotkey, coldkey) ); }); } @@ -226,8 +226,8 @@ fn test_do_swap_hotkey_ok_robust() { // Verify raw storage maps // Stake - for (coldkey, stake_amount) in Stake::::iter_prefix(old_hotkeys[i]) { - assert_eq!(Stake::::get(new_hotkeys[i], coldkey), stake_amount); + for (coldkey, stake_amount) in pallet_subtensor::Stake::::iter_prefix(old_hotkeys[i]) { + assert_eq!(pallet_subtensor::Stake::::get(new_hotkeys[i], coldkey), stake_amount); } let mut weight = Weight::zero(); @@ -236,8 +236,8 @@ fn test_do_swap_hotkey_ok_robust() { SubtensorModule::get_netuid_is_member(&old_hotkeys[i], &mut weight) { assert_eq!( - Uids::::get(netuid, new_hotkeys[i]), - Uids::::get(netuid, old_hotkeys[i]) + pallet_subtensor::Uids::::get(netuid, new_hotkeys[i]), + pallet_subtensor::Uids::::get(netuid, old_hotkeys[i]) ); } @@ -246,8 +246,8 @@ fn test_do_swap_hotkey_ok_robust() { SubtensorModule::get_netuid_is_member(&old_hotkeys[i], &mut weight) { assert_eq!( - Prometheus::::get(netuid, new_hotkeys[i]), - Prometheus::::get(netuid, old_hotkeys[i]) + pallet_subtensor::Prometheus::::get(netuid, new_hotkeys[i]), + pallet_subtensor::Prometheus::::get(netuid, old_hotkeys[i]) ); } @@ -256,8 +256,8 @@ fn test_do_swap_hotkey_ok_robust() { SubtensorModule::get_netuid_is_member(&old_hotkeys[i], &mut weight) { assert_eq!( - LoadedEmission::::get(netuid).unwrap(), - LoadedEmission::::get(netuid).unwrap() + pallet_subtensor::LoadedEmission::::get(netuid).unwrap(), + pallet_subtensor::LoadedEmission::::get(netuid).unwrap() ); } @@ -265,23 +265,23 @@ fn test_do_swap_hotkey_ok_robust() { for netuid in SubtensorModule::get_netuid_is_member(&old_hotkeys[i], &mut weight) { - assert!(IsNetworkMember::::contains_key( + assert!(pallet_subtensor::IsNetworkMember::::contains_key( new_hotkeys[i], netuid )); - assert!(!IsNetworkMember::::contains_key( + assert!(!pallet_subtensor::IsNetworkMember::::contains_key( old_hotkeys[i], netuid )); } // Owner - assert_eq!(Owner::::get(new_hotkeys[i]), coldkeys[i]); + assert_eq!(pallet_subtensor::Owner::::get(new_hotkeys[i]), coldkeys[i]); // Keys - for (uid, hotkey) in Keys::::iter_prefix(netuid) { + for (uid, hotkey) in pallet_subtensor::Keys::::iter_prefix(netuid) { if hotkey == old_hotkeys[i] { - assert_eq!(Keys::::get(netuid, uid), new_hotkeys[i]); + assert_eq!(pallet_subtensor::Keys::::get(netuid, uid), new_hotkeys[i]); } } @@ -730,7 +730,7 @@ fn test_swap_axons_success() { // Initialize Axons for old_hotkey for netuid in &netuid_is_member { - Axons::::insert(netuid, old_hotkey, axon_info.clone()); + pallet_subtensor::Axons::::insert(netuid, old_hotkey, axon_info.clone()); } // Perform the swap @@ -738,8 +738,8 @@ fn test_swap_axons_success() { // Verify the swap for netuid in &netuid_is_member { - assert_eq!(Axons::::get(netuid, new_hotkey).unwrap(), axon_info); - assert!(!Axons::::contains_key(netuid, old_hotkey)); + assert_eq!(pallet_subtensor::Axons::::get(netuid, new_hotkey).unwrap(), axon_info); + assert!(!pallet_subtensor::Axons::::contains_key(netuid, old_hotkey)); } }); } @@ -764,7 +764,7 @@ fn test_swap_axons_weight_update() { // Initialize Axons for old_hotkey for netuid in &netuid_is_member { - Axons::::insert(netuid, old_hotkey, axon_info.clone()); + pallet_subtensor::Axons::::insert(netuid, old_hotkey, axon_info.clone()); } // Perform the swap @@ -789,7 +789,7 @@ fn test_swap_keys_success() { // Initialize Keys for old_hotkey for netuid in &netuid_is_member { log::info!("Inserting old_hotkey:{:?} netuid:{:?}", old_hotkey, netuid); - Keys::::insert(*netuid, uid, old_hotkey); + pallet_subtensor::Keys::::insert(*netuid, uid, old_hotkey); } // Perform the swap @@ -803,7 +803,7 @@ fn test_swap_keys_success() { uid, new_hotkey ); - assert_eq!(Keys::::get(netuid, uid), new_hotkey); + assert_eq!(pallet_subtensor::Keys::::get(netuid, uid), new_hotkey); } }); } @@ -819,7 +819,7 @@ fn test_swap_keys_weight_update() { // Initialize Keys for old_hotkey for netuid in &netuid_is_member { - Keys::::insert(*netuid, uid, old_hotkey); + pallet_subtensor::Keys::::insert(*netuid, uid, old_hotkey); } // Perform the swap @@ -843,7 +843,7 @@ fn test_swap_loaded_emission_success() { // Initialize LoadedEmission for old_hotkey for netuid in &netuid_is_member { - LoadedEmission::::mutate(netuid, |emission_exists| { + pallet_subtensor::LoadedEmission::::mutate(netuid, |emission_exists| { if let Some(emissions) = emission_exists { emissions.push((old_hotkey, se, ve)); } else { @@ -862,7 +862,7 @@ fn test_swap_loaded_emission_success() { // Verify the swap for netuid in &netuid_is_member { - let emissions = LoadedEmission::::get(netuid).unwrap(); + let emissions = pallet_subtensor::LoadedEmission::::get(netuid).unwrap(); assert!(emissions.iter().any(|(hk, _, _)| hk == &new_hotkey)); assert!(!emissions.iter().any(|(hk, _, _)| hk == &old_hotkey)); } @@ -882,7 +882,7 @@ fn test_swap_loaded_emission_weight_update() { // Initialize LoadedEmission for old_hotkey for netuid in &netuid_is_member { - LoadedEmission::::mutate(netuid, |emission_exists| { + pallet_subtensor::LoadedEmission::::mutate(netuid, |emission_exists| { if let Some(emissions) = emission_exists { emissions.push((old_hotkey, se, ve)); } else { @@ -916,7 +916,7 @@ fn test_swap_uids_success() { // Initialize Uids for old_hotkey for netuid in &netuid_is_member { - Uids::::insert(netuid, old_hotkey, uid); + pallet_subtensor::Uids::::insert(netuid, old_hotkey, uid); } // Perform the swap @@ -924,8 +924,8 @@ fn test_swap_uids_success() { // Verify the swap for netuid in &netuid_is_member { - assert_eq!(Uids::::get(netuid, new_hotkey).unwrap(), uid); - assert!(!Uids::::contains_key(netuid, old_hotkey)); + assert_eq!(pallet_subtensor::Uids::::get(netuid, new_hotkey).unwrap(), uid); + assert!(!pallet_subtensor::Uids::::contains_key(netuid, old_hotkey)); } }); } @@ -941,7 +941,7 @@ fn test_swap_uids_weight_update() { // Initialize Uids for old_hotkey for netuid in &netuid_is_member { - Uids::::insert(netuid, old_hotkey, uid); + pallet_subtensor::Uids::::insert(netuid, old_hotkey, uid); } // Perform the swap @@ -970,7 +970,7 @@ fn test_swap_prometheus_success() { // Initialize Prometheus for old_hotkey for netuid in &netuid_is_member { - Prometheus::::insert(netuid, old_hotkey, prometheus_info.clone()); + pallet_subtensor::Prometheus::::insert(netuid, old_hotkey, prometheus_info.clone()); } // Perform the swap @@ -979,10 +979,10 @@ fn test_swap_prometheus_success() { // Verify the swap for netuid in &netuid_is_member { assert_eq!( - Prometheus::::get(netuid, new_hotkey).unwrap(), + pallet_subtensor::Prometheus::::get(netuid, new_hotkey).unwrap(), prometheus_info ); - assert!(!Prometheus::::contains_key(netuid, old_hotkey)); + assert!(!pallet_subtensor::Prometheus::::contains_key(netuid, old_hotkey)); } }); } @@ -1004,7 +1004,7 @@ fn test_swap_prometheus_weight_update() { // Initialize Prometheus for old_hotkey for netuid in &netuid_is_member { - Prometheus::::insert(netuid, old_hotkey, prometheus_info.clone()); + pallet_subtensor::Prometheus::::insert(netuid, old_hotkey, prometheus_info.clone()); } // Perform the swap diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index a4abd124f..0ed3cd10f 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -880,7 +880,6 @@ parameter_types! { pub const InitialAlphaHigh: u16 = 58982; // Represents 0.9 as per the production default pub const InitialAlphaLow: u16 = 45875; // Represents 0.7 as per the production default pub const InitialLiquidAlphaOn: bool = false; // Default value for LiquidAlphaOn - pub const SubtensorInitialBaseDifficulty: u64 = 10_000_000; // Base difficulty } impl pallet_subtensor::Config for Runtime { @@ -936,7 +935,6 @@ impl pallet_subtensor::Config for Runtime { type AlphaHigh = InitialAlphaHigh; type AlphaLow = InitialAlphaLow; type LiquidAlphaOn = InitialLiquidAlphaOn; - type InitialBaseDifficulty = SubtensorInitialBaseDifficulty; } use sp_runtime::BoundedVec; From 0f8d50b19b27a0664eef46526b6e3d5d7905b317 Mon Sep 17 00:00:00 2001 From: const Date: Mon, 15 Jul 2024 14:10:33 -0500 Subject: [PATCH 09/58] pre fix --- pallets/subtensor/src/lib.rs | 2 +- pallets/subtensor/src/migration.rs | 661 -------------- pallets/subtensor/src/staking.rs | 851 ------------------ pallets/subtensor/src/staking/add_stake.rs | 125 +++ .../subtensor/src/staking/become_delegate.rs | 96 ++ .../subtensor/src/staking/decrease_take.rs | 82 ++ pallets/subtensor/src/staking/helpers.rs | 397 ++++++++ .../subtensor/src/staking/increase_take.rs | 99 ++ pallets/subtensor/src/staking/mod.rs | 7 + pallets/subtensor/src/staking/remove_stake.rs | 120 +++ pallets/subtensor/src/swap/swap_coldkey.rs | 2 +- 11 files changed, 928 insertions(+), 1514 deletions(-) delete mode 100644 pallets/subtensor/src/migration.rs delete mode 100644 pallets/subtensor/src/staking.rs create mode 100644 pallets/subtensor/src/staking/add_stake.rs create mode 100644 pallets/subtensor/src/staking/become_delegate.rs create mode 100644 pallets/subtensor/src/staking/decrease_take.rs create mode 100644 pallets/subtensor/src/staking/helpers.rs create mode 100644 pallets/subtensor/src/staking/increase_take.rs create mode 100644 pallets/subtensor/src/staking/mod.rs create mode 100644 pallets/subtensor/src/staking/remove_stake.rs diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index 329cebcdc..7596029e0 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -39,13 +39,13 @@ mod rpc_info; mod coinbase; pub mod epoch; pub mod swap; +pub mod staking; mod macros; use macros::{events, errors, dispatches, genesis, hooks, config}; mod registration; mod root; mod serving; -mod staking; mod uids; mod utils; mod weights; diff --git a/pallets/subtensor/src/migration.rs b/pallets/subtensor/src/migration.rs deleted file mode 100644 index cd99f0128..000000000 --- a/pallets/subtensor/src/migration.rs +++ /dev/null @@ -1,661 +0,0 @@ -use super::*; -use frame_support::traits::DefensiveResult; -use frame_support::{ - pallet_prelude::{Identity, OptionQuery}, - storage_alias, - traits::{fungible::Inspect as _, Get, GetStorageVersion, StorageVersion}, - weights::Weight, -}; -use log::info; -use sp_runtime::Saturating; -use sp_std::vec::Vec; - -// TODO (camfairchild): TEST MIGRATION - -const LOG_TARGET: &str = "loadedemissionmigration"; - -pub mod deprecated_loaded_emission_format { - use super::*; - - type AccountIdOf = ::AccountId; - - #[storage_alias] - pub(super) type LoadedEmission = - StorageMap, Identity, u16, Vec<(AccountIdOf, u64)>, OptionQuery>; -} - -/// Migrates and fixes the total coldkey stake. -/// -/// This function iterates through all staking hotkeys, calculates the total stake for each coldkey, -/// and updates the `TotalColdkeyStake` storage accordingly. The migration is only performed if the -/// on-chain storage version is 6. -/// -/// # Returns -/// The weight of the migration process. -pub fn do_migrate_fix_total_coldkey_stake() -> Weight { - // Initialize the weight with one read operation. - let mut weight = T::DbWeight::get().reads(1); - - // Iterate through all staking hotkeys. - for (coldkey, hotkey_vec) in StakingHotkeys::::iter() { - // Init the zero value. - let mut coldkey_stake_sum: u64 = 0; - weight = weight.saturating_add(T::DbWeight::get().reads(1)); - - // Calculate the total stake for the current coldkey. - for hotkey in hotkey_vec { - // Cant fail on retrieval. - coldkey_stake_sum = - coldkey_stake_sum.saturating_add(Stake::::get(hotkey, coldkey.clone())); - weight = weight.saturating_add(T::DbWeight::get().reads(1)); - } - // Update the `TotalColdkeyStake` storage with the calculated stake sum. - // Cant fail on insert. - TotalColdkeyStake::::insert(coldkey.clone(), coldkey_stake_sum); - weight = weight.saturating_add(T::DbWeight::get().writes(1)); - } - weight -} -// Public migrate function to be called by Lib.rs on upgrade. -pub fn migrate_fix_total_coldkey_stake() -> Weight { - let current_storage_version: u16 = 7; - let next_storage_version: u16 = 8; - - // Initialize the weight with one read operation. - let mut weight = T::DbWeight::get().reads(1); - - // Grab the current on-chain storage version. - // Cant fail on retrieval. - let onchain_version = Pallet::::on_chain_storage_version(); - - // Only run this migration on storage version 6. - if onchain_version == current_storage_version { - weight = weight.saturating_add(do_migrate_fix_total_coldkey_stake::()); - // Cant fail on insert. - StorageVersion::new(next_storage_version).put::>(); - weight.saturating_accrue(T::DbWeight::get().writes(1)); - } - - // Return the migration weight. - weight -} - -/// Performs migration to update the total issuance based on the sum of stakes and total balances. -/// This migration is applicable only if the current storage version is 5, after which it updates the storage version to 6. -/// -/// # Returns -/// Weight of the migration process. -pub fn migrate_total_issuance(test: bool) -> Weight { - let mut weight = T::DbWeight::get().reads(1); // Initialize migration weight - - // Execute migration if the current storage version is 5 - if Pallet::::on_chain_storage_version() == StorageVersion::new(5) || test { - // Calculate the sum of all stake values - let stake_sum: u64 = Stake::::iter().fold(0, |accumulator, (_, _, stake_value)| { - accumulator.saturating_add(stake_value) - }); - weight = weight - .saturating_add(T::DbWeight::get().reads_writes(Stake::::iter().count() as u64, 0)); - - // Calculate the sum of all stake values - let locked_sum: u64 = SubnetLocked::::iter() - .fold(0, |accumulator, (_, locked_value)| { - accumulator.saturating_add(locked_value) - }); - weight = weight.saturating_add( - T::DbWeight::get().reads_writes(SubnetLocked::::iter().count() as u64, 0), - ); - - // Retrieve the total balance sum - let total_balance = T::Currency::total_issuance(); - match TryInto::::try_into(total_balance) { - Ok(total_balance_sum) => { - weight = weight.saturating_add(T::DbWeight::get().reads(1)); - - // Compute the total issuance value - let total_issuance_value: u64 = stake_sum - .saturating_add(total_balance_sum) - .saturating_add(locked_sum); - - // Update the total issuance in storage - TotalIssuance::::put(total_issuance_value); - - // Update the storage version to 6 - StorageVersion::new(6).put::>(); - weight = weight.saturating_add(T::DbWeight::get().writes(1)); - } - Err(_) => { - log::error!("Failed to convert total balance to u64, bailing"); - } - } - } - - weight // Return the computed weight of the migration process -} - -pub fn migrate_transfer_ownership_to_foundation(coldkey: [u8; 32]) -> Weight { - let new_storage_version = 3; - - // Setup migration weight - let mut weight = T::DbWeight::get().reads(1); - - // Grab current version - let onchain_version = Pallet::::on_chain_storage_version(); - - // Only runs if we haven't already updated version past above new_storage_version. - if onchain_version < new_storage_version { - info!(target: LOG_TARGET_1, ">>> Migrating subnet 1 and 11 to foundation control {:?}", onchain_version); - - // We have to decode this using a byte slice as we don't have crypto-std - let coldkey_account: ::AccountId = - ::AccountId::decode(&mut &coldkey[..]) - .expect("coldkey is 32-byte array; qed"); - info!("Foundation coldkey: {:?}", coldkey_account); - - let current_block = Pallet::::get_current_block_as_u64(); - weight.saturating_accrue(T::DbWeight::get().reads(1)); - - // Migrate ownership and set creation time as now - SubnetOwner::::insert(1, coldkey_account.clone()); - SubnetOwner::::insert(11, coldkey_account); - - // We are setting the NetworkRegisteredAt storage to a future block to extend the immunity period to 2 weeks - NetworkRegisteredAt::::insert(1, current_block.saturating_add(13 * 7200)); - NetworkRegisteredAt::::insert(11, current_block); - - weight.saturating_accrue(T::DbWeight::get().writes(4)); - - // Update storage version. - StorageVersion::new(new_storage_version).put::>(); // Update to version so we don't run this again. - weight.saturating_accrue(T::DbWeight::get().writes(1)); - - weight - } else { - info!(target: LOG_TARGET_1, "Migration to v3 already done!"); - Weight::zero() - } -} - -pub fn migrate_create_root_network() -> Weight { - // Get the root network uid. - let root_netuid: u16 = 0; - - // Setup migration weight - let mut weight = T::DbWeight::get().reads(1); - - // Check if root network already exists. - if NetworksAdded::::get(root_netuid) { - // Since we read from the database once to determine this - return weight; - } - - // Set the root network as added. - NetworksAdded::::insert(root_netuid, true); - - // Increment the number of total networks. - TotalNetworks::::mutate(|n| n.saturating_inc()); - - // Set the maximum number to the number of senate members. - MaxAllowedUids::::insert(root_netuid, 64); - - // Set the maximum number to the number of validators to all members. - MaxAllowedValidators::::insert(root_netuid, 64); - - // Set the min allowed weights to zero, no weights restrictions. - MinAllowedWeights::::insert(root_netuid, 0); - - // Set the max weight limit to infitiy, no weight restrictions. - MaxWeightsLimit::::insert(root_netuid, u16::MAX); - - // Add default root tempo. - Tempo::::insert(root_netuid, 100); - - // Set the root network as open. - NetworkRegistrationAllowed::::insert(root_netuid, true); - - // Set target registrations for validators as 1 per block. - TargetRegistrationsPerInterval::::insert(root_netuid, 1); - - // Set weight setting rate limit to 1 day - //WeightsSetRateLimit::::insert(root_netuid, 7200); - - // Add our weights for writing to database - weight.saturating_accrue(T::DbWeight::get().writes(8)); - - // Empty senate members entirely, they will be filled by by registrations - // on the subnet. - for hotkey_i in T::SenateMembers::members().iter() { - T::TriumvirateInterface::remove_votes(hotkey_i).defensive_ok(); - T::SenateMembers::remove_member(hotkey_i).defensive_ok(); - - weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2)); - } - - weight -} - -pub fn migrate_delete_subnet_3() -> Weight { - let new_storage_version = 5; - - // Setup migration weight - let mut weight = T::DbWeight::get().reads(1); - - // Grab current version - let onchain_version = Pallet::::on_chain_storage_version(); - - // Only runs if we haven't already updated version past above new_storage_version. - if onchain_version < new_storage_version && Pallet::::if_subnet_exist(3) { - info!(target: LOG_TARGET_1, ">>> Removing subnet 3 {:?}", onchain_version); - - let netuid = 3; - - // We do this all manually as we don't want to call code related to giving subnet owner back their locked token cost. - // --- 2. Remove network count. - SubnetworkN::::remove(netuid); - - // --- 3. Remove network modality storage. - NetworkModality::::remove(netuid); - - // --- 4. Remove netuid from added networks. - NetworksAdded::::remove(netuid); - - // --- 6. Decrement the network counter. - TotalNetworks::::mutate(|n| n.saturating_dec()); - - // --- 7. Remove various network-related storages. - NetworkRegisteredAt::::remove(netuid); - - weight.saturating_accrue(T::DbWeight::get().writes(5)); - - // --- 8. Remove incentive mechanism memory. - let _ = Uids::::clear_prefix(netuid, u32::MAX, None); - let _ = Keys::::clear_prefix(netuid, u32::MAX, None); - let _ = Bonds::::clear_prefix(netuid, u32::MAX, None); - let _ = Weights::::clear_prefix(netuid, u32::MAX, None); - - weight.saturating_accrue(T::DbWeight::get().writes(4)); - - // --- 9. Remove various network-related parameters. - Rank::::remove(netuid); - Trust::::remove(netuid); - Active::::remove(netuid); - Emission::::remove(netuid); - Incentive::::remove(netuid); - Consensus::::remove(netuid); - Dividends::::remove(netuid); - PruningScores::::remove(netuid); - LastUpdate::::remove(netuid); - ValidatorPermit::::remove(netuid); - ValidatorTrust::::remove(netuid); - - weight.saturating_accrue(T::DbWeight::get().writes(11)); - - // --- 10. Erase network parameters. - Tempo::::remove(netuid); - Kappa::::remove(netuid); - Difficulty::::remove(netuid); - MaxAllowedUids::::remove(netuid); - ImmunityPeriod::::remove(netuid); - ActivityCutoff::::remove(netuid); - EmissionValues::::remove(netuid); - MaxWeightsLimit::::remove(netuid); - MinAllowedWeights::::remove(netuid); - RegistrationsThisInterval::::remove(netuid); - POWRegistrationsThisInterval::::remove(netuid); - BurnRegistrationsThisInterval::::remove(netuid); - - weight.saturating_accrue(T::DbWeight::get().writes(12)); - - // Update storage version. - StorageVersion::new(new_storage_version).put::>(); // Update version so we don't run this again. - // One write to storage version - weight.saturating_accrue(T::DbWeight::get().writes(1)); - - weight - } else { - info!(target: LOG_TARGET_1, "Migration to v3 already done!"); - Weight::zero() - } -} - -pub fn migrate_delete_subnet_21() -> Weight { - let new_storage_version = 4; - - // Setup migration weight - let mut weight = T::DbWeight::get().reads(1); - - // Grab current version - let onchain_version = Pallet::::on_chain_storage_version(); - - // Only runs if we haven't already updated version past above new_storage_version. - if onchain_version < new_storage_version && Pallet::::if_subnet_exist(21) { - info!(target: LOG_TARGET_1, ">>> Removing subnet 21 {:?}", onchain_version); - - let netuid = 21; - - // We do this all manually as we don't want to call code related to giving subnet owner back their locked token cost. - // --- 2. Remove network count. - SubnetworkN::::remove(netuid); - - // --- 3. Remove network modality storage. - NetworkModality::::remove(netuid); - - // --- 4. Remove netuid from added networks. - NetworksAdded::::remove(netuid); - - // --- 6. Decrement the network counter. - TotalNetworks::::mutate(|n| n.saturating_dec()); - - // --- 7. Remove various network-related storages. - NetworkRegisteredAt::::remove(netuid); - - weight.saturating_accrue(T::DbWeight::get().writes(5)); - - // --- 8. Remove incentive mechanism memory. - let _ = Uids::::clear_prefix(netuid, u32::MAX, None); - let _ = Keys::::clear_prefix(netuid, u32::MAX, None); - let _ = Bonds::::clear_prefix(netuid, u32::MAX, None); - let _ = Weights::::clear_prefix(netuid, u32::MAX, None); - - weight.saturating_accrue(T::DbWeight::get().writes(4)); - - // --- 9. Remove various network-related parameters. - Rank::::remove(netuid); - Trust::::remove(netuid); - Active::::remove(netuid); - Emission::::remove(netuid); - Incentive::::remove(netuid); - Consensus::::remove(netuid); - Dividends::::remove(netuid); - PruningScores::::remove(netuid); - LastUpdate::::remove(netuid); - ValidatorPermit::::remove(netuid); - ValidatorTrust::::remove(netuid); - - weight.saturating_accrue(T::DbWeight::get().writes(11)); - - // --- 10. Erase network parameters. - Tempo::::remove(netuid); - Kappa::::remove(netuid); - Difficulty::::remove(netuid); - MaxAllowedUids::::remove(netuid); - ImmunityPeriod::::remove(netuid); - ActivityCutoff::::remove(netuid); - EmissionValues::::remove(netuid); - MaxWeightsLimit::::remove(netuid); - MinAllowedWeights::::remove(netuid); - RegistrationsThisInterval::::remove(netuid); - POWRegistrationsThisInterval::::remove(netuid); - BurnRegistrationsThisInterval::::remove(netuid); - - weight.saturating_accrue(T::DbWeight::get().writes(12)); - - // Update storage version. - StorageVersion::new(new_storage_version).put::>(); // Update version so we don't run this again. - // One write to storage version - weight.saturating_accrue(T::DbWeight::get().writes(1)); - - weight - } else { - info!(target: LOG_TARGET_1, "Migration to v4 already done!"); - Weight::zero() - } -} - -pub fn migrate_to_v1_separate_emission() -> Weight { - use deprecated_loaded_emission_format as old; - // Check storage version - let mut weight = T::DbWeight::get().reads_writes(1, 0); - - // Grab current version - let onchain_version = Pallet::::on_chain_storage_version(); - - // Only runs if we haven't already updated version to 1. - if onchain_version < 1 { - info!(target: LOG_TARGET, ">>> Updating the LoadedEmission to a new format {:?}", onchain_version); - - // We transform the storage values from the old into the new format. - - // Start by removing any undecodable entries. - let curr_loaded_emission: Vec = old::LoadedEmission::::iter_keys().collect(); - for netuid in curr_loaded_emission { - // Iterates over the netuids - weight.saturating_accrue(T::DbWeight::get().reads(1)); - if old::LoadedEmission::::try_get(netuid).is_err() { - weight.saturating_accrue(T::DbWeight::get().writes(1)); - old::LoadedEmission::::remove(netuid); - log::warn!( - "Was unable to decode old loaded_emisssion for netuid {}", - netuid - ); - } - } - - // Translate the old storage values into the new format. - LoadedEmission::::translate::, u64)>, _>( - |netuid: u16, - netuid_emissions: Vec<(AccountIdOf, u64)>| - -> Option, u64, u64)>> { - info!(target: LOG_TARGET, " Do migration of netuid: {:?}...", netuid); - - // We will assume all loaded emission is validator emissions, - // so this will get distributed over delegatees (nominators), if there are any - // This will NOT effect any servers that are not (also) a delegate validator. - // server_emission will be 0 for any alread loaded emission. - - let mut new_netuid_emissions = Vec::new(); - for (server, validator_emission) in netuid_emissions { - new_netuid_emissions.push((server, 0_u64, validator_emission)); - } - - // One read (old) and write (new) per netuid - weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); - - Some(new_netuid_emissions) - }, - ); - - // Update storage version. - StorageVersion::new(1).put::>(); // Update to version 2 so we don't run this again. - // One write to storage version - weight.saturating_accrue(T::DbWeight::get().writes(1)); - - weight - } else { - info!(target: LOG_TARGET_1, "Migration to v2 already done!"); - Weight::zero() - } -} - -const LOG_TARGET_1: &str = "fixtotalstakestorage"; - -pub fn migrate_to_v2_fixed_total_stake() -> Weight { - let new_storage_version = 2; - - // Check storage version - let mut weight = T::DbWeight::get().reads(1); - - // Grab current version - let onchain_version = Pallet::::on_chain_storage_version(); - - // Only runs if we haven't already updated version past above new_storage_version. - if onchain_version < new_storage_version { - info!(target: LOG_TARGET_1, ">>> Fixing the TotalStake and TotalColdkeyStake storage {:?}", onchain_version); - - // Stake and TotalHotkeyStake are known to be accurate - // TotalColdkeyStake is known to be inaccurate - // TotalStake is known to be inaccurate - - TotalStake::::put(0); // Set to 0 - weight.saturating_accrue(T::DbWeight::get().writes(1)); - - // We iterate over TotalColdkeyStake keys and set them to 0 - let total_coldkey_stake_keys = TotalColdkeyStake::::iter_keys().collect::>(); - for coldkey in total_coldkey_stake_keys { - weight.saturating_accrue(T::DbWeight::get().reads(1)); - TotalColdkeyStake::::insert(coldkey, 0); // Set to 0 - weight.saturating_accrue(T::DbWeight::get().writes(1)); - } - - // Now we iterate over the entire stake map, and sum each coldkey stake - // We also track TotalStake - for (_, coldkey, stake) in Stake::::iter() { - weight.saturating_accrue(T::DbWeight::get().reads(1)); - // Get the current coldkey stake - let mut total_coldkey_stake = TotalColdkeyStake::::get(coldkey.clone()); - weight.saturating_accrue(T::DbWeight::get().reads(1)); - // Add the stake to the coldkey stake - total_coldkey_stake = total_coldkey_stake.saturating_add(stake); - // Update the coldkey stake - TotalColdkeyStake::::insert(coldkey, total_coldkey_stake); - weight.saturating_accrue(T::DbWeight::get().writes(1)); - - // Get the current total stake - let mut total_stake = TotalStake::::get(); - weight.saturating_accrue(T::DbWeight::get().reads(1)); - // Add the stake to the total stake - total_stake = total_stake.saturating_add(stake); - // Update the total stake - TotalStake::::put(total_stake); - weight.saturating_accrue(T::DbWeight::get().writes(1)); - } - - // Now both TotalStake and TotalColdkeyStake are accurate - - // Update storage version. - StorageVersion::new(new_storage_version).put::>(); // Update to version so we don't run this again. - // One write to storage version - weight.saturating_accrue(T::DbWeight::get().writes(1)); - - weight - } else { - info!(target: LOG_TARGET_1, "Migration to v2 already done!"); - Weight::zero() - } -} - -/// Migrate the OwnedHotkeys map to the new storage format -pub fn migrate_populate_owned() -> Weight { - // Setup migration weight - let mut weight = T::DbWeight::get().reads(1); - let migration_name = "Populate OwnedHotkeys map"; - - // Check if this migration is needed (if OwnedHotkeys map is empty) - let migrate = OwnedHotkeys::::iter().next().is_none(); - - // Only runs if the migration is needed - if migrate { - info!(target: LOG_TARGET_1, ">>> Starting Migration: {}", migration_name); - - let mut longest_hotkey_vector: usize = 0; - let mut longest_coldkey: Option = None; - let mut keys_touched: u64 = 0; - let mut storage_reads: u64 = 0; - let mut storage_writes: u64 = 0; - - // Iterate through all Owner entries - Owner::::iter().for_each(|(hotkey, coldkey)| { - storage_reads = storage_reads.saturating_add(1); // Read from Owner storage - let mut hotkeys = OwnedHotkeys::::get(&coldkey); - storage_reads = storage_reads.saturating_add(1); // Read from OwnedHotkeys storage - - // Add the hotkey if it's not already in the vector - if !hotkeys.contains(&hotkey) { - hotkeys.push(hotkey); - keys_touched = keys_touched.saturating_add(1); - - // Update longest hotkey vector info - if longest_hotkey_vector < hotkeys.len() { - longest_hotkey_vector = hotkeys.len(); - longest_coldkey = Some(coldkey.clone()); - } - - // Update the OwnedHotkeys storage - OwnedHotkeys::::insert(&coldkey, hotkeys); - storage_writes = storage_writes.saturating_add(1); // Write to OwnedHotkeys storage - } - - // Accrue weight for reads and writes - weight = weight.saturating_add(T::DbWeight::get().reads_writes(2, 1)); - }); - - // Log migration results - info!( - target: LOG_TARGET_1, - "Migration {} finished. Keys touched: {}, Longest hotkey vector: {}, Storage reads: {}, Storage writes: {}", - migration_name, keys_touched, longest_hotkey_vector, storage_reads, storage_writes - ); - if let Some(c) = longest_coldkey { - info!(target: LOG_TARGET_1, "Longest hotkey vector is controlled by: {:?}", c); - } - - weight - } else { - info!(target: LOG_TARGET_1, "Migration {} already done!", migration_name); - Weight::zero() - } -} - -/// Populate the StakingHotkeys map from Stake map -pub fn migrate_populate_staking_hotkeys() -> Weight { - // Setup migration weight - let mut weight = T::DbWeight::get().reads(1); - let migration_name = "Populate StakingHotkeys map"; - - // Check if this migration is needed (if StakingHotkeys map is empty) - let migrate = StakingHotkeys::::iter().next().is_none(); - - // Only runs if the migration is needed - if migrate { - info!(target: LOG_TARGET_1, ">>> Starting Migration: {}", migration_name); - - let mut longest_hotkey_vector: usize = 0; - let mut longest_coldkey: Option = None; - let mut keys_touched: u64 = 0; - let mut storage_reads: u64 = 0; - let mut storage_writes: u64 = 0; - - // Iterate through all Owner entries - Stake::::iter().for_each(|(hotkey, coldkey, stake)| { - storage_reads = storage_reads.saturating_add(1); // Read from Owner storage - if stake > 0 { - let mut hotkeys = StakingHotkeys::::get(&coldkey); - storage_reads = storage_reads.saturating_add(1); // Read from StakingHotkeys storage - - // Add the hotkey if it's not already in the vector - if !hotkeys.contains(&hotkey) { - hotkeys.push(hotkey); - keys_touched = keys_touched.saturating_add(1); - - // Update longest hotkey vector info - if longest_hotkey_vector < hotkeys.len() { - longest_hotkey_vector = hotkeys.len(); - longest_coldkey = Some(coldkey.clone()); - } - - // Update the StakingHotkeys storage - StakingHotkeys::::insert(&coldkey, hotkeys); - storage_writes = storage_writes.saturating_add(1); // Write to StakingHotkeys storage - } - - // Accrue weight for reads and writes - weight = weight.saturating_add(T::DbWeight::get().reads_writes(2, 1)); - } - }); - - // Log migration results - info!( - target: LOG_TARGET_1, - "Migration {} finished. Keys touched: {}, Longest hotkey vector: {}, Storage reads: {}, Storage writes: {}", - migration_name, keys_touched, longest_hotkey_vector, storage_reads, storage_writes - ); - if let Some(c) = longest_coldkey { - info!(target: LOG_TARGET_1, "Longest hotkey vector is controlled by: {:?}", c); - } - - weight - } else { - info!(target: LOG_TARGET_1, "Migration {} already done!", migration_name); - Weight::zero() - } -} diff --git a/pallets/subtensor/src/staking.rs b/pallets/subtensor/src/staking.rs deleted file mode 100644 index 2707d90ef..000000000 --- a/pallets/subtensor/src/staking.rs +++ /dev/null @@ -1,851 +0,0 @@ -use super::*; -use frame_support::{ - storage::IterableStorageDoubleMap, - traits::{ - tokens::{ - fungible::{Balanced as _, Inspect as _, Mutate as _}, - Fortitude, Precision, Preservation, - }, - Imbalance, - }, -}; - -impl Pallet { - /// ---- The implementation for the extrinsic become_delegate: signals that this hotkey allows delegated stake. - /// - /// # Args: - /// * 'origin': (RuntimeOrigin): - /// - The signature of the caller's coldkey. - /// - /// * 'hotkey' (T::AccountId): - /// - The hotkey we are delegating (must be owned by the coldkey.) - /// - /// * 'take' (u16): - /// - The stake proportion that this hotkey takes from delegations. - /// - /// # Event: - /// * DelegateAdded; - /// - On successfully setting a hotkey as a delegate. - /// - /// # Raises: - /// * 'NotRegistered': - /// - The hotkey we are delegating is not registered on the network. - /// - /// * 'NonAssociatedColdKey': - /// - The hotkey we are delegating is not owned by the calling coldket. - /// - /// * 'TxRateLimitExceeded': - /// - Thrown if key has hit transaction rate limit - /// - pub fn do_become_delegate( - origin: T::RuntimeOrigin, - hotkey: T::AccountId, - take: u16, - ) -> dispatch::DispatchResult { - // --- 1. We check the coldkey signuture. - let coldkey = ensure_signed(origin)?; - log::info!( - "do_become_delegate( origin:{:?} hotkey:{:?}, take:{:?} )", - coldkey, - hotkey, - take - ); - - // --- 2. Ensure we are delegating an known key. - // --- 3. Ensure that the coldkey is the owner. - Self::do_take_checks(&coldkey, &hotkey)?; - - // --- 4. Ensure we are not already a delegate (dont allow changing delegate take.) - ensure!( - !Self::hotkey_is_delegate(&hotkey), - Error::::HotKeyAlreadyDelegate - ); - - // --- 5. Ensure we don't exceed tx rate limit - let block: u64 = Self::get_current_block_as_u64(); - ensure!( - !Self::exceeds_tx_rate_limit(Self::get_last_tx_block(&coldkey), block), - Error::::DelegateTxRateLimitExceeded - ); - - // --- 5.1 Ensure take is within the min ..= InitialDefaultTake (18%) range - let min_take = MinTake::::get(); - let max_take = MaxTake::::get(); - ensure!(take >= min_take, Error::::DelegateTakeTooLow); - ensure!(take <= max_take, Error::::DelegateTakeTooHigh); - - // --- 6. Delegate the key. - Self::delegate_hotkey(&hotkey, take); - - // Set last block for rate limiting - Self::set_last_tx_block(&coldkey, block); - Self::set_last_tx_block_delegate_take(&coldkey, block); - - // --- 7. Emit the staking event. - log::info!( - "DelegateAdded( coldkey:{:?}, hotkey:{:?}, take:{:?} )", - coldkey, - hotkey, - take - ); - Self::deposit_event(Event::DelegateAdded(coldkey, hotkey, take)); - - // --- 8. Ok and return. - Ok(()) - } - - /// ---- The implementation for the extrinsic decrease_take - /// - /// # Args: - /// * 'origin': (::RuntimeOrigin): - /// - The signature of the caller's coldkey. - /// - /// * 'hotkey' (T::AccountId): - /// - The hotkey we are delegating (must be owned by the coldkey.) - /// - /// * 'take' (u16): - /// - The stake proportion that this hotkey takes from delegations for subnet ID. - /// - /// # Event: - /// * TakeDecreased; - /// - On successfully setting a decreased take for this hotkey. - /// - /// # Raises: - /// * 'NotRegistered': - /// - The hotkey we are delegating is not registered on the network. - /// - /// * 'NonAssociatedColdKey': - /// - The hotkey we are delegating is not owned by the calling coldket. - /// - /// * 'DelegateTakeTooLow': - /// - The delegate is setting a take which is not lower than the previous. - /// - pub fn do_decrease_take( - origin: T::RuntimeOrigin, - hotkey: T::AccountId, - take: u16, - ) -> dispatch::DispatchResult { - // --- 1. We check the coldkey signature. - let coldkey = ensure_signed(origin)?; - log::info!( - "do_decrease_take( origin:{:?} hotkey:{:?}, take:{:?} )", - coldkey, - hotkey, - take - ); - - // --- 2. Ensure we are delegating a known key. - // Ensure that the coldkey is the owner. - Self::do_take_checks(&coldkey, &hotkey)?; - - // --- 3. Ensure we are always strictly decreasing, never increasing take - if let Ok(current_take) = Delegates::::try_get(&hotkey) { - ensure!(take < current_take, Error::::DelegateTakeTooLow); - } - - // --- 3.1 Ensure take is within the min ..= InitialDefaultTake (18%) range - let min_take = MinTake::::get(); - ensure!(take >= min_take, Error::::DelegateTakeTooLow); - - // --- 4. Set the new take value. - Delegates::::insert(hotkey.clone(), take); - - // --- 5. Emit the take value. - log::info!( - "TakeDecreased( coldkey:{:?}, hotkey:{:?}, take:{:?} )", - coldkey, - hotkey, - take - ); - Self::deposit_event(Event::TakeDecreased(coldkey, hotkey, take)); - - // --- 6. Ok and return. - Ok(()) - } - - /// ---- The implementation for the extrinsic increase_take - /// - /// # Args: - /// * 'origin': (::RuntimeOrigin): - /// - The signature of the caller's coldkey. - /// - /// * 'hotkey' (T::AccountId): - /// - The hotkey we are delegating (must be owned by the coldkey.) - /// - /// * 'take' (u16): - /// - The stake proportion that this hotkey takes from delegations for subnet ID. - /// - /// # Event: - /// * TakeIncreased; - /// - On successfully setting a increased take for this hotkey. - /// - /// # Raises: - /// * 'NotRegistered': - /// - The hotkey we are delegating is not registered on the network. - /// - /// * 'NonAssociatedColdKey': - /// - The hotkey we are delegating is not owned by the calling coldket. - /// - /// * 'TxRateLimitExceeded': - /// - Thrown if key has hit transaction rate limit - /// - /// * 'DelegateTakeTooLow': - /// - The delegate is setting a take which is not greater than the previous. - /// - pub fn do_increase_take( - origin: T::RuntimeOrigin, - hotkey: T::AccountId, - take: u16, - ) -> dispatch::DispatchResult { - // --- 1. We check the coldkey signature. - let coldkey = ensure_signed(origin)?; - log::info!( - "do_increase_take( origin:{:?} hotkey:{:?}, take:{:?} )", - coldkey, - hotkey, - take - ); - - // --- 2. Ensure we are delegating a known key. - // Ensure that the coldkey is the owner. - Self::do_take_checks(&coldkey, &hotkey)?; - - // --- 3. Ensure we are strinctly increasing take - if let Ok(current_take) = Delegates::::try_get(&hotkey) { - ensure!(take > current_take, Error::::DelegateTakeTooLow); - } - - // --- 4. Ensure take is within the min ..= InitialDefaultTake (18%) range - let max_take = MaxTake::::get(); - ensure!(take <= max_take, Error::::DelegateTakeTooHigh); - - // --- 5. Enforce the rate limit (independently on do_add_stake rate limits) - let block: u64 = Self::get_current_block_as_u64(); - ensure!( - !Self::exceeds_tx_delegate_take_rate_limit( - Self::get_last_tx_block_delegate_take(&coldkey), - block - ), - Error::::DelegateTxRateLimitExceeded - ); - - // Set last block for rate limiting - Self::set_last_tx_block_delegate_take(&coldkey, block); - - // --- 6. Set the new take value. - Delegates::::insert(hotkey.clone(), take); - - // --- 7. Emit the take value. - log::info!( - "TakeIncreased( coldkey:{:?}, hotkey:{:?}, take:{:?} )", - coldkey, - hotkey, - take - ); - Self::deposit_event(Event::TakeIncreased(coldkey, hotkey, take)); - - // --- 8. Ok and return. - Ok(()) - } - - /// ---- The implementation for the extrinsic add_stake: Adds stake to a hotkey account. - /// - /// # Args: - /// * 'origin': (RuntimeOrigin): - /// - The signature of the caller's coldkey. - /// - /// * 'hotkey' (T::AccountId): - /// - The associated hotkey account. - /// - /// * 'stake_to_be_added' (u64): - /// - The amount of stake to be added to the hotkey staking account. - /// - /// # Event: - /// * StakeAdded; - /// - On the successfully adding stake to a global account. - /// - /// # Raises: - /// * 'NotEnoughBalanceToStake': - /// - Not enough balance on the coldkey to add onto the global account. - /// - /// * 'NonAssociatedColdKey': - /// - The calling coldkey is not associated with this hotkey. - /// - /// * 'BalanceWithdrawalError': - /// - Errors stemming from transaction pallet. - /// - /// * 'TxRateLimitExceeded': - /// - Thrown if key has hit transaction rate limit - /// - pub fn do_add_stake( - origin: T::RuntimeOrigin, - hotkey: T::AccountId, - stake_to_be_added: u64, - ) -> dispatch::DispatchResult { - // We check that the transaction is signed by the caller and retrieve the T::AccountId coldkey information. - let coldkey = ensure_signed(origin)?; - log::info!( - "do_add_stake( origin:{:?} hotkey:{:?}, stake_to_be_added:{:?} )", - coldkey, - hotkey, - stake_to_be_added - ); - - // Ensure the callers coldkey has enough stake to perform the transaction. - ensure!( - Self::can_remove_balance_from_coldkey_account(&coldkey, stake_to_be_added), - Error::::NotEnoughBalanceToStake - ); - - // Ensure that the hotkey account exists this is only possible through registration. - ensure!( - Self::hotkey_account_exists(&hotkey), - Error::::HotKeyAccountNotExists - ); - - // Ensure that the hotkey allows delegation or that the hotkey is owned by the calling coldkey. - ensure!( - Self::hotkey_is_delegate(&hotkey) || Self::coldkey_owns_hotkey(&coldkey, &hotkey), - Error::::HotKeyNotDelegateAndSignerNotOwnHotKey - ); - - // Ensure we don't exceed stake rate limit - let stakes_this_interval = - Self::get_stakes_this_interval_for_coldkey_hotkey(&coldkey, &hotkey); - ensure!( - stakes_this_interval < Self::get_target_stakes_per_interval(), - Error::::StakeRateLimitExceeded - ); - - // If this is a nomination stake, check if total stake after adding will be above - // the minimum required stake. - - // If coldkey is not owner of the hotkey, it's a nomination stake. - if !Self::coldkey_owns_hotkey(&coldkey, &hotkey) { - let total_stake_after_add = - Stake::::get(&hotkey, &coldkey).saturating_add(stake_to_be_added); - - ensure!( - total_stake_after_add >= NominatorMinRequiredStake::::get(), - Error::::NomStakeBelowMinimumThreshold - ); - } - - // Ensure the remove operation from the coldkey is a success. - let actual_amount_to_stake = - Self::remove_balance_from_coldkey_account(&coldkey, stake_to_be_added)?; - - // If we reach here, add the balance to the hotkey. - Self::increase_stake_on_coldkey_hotkey_account(&coldkey, &hotkey, actual_amount_to_stake); - - // Set last block for rate limiting - let block: u64 = Self::get_current_block_as_u64(); - Self::set_last_tx_block(&coldkey, block); - - // Emit the staking event. - Self::set_stakes_this_interval_for_coldkey_hotkey( - &coldkey, - &hotkey, - stakes_this_interval.saturating_add(1), - block, - ); - log::info!( - "StakeAdded( hotkey:{:?}, stake_to_be_added:{:?} )", - hotkey, - actual_amount_to_stake - ); - Self::deposit_event(Event::StakeAdded(hotkey, actual_amount_to_stake)); - - // Ok and return. - Ok(()) - } - - /// ---- The implementation for the extrinsic remove_stake: Removes stake from a hotkey account and adds it onto a coldkey. - /// - /// # Args: - /// * 'origin': (RuntimeOrigin): - /// - The signature of the caller's coldkey. - /// - /// * 'hotkey' (T::AccountId): - /// - The associated hotkey account. - /// - /// * 'stake_to_be_added' (u64): - /// - The amount of stake to be added to the hotkey staking account. - /// - /// # Event: - /// * StakeRemoved; - /// - On the successfully removing stake from the hotkey account. - /// - /// # Raises: - /// * 'NotRegistered': - /// - Thrown if the account we are attempting to unstake from is non existent. - /// - /// * 'NonAssociatedColdKey': - /// - Thrown if the coldkey does not own the hotkey we are unstaking from. - /// - /// * 'NotEnoughStakeToWithdraw': - /// - Thrown if there is not enough stake on the hotkey to withdwraw this amount. - /// - /// * 'TxRateLimitExceeded': - /// - Thrown if key has hit transaction rate limit - /// - pub fn do_remove_stake( - origin: T::RuntimeOrigin, - hotkey: T::AccountId, - stake_to_be_removed: u64, - ) -> dispatch::DispatchResult { - // We check the transaction is signed by the caller and retrieve the T::AccountId coldkey information. - let coldkey = ensure_signed(origin)?; - log::info!( - "do_remove_stake( origin:{:?} hotkey:{:?}, stake_to_be_removed:{:?} )", - coldkey, - hotkey, - stake_to_be_removed - ); - - // Ensure that the hotkey account exists this is only possible through registration. - ensure!( - Self::hotkey_account_exists(&hotkey), - Error::::HotKeyAccountNotExists - ); - - // Ensure that the hotkey allows delegation or that the hotkey is owned by the calling coldkey. - ensure!( - Self::hotkey_is_delegate(&hotkey) || Self::coldkey_owns_hotkey(&coldkey, &hotkey), - Error::::HotKeyNotDelegateAndSignerNotOwnHotKey - ); - - // Ensure that the stake amount to be removed is above zero. - ensure!(stake_to_be_removed > 0, Error::::StakeToWithdrawIsZero); - - // Ensure that the hotkey has enough stake to withdraw. - ensure!( - Self::has_enough_stake(&coldkey, &hotkey, stake_to_be_removed), - Error::::NotEnoughStakeToWithdraw - ); - - // Ensure we don't exceed stake rate limit - let unstakes_this_interval = - Self::get_stakes_this_interval_for_coldkey_hotkey(&coldkey, &hotkey); - ensure!( - unstakes_this_interval < Self::get_target_stakes_per_interval(), - Error::::UnstakeRateLimitExceeded - ); - - // We remove the balance from the hotkey. - Self::decrease_stake_on_coldkey_hotkey_account(&coldkey, &hotkey, stake_to_be_removed); - - // We add the balance to the coldkey. If the above fails we will not credit this coldkey. - Self::add_balance_to_coldkey_account(&coldkey, stake_to_be_removed); - - // If the stake is below the minimum, we clear the nomination from storage. - // This only applies to nominator stakes. - // If the coldkey does not own the hotkey, it's a nominator stake. - let new_stake = Self::get_stake_for_coldkey_and_hotkey(&coldkey, &hotkey); - Self::clear_small_nomination_if_required(&hotkey, &coldkey, new_stake); - - // Set last block for rate limiting - let block: u64 = Self::get_current_block_as_u64(); - Self::set_last_tx_block(&coldkey, block); - - // Emit the unstaking event. - Self::set_stakes_this_interval_for_coldkey_hotkey( - &coldkey, - &hotkey, - unstakes_this_interval.saturating_add(1), - block, - ); - log::info!( - "StakeRemoved( hotkey:{:?}, stake_to_be_removed:{:?} )", - hotkey, - stake_to_be_removed - ); - Self::deposit_event(Event::StakeRemoved(hotkey, stake_to_be_removed)); - - // Done and ok. - Ok(()) - } - - // Returns true if the passed hotkey allow delegative staking. - // - pub fn hotkey_is_delegate(hotkey: &T::AccountId) -> bool { - Delegates::::contains_key(hotkey) - } - - // Sets the hotkey as a delegate with take. - // - pub fn delegate_hotkey(hotkey: &T::AccountId, take: u16) { - Delegates::::insert(hotkey, take); - } - - // Returns the total amount of stake in the staking table. - // - pub fn get_total_stake() -> u64 { - TotalStake::::get() - } - - // Increases the total amount of stake by the passed amount. - // - pub fn increase_total_stake(increment: u64) { - 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: u64) { - TotalStake::::put(Self::get_total_stake().saturating_sub(decrement)); - } - - // Returns the total amount of stake under a hotkey (delegative or otherwise) - // - pub fn get_total_stake_for_hotkey(hotkey: &T::AccountId) -> u64 { - TotalHotkeyStake::::get(hotkey) - } - - // Returns the total amount of stake held by the coldkey (delegative or otherwise) - // - pub fn get_total_stake_for_coldkey(coldkey: &T::AccountId) -> u64 { - TotalColdkeyStake::::get(coldkey) - } - - // Returns the stake under the cold - hot pairing in the staking table. - // - pub fn get_stake_for_coldkey_and_hotkey(coldkey: &T::AccountId, hotkey: &T::AccountId) -> u64 { - Stake::::get(hotkey, coldkey) - } - - // Retrieves the total stakes for a given hotkey (account ID) for the current staking interval. - pub fn get_stakes_this_interval_for_coldkey_hotkey( - coldkey: &T::AccountId, - hotkey: &T::AccountId, - ) -> u64 { - // Retrieve the configured stake interval duration from storage. - let stake_interval = StakeInterval::::get(); - - // Obtain the current block number as an unsigned 64-bit integer. - let current_block = Self::get_current_block_as_u64(); - - // Fetch the total stakes and the last block number when stakes were made for the hotkey. - let (stakes, block_last_staked_at) = - TotalHotkeyColdkeyStakesThisInterval::::get(coldkey, hotkey); - - // Calculate the block number after which the stakes for the hotkey should be reset. - let block_to_reset_after = block_last_staked_at.saturating_add(stake_interval); - - // If the current block number is beyond the reset point, - // it indicates the end of the staking interval for the hotkey. - if block_to_reset_after <= current_block { - // Reset the stakes for this hotkey for the current interval. - Self::set_stakes_this_interval_for_coldkey_hotkey( - coldkey, - hotkey, - 0, - block_last_staked_at, - ); - // Return 0 as the stake amount since we've just reset the stakes. - return 0; - } - - // If the staking interval has not yet ended, return the current stake amount. - stakes - } - - pub fn get_target_stakes_per_interval() -> u64 { - TargetStakesPerInterval::::get() - } - - // Creates a cold - hot pairing account if the hotkey is not already an active account. - // - pub fn create_account_if_non_existent(coldkey: &T::AccountId, hotkey: &T::AccountId) { - if !Self::hotkey_account_exists(hotkey) { - Stake::::insert(hotkey, coldkey, 0); - Owner::::insert(hotkey, coldkey); - - // Update OwnedHotkeys map - let mut hotkeys = OwnedHotkeys::::get(coldkey); - if !hotkeys.contains(hotkey) { - hotkeys.push(hotkey.clone()); - OwnedHotkeys::::insert(coldkey, hotkeys); - } - - // Update StakingHotkeys map - let mut staking_hotkeys = StakingHotkeys::::get(coldkey); - if !staking_hotkeys.contains(hotkey) { - staking_hotkeys.push(hotkey.clone()); - StakingHotkeys::::insert(coldkey, staking_hotkeys); - } - } - } - - // Returns the coldkey owning this hotkey. This function should only be called for active accounts. - // - pub fn get_owning_coldkey_for_hotkey(hotkey: &T::AccountId) -> T::AccountId { - Owner::::get(hotkey) - } - - // Returns the hotkey take - // - pub fn get_hotkey_take(hotkey: &T::AccountId) -> u16 { - Delegates::::get(hotkey) - } - - // Returns true if the hotkey account has been created. - // - pub fn hotkey_account_exists(hotkey: &T::AccountId) -> bool { - Owner::::contains_key(hotkey) - } - - // Return true if the passed coldkey owns the hotkey. - // - pub fn coldkey_owns_hotkey(coldkey: &T::AccountId, hotkey: &T::AccountId) -> bool { - if Self::hotkey_account_exists(hotkey) { - Owner::::get(hotkey) == *coldkey - } else { - false - } - } - - // Returns true if the cold-hot staking account has enough balance to fufil the decrement. - // - pub fn has_enough_stake(coldkey: &T::AccountId, hotkey: &T::AccountId, decrement: u64) -> bool { - Self::get_stake_for_coldkey_and_hotkey(coldkey, hotkey) >= decrement - } - - // Increases the stake on the hotkey account under its owning coldkey. - // - pub fn increase_stake_on_hotkey_account(hotkey: &T::AccountId, increment: u64) { - Self::increase_stake_on_coldkey_hotkey_account( - &Self::get_owning_coldkey_for_hotkey(hotkey), - hotkey, - increment, - ); - } - - // Decreases the stake on the hotkey account under its owning coldkey. - // - pub fn decrease_stake_on_hotkey_account(hotkey: &T::AccountId, decrement: u64) { - Self::decrease_stake_on_coldkey_hotkey_account( - &Self::get_owning_coldkey_for_hotkey(hotkey), - hotkey, - decrement, - ); - } - - // Increases the stake on the cold - hot pairing by increment while also incrementing other counters. - // This function should be called rather than set_stake under account. - // - pub fn increase_stake_on_coldkey_hotkey_account( - coldkey: &T::AccountId, - hotkey: &T::AccountId, - increment: u64, - ) { - TotalColdkeyStake::::insert( - coldkey, - TotalColdkeyStake::::get(coldkey).saturating_add(increment), - ); - TotalHotkeyStake::::insert( - hotkey, - TotalHotkeyStake::::get(hotkey).saturating_add(increment), - ); - Stake::::insert( - hotkey, - coldkey, - Stake::::get(hotkey, coldkey).saturating_add(increment), - ); - TotalStake::::put(TotalStake::::get().saturating_add(increment)); - - // Update StakingHotkeys map - let mut staking_hotkeys = StakingHotkeys::::get(coldkey); - if !staking_hotkeys.contains(hotkey) { - staking_hotkeys.push(hotkey.clone()); - StakingHotkeys::::insert(coldkey, staking_hotkeys); - } - } - - // Decreases the stake on the cold - hot pairing by the decrement while decreasing other counters. - // - pub fn decrease_stake_on_coldkey_hotkey_account( - coldkey: &T::AccountId, - hotkey: &T::AccountId, - decrement: u64, - ) { - TotalColdkeyStake::::mutate(coldkey, |old| *old = old.saturating_sub(decrement)); - TotalHotkeyStake::::insert( - hotkey, - TotalHotkeyStake::::get(hotkey).saturating_sub(decrement), - ); - Stake::::insert( - hotkey, - coldkey, - Stake::::get(hotkey, coldkey).saturating_sub(decrement), - ); - TotalStake::::put(TotalStake::::get().saturating_sub(decrement)); - - // TODO: Tech debt: Remove StakingHotkeys entry if stake goes to 0 - } - - /// Empties the stake associated with a given coldkey-hotkey account pairing. - /// This function retrieves the current stake for the specified coldkey-hotkey pairing, - /// then subtracts this stake amount from both the TotalColdkeyStake and TotalHotkeyStake. - /// It also removes the stake entry for the hotkey-coldkey pairing and adjusts the TotalStake - /// and TotalIssuance by subtracting the removed stake amount. - /// - /// Returns the amount of stake that was removed. - /// - /// # Arguments - /// - /// * `coldkey` - A reference to the AccountId of the coldkey involved in the staking. - /// * `hotkey` - A reference to the AccountId of the hotkey associated with the coldkey. - pub fn empty_stake_on_coldkey_hotkey_account( - coldkey: &T::AccountId, - hotkey: &T::AccountId, - ) -> u64 { - let current_stake: u64 = Stake::::get(hotkey, coldkey); - TotalColdkeyStake::::mutate(coldkey, |old| *old = old.saturating_sub(current_stake)); - TotalHotkeyStake::::mutate(hotkey, |stake| *stake = stake.saturating_sub(current_stake)); - Stake::::remove(hotkey, coldkey); - TotalStake::::mutate(|stake| *stake = stake.saturating_sub(current_stake)); - TotalIssuance::::mutate(|issuance| *issuance = issuance.saturating_sub(current_stake)); - - // Update StakingHotkeys map - let mut staking_hotkeys = StakingHotkeys::::get(coldkey); - staking_hotkeys.retain(|h| h != hotkey); - StakingHotkeys::::insert(coldkey, staking_hotkeys); - - current_stake - } - - /// Clears the nomination for an account, if it is a nominator account and the stake is below the minimum required threshold. - pub fn clear_small_nomination_if_required( - hotkey: &T::AccountId, - coldkey: &T::AccountId, - stake: u64, - ) { - // Verify if the account is a nominator account by checking ownership of the hotkey by the coldkey. - if !Self::coldkey_owns_hotkey(coldkey, hotkey) { - // If the stake is below the minimum required, it's considered a small nomination and needs to be cleared. - if stake < Self::get_nominator_min_required_stake() { - // Remove the stake from the nominator account. (this is a more forceful unstake operation which ) - // Actually deletes the staking account. - let cleared_stake = Self::empty_stake_on_coldkey_hotkey_account(coldkey, hotkey); - // Add the stake to the coldkey account. - Self::add_balance_to_coldkey_account(coldkey, cleared_stake); - } - } - } - - /// Clears small nominations for all accounts. - /// - /// WARN: This is an O(N) operation, where N is the number of staking accounts. It should be - /// used with caution. - pub fn clear_small_nominations() { - // Loop through all staking accounts to identify and clear nominations below the minimum stake. - for (hotkey, coldkey, stake) in Stake::::iter() { - Self::clear_small_nomination_if_required(&hotkey, &coldkey, stake); - } - } - - pub fn add_balance_to_coldkey_account( - coldkey: &T::AccountId, - amount: <::Currency as fungible::Inspect<::AccountId>>::Balance, - ) { - // infallible - let _ = T::Currency::deposit(coldkey, amount, Precision::BestEffort); - } - - pub fn set_balance_on_coldkey_account( - coldkey: &T::AccountId, - amount: <::Currency as fungible::Inspect<::AccountId>>::Balance, - ) { - T::Currency::set_balance(coldkey, amount); - } - - pub fn can_remove_balance_from_coldkey_account( - coldkey: &T::AccountId, - amount: <::Currency as fungible::Inspect<::AccountId>>::Balance, - ) -> bool { - let current_balance = Self::get_coldkey_balance(coldkey); - if amount > current_balance { - return false; - } - - // This bit is currently untested. @todo - - T::Currency::can_withdraw(coldkey, amount) - .into_result(false) - .is_ok() - } - - pub fn get_coldkey_balance( - coldkey: &T::AccountId, - ) -> <::Currency as fungible::Inspect<::AccountId>>::Balance - { - T::Currency::reducible_balance(coldkey, Preservation::Expendable, Fortitude::Polite) - } - - #[must_use = "Balance must be used to preserve total issuance of token"] - pub fn remove_balance_from_coldkey_account( - coldkey: &T::AccountId, - amount: <::Currency as fungible::Inspect<::AccountId>>::Balance, - ) -> Result { - if amount == 0 { - return Ok(0); - } - - let credit = T::Currency::withdraw( - coldkey, - amount, - Precision::BestEffort, - Preservation::Preserve, - Fortitude::Polite, - ) - .map_err(|_| Error::::BalanceWithdrawalError)? - .peek(); - - if credit == 0 { - return Err(Error::::ZeroBalanceAfterWithdrawn.into()); - } - - Ok(credit) - } - - pub fn kill_coldkey_account( - coldkey: &T::AccountId, - amount: <::Currency as fungible::Inspect<::AccountId>>::Balance, - ) -> Result { - if amount == 0 { - return Ok(0); - } - - let credit = T::Currency::withdraw( - coldkey, - amount, - Precision::Exact, - Preservation::Expendable, - Fortitude::Force, - ) - .map_err(|_| Error::::BalanceWithdrawalError)? - .peek(); - - if credit == 0 { - return Err(Error::::ZeroBalanceAfterWithdrawn.into()); - } - - Ok(credit) - } - - pub fn unstake_all_coldkeys_from_hotkey_account(hotkey: &T::AccountId) { - // Iterate through all coldkeys that have a stake on this hotkey account. - for (delegate_coldkey_i, stake_i) in - as IterableStorageDoubleMap>::iter_prefix( - hotkey, - ) - { - // Remove the stake from the coldkey - hotkey pairing. - Self::decrease_stake_on_coldkey_hotkey_account(&delegate_coldkey_i, hotkey, stake_i); - - // Add the balance to the coldkey account. - Self::add_balance_to_coldkey_account(&delegate_coldkey_i, stake_i); - } - } -} diff --git a/pallets/subtensor/src/staking/add_stake.rs b/pallets/subtensor/src/staking/add_stake.rs new file mode 100644 index 000000000..89104de82 --- /dev/null +++ b/pallets/subtensor/src/staking/add_stake.rs @@ -0,0 +1,125 @@ +use super::*; +use frame_support::{ + storage::IterableStorageDoubleMap, + traits::{ + tokens::{ + fungible::{Balanced as _, Inspect as _, Mutate as _}, + Fortitude, Precision, Preservation, + }, + Imbalance, + }, +}; + +impl Pallet { + /// ---- The implementation for the extrinsic add_stake: Adds stake to a hotkey account. + /// + /// # Args: + /// * 'origin': (RuntimeOrigin): + /// - The signature of the caller's coldkey. + /// + /// * 'hotkey' (T::AccountId): + /// - The associated hotkey account. + /// + /// * 'stake_to_be_added' (u64): + /// - The amount of stake to be added to the hotkey staking account. + /// + /// # Event: + /// * StakeAdded; + /// - On the successfully adding stake to a global account. + /// + /// # Raises: + /// * 'NotEnoughBalanceToStake': + /// - Not enough balance on the coldkey to add onto the global account. + /// + /// * 'NonAssociatedColdKey': + /// - The calling coldkey is not associated with this hotkey. + /// + /// * 'BalanceWithdrawalError': + /// - Errors stemming from transaction pallet. + /// + /// * 'TxRateLimitExceeded': + /// - Thrown if key has hit transaction rate limit + /// + pub fn do_add_stake( + origin: T::RuntimeOrigin, + hotkey: T::AccountId, + stake_to_be_added: u64, + ) -> dispatch::DispatchResult { + // We check that the transaction is signed by the caller and retrieve the T::AccountId coldkey information. + let coldkey = ensure_signed(origin)?; + log::info!( + "do_add_stake( origin:{:?} hotkey:{:?}, stake_to_be_added:{:?} )", + coldkey, + hotkey, + stake_to_be_added + ); + + // Ensure the callers coldkey has enough stake to perform the transaction. + ensure!( + Self::can_remove_balance_from_coldkey_account(&coldkey, stake_to_be_added), + Error::::NotEnoughBalanceToStake + ); + + // Ensure that the hotkey account exists this is only possible through registration. + ensure!( + Self::hotkey_account_exists(&hotkey), + Error::::HotKeyAccountNotExists + ); + + // Ensure that the hotkey allows delegation or that the hotkey is owned by the calling coldkey. + ensure!( + Self::hotkey_is_delegate(&hotkey) || Self::coldkey_owns_hotkey(&coldkey, &hotkey), + Error::::HotKeyNotDelegateAndSignerNotOwnHotKey + ); + + // Ensure we don't exceed stake rate limit + let stakes_this_interval = + Self::get_stakes_this_interval_for_coldkey_hotkey(&coldkey, &hotkey); + ensure!( + stakes_this_interval < Self::get_target_stakes_per_interval(), + Error::::StakeRateLimitExceeded + ); + + // If this is a nomination stake, check if total stake after adding will be above + // the minimum required stake. + + // If coldkey is not owner of the hotkey, it's a nomination stake. + if !Self::coldkey_owns_hotkey(&coldkey, &hotkey) { + let total_stake_after_add = + Stake::::get(&hotkey, &coldkey).saturating_add(stake_to_be_added); + + ensure!( + total_stake_after_add >= NominatorMinRequiredStake::::get(), + Error::::NomStakeBelowMinimumThreshold + ); + } + + // Ensure the remove operation from the coldkey is a success. + let actual_amount_to_stake = + Self::remove_balance_from_coldkey_account(&coldkey, stake_to_be_added)?; + + // If we reach here, add the balance to the hotkey. + Self::increase_stake_on_coldkey_hotkey_account(&coldkey, &hotkey, actual_amount_to_stake); + + // Set last block for rate limiting + let block: u64 = Self::get_current_block_as_u64(); + Self::set_last_tx_block(&coldkey, block); + + // Emit the staking event. + Self::set_stakes_this_interval_for_coldkey_hotkey( + &coldkey, + &hotkey, + stakes_this_interval.saturating_add(1), + block, + ); + log::info!( + "StakeAdded( hotkey:{:?}, stake_to_be_added:{:?} )", + hotkey, + actual_amount_to_stake + ); + Self::deposit_event(Event::StakeAdded(hotkey, actual_amount_to_stake)); + + // Ok and return. + Ok(()) + } +} \ No newline at end of file diff --git a/pallets/subtensor/src/staking/become_delegate.rs b/pallets/subtensor/src/staking/become_delegate.rs new file mode 100644 index 000000000..28d3b25f4 --- /dev/null +++ b/pallets/subtensor/src/staking/become_delegate.rs @@ -0,0 +1,96 @@ +use super::*; +use frame_support::{ + storage::IterableStorageDoubleMap, + traits::{ + tokens::{ + fungible::{Balanced as _, Inspect as _, Mutate as _}, + Fortitude, Precision, Preservation, + }, + Imbalance, + }, +}; + +impl Pallet { + /// ---- The implementation for the extrinsic become_delegate: signals that this hotkey allows delegated stake. + /// + /// # Args: + /// * 'origin': (RuntimeOrigin): + /// - The signature of the caller's coldkey. + /// + /// * 'hotkey' (T::AccountId): + /// - The hotkey we are delegating (must be owned by the coldkey.) + /// + /// * 'take' (u16): + /// - The stake proportion that this hotkey takes from delegations. + /// + /// # Event: + /// * DelegateAdded; + /// - On successfully setting a hotkey as a delegate. + /// + /// # Raises: + /// * 'NotRegistered': + /// - The hotkey we are delegating is not registered on the network. + /// + /// * 'NonAssociatedColdKey': + /// - The hotkey we are delegating is not owned by the calling coldket. + /// + /// * 'TxRateLimitExceeded': + /// - Thrown if key has hit transaction rate limit + /// + pub fn do_become_delegate( + origin: T::RuntimeOrigin, + hotkey: T::AccountId, + take: u16, + ) -> dispatch::DispatchResult { + // --- 1. We check the coldkey signuture. + let coldkey = ensure_signed(origin)?; + log::info!( + "do_become_delegate( origin:{:?} hotkey:{:?}, take:{:?} )", + coldkey, + hotkey, + take + ); + + // --- 2. Ensure we are delegating an known key. + // --- 3. Ensure that the coldkey is the owner. + Self::do_take_checks(&coldkey, &hotkey)?; + + // --- 4. Ensure we are not already a delegate (dont allow changing delegate take.) + ensure!( + !Self::hotkey_is_delegate(&hotkey), + Error::::HotKeyAlreadyDelegate + ); + + // --- 5. Ensure we don't exceed tx rate limit + let block: u64 = Self::get_current_block_as_u64(); + ensure!( + !Self::exceeds_tx_rate_limit(Self::get_last_tx_block(&coldkey), block), + Error::::DelegateTxRateLimitExceeded + ); + + // --- 5.1 Ensure take is within the min ..= InitialDefaultTake (18%) range + let min_take = MinTake::::get(); + let max_take = MaxTake::::get(); + ensure!(take >= min_take, Error::::DelegateTakeTooLow); + ensure!(take <= max_take, Error::::DelegateTakeTooHigh); + + // --- 6. Delegate the key. + Self::delegate_hotkey(&hotkey, take); + + // Set last block for rate limiting + Self::set_last_tx_block(&coldkey, block); + Self::set_last_tx_block_delegate_take(&coldkey, block); + + // --- 7. Emit the staking event. + log::info!( + "DelegateAdded( coldkey:{:?}, hotkey:{:?}, take:{:?} )", + coldkey, + hotkey, + take + ); + Self::deposit_event(Event::DelegateAdded(coldkey, hotkey, take)); + + // --- 8. Ok and return. + Ok(()) + } +} diff --git a/pallets/subtensor/src/staking/decrease_take.rs b/pallets/subtensor/src/staking/decrease_take.rs new file mode 100644 index 000000000..4290a1d24 --- /dev/null +++ b/pallets/subtensor/src/staking/decrease_take.rs @@ -0,0 +1,82 @@ +use super::*; +use frame_support::{ + storage::IterableStorageDoubleMap, + traits::{ + tokens::{ + fungible::{Balanced as _, Inspect as _, Mutate as _}, + Fortitude, Precision, Preservation, + }, + Imbalance, + }, +}; + +impl Pallet { + /// ---- The implementation for the extrinsic decrease_take + /// + /// # Args: + /// * 'origin': (::RuntimeOrigin): + /// - The signature of the caller's coldkey. + /// + /// * 'hotkey' (T::AccountId): + /// - The hotkey we are delegating (must be owned by the coldkey.) + /// + /// * 'take' (u16): + /// - The stake proportion that this hotkey takes from delegations for subnet ID. + /// + /// # Event: + /// * TakeDecreased; + /// - On successfully setting a decreased take for this hotkey. + /// + /// # Raises: + /// * 'NotRegistered': + /// - The hotkey we are delegating is not registered on the network. + /// + /// * 'NonAssociatedColdKey': + /// - The hotkey we are delegating is not owned by the calling coldket. + /// + /// * 'DelegateTakeTooLow': + /// - The delegate is setting a take which is not lower than the previous. + /// + pub fn do_decrease_take( + origin: T::RuntimeOrigin, + hotkey: T::AccountId, + take: u16, + ) -> dispatch::DispatchResult { + // --- 1. We check the coldkey signature. + let coldkey = ensure_signed(origin)?; + log::info!( + "do_decrease_take( origin:{:?} hotkey:{:?}, take:{:?} )", + coldkey, + hotkey, + take + ); + + // --- 2. Ensure we are delegating a known key. + // Ensure that the coldkey is the owner. + Self::do_take_checks(&coldkey, &hotkey)?; + + // --- 3. Ensure we are always strictly decreasing, never increasing take + if let Ok(current_take) = Delegates::::try_get(&hotkey) { + ensure!(take < current_take, Error::::DelegateTakeTooLow); + } + + // --- 3.1 Ensure take is within the min ..= InitialDefaultTake (18%) range + let min_take = MinTake::::get(); + ensure!(take >= min_take, Error::::DelegateTakeTooLow); + + // --- 4. Set the new take value. + Delegates::::insert(hotkey.clone(), take); + + // --- 5. Emit the take value. + log::info!( + "TakeDecreased( coldkey:{:?}, hotkey:{:?}, take:{:?} )", + coldkey, + hotkey, + take + ); + Self::deposit_event(Event::TakeDecreased(coldkey, hotkey, take)); + + // --- 6. Ok and return. + Ok(()) + } +} diff --git a/pallets/subtensor/src/staking/helpers.rs b/pallets/subtensor/src/staking/helpers.rs new file mode 100644 index 000000000..6da16e833 --- /dev/null +++ b/pallets/subtensor/src/staking/helpers.rs @@ -0,0 +1,397 @@ +use super::*; +use frame_support::{ + storage::IterableStorageDoubleMap, + traits::{ + tokens::{ + fungible::{Balanced as _, Inspect as _, Mutate as _}, + Fortitude, Precision, Preservation, + }, + Imbalance, + }, +}; + +impl Pallet { + + // Returns true if the passed hotkey allow delegative staking. + // + pub fn hotkey_is_delegate(hotkey: &T::AccountId) -> bool { + Delegates::::contains_key(hotkey) + } + + // Sets the hotkey as a delegate with take. + // + pub fn delegate_hotkey(hotkey: &T::AccountId, take: u16) { + Delegates::::insert(hotkey, take); + } + + // Returns the total amount of stake in the staking table. + // + pub fn get_total_stake() -> u64 { + TotalStake::::get() + } + + // Increases the total amount of stake by the passed amount. + // + pub fn increase_total_stake(increment: u64) { + 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: u64) { + TotalStake::::put(Self::get_total_stake().saturating_sub(decrement)); + } + + // Returns the total amount of stake under a hotkey (delegative or otherwise) + // + pub fn get_total_stake_for_hotkey(hotkey: &T::AccountId) -> u64 { + TotalHotkeyStake::::get(hotkey) + } + + // Returns the total amount of stake held by the coldkey (delegative or otherwise) + // + pub fn get_total_stake_for_coldkey(coldkey: &T::AccountId) -> u64 { + TotalColdkeyStake::::get(coldkey) + } + + // Returns the stake under the cold - hot pairing in the staking table. + // + pub fn get_stake_for_coldkey_and_hotkey(coldkey: &T::AccountId, hotkey: &T::AccountId) -> u64 { + Stake::::get(hotkey, coldkey) + } + + // Retrieves the total stakes for a given hotkey (account ID) for the current staking interval. + pub fn get_stakes_this_interval_for_coldkey_hotkey( + coldkey: &T::AccountId, + hotkey: &T::AccountId, + ) -> u64 { + // Retrieve the configured stake interval duration from storage. + let stake_interval = StakeInterval::::get(); + + // Obtain the current block number as an unsigned 64-bit integer. + let current_block = Self::get_current_block_as_u64(); + + // Fetch the total stakes and the last block number when stakes were made for the hotkey. + let (stakes, block_last_staked_at) = + TotalHotkeyColdkeyStakesThisInterval::::get(coldkey, hotkey); + + // Calculate the block number after which the stakes for the hotkey should be reset. + let block_to_reset_after = block_last_staked_at.saturating_add(stake_interval); + + // If the current block number is beyond the reset point, + // it indicates the end of the staking interval for the hotkey. + if block_to_reset_after <= current_block { + // Reset the stakes for this hotkey for the current interval. + Self::set_stakes_this_interval_for_coldkey_hotkey( + coldkey, + hotkey, + 0, + block_last_staked_at, + ); + // Return 0 as the stake amount since we've just reset the stakes. + return 0; + } + + // If the staking interval has not yet ended, return the current stake amount. + stakes + } + + pub fn get_target_stakes_per_interval() -> u64 { + TargetStakesPerInterval::::get() + } + + // Creates a cold - hot pairing account if the hotkey is not already an active account. + // + pub fn create_account_if_non_existent(coldkey: &T::AccountId, hotkey: &T::AccountId) { + if !Self::hotkey_account_exists(hotkey) { + Stake::::insert(hotkey, coldkey, 0); + Owner::::insert(hotkey, coldkey); + + // Update OwnedHotkeys map + let mut hotkeys = OwnedHotkeys::::get(coldkey); + if !hotkeys.contains(hotkey) { + hotkeys.push(hotkey.clone()); + OwnedHotkeys::::insert(coldkey, hotkeys); + } + + // Update StakingHotkeys map + let mut staking_hotkeys = StakingHotkeys::::get(coldkey); + if !staking_hotkeys.contains(hotkey) { + staking_hotkeys.push(hotkey.clone()); + StakingHotkeys::::insert(coldkey, staking_hotkeys); + } + } + } + + // Returns the coldkey owning this hotkey. This function should only be called for active accounts. + // + pub fn get_owning_coldkey_for_hotkey(hotkey: &T::AccountId) -> T::AccountId { + Owner::::get(hotkey) + } + + // Returns the hotkey take + // + pub fn get_hotkey_take(hotkey: &T::AccountId) -> u16 { + Delegates::::get(hotkey) + } + + // Returns true if the hotkey account has been created. + // + pub fn hotkey_account_exists(hotkey: &T::AccountId) -> bool { + Owner::::contains_key(hotkey) + } + + // Return true if the passed coldkey owns the hotkey. + // + pub fn coldkey_owns_hotkey(coldkey: &T::AccountId, hotkey: &T::AccountId) -> bool { + if Self::hotkey_account_exists(hotkey) { + Owner::::get(hotkey) == *coldkey + } else { + false + } + } + + // Returns true if the cold-hot staking account has enough balance to fufil the decrement. + // + pub fn has_enough_stake(coldkey: &T::AccountId, hotkey: &T::AccountId, decrement: u64) -> bool { + Self::get_stake_for_coldkey_and_hotkey(coldkey, hotkey) >= decrement + } + + // Increases the stake on the hotkey account under its owning coldkey. + // + pub fn increase_stake_on_hotkey_account(hotkey: &T::AccountId, increment: u64) { + Self::increase_stake_on_coldkey_hotkey_account( + &Self::get_owning_coldkey_for_hotkey(hotkey), + hotkey, + increment, + ); + } + + // Decreases the stake on the hotkey account under its owning coldkey. + // + pub fn decrease_stake_on_hotkey_account(hotkey: &T::AccountId, decrement: u64) { + Self::decrease_stake_on_coldkey_hotkey_account( + &Self::get_owning_coldkey_for_hotkey(hotkey), + hotkey, + decrement, + ); + } + + // Increases the stake on the cold - hot pairing by increment while also incrementing other counters. + // This function should be called rather than set_stake under account. + // + pub fn increase_stake_on_coldkey_hotkey_account( + coldkey: &T::AccountId, + hotkey: &T::AccountId, + increment: u64, + ) { + TotalColdkeyStake::::insert( + coldkey, + TotalColdkeyStake::::get(coldkey).saturating_add(increment), + ); + TotalHotkeyStake::::insert( + hotkey, + TotalHotkeyStake::::get(hotkey).saturating_add(increment), + ); + Stake::::insert( + hotkey, + coldkey, + Stake::::get(hotkey, coldkey).saturating_add(increment), + ); + TotalStake::::put(TotalStake::::get().saturating_add(increment)); + + // Update StakingHotkeys map + let mut staking_hotkeys = StakingHotkeys::::get(coldkey); + if !staking_hotkeys.contains(hotkey) { + staking_hotkeys.push(hotkey.clone()); + StakingHotkeys::::insert(coldkey, staking_hotkeys); + } + } + + // Decreases the stake on the cold - hot pairing by the decrement while decreasing other counters. + // + pub fn decrease_stake_on_coldkey_hotkey_account( + coldkey: &T::AccountId, + hotkey: &T::AccountId, + decrement: u64, + ) { + TotalColdkeyStake::::mutate(coldkey, |old| *old = old.saturating_sub(decrement)); + TotalHotkeyStake::::insert( + hotkey, + TotalHotkeyStake::::get(hotkey).saturating_sub(decrement), + ); + Stake::::insert( + hotkey, + coldkey, + Stake::::get(hotkey, coldkey).saturating_sub(decrement), + ); + TotalStake::::put(TotalStake::::get().saturating_sub(decrement)); + + // TODO: Tech debt: Remove StakingHotkeys entry if stake goes to 0 + } + + /// Empties the stake associated with a given coldkey-hotkey account pairing. + /// This function retrieves the current stake for the specified coldkey-hotkey pairing, + /// then subtracts this stake amount from both the TotalColdkeyStake and TotalHotkeyStake. + /// It also removes the stake entry for the hotkey-coldkey pairing and adjusts the TotalStake + /// and TotalIssuance by subtracting the removed stake amount. + /// + /// Returns the amount of stake that was removed. + /// + /// # Arguments + /// + /// * `coldkey` - A reference to the AccountId of the coldkey involved in the staking. + /// * `hotkey` - A reference to the AccountId of the hotkey associated with the coldkey. + pub fn empty_stake_on_coldkey_hotkey_account( + coldkey: &T::AccountId, + hotkey: &T::AccountId, + ) -> u64 { + let current_stake: u64 = Stake::::get(hotkey, coldkey); + TotalColdkeyStake::::mutate(coldkey, |old| *old = old.saturating_sub(current_stake)); + TotalHotkeyStake::::mutate(hotkey, |stake| *stake = stake.saturating_sub(current_stake)); + Stake::::remove(hotkey, coldkey); + TotalStake::::mutate(|stake| *stake = stake.saturating_sub(current_stake)); + TotalIssuance::::mutate(|issuance| *issuance = issuance.saturating_sub(current_stake)); + + // Update StakingHotkeys map + let mut staking_hotkeys = StakingHotkeys::::get(coldkey); + staking_hotkeys.retain(|h| h != hotkey); + StakingHotkeys::::insert(coldkey, staking_hotkeys); + + current_stake + } + + /// Clears the nomination for an account, if it is a nominator account and the stake is below the minimum required threshold. + pub fn clear_small_nomination_if_required( + hotkey: &T::AccountId, + coldkey: &T::AccountId, + stake: u64, + ) { + // Verify if the account is a nominator account by checking ownership of the hotkey by the coldkey. + if !Self::coldkey_owns_hotkey(coldkey, hotkey) { + // If the stake is below the minimum required, it's considered a small nomination and needs to be cleared. + if stake < Self::get_nominator_min_required_stake() { + // Remove the stake from the nominator account. (this is a more forceful unstake operation which ) + // Actually deletes the staking account. + let cleared_stake = Self::empty_stake_on_coldkey_hotkey_account(coldkey, hotkey); + // Add the stake to the coldkey account. + Self::add_balance_to_coldkey_account(coldkey, cleared_stake); + } + } + } + + /// Clears small nominations for all accounts. + /// + /// WARN: This is an O(N) operation, where N is the number of staking accounts. It should be + /// used with caution. + pub fn clear_small_nominations() { + // Loop through all staking accounts to identify and clear nominations below the minimum stake. + for (hotkey, coldkey, stake) in Stake::::iter() { + Self::clear_small_nomination_if_required(&hotkey, &coldkey, stake); + } + } + + pub fn add_balance_to_coldkey_account( + coldkey: &T::AccountId, + amount: <::Currency as fungible::Inspect<::AccountId>>::Balance, + ) { + // infallible + let _ = T::Currency::deposit(coldkey, amount, Precision::BestEffort); + } + + pub fn set_balance_on_coldkey_account( + coldkey: &T::AccountId, + amount: <::Currency as fungible::Inspect<::AccountId>>::Balance, + ) { + T::Currency::set_balance(coldkey, amount); + } + + pub fn can_remove_balance_from_coldkey_account( + coldkey: &T::AccountId, + amount: <::Currency as fungible::Inspect<::AccountId>>::Balance, + ) -> bool { + let current_balance = Self::get_coldkey_balance(coldkey); + if amount > current_balance { + return false; + } + + // This bit is currently untested. @todo + + T::Currency::can_withdraw(coldkey, amount) + .into_result(false) + .is_ok() + } + + pub fn get_coldkey_balance( + coldkey: &T::AccountId, + ) -> <::Currency as fungible::Inspect<::AccountId>>::Balance + { + T::Currency::reducible_balance(coldkey, Preservation::Expendable, Fortitude::Polite) + } + + #[must_use = "Balance must be used to preserve total issuance of token"] + pub fn remove_balance_from_coldkey_account( + coldkey: &T::AccountId, + amount: <::Currency as fungible::Inspect<::AccountId>>::Balance, + ) -> Result { + if amount == 0 { + return Ok(0); + } + + let credit = T::Currency::withdraw( + coldkey, + amount, + Precision::BestEffort, + Preservation::Preserve, + Fortitude::Polite, + ) + .map_err(|_| Error::::BalanceWithdrawalError)? + .peek(); + + if credit == 0 { + return Err(Error::::ZeroBalanceAfterWithdrawn.into()); + } + + Ok(credit) + } + + pub fn kill_coldkey_account( + coldkey: &T::AccountId, + amount: <::Currency as fungible::Inspect<::AccountId>>::Balance, + ) -> Result { + if amount == 0 { + return Ok(0); + } + + let credit = T::Currency::withdraw( + coldkey, + amount, + Precision::Exact, + Preservation::Expendable, + Fortitude::Force, + ) + .map_err(|_| Error::::BalanceWithdrawalError)? + .peek(); + + if credit == 0 { + return Err(Error::::ZeroBalanceAfterWithdrawn.into()); + } + + Ok(credit) + } + + pub fn unstake_all_coldkeys_from_hotkey_account(hotkey: &T::AccountId) { + // Iterate through all coldkeys that have a stake on this hotkey account. + for (delegate_coldkey_i, stake_i) in + as IterableStorageDoubleMap>::iter_prefix( + hotkey, + ) + { + // Remove the stake from the coldkey - hotkey pairing. + Self::decrease_stake_on_coldkey_hotkey_account(&delegate_coldkey_i, hotkey, stake_i); + + // Add the balance to the coldkey account. + Self::add_balance_to_coldkey_account(&delegate_coldkey_i, stake_i); + } + } +} diff --git a/pallets/subtensor/src/staking/increase_take.rs b/pallets/subtensor/src/staking/increase_take.rs new file mode 100644 index 000000000..744027a9b --- /dev/null +++ b/pallets/subtensor/src/staking/increase_take.rs @@ -0,0 +1,99 @@ + +use super::*; +use frame_support::{ + storage::IterableStorageDoubleMap, + traits::{ + tokens::{ + fungible::{Balanced as _, Inspect as _, Mutate as _}, + Fortitude, Precision, Preservation, + }, + Imbalance, + }, +}; + +impl Pallet { + /// ---- The implementation for the extrinsic increase_take + /// + /// # Args: + /// * 'origin': (::RuntimeOrigin): + /// - The signature of the caller's coldkey. + /// + /// * 'hotkey' (T::AccountId): + /// - The hotkey we are delegating (must be owned by the coldkey.) + /// + /// * 'take' (u16): + /// - The stake proportion that this hotkey takes from delegations for subnet ID. + /// + /// # Event: + /// * TakeIncreased; + /// - On successfully setting a increased take for this hotkey. + /// + /// # Raises: + /// * 'NotRegistered': + /// - The hotkey we are delegating is not registered on the network. + /// + /// * 'NonAssociatedColdKey': + /// - The hotkey we are delegating is not owned by the calling coldket. + /// + /// * 'TxRateLimitExceeded': + /// - Thrown if key has hit transaction rate limit + /// + /// * 'DelegateTakeTooLow': + /// - The delegate is setting a take which is not greater than the previous. + /// + pub fn do_increase_take( + origin: T::RuntimeOrigin, + hotkey: T::AccountId, + take: u16, + ) -> dispatch::DispatchResult { + // --- 1. We check the coldkey signature. + let coldkey = ensure_signed(origin)?; + log::info!( + "do_increase_take( origin:{:?} hotkey:{:?}, take:{:?} )", + coldkey, + hotkey, + take + ); + + // --- 2. Ensure we are delegating a known key. + // Ensure that the coldkey is the owner. + Self::do_take_checks(&coldkey, &hotkey)?; + + // --- 3. Ensure we are strinctly increasing take + if let Ok(current_take) = Delegates::::try_get(&hotkey) { + ensure!(take > current_take, Error::::DelegateTakeTooLow); + } + + // --- 4. Ensure take is within the min ..= InitialDefaultTake (18%) range + let max_take = MaxTake::::get(); + ensure!(take <= max_take, Error::::DelegateTakeTooHigh); + + // --- 5. Enforce the rate limit (independently on do_add_stake rate limits) + let block: u64 = Self::get_current_block_as_u64(); + ensure!( + !Self::exceeds_tx_delegate_take_rate_limit( + Self::get_last_tx_block_delegate_take(&coldkey), + block + ), + Error::::DelegateTxRateLimitExceeded + ); + + // Set last block for rate limiting + Self::set_last_tx_block_delegate_take(&coldkey, block); + + // --- 6. Set the new take value. + Delegates::::insert(hotkey.clone(), take); + + // --- 7. Emit the take value. + log::info!( + "TakeIncreased( coldkey:{:?}, hotkey:{:?}, take:{:?} )", + coldkey, + hotkey, + take + ); + Self::deposit_event(Event::TakeIncreased(coldkey, hotkey, take)); + + // --- 8. Ok and return. + Ok(()) + } +} \ No newline at end of file diff --git a/pallets/subtensor/src/staking/mod.rs b/pallets/subtensor/src/staking/mod.rs new file mode 100644 index 000000000..7015b455a --- /dev/null +++ b/pallets/subtensor/src/staking/mod.rs @@ -0,0 +1,7 @@ +use super::*; +pub mod helpers; +pub mod add_stake; +pub mod remove_stake; +pub mod decrease_take; +pub mod increase_take; +pub mod become_delegate; \ No newline at end of file diff --git a/pallets/subtensor/src/staking/remove_stake.rs b/pallets/subtensor/src/staking/remove_stake.rs new file mode 100644 index 000000000..5f467e009 --- /dev/null +++ b/pallets/subtensor/src/staking/remove_stake.rs @@ -0,0 +1,120 @@ + +use super::*; +use frame_support::{ + storage::IterableStorageDoubleMap, + traits::{ + tokens::{ + fungible::{Balanced as _, Inspect as _, Mutate as _}, + Fortitude, Precision, Preservation, + }, + Imbalance, + }, +}; + +impl Pallet { + /// ---- The implementation for the extrinsic remove_stake: Removes stake from a hotkey account and adds it onto a coldkey. + /// + /// # Args: + /// * 'origin': (RuntimeOrigin): + /// - The signature of the caller's coldkey. + /// + /// * 'hotkey' (T::AccountId): + /// - The associated hotkey account. + /// + /// * 'stake_to_be_added' (u64): + /// - The amount of stake to be added to the hotkey staking account. + /// + /// # Event: + /// * StakeRemoved; + /// - On the successfully removing stake from the hotkey account. + /// + /// # Raises: + /// * 'NotRegistered': + /// - Thrown if the account we are attempting to unstake from is non existent. + /// + /// * 'NonAssociatedColdKey': + /// - Thrown if the coldkey does not own the hotkey we are unstaking from. + /// + /// * 'NotEnoughStakeToWithdraw': + /// - Thrown if there is not enough stake on the hotkey to withdwraw this amount. + /// + /// * 'TxRateLimitExceeded': + /// - Thrown if key has hit transaction rate limit + /// + pub fn do_remove_stake( + origin: T::RuntimeOrigin, + hotkey: T::AccountId, + stake_to_be_removed: u64, + ) -> dispatch::DispatchResult { + // We check the transaction is signed by the caller and retrieve the T::AccountId coldkey information. + let coldkey = ensure_signed(origin)?; + log::info!( + "do_remove_stake( origin:{:?} hotkey:{:?}, stake_to_be_removed:{:?} )", + coldkey, + hotkey, + stake_to_be_removed + ); + + // Ensure that the hotkey account exists this is only possible through registration. + ensure!( + Self::hotkey_account_exists(&hotkey), + Error::::HotKeyAccountNotExists + ); + + // Ensure that the hotkey allows delegation or that the hotkey is owned by the calling coldkey. + ensure!( + Self::hotkey_is_delegate(&hotkey) || Self::coldkey_owns_hotkey(&coldkey, &hotkey), + Error::::HotKeyNotDelegateAndSignerNotOwnHotKey + ); + + // Ensure that the stake amount to be removed is above zero. + ensure!(stake_to_be_removed > 0, Error::::StakeToWithdrawIsZero); + + // Ensure that the hotkey has enough stake to withdraw. + ensure!( + Self::has_enough_stake(&coldkey, &hotkey, stake_to_be_removed), + Error::::NotEnoughStakeToWithdraw + ); + + // Ensure we don't exceed stake rate limit + let unstakes_this_interval = + Self::get_stakes_this_interval_for_coldkey_hotkey(&coldkey, &hotkey); + ensure!( + unstakes_this_interval < Self::get_target_stakes_per_interval(), + Error::::UnstakeRateLimitExceeded + ); + + // We remove the balance from the hotkey. + Self::decrease_stake_on_coldkey_hotkey_account(&coldkey, &hotkey, stake_to_be_removed); + + // We add the balance to the coldkey. If the above fails we will not credit this coldkey. + Self::add_balance_to_coldkey_account(&coldkey, stake_to_be_removed); + + // If the stake is below the minimum, we clear the nomination from storage. + // This only applies to nominator stakes. + // If the coldkey does not own the hotkey, it's a nominator stake. + let new_stake = Self::get_stake_for_coldkey_and_hotkey(&coldkey, &hotkey); + Self::clear_small_nomination_if_required(&hotkey, &coldkey, new_stake); + + // Set last block for rate limiting + let block: u64 = Self::get_current_block_as_u64(); + Self::set_last_tx_block(&coldkey, block); + + // Emit the unstaking event. + Self::set_stakes_this_interval_for_coldkey_hotkey( + &coldkey, + &hotkey, + unstakes_this_interval.saturating_add(1), + block, + ); + log::info!( + "StakeRemoved( hotkey:{:?}, stake_to_be_removed:{:?} )", + hotkey, + stake_to_be_removed + ); + Self::deposit_event(Event::StakeRemoved(hotkey, stake_to_be_removed)); + + // Done and ok. + Ok(()) + } +} \ No newline at end of file diff --git a/pallets/subtensor/src/swap/swap_coldkey.rs b/pallets/subtensor/src/swap/swap_coldkey.rs index 83bad5134..78508f9c5 100644 --- a/pallets/subtensor/src/swap/swap_coldkey.rs +++ b/pallets/subtensor/src/swap/swap_coldkey.rs @@ -1,7 +1,7 @@ use super::*; use frame_support::traits::fungible::Mutate; use frame_support::traits::tokens::Preservation; -use frame_support::{storage::IterableStorageDoubleMap, weights::Weight}; +use frame_support::weights::Weight; use sp_core::Get; impl Pallet { From fcbf66235f0d2b358a8ef869bfd00eacaef5bcb2 Mon Sep 17 00:00:00 2001 From: const Date: Mon, 15 Jul 2024 14:10:49 -0500 Subject: [PATCH 10/58] fmt --- pallets/subtensor/src/coinbase/mod.rs | 2 +- pallets/subtensor/src/epoch/mod.rs | 2 +- pallets/subtensor/src/lib.rs | 1229 ++++++++++++----- pallets/subtensor/src/macros/config.rs | 2 +- pallets/subtensor/src/macros/dispatches.rs | 2 +- pallets/subtensor/src/macros/genesis.rs | 3 +- pallets/subtensor/src/macros/hooks.rs | 2 +- pallets/subtensor/src/macros/mod.rs | 6 +- .../migrations/migrate_create_root_network.rs | 4 +- .../migrations/migrate_delete_subnet_21.rs | 5 +- .../src/migrations/migrate_delete_subnet_3.rs | 5 +- .../migrate_populate_owned_hotkeys.rs | 5 +- .../migrate_populate_staking_hotkeys.rs | 4 +- .../migrate_to_v1_separate_emission.rs | 9 +- .../migrate_to_v2_fixed_total_stake.rs | 7 +- .../src/migrations/migrate_total_issuance.rs | 17 +- ...igrate_transfer_ownership_to_foundation.rs | 2 +- pallets/subtensor/src/migrations/mod.rs | 10 +- pallets/subtensor/src/root.rs | 3 +- pallets/subtensor/src/rpc_info/mod.rs | 2 +- pallets/subtensor/src/staking/add_stake.rs | 2 +- pallets/subtensor/src/staking/helpers.rs | 1 - .../subtensor/src/staking/increase_take.rs | 3 +- pallets/subtensor/src/staking/mod.rs | 6 +- pallets/subtensor/src/staking/remove_stake.rs | 3 +- pallets/subtensor/src/swap/mod.rs | 2 +- pallets/subtensor/src/swap/swap_coldkey.rs | 4 - pallets/subtensor/src/swap/swap_hotkey.rs | 3 +- pallets/subtensor/tests/staking.rs | 2 +- pallets/subtensor/tests/swap.rs | 69 +- 30 files changed, 985 insertions(+), 431 deletions(-) diff --git a/pallets/subtensor/src/coinbase/mod.rs b/pallets/subtensor/src/coinbase/mod.rs index e86c66b59..cc5b589f1 100644 --- a/pallets/subtensor/src/coinbase/mod.rs +++ b/pallets/subtensor/src/coinbase/mod.rs @@ -1,2 +1,2 @@ use super::*; -pub mod block_step; \ No newline at end of file +pub mod block_step; diff --git a/pallets/subtensor/src/epoch/mod.rs b/pallets/subtensor/src/epoch/mod.rs index 74f3b1094..723e68ee4 100644 --- a/pallets/subtensor/src/epoch/mod.rs +++ b/pallets/subtensor/src/epoch/mod.rs @@ -1,3 +1,3 @@ use super::*; +pub mod epoch; pub mod math; -pub mod epoch; \ No newline at end of file diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index 7596029e0..23adeee02 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -35,13 +35,13 @@ mod benchmarks; // ========================= // ==== Pallet Imports ===== // ========================= -mod rpc_info; mod coinbase; pub mod epoch; -pub mod swap; -pub mod staking; mod macros; -use macros::{events, errors, dispatches, genesis, hooks, config}; +mod rpc_info; +pub mod staking; +pub mod swap; +use macros::{config, dispatches, errors, events, genesis, hooks}; mod registration; mod root; @@ -64,12 +64,12 @@ pub mod migrations; #[frame_support::pallet] pub mod pallet { + use crate::migrations; use frame_support::{ dispatch::GetDispatchInfo, pallet_prelude::{DispatchResult, StorageMap, ValueQuery, *}, traits::{tokens::fungible, UnfilteredDispatchable}, }; - use crate::migrations; use frame_system::pallet_prelude::*; use sp_core::H256; use sp_runtime::traits::TrailingZeroInput; @@ -137,178 +137,427 @@ pub mod pallet { pub ip_type: u8, } - /// ============================ /// ==== Staking + Accounts ==== /// ============================ - #[pallet::type_value] /// Total Rao in circulation. - pub fn TotalSupply() -> u64 { 21_000_000_000_000_000 } - #[pallet::type_value] /// Default total stake. - pub fn DefaultDefaultTake() -> u16 { T::InitialDefaultTake::get() } - #[pallet::type_value] /// Default minimum take. - pub fn DefaultMinTake() -> u16 { T::InitialMinTake::get() } - #[pallet::type_value] /// Default account take. - pub fn DefaultAccountTake() -> u64 { 0 } - #[pallet::type_value] /// Default stakes per interval. - pub fn DefaultStakesPerInterval() -> (u64, u64) { (0, 0) } - #[pallet::type_value] /// Default emission per block. - pub fn DefaultBlockEmission() -> u64 { 1_000_000_000 } - #[pallet::type_value] /// Default allowed delegation. - pub fn DefaultAllowsDelegation() -> bool { false } - #[pallet::type_value] /// Default total issuance. - pub fn DefaultTotalIssuance() -> u64 { T::InitialIssuance::get() } - #[pallet::type_value] /// Default account, derived from zero trailing bytes. - pub fn DefaultAccount() -> T::AccountId { T::AccountId::decode(&mut TrailingZeroInput::zeroes()).expect("trailing zeroes always produce a valid account ID; qed") } - #[pallet::type_value] /// Default target stakes per interval. - pub fn DefaultTargetStakesPerInterval() -> u64 { T::InitialTargetStakesPerInterval::get() } - #[pallet::type_value] /// Default stake interval. - pub fn DefaultStakeInterval() -> u64 { 360 } - #[pallet::type_value] /// Default account linkage - pub fn DefaultAccountLinkage() -> Vec<(u64, T::AccountId)> { vec![] } - #[pallet::type_value] /// Default account linkage - pub fn DefaultProportion() -> u64 { 0 } - #[pallet::type_value] /// Default accumulated emission for a hotkey - pub fn DefaultAccumulatedEmission() -> u64 { 0 } - #[pallet::type_value] /// Default last adjustment block. - pub fn DefaultLastAdjustmentBlock() -> u64 { 0 } - #[pallet::type_value] /// Default last adjustment block. - pub fn DefaultRegistrationsThisBlock() -> u16 { 0 } - #[pallet::type_value] /// Default registrations this block. - pub fn DefaultBurn() -> u64 { T::InitialBurn::get() } - #[pallet::type_value] /// Default burn token. - pub fn DefaultMinBurn() -> u64 { T::InitialMinBurn::get() } - #[pallet::type_value] /// Default min burn token. - pub fn DefaultMaxBurn() -> u64 { T::InitialMaxBurn::get() } - #[pallet::type_value] /// Default max burn token. - pub fn DefaultDifficulty() -> u64 { T::InitialDifficulty::get() } - #[pallet::type_value] /// Default difficulty value. - pub fn DefaultMinDifficulty() -> u64 { T::InitialMinDifficulty::get() } - #[pallet::type_value] /// Default min difficulty value. - pub fn DefaultMaxDifficulty() -> u64 { T::InitialMaxDifficulty::get() } - #[pallet::type_value] /// Default max difficulty value. - pub fn DefaultMaxRegistrationsPerBlock() -> u16 { T::InitialMaxRegistrationsPerBlock::get() } - #[pallet::type_value] /// Default max registrations per block. - pub fn DefaultRAORecycledForRegistration() -> u64 { T::InitialRAORecycledForRegistration::get() } - #[pallet::type_value] /// Default number of networks. - pub fn DefaultN() -> u16 { 0 } - #[pallet::type_value] /// Default value for modality. - pub fn DefaultModality() -> u16 { 0 } - #[pallet::type_value] /// Default value for hotkeys. - pub fn DefaultHotkeys() -> Vec { vec![] } - #[pallet::type_value] /// Default value if network is added. - pub fn DefaultNeworksAdded() -> bool { false } - #[pallet::type_value] /// Default value for network member. - pub fn DefaultIsNetworkMember() -> bool { false } - #[pallet::type_value] /// Default value for registration allowed. - pub fn DefaultRegistrationAllowed() -> bool { false } - #[pallet::type_value] /// Default value for network registered at. - pub fn DefaultNetworkRegisteredAt() -> u64 { 0 } - #[pallet::type_value] /// Default value for network immunity period. - pub fn DefaultNetworkImmunityPeriod() -> u64 { T::InitialNetworkImmunityPeriod::get() } - #[pallet::type_value] /// Default value for network last registered. - pub fn DefaultNetworkLastRegistered() -> u64 { 0 } - #[pallet::type_value] /// Default value for nominator min required stake. - pub fn DefaultNominatorMinRequiredStake() -> u64 { 0 } - #[pallet::type_value] /// Default value for network min allowed UIDs. - pub fn DefaultNetworkMinAllowedUids() -> u16 { T::InitialNetworkMinAllowedUids::get() } - #[pallet::type_value] /// Default value for network min lock cost. - pub fn DefaultNetworkMinLockCost() -> u64 { T::InitialNetworkMinLockCost::get() } - #[pallet::type_value] /// Default value for network lock reduction interval. - pub fn DefaultNetworkLockReductionInterval() -> u64 { T::InitialNetworkLockReductionInterval::get() } - #[pallet::type_value] /// Default value for subnet owner cut. - pub fn DefaultSubnetOwnerCut() -> u16 { T::InitialSubnetOwnerCut::get() } - #[pallet::type_value] /// Default value for subnet limit. - pub fn DefaultSubnetLimit() -> u16 { T::InitialSubnetLimit::get() } - #[pallet::type_value] /// Default value for network rate limit. - pub fn DefaultNetworkRateLimit() -> u64 { if cfg!(feature = "pow-faucet") { return 0; } T::InitialNetworkRateLimit::get() } + #[pallet::type_value] + /// Total Rao in circulation. + pub fn TotalSupply() -> u64 { + 21_000_000_000_000_000 + } + #[pallet::type_value] + /// Default total stake. + pub fn DefaultDefaultTake() -> u16 { + T::InitialDefaultTake::get() + } + #[pallet::type_value] + /// Default minimum take. + pub fn DefaultMinTake() -> u16 { + T::InitialMinTake::get() + } + #[pallet::type_value] + /// Default account take. + pub fn DefaultAccountTake() -> u64 { + 0 + } + #[pallet::type_value] + /// Default stakes per interval. + pub fn DefaultStakesPerInterval() -> (u64, u64) { + (0, 0) + } + #[pallet::type_value] + /// Default emission per block. + pub fn DefaultBlockEmission() -> u64 { + 1_000_000_000 + } + #[pallet::type_value] + /// Default allowed delegation. + pub fn DefaultAllowsDelegation() -> bool { + false + } + #[pallet::type_value] + /// Default total issuance. + pub fn DefaultTotalIssuance() -> u64 { + T::InitialIssuance::get() + } + #[pallet::type_value] + /// Default account, derived from zero trailing bytes. + pub fn DefaultAccount() -> T::AccountId { + T::AccountId::decode(&mut TrailingZeroInput::zeroes()) + .expect("trailing zeroes always produce a valid account ID; qed") + } + #[pallet::type_value] + /// Default target stakes per interval. + pub fn DefaultTargetStakesPerInterval() -> u64 { + T::InitialTargetStakesPerInterval::get() + } + #[pallet::type_value] + /// Default stake interval. + pub fn DefaultStakeInterval() -> u64 { + 360 + } + #[pallet::type_value] + /// Default account linkage + pub fn DefaultAccountLinkage() -> Vec<(u64, T::AccountId)> { + vec![] + } + #[pallet::type_value] + /// Default account linkage + pub fn DefaultProportion() -> u64 { + 0 + } + #[pallet::type_value] + /// Default accumulated emission for a hotkey + pub fn DefaultAccumulatedEmission() -> u64 { + 0 + } + #[pallet::type_value] + /// Default last adjustment block. + pub fn DefaultLastAdjustmentBlock() -> u64 { + 0 + } + #[pallet::type_value] + /// Default last adjustment block. + pub fn DefaultRegistrationsThisBlock() -> u16 { + 0 + } + #[pallet::type_value] + /// Default registrations this block. + pub fn DefaultBurn() -> u64 { + T::InitialBurn::get() + } + #[pallet::type_value] + /// Default burn token. + pub fn DefaultMinBurn() -> u64 { + T::InitialMinBurn::get() + } + #[pallet::type_value] + /// Default min burn token. + pub fn DefaultMaxBurn() -> u64 { + T::InitialMaxBurn::get() + } + #[pallet::type_value] + /// Default max burn token. + pub fn DefaultDifficulty() -> u64 { + T::InitialDifficulty::get() + } + #[pallet::type_value] + /// Default difficulty value. + pub fn DefaultMinDifficulty() -> u64 { + T::InitialMinDifficulty::get() + } + #[pallet::type_value] + /// Default min difficulty value. + pub fn DefaultMaxDifficulty() -> u64 { + T::InitialMaxDifficulty::get() + } + #[pallet::type_value] + /// Default max difficulty value. + pub fn DefaultMaxRegistrationsPerBlock() -> u16 { + T::InitialMaxRegistrationsPerBlock::get() + } + #[pallet::type_value] + /// Default max registrations per block. + pub fn DefaultRAORecycledForRegistration() -> u64 { + T::InitialRAORecycledForRegistration::get() + } + #[pallet::type_value] + /// Default number of networks. + pub fn DefaultN() -> u16 { + 0 + } + #[pallet::type_value] + /// Default value for modality. + pub fn DefaultModality() -> u16 { + 0 + } + #[pallet::type_value] + /// Default value for hotkeys. + pub fn DefaultHotkeys() -> Vec { + vec![] + } + #[pallet::type_value] + /// Default value if network is added. + pub fn DefaultNeworksAdded() -> bool { + false + } + #[pallet::type_value] + /// Default value for network member. + pub fn DefaultIsNetworkMember() -> bool { + false + } + #[pallet::type_value] + /// Default value for registration allowed. + pub fn DefaultRegistrationAllowed() -> bool { + false + } + #[pallet::type_value] + /// Default value for network registered at. + pub fn DefaultNetworkRegisteredAt() -> u64 { + 0 + } + #[pallet::type_value] + /// Default value for network immunity period. + pub fn DefaultNetworkImmunityPeriod() -> u64 { + T::InitialNetworkImmunityPeriod::get() + } + #[pallet::type_value] + /// Default value for network last registered. + pub fn DefaultNetworkLastRegistered() -> u64 { + 0 + } + #[pallet::type_value] + /// Default value for nominator min required stake. + pub fn DefaultNominatorMinRequiredStake() -> u64 { + 0 + } + #[pallet::type_value] + /// Default value for network min allowed UIDs. + pub fn DefaultNetworkMinAllowedUids() -> u16 { + T::InitialNetworkMinAllowedUids::get() + } + #[pallet::type_value] + /// Default value for network min lock cost. + pub fn DefaultNetworkMinLockCost() -> u64 { + T::InitialNetworkMinLockCost::get() + } + #[pallet::type_value] + /// Default value for network lock reduction interval. + pub fn DefaultNetworkLockReductionInterval() -> u64 { + T::InitialNetworkLockReductionInterval::get() + } + #[pallet::type_value] + /// Default value for subnet owner cut. + pub fn DefaultSubnetOwnerCut() -> u16 { + T::InitialSubnetOwnerCut::get() + } + #[pallet::type_value] + /// Default value for subnet limit. + pub fn DefaultSubnetLimit() -> u16 { + T::InitialSubnetLimit::get() + } + #[pallet::type_value] + /// Default value for network rate limit. + pub fn DefaultNetworkRateLimit() -> u64 { + if cfg!(feature = "pow-faucet") { + return 0; + } + T::InitialNetworkRateLimit::get() + } // #[pallet::type_value] /// Default value for network max stake. // pub fn DefaultNetworkMaxStake() -> u64 { T::InitialNetworkMaxStake::get() } - #[pallet::type_value] /// Default value for emission values. - pub fn DefaultEmissionValues() -> u64 { 0 } - #[pallet::type_value] /// Default value for pending emission. - pub fn DefaultPendingEmission() -> u64 { 0 } - #[pallet::type_value] /// Default value for blocks since last step. - pub fn DefaultBlocksSinceLastStep() -> u64 { 0 } - #[pallet::type_value] /// Default value for last mechanism step block. - pub fn DefaultLastMechanismStepBlock() -> u64 { 0 } - #[pallet::type_value] /// Default value for subnet owner. - pub fn DefaultSubnetOwner() -> T::AccountId { T::AccountId::decode(&mut sp_runtime::traits::TrailingZeroInput::zeroes()).expect("trailing zeroes always produce a valid account ID; qed") } - #[pallet::type_value] /// Default value for subnet locked. - pub fn DefaultSubnetLocked() -> u64 { 0 } - #[pallet::type_value] /// Default value for network tempo - pub fn DefaultTempo() -> u16 { T::InitialTempo::get() } - #[pallet::type_value] /// Default value for weights set rate limit. - pub fn DefaultWeightsSetRateLimit() -> u64 { 100 } - #[pallet::type_value] /// Default block number at registration. - pub fn DefaultBlockAtRegistration() -> u64 { 0 } - #[pallet::type_value] /// Default value for rho parameter. - pub fn DefaultRho() -> u16 { T::InitialRho::get() } - #[pallet::type_value] /// Default value for kappa parameter. - pub fn DefaultKappa() -> u16 { T::InitialKappa::get() } - #[pallet::type_value] /// Default maximum allowed UIDs. - pub fn DefaultMaxAllowedUids() -> u16 { T::InitialMaxAllowedUids::get() } - #[pallet::type_value] /// Default immunity period. - pub fn DefaultImmunityPeriod() -> u16 { T::InitialImmunityPeriod::get() } - #[pallet::type_value] /// Default activity cutoff. - pub fn DefaultActivityCutoff() -> u16 { T::InitialActivityCutoff::get() } - #[pallet::type_value] /// Default maximum weights limit. - pub fn DefaultMaxWeightsLimit() -> u16 { T::InitialMaxWeightsLimit::get() } - #[pallet::type_value] /// Default weights version key. - pub fn DefaultWeightsVersionKey() -> u64 { T::InitialWeightsVersionKey::get() } - #[pallet::type_value] /// Default minimum allowed weights. - pub fn DefaultMinAllowedWeights() -> u16 { T::InitialMinAllowedWeights::get() } - #[pallet::type_value] /// Default maximum allowed validators. - pub fn DefaultMaxAllowedValidators() -> u16 { T::InitialMaxAllowedValidators::get() } - #[pallet::type_value] /// Default adjustment interval. - pub fn DefaultAdjustmentInterval() -> u16 { T::InitialAdjustmentInterval::get() } - #[pallet::type_value] /// Default bonds moving average. - pub fn DefaultBondsMovingAverage() -> u64 { T::InitialBondsMovingAverage::get() } - #[pallet::type_value] /// Default validator prune length. - pub fn DefaultValidatorPruneLen() -> u64 { T::InitialValidatorPruneLen::get() } - #[pallet::type_value] /// Default scaling law power. - pub fn DefaultScalingLawPower() -> u16 { T::InitialScalingLawPower::get() } - #[pallet::type_value] /// Default target registrations per interval. - pub fn DefaultTargetRegistrationsPerInterval() -> u16 { T::InitialTargetRegistrationsPerInterval::get() } - #[pallet::type_value] /// Default adjustment alpha. - pub fn DefaultAdjustmentAlpha() -> u64 { T::InitialAdjustmentAlpha::get() } - #[pallet::type_value] /// Default minimum stake for weights. - pub fn DefaultWeightsMinStake() -> u64 { 0 } - #[pallet::type_value] /// Value definition for vector of u16. - pub fn EmptyU16Vec() -> Vec { vec![] } - #[pallet::type_value] /// Value definition for vector of u64. - pub fn EmptyU64Vec() -> Vec { vec![] } - #[pallet::type_value] /// Value definition for vector of bool. - pub fn EmptyBoolVec() -> Vec { vec![] } - #[pallet::type_value] /// Value definition for bonds with type vector of (u16, u16). - pub fn DefaultBonds() -> Vec<(u16, u16)> { vec![] } - #[pallet::type_value] /// Value definition for weights with vector of (u16, u16). - pub fn DefaultWeights() -> Vec<(u16, u16)> { vec![] } - #[pallet::type_value] /// Default value for key with type T::AccountId derived from trailing zeroes. - pub fn DefaultKey() -> T::AccountId { T::AccountId::decode(&mut sp_runtime::traits::TrailingZeroInput::zeroes()).expect("trailing zeroes always produce a valid account ID; qed") } - #[pallet::type_value] /// Default value for network immunity period. - pub fn DefaultHotkeyEmissionTempo() -> u64 { 7200 } - #[pallet::type_value] /// Default value for rate limiting - pub fn DefaultTxRateLimit() -> u64 { T::InitialTxRateLimit::get() } - #[pallet::type_value] /// Default value for delegate take rate limiting - pub fn DefaultTxDelegateTakeRateLimit() -> u64 { T::InitialTxDelegateTakeRateLimit::get() } - #[pallet::type_value] /// Default value for last extrinsic block. - pub fn DefaultLastTxBlock() -> u64 { 0 } - #[pallet::type_value] /// Default value for serving rate limit. - pub fn DefaultServingRateLimit() -> u64 { T::InitialServingRateLimit::get() } - #[pallet::type_value] /// Default value for weight commit reveal interval. - pub fn DefaultWeightCommitRevealInterval() -> u64 { 1000 } - #[pallet::type_value] /// Default value for weight commit/reveal enabled. - pub fn DefaultCommitRevealWeightsEnabled() -> bool { false } - #[pallet::type_value] /// Senate requirements - pub fn DefaultSenateRequiredStakePercentage() -> u64 { T::InitialSenateRequiredStakePercentage::get() } - #[pallet::type_value] /// -- ITEM (switches liquid alpha on) - pub fn DefaultLiquidAlpha() -> bool {false} - #[pallet::type_value] /// (alpha_low: 0.7, alpha_high: 0.9) - pub fn DefaultAlphaValues() -> (u16, u16) { (45875, 58982) } - - #[pallet::storage] - pub type SenateRequiredStakePercentage = StorageValue<_, u64, ValueQuery, DefaultSenateRequiredStakePercentage>; + #[pallet::type_value] + /// Default value for emission values. + pub fn DefaultEmissionValues() -> u64 { + 0 + } + #[pallet::type_value] + /// Default value for pending emission. + pub fn DefaultPendingEmission() -> u64 { + 0 + } + #[pallet::type_value] + /// Default value for blocks since last step. + pub fn DefaultBlocksSinceLastStep() -> u64 { + 0 + } + #[pallet::type_value] + /// Default value for last mechanism step block. + pub fn DefaultLastMechanismStepBlock() -> u64 { + 0 + } + #[pallet::type_value] + /// Default value for subnet owner. + pub fn DefaultSubnetOwner() -> T::AccountId { + T::AccountId::decode(&mut sp_runtime::traits::TrailingZeroInput::zeroes()) + .expect("trailing zeroes always produce a valid account ID; qed") + } + #[pallet::type_value] + /// Default value for subnet locked. + pub fn DefaultSubnetLocked() -> u64 { + 0 + } + #[pallet::type_value] + /// Default value for network tempo + pub fn DefaultTempo() -> u16 { + T::InitialTempo::get() + } + #[pallet::type_value] + /// Default value for weights set rate limit. + pub fn DefaultWeightsSetRateLimit() -> u64 { + 100 + } + #[pallet::type_value] + /// Default block number at registration. + pub fn DefaultBlockAtRegistration() -> u64 { + 0 + } + #[pallet::type_value] + /// Default value for rho parameter. + pub fn DefaultRho() -> u16 { + T::InitialRho::get() + } + #[pallet::type_value] + /// Default value for kappa parameter. + pub fn DefaultKappa() -> u16 { + T::InitialKappa::get() + } + #[pallet::type_value] + /// Default maximum allowed UIDs. + pub fn DefaultMaxAllowedUids() -> u16 { + T::InitialMaxAllowedUids::get() + } + #[pallet::type_value] + /// Default immunity period. + pub fn DefaultImmunityPeriod() -> u16 { + T::InitialImmunityPeriod::get() + } + #[pallet::type_value] + /// Default activity cutoff. + pub fn DefaultActivityCutoff() -> u16 { + T::InitialActivityCutoff::get() + } + #[pallet::type_value] + /// Default maximum weights limit. + pub fn DefaultMaxWeightsLimit() -> u16 { + T::InitialMaxWeightsLimit::get() + } + #[pallet::type_value] + /// Default weights version key. + pub fn DefaultWeightsVersionKey() -> u64 { + T::InitialWeightsVersionKey::get() + } + #[pallet::type_value] + /// Default minimum allowed weights. + pub fn DefaultMinAllowedWeights() -> u16 { + T::InitialMinAllowedWeights::get() + } + #[pallet::type_value] + /// Default maximum allowed validators. + pub fn DefaultMaxAllowedValidators() -> u16 { + T::InitialMaxAllowedValidators::get() + } + #[pallet::type_value] + /// Default adjustment interval. + pub fn DefaultAdjustmentInterval() -> u16 { + T::InitialAdjustmentInterval::get() + } + #[pallet::type_value] + /// Default bonds moving average. + pub fn DefaultBondsMovingAverage() -> u64 { + T::InitialBondsMovingAverage::get() + } + #[pallet::type_value] + /// Default validator prune length. + pub fn DefaultValidatorPruneLen() -> u64 { + T::InitialValidatorPruneLen::get() + } + #[pallet::type_value] + /// Default scaling law power. + pub fn DefaultScalingLawPower() -> u16 { + T::InitialScalingLawPower::get() + } + #[pallet::type_value] + /// Default target registrations per interval. + pub fn DefaultTargetRegistrationsPerInterval() -> u16 { + T::InitialTargetRegistrationsPerInterval::get() + } + #[pallet::type_value] + /// Default adjustment alpha. + pub fn DefaultAdjustmentAlpha() -> u64 { + T::InitialAdjustmentAlpha::get() + } + #[pallet::type_value] + /// Default minimum stake for weights. + pub fn DefaultWeightsMinStake() -> u64 { + 0 + } + #[pallet::type_value] + /// Value definition for vector of u16. + pub fn EmptyU16Vec() -> Vec { + vec![] + } + #[pallet::type_value] + /// Value definition for vector of u64. + pub fn EmptyU64Vec() -> Vec { + vec![] + } + #[pallet::type_value] + /// Value definition for vector of bool. + pub fn EmptyBoolVec() -> Vec { + vec![] + } + #[pallet::type_value] + /// Value definition for bonds with type vector of (u16, u16). + pub fn DefaultBonds() -> Vec<(u16, u16)> { + vec![] + } + #[pallet::type_value] + /// Value definition for weights with vector of (u16, u16). + pub fn DefaultWeights() -> Vec<(u16, u16)> { + vec![] + } + #[pallet::type_value] + /// Default value for key with type T::AccountId derived from trailing zeroes. + pub fn DefaultKey() -> T::AccountId { + T::AccountId::decode(&mut sp_runtime::traits::TrailingZeroInput::zeroes()) + .expect("trailing zeroes always produce a valid account ID; qed") + } + #[pallet::type_value] + /// Default value for network immunity period. + pub fn DefaultHotkeyEmissionTempo() -> u64 { + 7200 + } + #[pallet::type_value] + /// Default value for rate limiting + pub fn DefaultTxRateLimit() -> u64 { + T::InitialTxRateLimit::get() + } + #[pallet::type_value] + /// Default value for delegate take rate limiting + pub fn DefaultTxDelegateTakeRateLimit() -> u64 { + T::InitialTxDelegateTakeRateLimit::get() + } + #[pallet::type_value] + /// Default value for last extrinsic block. + pub fn DefaultLastTxBlock() -> u64 { + 0 + } + #[pallet::type_value] + /// Default value for serving rate limit. + pub fn DefaultServingRateLimit() -> u64 { + T::InitialServingRateLimit::get() + } + #[pallet::type_value] + /// Default value for weight commit reveal interval. + pub fn DefaultWeightCommitRevealInterval() -> u64 { + 1000 + } + #[pallet::type_value] + /// Default value for weight commit/reveal enabled. + pub fn DefaultCommitRevealWeightsEnabled() -> bool { + false + } + #[pallet::type_value] + /// Senate requirements + pub fn DefaultSenateRequiredStakePercentage() -> u64 { + T::InitialSenateRequiredStakePercentage::get() + } + #[pallet::type_value] + /// -- ITEM (switches liquid alpha on) + pub fn DefaultLiquidAlpha() -> bool { + false + } + #[pallet::type_value] + /// (alpha_low: 0.7, alpha_high: 0.9) + pub fn DefaultAlphaValues() -> (u16, u16) { + (45875, 58982) + } + + #[pallet::storage] + pub type SenateRequiredStakePercentage = + StorageValue<_, u64, ValueQuery, DefaultSenateRequiredStakePercentage>; /// ============================ /// ==== Staking Variables ==== @@ -324,227 +573,499 @@ pub mod pallet { #[pallet::storage] // --- ITEM ( global_block_emission ) pub type BlockEmission = StorageValue<_, u64, ValueQuery, DefaultBlockEmission>; #[pallet::storage] // --- ITEM (target_stakes_per_interval) - pub type TargetStakesPerInterval = StorageValue<_, u64, ValueQuery, DefaultTargetStakesPerInterval>; + pub type TargetStakesPerInterval = + StorageValue<_, u64, ValueQuery, DefaultTargetStakesPerInterval>; #[pallet::storage] // --- ITEM (default_stake_interval) pub type StakeInterval = StorageValue<_, u64, ValueQuery, DefaultStakeInterval>; #[pallet::storage] // --- MAP ( hot ) --> stake | Returns the total amount of stake under a hotkey. - pub type TotalHotkeyStake = StorageMap<_, Identity, T::AccountId, u64, ValueQuery, DefaultAccountTake>; + pub type TotalHotkeyStake = + StorageMap<_, Identity, T::AccountId, u64, ValueQuery, DefaultAccountTake>; #[pallet::storage] // --- MAP ( cold ) --> stake | Returns the total amount of stake under a coldkey. - pub type TotalColdkeyStake = StorageMap<_, Identity, T::AccountId, u64, ValueQuery, DefaultAccountTake>; - #[pallet::storage] /// MAP (hot, cold) --> stake | Returns a tuple (u64: stakes, u64: block_number) - pub type TotalHotkeyColdkeyStakesThisInterval = StorageDoubleMap<_, Identity, T::AccountId, Identity, T::AccountId, (u64, u64), ValueQuery, DefaultStakesPerInterval>; - #[pallet::storage] /// MAP ( hot ) --> cold | Returns the controlling coldkey for a hotkey. - pub type Owner = StorageMap<_, Blake2_128Concat, T::AccountId, T::AccountId, ValueQuery, DefaultAccount>; - #[pallet::storage] /// MAP ( hot ) --> take | Returns the hotkey delegation take. And signals that this key is open for delegation. - pub type Delegates = StorageMap<_, Blake2_128Concat, T::AccountId, u16, ValueQuery, DefaultDefaultTake>; - #[pallet::storage] /// DMAP ( hot, cold ) --> stake | Returns the stake under a coldkey prefixed by hotkey. - pub type Stake = StorageDoubleMap<_, Blake2_128Concat, T::AccountId, Identity, T::AccountId, u64, ValueQuery, DefaultAccountTake>; - #[pallet::storage] /// Map ( hot ) --> last_hotkey_emission_drain | Last block we drained this hotkey's emission. - pub type LastHotkeyEmissionDrain = StorageMap<_, Blake2_128Concat, T::AccountId, u64, ValueQuery, DefaultAccumulatedEmission>; - #[pallet::storage] /// ITEM ( hotkey_emission_tempo ) - pub type HotkeyEmissionTempo = StorageValue<_, u64, ValueQuery, DefaultHotkeyEmissionTempo>; - #[pallet::storage] /// Map ( hot ) --> emission | Accumulated hotkey emission. - pub type PendingdHotkeyEmission = StorageMap<_, Blake2_128Concat, T::AccountId, u64, ValueQuery, DefaultAccumulatedEmission>; - #[pallet::storage] /// Map ( hot, cold ) --> block_number | Last add stake increase. - pub type LastAddStakeIncrease = StorageDoubleMap<_, Blake2_128Concat, T::AccountId, Identity, T::AccountId, u64, ValueQuery, DefaultAccountTake>; - #[pallet::storage] /// DMAP ( parent, netuid ) --> Vec<(proportion,child)> - pub type ChildKeys = StorageDoubleMap<_, Blake2_128Concat, T::AccountId, Identity, u16, Vec<(u64, T::AccountId)>, ValueQuery, DefaultAccountLinkage>; - #[pallet::storage] /// DMAP ( child, netuid ) --> Vec<(proportion,parent)> - pub type ParentKeys = StorageDoubleMap<_, Blake2_128Concat, T::AccountId, Identity, u16, Vec<(u64, T::AccountId)>, ValueQuery, DefaultAccountLinkage>; + pub type TotalColdkeyStake = + StorageMap<_, Identity, T::AccountId, u64, ValueQuery, DefaultAccountTake>; + #[pallet::storage] + /// MAP (hot, cold) --> stake | Returns a tuple (u64: stakes, u64: block_number) + pub type TotalHotkeyColdkeyStakesThisInterval = StorageDoubleMap< + _, + Identity, + T::AccountId, + Identity, + T::AccountId, + (u64, u64), + ValueQuery, + DefaultStakesPerInterval, + >; + #[pallet::storage] + /// MAP ( hot ) --> cold | Returns the controlling coldkey for a hotkey. + pub type Owner = + StorageMap<_, Blake2_128Concat, T::AccountId, T::AccountId, ValueQuery, DefaultAccount>; + #[pallet::storage] + /// MAP ( hot ) --> take | Returns the hotkey delegation take. And signals that this key is open for delegation. + pub type Delegates = + StorageMap<_, Blake2_128Concat, T::AccountId, u16, ValueQuery, DefaultDefaultTake>; + #[pallet::storage] + /// DMAP ( hot, cold ) --> stake | Returns the stake under a coldkey prefixed by hotkey. + pub type Stake = StorageDoubleMap< + _, + Blake2_128Concat, + T::AccountId, + Identity, + T::AccountId, + u64, + ValueQuery, + DefaultAccountTake, + >; + #[pallet::storage] + /// Map ( hot ) --> last_hotkey_emission_drain | Last block we drained this hotkey's emission. + pub type LastHotkeyEmissionDrain = StorageMap< + _, + Blake2_128Concat, + T::AccountId, + u64, + ValueQuery, + DefaultAccumulatedEmission, + >; + #[pallet::storage] + /// ITEM ( hotkey_emission_tempo ) + pub type HotkeyEmissionTempo = + StorageValue<_, u64, ValueQuery, DefaultHotkeyEmissionTempo>; + #[pallet::storage] + /// Map ( hot ) --> emission | Accumulated hotkey emission. + pub type PendingdHotkeyEmission = StorageMap< + _, + Blake2_128Concat, + T::AccountId, + u64, + ValueQuery, + DefaultAccumulatedEmission, + >; + #[pallet::storage] + /// Map ( hot, cold ) --> block_number | Last add stake increase. + pub type LastAddStakeIncrease = StorageDoubleMap< + _, + Blake2_128Concat, + T::AccountId, + Identity, + T::AccountId, + u64, + ValueQuery, + DefaultAccountTake, + >; + #[pallet::storage] + /// DMAP ( parent, netuid ) --> Vec<(proportion,child)> + pub type ChildKeys = StorageDoubleMap< + _, + Blake2_128Concat, + T::AccountId, + Identity, + u16, + Vec<(u64, T::AccountId)>, + ValueQuery, + DefaultAccountLinkage, + >; + #[pallet::storage] + /// DMAP ( child, netuid ) --> Vec<(proportion,parent)> + pub type ParentKeys = StorageDoubleMap< + _, + Blake2_128Concat, + T::AccountId, + Identity, + u16, + Vec<(u64, T::AccountId)>, + ValueQuery, + DefaultAccountLinkage, + >; #[pallet::storage] // --- DMAP ( cold ) --> Vec | Maps coldkey to hotkeys that stake to it - pub type StakingHotkeys = StorageMap<_, Blake2_128Concat, T::AccountId, Vec, ValueQuery>; + pub type StakingHotkeys = + StorageMap<_, Blake2_128Concat, T::AccountId, Vec, ValueQuery>; #[pallet::storage] // --- MAP ( cold ) --> Vec | Returns the vector of hotkeys controlled by this coldkey. - pub type OwnedHotkeys = StorageMap<_, Blake2_128Concat, T::AccountId, Vec, ValueQuery>; - + pub type OwnedHotkeys = + StorageMap<_, Blake2_128Concat, T::AccountId, Vec, ValueQuery>; /// ============================ /// ==== Global Parameters ===== /// ============================ - #[pallet::storage] /// --- StorageItem Global Used Work. + #[pallet::storage] + /// --- StorageItem Global Used Work. pub type UsedWork = StorageMap<_, Identity, Vec, u64, ValueQuery>; - #[pallet::storage] /// --- ITEM( global_max_registrations_per_block ) - pub type MaxRegistrationsPerBlock = StorageMap<_, Identity, u16, u16, ValueQuery, DefaultMaxRegistrationsPerBlock>; - #[pallet::storage] /// --- ITEM( maximum_number_of_networks ) + #[pallet::storage] + /// --- ITEM( global_max_registrations_per_block ) + pub type MaxRegistrationsPerBlock = + StorageMap<_, Identity, u16, u16, ValueQuery, DefaultMaxRegistrationsPerBlock>; + #[pallet::storage] + /// --- ITEM( maximum_number_of_networks ) pub type SubnetLimit = StorageValue<_, u16, ValueQuery, DefaultSubnetLimit>; - #[pallet::storage] /// --- ITEM( total_number_of_existing_networks ) + #[pallet::storage] + /// --- ITEM( total_number_of_existing_networks ) pub type TotalNetworks = StorageValue<_, u16, ValueQuery>; - #[pallet::storage] /// ITEM( network_immunity_period ) - pub type NetworkImmunityPeriod = StorageValue<_, u64, ValueQuery, DefaultNetworkImmunityPeriod>; - #[pallet::storage] /// ITEM( network_last_registered_block ) - pub type NetworkLastRegistered = StorageValue<_, u64, ValueQuery, DefaultNetworkLastRegistered>; - #[pallet::storage] /// ITEM( network_min_allowed_uids ) - pub type NetworkMinAllowedUids = StorageValue<_, u16, ValueQuery, DefaultNetworkMinAllowedUids>; - #[pallet::storage] /// ITEM( min_network_lock_cost ) + #[pallet::storage] + /// ITEM( network_immunity_period ) + pub type NetworkImmunityPeriod = + StorageValue<_, u64, ValueQuery, DefaultNetworkImmunityPeriod>; + #[pallet::storage] + /// ITEM( network_last_registered_block ) + pub type NetworkLastRegistered = + StorageValue<_, u64, ValueQuery, DefaultNetworkLastRegistered>; + #[pallet::storage] + /// ITEM( network_min_allowed_uids ) + pub type NetworkMinAllowedUids = + StorageValue<_, u16, ValueQuery, DefaultNetworkMinAllowedUids>; + #[pallet::storage] + /// ITEM( min_network_lock_cost ) pub type NetworkMinLockCost = StorageValue<_, u64, ValueQuery, DefaultNetworkMinLockCost>; - #[pallet::storage] /// ITEM( last_network_lock_cost ) - pub type NetworkLastLockCost = StorageValue<_, u64, ValueQuery, DefaultNetworkMinLockCost>; - #[pallet::storage] /// ITEM( network_lock_reduction_interval ) - pub type NetworkLockReductionInterval = StorageValue<_, u64, ValueQuery, DefaultNetworkLockReductionInterval>; - #[pallet::storage] /// ITEM( subnet_owner_cut ) + #[pallet::storage] + /// ITEM( last_network_lock_cost ) + pub type NetworkLastLockCost = + StorageValue<_, u64, ValueQuery, DefaultNetworkMinLockCost>; + #[pallet::storage] + /// ITEM( network_lock_reduction_interval ) + pub type NetworkLockReductionInterval = + StorageValue<_, u64, ValueQuery, DefaultNetworkLockReductionInterval>; + #[pallet::storage] + /// ITEM( subnet_owner_cut ) pub type SubnetOwnerCut = StorageValue<_, u16, ValueQuery, DefaultSubnetOwnerCut>; - #[pallet::storage] /// ITEM( network_rate_limit ) + #[pallet::storage] + /// ITEM( network_rate_limit ) pub type NetworkRateLimit = StorageValue<_, u64, ValueQuery, DefaultNetworkRateLimit>; - #[pallet::storage] /// ITEM( nominator_min_required_stake ) - pub type NominatorMinRequiredStake = StorageValue<_, u64, ValueQuery, DefaultNominatorMinRequiredStake>; + #[pallet::storage] + /// ITEM( nominator_min_required_stake ) + pub type NominatorMinRequiredStake = + StorageValue<_, u64, ValueQuery, DefaultNominatorMinRequiredStake>; /// ============================ /// ==== Subnet Parameters ===== /// ============================ - #[pallet::storage] /// --- MAP ( netuid ) --> subnetwork_n (Number of UIDs in the network). + #[pallet::storage] + /// --- MAP ( netuid ) --> subnetwork_n (Number of UIDs in the network). pub type SubnetworkN = StorageMap<_, Identity, u16, u16, ValueQuery, DefaultN>; - #[pallet::storage] /// --- MAP ( netuid ) --> modality TEXT: 0, IMAGE: 1, TENSOR: 2 + #[pallet::storage] + /// --- MAP ( netuid ) --> modality TEXT: 0, IMAGE: 1, TENSOR: 2 pub type NetworkModality = StorageMap<_, Identity, u16, u16, ValueQuery, DefaultModality>; - #[pallet::storage] /// --- MAP ( netuid ) --> network_is_added - pub type NetworksAdded = StorageMap<_, Identity, u16, bool, ValueQuery, DefaultNeworksAdded>; - #[pallet::storage] /// --- DMAP ( hotkey, netuid ) --> bool - pub type IsNetworkMember = StorageDoubleMap<_, Blake2_128Concat, T::AccountId, Identity, u16, bool, ValueQuery, DefaultIsNetworkMember>; - #[pallet::storage] /// --- MAP ( netuid ) --> network_registration_allowed - pub type NetworkRegistrationAllowed = StorageMap<_, Identity, u16, bool, ValueQuery, DefaultRegistrationAllowed>; - #[pallet::storage] /// --- MAP ( netuid ) --> network_pow_allowed - pub type NetworkPowRegistrationAllowed = StorageMap<_, Identity, u16, bool, ValueQuery, DefaultRegistrationAllowed>; - #[pallet::storage] /// --- MAP ( netuid ) --> block_created - pub type NetworkRegisteredAt = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultNetworkRegisteredAt>; - #[pallet::storage] /// --- MAP ( netuid ) --> tempo + #[pallet::storage] + /// --- MAP ( netuid ) --> network_is_added + pub type NetworksAdded = + StorageMap<_, Identity, u16, bool, ValueQuery, DefaultNeworksAdded>; + #[pallet::storage] + /// --- DMAP ( hotkey, netuid ) --> bool + pub type IsNetworkMember = StorageDoubleMap< + _, + Blake2_128Concat, + T::AccountId, + Identity, + u16, + bool, + ValueQuery, + DefaultIsNetworkMember, + >; + #[pallet::storage] + /// --- MAP ( netuid ) --> network_registration_allowed + pub type NetworkRegistrationAllowed = + StorageMap<_, Identity, u16, bool, ValueQuery, DefaultRegistrationAllowed>; + #[pallet::storage] + /// --- MAP ( netuid ) --> network_pow_allowed + pub type NetworkPowRegistrationAllowed = + StorageMap<_, Identity, u16, bool, ValueQuery, DefaultRegistrationAllowed>; + #[pallet::storage] + /// --- MAP ( netuid ) --> block_created + pub type NetworkRegisteredAt = + StorageMap<_, Identity, u16, u64, ValueQuery, DefaultNetworkRegisteredAt>; + #[pallet::storage] + /// --- MAP ( netuid ) --> tempo pub type Tempo = StorageMap<_, Identity, u16, u16, ValueQuery, DefaultTempo>; - #[pallet::storage] /// --- MAP ( netuid ) --> emission_values - pub type EmissionValues = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultEmissionValues>; - #[pallet::storage] /// --- MAP ( netuid ) --> pending_emission - pub type PendingEmission = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultPendingEmission>; - #[pallet::storage] /// --- MAP ( netuid ) --> blocks_since_last_step - pub type BlocksSinceLastStep = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultBlocksSinceLastStep>; - #[pallet::storage] /// --- MAP ( netuid ) --> last_mechanism_step_block - pub type LastMechansimStepBlock = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultLastMechanismStepBlock>; - #[pallet::storage] /// --- MAP ( netuid ) --> subnet_owner - pub type SubnetOwner = StorageMap<_, Identity, u16, T::AccountId, ValueQuery, DefaultSubnetOwner>; - #[pallet::storage] /// --- MAP ( netuid ) --> subnet_locked - pub type SubnetLocked = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultSubnetLocked>; - #[pallet::storage] /// --- MAP ( netuid ) --> serving_rate_limit - pub type ServingRateLimit = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultServingRateLimit>; - #[pallet::storage] /// --- MAP ( netuid ) --> Rho + #[pallet::storage] + /// --- MAP ( netuid ) --> emission_values + pub type EmissionValues = + StorageMap<_, Identity, u16, u64, ValueQuery, DefaultEmissionValues>; + #[pallet::storage] + /// --- MAP ( netuid ) --> pending_emission + pub type PendingEmission = + StorageMap<_, Identity, u16, u64, ValueQuery, DefaultPendingEmission>; + #[pallet::storage] + /// --- MAP ( netuid ) --> blocks_since_last_step + pub type BlocksSinceLastStep = + StorageMap<_, Identity, u16, u64, ValueQuery, DefaultBlocksSinceLastStep>; + #[pallet::storage] + /// --- MAP ( netuid ) --> last_mechanism_step_block + pub type LastMechansimStepBlock = + StorageMap<_, Identity, u16, u64, ValueQuery, DefaultLastMechanismStepBlock>; + #[pallet::storage] + /// --- MAP ( netuid ) --> subnet_owner + pub type SubnetOwner = + StorageMap<_, Identity, u16, T::AccountId, ValueQuery, DefaultSubnetOwner>; + #[pallet::storage] + /// --- MAP ( netuid ) --> subnet_locked + pub type SubnetLocked = + StorageMap<_, Identity, u16, u64, ValueQuery, DefaultSubnetLocked>; + #[pallet::storage] + /// --- MAP ( netuid ) --> serving_rate_limit + pub type ServingRateLimit = + StorageMap<_, Identity, u16, u64, ValueQuery, DefaultServingRateLimit>; + #[pallet::storage] + /// --- MAP ( netuid ) --> Rho pub type Rho = StorageMap<_, Identity, u16, u16, ValueQuery, DefaultRho>; - #[pallet::storage] /// --- MAP ( netuid ) --> Kappa + #[pallet::storage] + /// --- MAP ( netuid ) --> Kappa pub type Kappa = StorageMap<_, Identity, u16, u16, ValueQuery, DefaultKappa>; - #[pallet::storage] /// --- MAP ( netuid ) --> uid, we use to record uids to prune at next epoch. + #[pallet::storage] + /// --- MAP ( netuid ) --> uid, we use to record uids to prune at next epoch. pub type NeuronsToPruneAtNextEpoch = StorageMap<_, Identity, u16, u16, ValueQuery>; - #[pallet::storage] /// --- MAP ( netuid ) --> registrations_this_interval + #[pallet::storage] + /// --- MAP ( netuid ) --> registrations_this_interval pub type RegistrationsThisInterval = StorageMap<_, Identity, u16, u16, ValueQuery>; - #[pallet::storage] /// --- MAP ( netuid ) --> pow_registrations_this_interval - pub type POWRegistrationsThisInterval = StorageMap<_, Identity, u16, u16, ValueQuery>; - #[pallet::storage] /// --- MAP ( netuid ) --> burn_registrations_this_interval - pub type BurnRegistrationsThisInterval = StorageMap<_, Identity, u16, u16, ValueQuery>; - #[pallet::storage] /// --- MAP ( netuid ) --> max_allowed_uids - pub type MaxAllowedUids = StorageMap<_, Identity, u16, u16, ValueQuery, DefaultMaxAllowedUids>; - #[pallet::storage] /// --- MAP ( netuid ) --> immunity_period - pub type ImmunityPeriod = StorageMap<_, Identity, u16, u16, ValueQuery, DefaultImmunityPeriod>; - #[pallet::storage] /// --- MAP ( netuid ) --> activity_cutoff - pub type ActivityCutoff = StorageMap<_, Identity, u16, u16, ValueQuery, DefaultActivityCutoff>; - #[pallet::storage] /// --- MAP ( netuid ) --> max_weight_limit - pub type MaxWeightsLimit = StorageMap<_, Identity, u16, u16, ValueQuery, DefaultMaxWeightsLimit>; - #[pallet::storage] /// --- MAP ( netuid ) --> weights_version_key - pub type WeightsVersionKey = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultWeightsVersionKey>; - #[pallet::storage] /// --- MAP ( netuid ) --> min_allowed_weights - pub type MinAllowedWeights = StorageMap<_, Identity, u16, u16, ValueQuery, DefaultMinAllowedWeights>; - #[pallet::storage] /// --- MAP ( netuid ) --> max_allowed_validators - pub type MaxAllowedValidators = StorageMap<_, Identity, u16, u16, ValueQuery, DefaultMaxAllowedValidators>; - #[pallet::storage] /// --- MAP ( netuid ) --> adjustment_interval - pub type AdjustmentInterval = StorageMap<_, Identity, u16, u16, ValueQuery, DefaultAdjustmentInterval>; - #[pallet::storage] /// --- MAP ( netuid ) --> bonds_moving_average - pub type BondsMovingAverage = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultBondsMovingAverage>; - #[pallet::storage] /// --- MAP ( netuid ) --> weights_set_rate_limit - pub type WeightsSetRateLimit = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultWeightsSetRateLimit>; - #[pallet::storage] /// --- MAP ( netuid ) --> validator_prune_len - pub type ValidatorPruneLen = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultValidatorPruneLen>; - #[pallet::storage] /// --- MAP ( netuid ) --> scaling_law_power - pub type ScalingLawPower = StorageMap<_, Identity, u16, u16, ValueQuery, DefaultScalingLawPower>; - #[pallet::storage] /// --- MAP ( netuid ) --> target_registrations_this_interval - pub type TargetRegistrationsPerInterval = StorageMap<_, Identity, u16, u16, ValueQuery, DefaultTargetRegistrationsPerInterval>; - #[pallet::storage] /// --- MAP ( netuid ) --> adjustment_alpha - pub type AdjustmentAlpha = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultAdjustmentAlpha>; - #[pallet::storage] /// --- MAP ( netuid ) --> interval - pub type WeightCommitRevealInterval = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultWeightCommitRevealInterval>; - #[pallet::storage] /// --- MAP ( netuid ) --> interval - pub type CommitRevealWeightsEnabled = StorageMap<_, Identity, u16, bool, ValueQuery, DefaultCommitRevealWeightsEnabled>; - #[pallet::storage] /// --- MAP ( netuid ) --> Burn + #[pallet::storage] + /// --- MAP ( netuid ) --> pow_registrations_this_interval + pub type POWRegistrationsThisInterval = + StorageMap<_, Identity, u16, u16, ValueQuery>; + #[pallet::storage] + /// --- MAP ( netuid ) --> burn_registrations_this_interval + pub type BurnRegistrationsThisInterval = + StorageMap<_, Identity, u16, u16, ValueQuery>; + #[pallet::storage] + /// --- MAP ( netuid ) --> max_allowed_uids + pub type MaxAllowedUids = + StorageMap<_, Identity, u16, u16, ValueQuery, DefaultMaxAllowedUids>; + #[pallet::storage] + /// --- MAP ( netuid ) --> immunity_period + pub type ImmunityPeriod = + StorageMap<_, Identity, u16, u16, ValueQuery, DefaultImmunityPeriod>; + #[pallet::storage] + /// --- MAP ( netuid ) --> activity_cutoff + pub type ActivityCutoff = + StorageMap<_, Identity, u16, u16, ValueQuery, DefaultActivityCutoff>; + #[pallet::storage] + /// --- MAP ( netuid ) --> max_weight_limit + pub type MaxWeightsLimit = + StorageMap<_, Identity, u16, u16, ValueQuery, DefaultMaxWeightsLimit>; + #[pallet::storage] + /// --- MAP ( netuid ) --> weights_version_key + pub type WeightsVersionKey = + StorageMap<_, Identity, u16, u64, ValueQuery, DefaultWeightsVersionKey>; + #[pallet::storage] + /// --- MAP ( netuid ) --> min_allowed_weights + pub type MinAllowedWeights = + StorageMap<_, Identity, u16, u16, ValueQuery, DefaultMinAllowedWeights>; + #[pallet::storage] + /// --- MAP ( netuid ) --> max_allowed_validators + pub type MaxAllowedValidators = + StorageMap<_, Identity, u16, u16, ValueQuery, DefaultMaxAllowedValidators>; + #[pallet::storage] + /// --- MAP ( netuid ) --> adjustment_interval + pub type AdjustmentInterval = + StorageMap<_, Identity, u16, u16, ValueQuery, DefaultAdjustmentInterval>; + #[pallet::storage] + /// --- MAP ( netuid ) --> bonds_moving_average + pub type BondsMovingAverage = + StorageMap<_, Identity, u16, u64, ValueQuery, DefaultBondsMovingAverage>; + #[pallet::storage] + /// --- MAP ( netuid ) --> weights_set_rate_limit + pub type WeightsSetRateLimit = + StorageMap<_, Identity, u16, u64, ValueQuery, DefaultWeightsSetRateLimit>; + #[pallet::storage] + /// --- MAP ( netuid ) --> validator_prune_len + pub type ValidatorPruneLen = + StorageMap<_, Identity, u16, u64, ValueQuery, DefaultValidatorPruneLen>; + #[pallet::storage] + /// --- MAP ( netuid ) --> scaling_law_power + pub type ScalingLawPower = + StorageMap<_, Identity, u16, u16, ValueQuery, DefaultScalingLawPower>; + #[pallet::storage] + /// --- MAP ( netuid ) --> target_registrations_this_interval + pub type TargetRegistrationsPerInterval = + StorageMap<_, Identity, u16, u16, ValueQuery, DefaultTargetRegistrationsPerInterval>; + #[pallet::storage] + /// --- MAP ( netuid ) --> adjustment_alpha + pub type AdjustmentAlpha = + StorageMap<_, Identity, u16, u64, ValueQuery, DefaultAdjustmentAlpha>; + #[pallet::storage] + /// --- MAP ( netuid ) --> interval + pub type WeightCommitRevealInterval = + StorageMap<_, Identity, u16, u64, ValueQuery, DefaultWeightCommitRevealInterval>; + #[pallet::storage] + /// --- MAP ( netuid ) --> interval + pub type CommitRevealWeightsEnabled = + StorageMap<_, Identity, u16, bool, ValueQuery, DefaultCommitRevealWeightsEnabled>; + #[pallet::storage] + /// --- MAP ( netuid ) --> Burn pub type Burn = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultBurn>; - #[pallet::storage] /// --- MAP ( netuid ) --> Difficulty + #[pallet::storage] + /// --- MAP ( netuid ) --> Difficulty pub type Difficulty = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultDifficulty>; - #[pallet::storage] /// --- MAP ( netuid ) --> MinBurn + #[pallet::storage] + /// --- MAP ( netuid ) --> MinBurn pub type MinBurn = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultMinBurn>; - #[pallet::storage] /// --- MAP ( netuid ) --> MaxBurn + #[pallet::storage] + /// --- MAP ( netuid ) --> MaxBurn pub type MaxBurn = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultMaxBurn>; - #[pallet::storage] /// --- MAP ( netuid ) --> MinDifficulty - pub type MinDifficulty = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultMinDifficulty>; - #[pallet::storage] /// --- MAP ( netuid ) --> MaxDifficulty - pub type MaxDifficulty = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultMaxDifficulty>; - #[pallet::storage] /// --- MAP ( netuid ) --> Block at last adjustment. - pub type LastAdjustmentBlock = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultLastAdjustmentBlock>; - #[pallet::storage] /// --- MAP ( netuid ) --> Registrations of this Block. - pub type RegistrationsThisBlock = StorageMap<_, Identity, u16, u16, ValueQuery, DefaultRegistrationsThisBlock>; - #[pallet::storage] /// --- MAP ( netuid ) --> global_RAO_recycled_for_registration - pub type RAORecycledForRegistration = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultRAORecycledForRegistration>; - #[pallet::storage] /// --- ITEM ( tx_rate_limit ) + #[pallet::storage] + /// --- MAP ( netuid ) --> MinDifficulty + pub type MinDifficulty = + StorageMap<_, Identity, u16, u64, ValueQuery, DefaultMinDifficulty>; + #[pallet::storage] + /// --- MAP ( netuid ) --> MaxDifficulty + pub type MaxDifficulty = + StorageMap<_, Identity, u16, u64, ValueQuery, DefaultMaxDifficulty>; + #[pallet::storage] + /// --- MAP ( netuid ) --> Block at last adjustment. + pub type LastAdjustmentBlock = + StorageMap<_, Identity, u16, u64, ValueQuery, DefaultLastAdjustmentBlock>; + #[pallet::storage] + /// --- MAP ( netuid ) --> Registrations of this Block. + pub type RegistrationsThisBlock = + StorageMap<_, Identity, u16, u16, ValueQuery, DefaultRegistrationsThisBlock>; + #[pallet::storage] + /// --- MAP ( netuid ) --> global_RAO_recycled_for_registration + pub type RAORecycledForRegistration = + StorageMap<_, Identity, u16, u64, ValueQuery, DefaultRAORecycledForRegistration>; + #[pallet::storage] + /// --- ITEM ( tx_rate_limit ) pub type TxRateLimit = StorageValue<_, u64, ValueQuery, DefaultTxRateLimit>; - #[pallet::storage] /// --- ITEM ( tx_rate_limit ) - pub type TxDelegateTakeRateLimit = StorageValue<_, u64, ValueQuery, DefaultTxDelegateTakeRateLimit>; - #[pallet::storage] /// --- MAP ( netuid ) --> Whether or not Liquid Alpha is enabled - pub type LiquidAlphaOn = StorageMap<_, Blake2_128Concat, u16, bool, ValueQuery, DefaultLiquidAlpha>; - #[pallet::storage] /// MAP ( netuid ) --> (alpha_low, alpha_high) - pub type AlphaValues = StorageMap<_, Identity, u16, (u16, u16), ValueQuery, DefaultAlphaValues>; - + #[pallet::storage] + /// --- ITEM ( tx_rate_limit ) + pub type TxDelegateTakeRateLimit = + StorageValue<_, u64, ValueQuery, DefaultTxDelegateTakeRateLimit>; + #[pallet::storage] + /// --- MAP ( netuid ) --> Whether or not Liquid Alpha is enabled + pub type LiquidAlphaOn = + StorageMap<_, Blake2_128Concat, u16, bool, ValueQuery, DefaultLiquidAlpha>; + #[pallet::storage] + /// MAP ( netuid ) --> (alpha_low, alpha_high) + pub type AlphaValues = + StorageMap<_, Identity, u16, (u16, u16), ValueQuery, DefaultAlphaValues>; /// ======================================= /// ==== Subnetwork Consensus Storage ==== /// ======================================= - #[pallet::storage] /// --- DMAP ( netuid, hotkey ) --> uid - pub type Uids = StorageDoubleMap<_, Identity, u16, Blake2_128Concat, T::AccountId, u16, OptionQuery>; - #[pallet::storage] /// --- DMAP ( netuid, uid ) --> hotkey - pub type Keys = StorageDoubleMap<_, Identity, u16, Identity, u16, T::AccountId, ValueQuery, DefaultKey>; - #[pallet::storage] /// --- DMAP ( netuid ) --> (hotkey, se, ve) - pub type LoadedEmission = StorageMap<_, Identity, u16, Vec<(T::AccountId, u64, u64)>, OptionQuery>; - #[pallet::storage] /// --- DMAP ( netuid ) --> active - pub type Active = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyBoolVec>; - #[pallet::storage] /// --- DMAP ( netuid ) --> rank + #[pallet::storage] + /// --- DMAP ( netuid, hotkey ) --> uid + pub type Uids = + StorageDoubleMap<_, Identity, u16, Blake2_128Concat, T::AccountId, u16, OptionQuery>; + #[pallet::storage] + /// --- DMAP ( netuid, uid ) --> hotkey + pub type Keys = + StorageDoubleMap<_, Identity, u16, Identity, u16, T::AccountId, ValueQuery, DefaultKey>; + #[pallet::storage] + /// --- DMAP ( netuid ) --> (hotkey, se, ve) + pub type LoadedEmission = + StorageMap<_, Identity, u16, Vec<(T::AccountId, u64, u64)>, OptionQuery>; + #[pallet::storage] + /// --- DMAP ( netuid ) --> active + pub type Active = + StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyBoolVec>; + #[pallet::storage] + /// --- DMAP ( netuid ) --> rank pub type Rank = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; - #[pallet::storage] /// --- DMAP ( netuid ) --> trust + #[pallet::storage] + /// --- DMAP ( netuid ) --> trust pub type Trust = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; - #[pallet::storage] /// --- DMAP ( netuid ) --> consensus - pub type Consensus = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; - #[pallet::storage] /// --- DMAP ( netuid ) --> incentive - pub type Incentive = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; - #[pallet::storage] /// --- DMAP ( netuid ) --> dividends - pub type Dividends = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; - #[pallet::storage] /// --- DMAP ( netuid ) --> emission - pub type Emission = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU64Vec>; - #[pallet::storage] /// --- DMAP ( netuid ) --> last_update - pub type LastUpdate = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU64Vec>; - #[pallet::storage] /// --- DMAP ( netuid ) --> validator_trust - pub type ValidatorTrust = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; - #[pallet::storage] /// --- DMAP ( netuid ) --> pruning_scores - pub type PruningScores = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; - #[pallet::storage] /// --- DMAP ( netuid ) --> validator_permit - pub type ValidatorPermit = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyBoolVec>; - #[pallet::storage] /// --- DMAP ( netuid, uid ) --> weights - pub type Weights = StorageDoubleMap<_, Identity, u16, Identity, u16, Vec<(u16, u16)>, ValueQuery, DefaultWeights>; - #[pallet::storage] /// --- DMAP ( netuid, uid ) --> bonds - pub type Bonds = StorageDoubleMap<_, Identity, u16, Identity, u16, Vec<(u16, u16)>, ValueQuery, DefaultBonds>; - #[pallet::storage] /// --- DMAP ( netuid, uid ) --> block_at_registration - pub type BlockAtRegistration = StorageDoubleMap<_, Identity, u16, Identity, u16, u64, ValueQuery, DefaultBlockAtRegistration>; - #[pallet::storage] /// --- MAP ( netuid, hotkey ) --> axon_info - pub type Axons = StorageDoubleMap<_, Identity, u16, Blake2_128Concat, T::AccountId, AxonInfoOf, OptionQuery>; - #[pallet::storage] /// --- MAP ( netuid, hotkey ) --> prometheus_info - pub type Prometheus = StorageDoubleMap<_, Identity, u16, Blake2_128Concat, T::AccountId, PrometheusInfoOf, OptionQuery>; + #[pallet::storage] + /// --- DMAP ( netuid ) --> consensus + pub type Consensus = + StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; + #[pallet::storage] + /// --- DMAP ( netuid ) --> incentive + pub type Incentive = + StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; + #[pallet::storage] + /// --- DMAP ( netuid ) --> dividends + pub type Dividends = + StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; + #[pallet::storage] + /// --- DMAP ( netuid ) --> emission + pub type Emission = + StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU64Vec>; + #[pallet::storage] + /// --- DMAP ( netuid ) --> last_update + pub type LastUpdate = + StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU64Vec>; + #[pallet::storage] + /// --- DMAP ( netuid ) --> validator_trust + pub type ValidatorTrust = + StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; + #[pallet::storage] + /// --- DMAP ( netuid ) --> pruning_scores + pub type PruningScores = + StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; + #[pallet::storage] + /// --- DMAP ( netuid ) --> validator_permit + pub type ValidatorPermit = + StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyBoolVec>; + #[pallet::storage] + /// --- DMAP ( netuid, uid ) --> weights + pub type Weights = StorageDoubleMap< + _, + Identity, + u16, + Identity, + u16, + Vec<(u16, u16)>, + ValueQuery, + DefaultWeights, + >; + #[pallet::storage] + /// --- DMAP ( netuid, uid ) --> bonds + pub type Bonds = StorageDoubleMap< + _, + Identity, + u16, + Identity, + u16, + Vec<(u16, u16)>, + ValueQuery, + DefaultBonds, + >; + #[pallet::storage] + /// --- DMAP ( netuid, uid ) --> block_at_registration + pub type BlockAtRegistration = StorageDoubleMap< + _, + Identity, + u16, + Identity, + u16, + u64, + ValueQuery, + DefaultBlockAtRegistration, + >; + #[pallet::storage] + /// --- MAP ( netuid, hotkey ) --> axon_info + pub type Axons = + StorageDoubleMap<_, Identity, u16, Blake2_128Concat, T::AccountId, AxonInfoOf, OptionQuery>; + #[pallet::storage] + /// --- MAP ( netuid, hotkey ) --> prometheus_info + pub type Prometheus = StorageDoubleMap< + _, + Identity, + u16, + Blake2_128Concat, + T::AccountId, + PrometheusInfoOf, + OptionQuery, + >; /// ================================= /// ==== Axon / Promo Endpoints ===== /// ================================= - #[pallet::storage] /// --- MAP ( key ) --> last_block - pub type LastTxBlock = StorageMap<_, Identity, T::AccountId, u64, ValueQuery, DefaultLastTxBlock>; - #[pallet::storage] /// --- MAP ( key ) --> last_block - pub type LastTxBlockDelegateTake = StorageMap<_, Identity, T::AccountId, u64, ValueQuery, DefaultLastTxBlock>; - #[pallet::storage] /// ITEM( weights_min_stake ) + #[pallet::storage] + /// --- MAP ( key ) --> last_block + pub type LastTxBlock = + StorageMap<_, Identity, T::AccountId, u64, ValueQuery, DefaultLastTxBlock>; + #[pallet::storage] + /// --- MAP ( key ) --> last_block + pub type LastTxBlockDelegateTake = + StorageMap<_, Identity, T::AccountId, u64, ValueQuery, DefaultLastTxBlock>; + #[pallet::storage] + /// ITEM( weights_min_stake ) pub type WeightsMinStake = StorageValue<_, u64, ValueQuery, DefaultWeightsMinStake>; - #[pallet::storage] /// --- MAP (netuid, who) --> (hash, weight) | Returns the hash and weight committed by an account for a given netuid. - pub type WeightCommits = StorageDoubleMap<_, Twox64Concat, u16, Twox64Concat, T::AccountId, (H256, u64), OptionQuery>; + #[pallet::storage] + /// --- MAP (netuid, who) --> (hash, weight) | Returns the hash and weight committed by an account for a given netuid. + pub type WeightCommits = StorageDoubleMap< + _, + Twox64Concat, + u16, + Twox64Concat, + T::AccountId, + (H256, u64), + OptionQuery, + >; /// ================== /// ==== Genesis ===== /// ================== @@ -773,12 +1294,10 @@ where priority: Self::get_priority_vanilla(), ..Default::default() }), - Some(Call::dissolve_network { .. }) => { - Ok(ValidTransaction { - priority: Self::get_priority_vanilla(), - ..Default::default() - }) - } + Some(Call::dissolve_network { .. }) => Ok(ValidTransaction { + priority: Self::get_priority_vanilla(), + ..Default::default() + }), _ => Ok(ValidTransaction { priority: Self::get_priority_vanilla(), ..Default::default() diff --git a/pallets/subtensor/src/macros/config.rs b/pallets/subtensor/src/macros/config.rs index 4e3cf5d2a..a640ecbb6 100644 --- a/pallets/subtensor/src/macros/config.rs +++ b/pallets/subtensor/src/macros/config.rs @@ -169,4 +169,4 @@ mod config { #[pallet::constant] type LiquidAlphaOn: Get; } -} \ No newline at end of file +} diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 6d4c588e9..228bec6e4 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -843,4 +843,4 @@ mod dispatches { Ok(()) } } -} \ No newline at end of file +} diff --git a/pallets/subtensor/src/macros/genesis.rs b/pallets/subtensor/src/macros/genesis.rs index 5fbf613d6..949667807 100644 --- a/pallets/subtensor/src/macros/genesis.rs +++ b/pallets/subtensor/src/macros/genesis.rs @@ -159,5 +159,4 @@ mod genesis { TargetRegistrationsPerInterval::::insert(root_netuid, 1); } } - -} \ No newline at end of file +} diff --git a/pallets/subtensor/src/macros/hooks.rs b/pallets/subtensor/src/macros/hooks.rs index 7e612fb4e..b04a29ff6 100644 --- a/pallets/subtensor/src/macros/hooks.rs +++ b/pallets/subtensor/src/macros/hooks.rs @@ -72,4 +72,4 @@ mod hooks { weight } } -} \ No newline at end of file +} diff --git a/pallets/subtensor/src/macros/mod.rs b/pallets/subtensor/src/macros/mod.rs index d64983d52..e491ec8c4 100644 --- a/pallets/subtensor/src/macros/mod.rs +++ b/pallets/subtensor/src/macros/mod.rs @@ -1,6 +1,6 @@ -pub mod events; -pub mod errors; +pub mod config; pub mod dispatches; +pub mod errors; +pub mod events; pub mod genesis; pub mod hooks; -pub mod config; \ No newline at end of file diff --git a/pallets/subtensor/src/migrations/migrate_create_root_network.rs b/pallets/subtensor/src/migrations/migrate_create_root_network.rs index 20ee82f0a..b4b003404 100644 --- a/pallets/subtensor/src/migrations/migrate_create_root_network.rs +++ b/pallets/subtensor/src/migrations/migrate_create_root_network.rs @@ -2,7 +2,7 @@ use super::*; use frame_support::{ pallet_prelude::{Identity, OptionQuery}, storage_alias, - traits::{Get, DefensiveResult}, + traits::{DefensiveResult, Get}, weights::Weight, }; use sp_std::vec::Vec; @@ -96,4 +96,4 @@ pub fn migrate_create_root_network() -> Weight { } weight -} \ No newline at end of file +} diff --git a/pallets/subtensor/src/migrations/migrate_delete_subnet_21.rs b/pallets/subtensor/src/migrations/migrate_delete_subnet_21.rs index 23fbe122f..c26c917a4 100644 --- a/pallets/subtensor/src/migrations/migrate_delete_subnet_21.rs +++ b/pallets/subtensor/src/migrations/migrate_delete_subnet_21.rs @@ -1,6 +1,7 @@ use super::*; use frame_support::{ - pallet_prelude::*, storage_alias, + pallet_prelude::*, + storage_alias, traits::{Get, GetStorageVersion, StorageVersion}, weights::Weight, }; @@ -124,4 +125,4 @@ pub fn migrate_delete_subnet_21() -> Weight { // TODO: Add unit tests for this migration // TODO: Consider adding error handling for storage operations -// TODO: Verify that all relevant storage items for subnet 21 are removed \ No newline at end of file +// TODO: Verify that all relevant storage items for subnet 21 are removed diff --git a/pallets/subtensor/src/migrations/migrate_delete_subnet_3.rs b/pallets/subtensor/src/migrations/migrate_delete_subnet_3.rs index 257752c19..bbe36db80 100644 --- a/pallets/subtensor/src/migrations/migrate_delete_subnet_3.rs +++ b/pallets/subtensor/src/migrations/migrate_delete_subnet_3.rs @@ -1,6 +1,7 @@ use super::*; use frame_support::{ - pallet_prelude::*, storage_alias, + pallet_prelude::*, + storage_alias, traits::{Get, GetStorageVersion, StorageVersion}, weights::Weight, }; @@ -127,4 +128,4 @@ pub fn migrate_delete_subnet_3() -> Weight { // TODO: Add unit tests for this migration // TODO: Consider adding error handling for storage operations -// TODO: Verify that all relevant storage items for subnet 3 are removed \ No newline at end of file +// TODO: Verify that all relevant storage items for subnet 3 are removed diff --git a/pallets/subtensor/src/migrations/migrate_populate_owned_hotkeys.rs b/pallets/subtensor/src/migrations/migrate_populate_owned_hotkeys.rs index 23cf90d33..e8fd212ec 100644 --- a/pallets/subtensor/src/migrations/migrate_populate_owned_hotkeys.rs +++ b/pallets/subtensor/src/migrations/migrate_populate_owned_hotkeys.rs @@ -2,7 +2,7 @@ use super::*; use frame_support::{ pallet_prelude::{Identity, OptionQuery}, storage_alias, - traits::{Get}, + traits::Get, weights::Weight, }; use log::info; @@ -19,7 +19,6 @@ pub mod deprecated_loaded_emission_format { StorageMap, Identity, u16, Vec<(AccountIdOf, u64)>, OptionQuery>; } - /// Migrate the OwnedHotkeys map to the new storage format pub fn migrate_populate_owned() -> Weight { // Setup migration weight @@ -80,4 +79,4 @@ pub fn migrate_populate_owned() -> Weight { info!(target: LOG_TARGET_1, "Migration {} already done!", migration_name); Weight::zero() } -} \ No newline at end of file +} diff --git a/pallets/subtensor/src/migrations/migrate_populate_staking_hotkeys.rs b/pallets/subtensor/src/migrations/migrate_populate_staking_hotkeys.rs index 2c0988bbd..0245ae3c9 100644 --- a/pallets/subtensor/src/migrations/migrate_populate_staking_hotkeys.rs +++ b/pallets/subtensor/src/migrations/migrate_populate_staking_hotkeys.rs @@ -1,9 +1,8 @@ - use super::*; use frame_support::{ pallet_prelude::{Identity, OptionQuery}, storage_alias, - traits::{Get}, + traits::Get, weights::Weight, }; use log::info; @@ -19,7 +18,6 @@ pub mod deprecated_loaded_emission_format { StorageMap, Identity, u16, Vec<(AccountIdOf, u64)>, OptionQuery>; } - /// Populate the StakingHotkeys map from Stake map pub fn migrate_populate_staking_hotkeys() -> Weight { // Setup migration weight diff --git a/pallets/subtensor/src/migrations/migrate_to_v1_separate_emission.rs b/pallets/subtensor/src/migrations/migrate_to_v1_separate_emission.rs index 5db04f0bc..5d28337dc 100644 --- a/pallets/subtensor/src/migrations/migrate_to_v1_separate_emission.rs +++ b/pallets/subtensor/src/migrations/migrate_to_v1_separate_emission.rs @@ -1,6 +1,7 @@ use super::*; use frame_support::{ - pallet_prelude::*, storage_alias, + pallet_prelude::*, + storage_alias, traits::{Get, GetStorageVersion, StorageVersion}, weights::Weight, }; @@ -39,7 +40,7 @@ pub mod deprecated_loaded_emission_format { /// ``` pub fn migrate_to_v1_separate_emission() -> Weight { use deprecated_loaded_emission_format as old; - + // Initialize weight counter let mut weight = T::DbWeight::get().reads_writes(1, 0); @@ -55,7 +56,7 @@ pub fn migrate_to_v1_separate_emission() -> Weight { // Collect all network IDs (netuids) from old LoadedEmission storage let curr_loaded_emission: Vec = old::LoadedEmission::::iter_keys().collect(); - + // Remove any undecodable entries for netuid in curr_loaded_emission { weight.saturating_accrue(T::DbWeight::get().reads(1)); @@ -103,4 +104,4 @@ pub fn migrate_to_v1_separate_emission() -> Weight { // TODO: Add unit tests for this migration // TODO: Consider adding error handling for edge cases -// TODO: Verify that all possible states of the old format are handled correctly \ No newline at end of file +// TODO: Verify that all possible states of the old format are handled correctly diff --git a/pallets/subtensor/src/migrations/migrate_to_v2_fixed_total_stake.rs b/pallets/subtensor/src/migrations/migrate_to_v2_fixed_total_stake.rs index ef9fe8880..f3e63b6fd 100644 --- a/pallets/subtensor/src/migrations/migrate_to_v2_fixed_total_stake.rs +++ b/pallets/subtensor/src/migrations/migrate_to_v2_fixed_total_stake.rs @@ -1,6 +1,7 @@ use super::*; use frame_support::{ - pallet_prelude::*, storage_alias, + pallet_prelude::*, + storage_alias, traits::{Get, GetStorageVersion, StorageVersion}, weights::Weight, }; @@ -71,7 +72,7 @@ pub fn migrate_to_v2_fixed_total_stake() -> Weight { // Recalculate TotalStake and TotalColdkeyStake based on the Stake map for (_, coldkey, stake) in Stake::::iter() { weight.saturating_accrue(T::DbWeight::get().reads(1)); - + // Update TotalColdkeyStake let mut total_coldkey_stake = TotalColdkeyStake::::get(coldkey.clone()); weight.saturating_accrue(T::DbWeight::get().reads(1)); @@ -100,4 +101,4 @@ pub fn migrate_to_v2_fixed_total_stake() -> Weight { // TODO: Add unit tests for this migration function // TODO: Consider adding error handling for potential arithmetic overflow -// TODO: Optimize the iteration over Stake map if possible to reduce database reads \ No newline at end of file +// TODO: Optimize the iteration over Stake map if possible to reduce database reads diff --git a/pallets/subtensor/src/migrations/migrate_total_issuance.rs b/pallets/subtensor/src/migrations/migrate_total_issuance.rs index 187967da3..9a4085379 100644 --- a/pallets/subtensor/src/migrations/migrate_total_issuance.rs +++ b/pallets/subtensor/src/migrations/migrate_total_issuance.rs @@ -1,4 +1,5 @@ use super::*; +use frame_support::pallet_prelude::OptionQuery; use frame_support::{ pallet_prelude::Identity, storage_alias, @@ -6,7 +7,6 @@ use frame_support::{ weights::Weight, }; use sp_std::vec::Vec; -use frame_support::pallet_prelude::OptionQuery; // TODO: Implement comprehensive tests for this migration @@ -43,14 +43,17 @@ pub fn migrate_total_issuance(test: bool) -> Weight { // Execute migration if the current storage version is 5 or if in test mode if Pallet::::on_chain_storage_version() == StorageVersion::new(5) || test { // Calculate the sum of all stake values - let stake_sum: u64 = Stake::::iter().fold(0, |acc, (_, _, stake)| acc.saturating_add(stake)); + let stake_sum: u64 = + Stake::::iter().fold(0, |acc, (_, _, stake)| acc.saturating_add(stake)); // Add weight for reading all stake entries weight = weight.saturating_add(T::DbWeight::get().reads(Stake::::iter().count() as u64)); // Calculate the sum of all locked subnet values - let locked_sum: u64 = SubnetLocked::::iter().fold(0, |acc, (_, locked)| acc.saturating_add(locked)); + let locked_sum: u64 = + SubnetLocked::::iter().fold(0, |acc, (_, locked)| acc.saturating_add(locked)); // Add weight for reading all subnet locked entries - weight = weight.saturating_add(T::DbWeight::get().reads(SubnetLocked::::iter().count() as u64)); + weight = weight + .saturating_add(T::DbWeight::get().reads(SubnetLocked::::iter().count() as u64)); // Retrieve the total balance sum let total_balance = T::Currency::total_issuance(); @@ -61,7 +64,9 @@ pub fn migrate_total_issuance(test: bool) -> Weight { match TryInto::::try_into(total_balance) { Ok(total_balance_sum) => { // Compute the total issuance value - let total_issuance_value: u64 = stake_sum.saturating_add(total_balance_sum).saturating_add(locked_sum); + let total_issuance_value: u64 = stake_sum + .saturating_add(total_balance_sum) + .saturating_add(locked_sum); // Update the total issuance in storage TotalIssuance::::put(total_issuance_value); @@ -81,4 +86,4 @@ pub fn migrate_total_issuance(test: bool) -> Weight { // Return the computed weight of the migration process weight -} \ No newline at end of file +} diff --git a/pallets/subtensor/src/migrations/migrate_transfer_ownership_to_foundation.rs b/pallets/subtensor/src/migrations/migrate_transfer_ownership_to_foundation.rs index 0ca4a7fa5..8d1bd437c 100644 --- a/pallets/subtensor/src/migrations/migrate_transfer_ownership_to_foundation.rs +++ b/pallets/subtensor/src/migrations/migrate_transfer_ownership_to_foundation.rs @@ -84,4 +84,4 @@ pub fn migrate_transfer_ownership_to_foundation(coldkey: [u8; 32]) -> info!(target: LOG_TARGET, "Migration to v3 already completed"); Weight::zero() } -} \ No newline at end of file +} diff --git a/pallets/subtensor/src/migrations/mod.rs b/pallets/subtensor/src/migrations/mod.rs index cdc512d63..df0f7ce06 100644 --- a/pallets/subtensor/src/migrations/mod.rs +++ b/pallets/subtensor/src/migrations/mod.rs @@ -1,11 +1,11 @@ use super::*; -pub mod migrate_delete_subnet_21; pub mod migrate_create_root_network; +pub mod migrate_delete_subnet_21; pub mod migrate_delete_subnet_3; +pub mod migrate_fix_total_coldkey_stake; +pub mod migrate_populate_owned_hotkeys; +pub mod migrate_populate_staking_hotkeys; pub mod migrate_to_v1_separate_emission; pub mod migrate_to_v2_fixed_total_stake; -pub mod migrate_transfer_ownership_to_foundation; pub mod migrate_total_issuance; -pub mod migrate_populate_owned_hotkeys; -pub mod migrate_populate_staking_hotkeys; -pub mod migrate_fix_total_coldkey_stake; \ No newline at end of file +pub mod migrate_transfer_ownership_to_foundation; diff --git a/pallets/subtensor/src/root.rs b/pallets/subtensor/src/root.rs index b3ac32f55..948c91f20 100644 --- a/pallets/subtensor/src/root.rs +++ b/pallets/subtensor/src/root.rs @@ -905,7 +905,6 @@ impl Pallet { // --- 0. Ensure the caller is a signed user. let coldkey = ensure_signed(origin)?; - // --- 1. Rate limit for network registrations. let current_block = Self::get_current_block_as_u64(); let last_lock_block = Self::get_network_last_lock_block(); @@ -993,7 +992,7 @@ impl Pallet { pub fn user_remove_network(origin: T::RuntimeOrigin, netuid: u16) -> dispatch::DispatchResult { // --- 1. Ensure the function caller is a signed user. let coldkey = ensure_signed(origin)?; - + // --- 2. Ensure this subnet exists. ensure!( Self::if_subnet_exist(netuid), diff --git a/pallets/subtensor/src/rpc_info/mod.rs b/pallets/subtensor/src/rpc_info/mod.rs index 70dc816cc..7d050b601 100644 --- a/pallets/subtensor/src/rpc_info/mod.rs +++ b/pallets/subtensor/src/rpc_info/mod.rs @@ -1,5 +1,5 @@ use super::*; +pub mod delegate_info; pub mod neuron_info; pub mod stake_info; pub mod subnet_info; -pub mod delegate_info; \ No newline at end of file diff --git a/pallets/subtensor/src/staking/add_stake.rs b/pallets/subtensor/src/staking/add_stake.rs index 89104de82..a2e7ccdc4 100644 --- a/pallets/subtensor/src/staking/add_stake.rs +++ b/pallets/subtensor/src/staking/add_stake.rs @@ -122,4 +122,4 @@ impl Pallet { // Ok and return. Ok(()) } -} \ No newline at end of file +} diff --git a/pallets/subtensor/src/staking/helpers.rs b/pallets/subtensor/src/staking/helpers.rs index 6da16e833..92aa394ed 100644 --- a/pallets/subtensor/src/staking/helpers.rs +++ b/pallets/subtensor/src/staking/helpers.rs @@ -11,7 +11,6 @@ use frame_support::{ }; impl Pallet { - // Returns true if the passed hotkey allow delegative staking. // pub fn hotkey_is_delegate(hotkey: &T::AccountId) -> bool { diff --git a/pallets/subtensor/src/staking/increase_take.rs b/pallets/subtensor/src/staking/increase_take.rs index 744027a9b..d5140b656 100644 --- a/pallets/subtensor/src/staking/increase_take.rs +++ b/pallets/subtensor/src/staking/increase_take.rs @@ -1,4 +1,3 @@ - use super::*; use frame_support::{ storage::IterableStorageDoubleMap, @@ -96,4 +95,4 @@ impl Pallet { // --- 8. Ok and return. Ok(()) } -} \ No newline at end of file +} diff --git a/pallets/subtensor/src/staking/mod.rs b/pallets/subtensor/src/staking/mod.rs index 7015b455a..5e1b5f6bf 100644 --- a/pallets/subtensor/src/staking/mod.rs +++ b/pallets/subtensor/src/staking/mod.rs @@ -1,7 +1,7 @@ use super::*; -pub mod helpers; pub mod add_stake; -pub mod remove_stake; +pub mod become_delegate; pub mod decrease_take; +pub mod helpers; pub mod increase_take; -pub mod become_delegate; \ No newline at end of file +pub mod remove_stake; diff --git a/pallets/subtensor/src/staking/remove_stake.rs b/pallets/subtensor/src/staking/remove_stake.rs index 5f467e009..59e96777b 100644 --- a/pallets/subtensor/src/staking/remove_stake.rs +++ b/pallets/subtensor/src/staking/remove_stake.rs @@ -1,4 +1,3 @@ - use super::*; use frame_support::{ storage::IterableStorageDoubleMap, @@ -117,4 +116,4 @@ impl Pallet { // Done and ok. Ok(()) } -} \ No newline at end of file +} diff --git a/pallets/subtensor/src/swap/mod.rs b/pallets/subtensor/src/swap/mod.rs index 0e71b1b1d..4e4b92907 100644 --- a/pallets/subtensor/src/swap/mod.rs +++ b/pallets/subtensor/src/swap/mod.rs @@ -1,3 +1,3 @@ use super::*; pub mod swap_coldkey; -pub mod swap_hotkey; \ No newline at end of file +pub mod swap_hotkey; diff --git a/pallets/subtensor/src/swap/swap_coldkey.rs b/pallets/subtensor/src/swap/swap_coldkey.rs index 78508f9c5..8651f0076 100644 --- a/pallets/subtensor/src/swap/swap_coldkey.rs +++ b/pallets/subtensor/src/swap/swap_coldkey.rs @@ -5,8 +5,6 @@ use frame_support::weights::Weight; use sp_core::Get; impl Pallet { - - /// Swaps the coldkey associated with a set of hotkeys from an old coldkey to a new coldkey. /// /// # Arguments @@ -130,7 +128,6 @@ impl Pallet { Ok(weight) } - /// Swaps the total stake associated with a coldkey from the old coldkey to the new coldkey. /// /// # Arguments @@ -387,5 +384,4 @@ impl Pallet { } weight.saturating_accrue(T::DbWeight::get().reads(TotalNetworks::::get() as u64)); } - } diff --git a/pallets/subtensor/src/swap/swap_hotkey.rs b/pallets/subtensor/src/swap/swap_hotkey.rs index 2755f1c4c..cf279ca10 100644 --- a/pallets/subtensor/src/swap/swap_hotkey.rs +++ b/pallets/subtensor/src/swap/swap_hotkey.rs @@ -92,7 +92,7 @@ impl Pallet { Ok(Some(weight).into()) } - + /// Retrieves the network membership status for a given hotkey. /// /// # Arguments @@ -422,7 +422,6 @@ impl Pallet { } } - pub fn swap_senate_member( old_hotkey: &T::AccountId, new_hotkey: &T::AccountId, diff --git a/pallets/subtensor/tests/staking.rs b/pallets/subtensor/tests/staking.rs index a923a7010..ece30391d 100644 --- a/pallets/subtensor/tests/staking.rs +++ b/pallets/subtensor/tests/staking.rs @@ -3383,4 +3383,4 @@ fn test_get_total_delegated_stake_exclude_owner_stake() { expected_delegated_stake, actual_delegated_stake ); }); -} \ No newline at end of file +} diff --git a/pallets/subtensor/tests/swap.rs b/pallets/subtensor/tests/swap.rs index 1d05b1c51..7b32a947b 100644 --- a/pallets/subtensor/tests/swap.rs +++ b/pallets/subtensor/tests/swap.rs @@ -88,8 +88,12 @@ fn test_do_swap_hotkey_ok() { // IsNetworkMember for netuid in SubtensorModule::get_netuid_is_member(&old_hotkey, &mut weight) { - assert!(pallet_subtensor::IsNetworkMember::::contains_key(new_hotkey, netuid)); - assert!(!pallet_subtensor::IsNetworkMember::::contains_key(old_hotkey, netuid)); + assert!(pallet_subtensor::IsNetworkMember::::contains_key( + new_hotkey, netuid + )); + assert!(!pallet_subtensor::IsNetworkMember::::contains_key( + old_hotkey, netuid + )); } // Owner @@ -123,8 +127,12 @@ fn test_do_swap_hotkey_ok() { // TotalHotkeyColdkeyStakesThisInterval assert_eq!( - pallet_subtensor::TotalHotkeyColdkeyStakesThisInterval::::get(new_hotkey, coldkey), - pallet_subtensor::TotalHotkeyColdkeyStakesThisInterval::::get(old_hotkey, coldkey) + pallet_subtensor::TotalHotkeyColdkeyStakesThisInterval::::get( + new_hotkey, coldkey + ), + pallet_subtensor::TotalHotkeyColdkeyStakesThisInterval::::get( + old_hotkey, coldkey + ) ); }); } @@ -226,8 +234,13 @@ fn test_do_swap_hotkey_ok_robust() { // Verify raw storage maps // Stake - for (coldkey, stake_amount) in pallet_subtensor::Stake::::iter_prefix(old_hotkeys[i]) { - assert_eq!(pallet_subtensor::Stake::::get(new_hotkeys[i], coldkey), stake_amount); + for (coldkey, stake_amount) in + pallet_subtensor::Stake::::iter_prefix(old_hotkeys[i]) + { + assert_eq!( + pallet_subtensor::Stake::::get(new_hotkeys[i], coldkey), + stake_amount + ); } let mut weight = Weight::zero(); @@ -276,12 +289,18 @@ fn test_do_swap_hotkey_ok_robust() { } // Owner - assert_eq!(pallet_subtensor::Owner::::get(new_hotkeys[i]), coldkeys[i]); + assert_eq!( + pallet_subtensor::Owner::::get(new_hotkeys[i]), + coldkeys[i] + ); // Keys for (uid, hotkey) in pallet_subtensor::Keys::::iter_prefix(netuid) { if hotkey == old_hotkeys[i] { - assert_eq!(pallet_subtensor::Keys::::get(netuid, uid), new_hotkeys[i]); + assert_eq!( + pallet_subtensor::Keys::::get(netuid, uid), + new_hotkeys[i] + ); } } @@ -738,8 +757,13 @@ fn test_swap_axons_success() { // Verify the swap for netuid in &netuid_is_member { - assert_eq!(pallet_subtensor::Axons::::get(netuid, new_hotkey).unwrap(), axon_info); - assert!(!pallet_subtensor::Axons::::contains_key(netuid, old_hotkey)); + assert_eq!( + pallet_subtensor::Axons::::get(netuid, new_hotkey).unwrap(), + axon_info + ); + assert!(!pallet_subtensor::Axons::::contains_key( + netuid, old_hotkey + )); } }); } @@ -924,8 +948,13 @@ fn test_swap_uids_success() { // Verify the swap for netuid in &netuid_is_member { - assert_eq!(pallet_subtensor::Uids::::get(netuid, new_hotkey).unwrap(), uid); - assert!(!pallet_subtensor::Uids::::contains_key(netuid, old_hotkey)); + assert_eq!( + pallet_subtensor::Uids::::get(netuid, new_hotkey).unwrap(), + uid + ); + assert!(!pallet_subtensor::Uids::::contains_key( + netuid, old_hotkey + )); } }); } @@ -970,7 +999,11 @@ fn test_swap_prometheus_success() { // Initialize Prometheus for old_hotkey for netuid in &netuid_is_member { - pallet_subtensor::Prometheus::::insert(netuid, old_hotkey, prometheus_info.clone()); + pallet_subtensor::Prometheus::::insert( + netuid, + old_hotkey, + prometheus_info.clone(), + ); } // Perform the swap @@ -982,7 +1015,9 @@ fn test_swap_prometheus_success() { pallet_subtensor::Prometheus::::get(netuid, new_hotkey).unwrap(), prometheus_info ); - assert!(!pallet_subtensor::Prometheus::::contains_key(netuid, old_hotkey)); + assert!(!pallet_subtensor::Prometheus::::contains_key( + netuid, old_hotkey + )); } }); } @@ -1004,7 +1039,11 @@ fn test_swap_prometheus_weight_update() { // Initialize Prometheus for old_hotkey for netuid in &netuid_is_member { - pallet_subtensor::Prometheus::::insert(netuid, old_hotkey, prometheus_info.clone()); + pallet_subtensor::Prometheus::::insert( + netuid, + old_hotkey, + prometheus_info.clone(), + ); } // Perform the swap From 4270cc4b816a86c75981da5a7504f0890c5494c8 Mon Sep 17 00:00:00 2001 From: const Date: Mon, 15 Jul 2024 14:20:33 -0500 Subject: [PATCH 11/58] clippy fmt --- pallets/subtensor/src/epoch/mod.rs | 2 +- .../src/epoch/{epoch.rs => run_epoch.rs} | 0 pallets/subtensor/src/macros/genesis.rs | 8 +-- .../migrations/migrate_create_root_network.rs | 2 +- .../migrations/migrate_delete_subnet_21.rs | 2 +- .../src/migrations/migrate_delete_subnet_3.rs | 2 +- pallets/subtensor/src/staking/add_stake.rs | 11 +--- .../subtensor/src/staking/become_delegate.rs | 11 +--- .../subtensor/src/staking/decrease_take.rs | 11 +--- pallets/subtensor/src/staking/helpers.rs | 62 ++++++++++++++----- .../subtensor/src/staking/increase_take.rs | 11 +--- pallets/subtensor/src/staking/remove_stake.rs | 11 +--- 12 files changed, 61 insertions(+), 72 deletions(-) rename pallets/subtensor/src/epoch/{epoch.rs => run_epoch.rs} (100%) diff --git a/pallets/subtensor/src/epoch/mod.rs b/pallets/subtensor/src/epoch/mod.rs index 723e68ee4..3b22f940e 100644 --- a/pallets/subtensor/src/epoch/mod.rs +++ b/pallets/subtensor/src/epoch/mod.rs @@ -1,3 +1,3 @@ use super::*; -pub mod epoch; pub mod math; +pub mod run_epoch; diff --git a/pallets/subtensor/src/epoch/epoch.rs b/pallets/subtensor/src/epoch/run_epoch.rs similarity index 100% rename from pallets/subtensor/src/epoch/epoch.rs rename to pallets/subtensor/src/epoch/run_epoch.rs diff --git a/pallets/subtensor/src/macros/genesis.rs b/pallets/subtensor/src/macros/genesis.rs index 949667807..34a888f28 100644 --- a/pallets/subtensor/src/macros/genesis.rs +++ b/pallets/subtensor/src/macros/genesis.rs @@ -77,7 +77,7 @@ mod genesis { // Set max allowed uids MaxAllowedUids::::insert(netuid, max_uids); - let mut next_uid = 0; + let mut next_uid: u16 = 0; for (coldkey, hotkeys) in self.stakes.iter() { for (hotkey, stake_uid) in hotkeys.iter() { @@ -116,7 +116,7 @@ mod genesis { Stake::::insert(hotkey.clone(), coldkey.clone(), stake); - next_uid += 1; + next_uid = next_uid.saturating_add(1); } } @@ -124,7 +124,7 @@ mod genesis { SubnetworkN::::insert(netuid, next_uid); // --- Increase total network count. - TotalNetworks::::mutate(|n| *n += 1); + TotalNetworks::::mutate(|n| n.saturating_add( 1 )); // Get the root network uid. let root_netuid: u16 = 0; @@ -133,7 +133,7 @@ mod genesis { NetworksAdded::::insert(root_netuid, true); // Increment the number of total networks. - TotalNetworks::::mutate(|n| *n += 1); + TotalNetworks::::mutate(|n| n.saturating_add(1)); // Set the number of validators to 1. SubnetworkN::::insert(root_netuid, 0); diff --git a/pallets/subtensor/src/migrations/migrate_create_root_network.rs b/pallets/subtensor/src/migrations/migrate_create_root_network.rs index b4b003404..fa9f34301 100644 --- a/pallets/subtensor/src/migrations/migrate_create_root_network.rs +++ b/pallets/subtensor/src/migrations/migrate_create_root_network.rs @@ -55,7 +55,7 @@ pub fn migrate_create_root_network() -> Weight { NetworksAdded::::insert(root_netuid, true); // Increment the total number of networks - TotalNetworks::::mutate(|n| *n += 1); + TotalNetworks::::mutate(|n| n.saturating_add( 1 )); // Set the maximum number of UIDs to the number of senate members MaxAllowedUids::::insert(root_netuid, 64); diff --git a/pallets/subtensor/src/migrations/migrate_delete_subnet_21.rs b/pallets/subtensor/src/migrations/migrate_delete_subnet_21.rs index c26c917a4..011d79de1 100644 --- a/pallets/subtensor/src/migrations/migrate_delete_subnet_21.rs +++ b/pallets/subtensor/src/migrations/migrate_delete_subnet_21.rs @@ -66,7 +66,7 @@ pub fn migrate_delete_subnet_21() -> Weight { NetworksAdded::::remove(netuid); // Decrement the network counter - TotalNetworks::::mutate(|n| *n -= 1); + TotalNetworks::::mutate(|n| n.saturating_sub( 1 )); // Remove network registration time NetworkRegisteredAt::::remove(netuid); diff --git a/pallets/subtensor/src/migrations/migrate_delete_subnet_3.rs b/pallets/subtensor/src/migrations/migrate_delete_subnet_3.rs index bbe36db80..a07434bcb 100644 --- a/pallets/subtensor/src/migrations/migrate_delete_subnet_3.rs +++ b/pallets/subtensor/src/migrations/migrate_delete_subnet_3.rs @@ -69,7 +69,7 @@ pub fn migrate_delete_subnet_3() -> Weight { NetworksAdded::::remove(netuid); // Decrement the network counter - TotalNetworks::::mutate(|n| *n -= 1); + TotalNetworks::::mutate(|n| n.saturating_sub(1)); // Remove network registration time NetworkRegisteredAt::::remove(netuid); diff --git a/pallets/subtensor/src/staking/add_stake.rs b/pallets/subtensor/src/staking/add_stake.rs index a2e7ccdc4..422dfa2e4 100644 --- a/pallets/subtensor/src/staking/add_stake.rs +++ b/pallets/subtensor/src/staking/add_stake.rs @@ -1,14 +1,5 @@ use super::*; -use frame_support::{ - storage::IterableStorageDoubleMap, - traits::{ - tokens::{ - fungible::{Balanced as _, Inspect as _, Mutate as _}, - Fortitude, Precision, Preservation, - }, - Imbalance, - }, -}; + impl Pallet { /// ---- The implementation for the extrinsic add_stake: Adds stake to a hotkey account. diff --git a/pallets/subtensor/src/staking/become_delegate.rs b/pallets/subtensor/src/staking/become_delegate.rs index 28d3b25f4..4df8adf2d 100644 --- a/pallets/subtensor/src/staking/become_delegate.rs +++ b/pallets/subtensor/src/staking/become_delegate.rs @@ -1,14 +1,5 @@ use super::*; -use frame_support::{ - storage::IterableStorageDoubleMap, - traits::{ - tokens::{ - fungible::{Balanced as _, Inspect as _, Mutate as _}, - Fortitude, Precision, Preservation, - }, - Imbalance, - }, -}; + impl Pallet { /// ---- The implementation for the extrinsic become_delegate: signals that this hotkey allows delegated stake. diff --git a/pallets/subtensor/src/staking/decrease_take.rs b/pallets/subtensor/src/staking/decrease_take.rs index 4290a1d24..6aac33651 100644 --- a/pallets/subtensor/src/staking/decrease_take.rs +++ b/pallets/subtensor/src/staking/decrease_take.rs @@ -1,14 +1,5 @@ use super::*; -use frame_support::{ - storage::IterableStorageDoubleMap, - traits::{ - tokens::{ - fungible::{Balanced as _, Inspect as _, Mutate as _}, - Fortitude, Precision, Preservation, - }, - Imbalance, - }, -}; + impl Pallet { /// ---- The implementation for the extrinsic decrease_take diff --git a/pallets/subtensor/src/staking/helpers.rs b/pallets/subtensor/src/staking/helpers.rs index 92aa394ed..486577712 100644 --- a/pallets/subtensor/src/staking/helpers.rs +++ b/pallets/subtensor/src/staking/helpers.rs @@ -122,26 +122,47 @@ impl Pallet { } } - // Returns the coldkey owning this hotkey. This function should only be called for active accounts. - // + /// Returns the coldkey owning this hotkey. This function should only be called for active accounts. + /// + /// # Arguments + /// * `hotkey` - The hotkey account ID. + /// + /// # Returns + /// The coldkey account ID that owns the hotkey. pub fn get_owning_coldkey_for_hotkey(hotkey: &T::AccountId) -> T::AccountId { Owner::::get(hotkey) } - // Returns the hotkey take - // + /// Returns the hotkey take. + /// + /// # Arguments + /// * `hotkey` - The hotkey account ID. + /// + /// # Returns + /// The take value of the hotkey. pub fn get_hotkey_take(hotkey: &T::AccountId) -> u16 { Delegates::::get(hotkey) } - // Returns true if the hotkey account has been created. - // + /// Returns true if the hotkey account has been created. + /// + /// # Arguments + /// * `hotkey` - The hotkey account ID. + /// + /// # Returns + /// True if the hotkey account exists, false otherwise. pub fn hotkey_account_exists(hotkey: &T::AccountId) -> bool { Owner::::contains_key(hotkey) } - // Return true if the passed coldkey owns the hotkey. - // + /// Returns true if the passed coldkey owns the hotkey. + /// + /// # Arguments + /// * `coldkey` - The coldkey account ID. + /// * `hotkey` - The hotkey account ID. + /// + /// # Returns + /// True if the coldkey owns the hotkey, false otherwise. pub fn coldkey_owns_hotkey(coldkey: &T::AccountId, hotkey: &T::AccountId) -> bool { if Self::hotkey_account_exists(hotkey) { Owner::::get(hotkey) == *coldkey @@ -150,14 +171,24 @@ impl Pallet { } } - // Returns true if the cold-hot staking account has enough balance to fufil the decrement. - // + /// Returns true if the cold-hot staking account has enough balance to fulfill the decrement. + /// + /// # Arguments + /// * `coldkey` - The coldkey account ID. + /// * `hotkey` - The hotkey account ID. + /// * `decrement` - The amount to be decremented. + /// + /// # Returns + /// True if the account has enough balance, false otherwise. pub fn has_enough_stake(coldkey: &T::AccountId, hotkey: &T::AccountId, decrement: u64) -> bool { Self::get_stake_for_coldkey_and_hotkey(coldkey, hotkey) >= decrement } - // Increases the stake on the hotkey account under its owning coldkey. - // + /// Increases the stake on the hotkey account under its owning coldkey. + /// + /// # Arguments + /// * `hotkey` - The hotkey account ID. + /// * `increment` - The amount to be incremented. pub fn increase_stake_on_hotkey_account(hotkey: &T::AccountId, increment: u64) { Self::increase_stake_on_coldkey_hotkey_account( &Self::get_owning_coldkey_for_hotkey(hotkey), @@ -166,8 +197,11 @@ impl Pallet { ); } - // Decreases the stake on the hotkey account under its owning coldkey. - // + /// Decreases the stake on the hotkey account under its owning coldkey. + /// + /// # Arguments + /// * `hotkey` - The hotkey account ID. + /// * `decrement` - The amount to be decremented. pub fn decrease_stake_on_hotkey_account(hotkey: &T::AccountId, decrement: u64) { Self::decrease_stake_on_coldkey_hotkey_account( &Self::get_owning_coldkey_for_hotkey(hotkey), diff --git a/pallets/subtensor/src/staking/increase_take.rs b/pallets/subtensor/src/staking/increase_take.rs index d5140b656..7e215905a 100644 --- a/pallets/subtensor/src/staking/increase_take.rs +++ b/pallets/subtensor/src/staking/increase_take.rs @@ -1,14 +1,5 @@ use super::*; -use frame_support::{ - storage::IterableStorageDoubleMap, - traits::{ - tokens::{ - fungible::{Balanced as _, Inspect as _, Mutate as _}, - Fortitude, Precision, Preservation, - }, - Imbalance, - }, -}; + impl Pallet { /// ---- The implementation for the extrinsic increase_take diff --git a/pallets/subtensor/src/staking/remove_stake.rs b/pallets/subtensor/src/staking/remove_stake.rs index 59e96777b..e93d63f11 100644 --- a/pallets/subtensor/src/staking/remove_stake.rs +++ b/pallets/subtensor/src/staking/remove_stake.rs @@ -1,14 +1,5 @@ use super::*; -use frame_support::{ - storage::IterableStorageDoubleMap, - traits::{ - tokens::{ - fungible::{Balanced as _, Inspect as _, Mutate as _}, - Fortitude, Precision, Preservation, - }, - Imbalance, - }, -}; + impl Pallet { /// ---- The implementation for the extrinsic remove_stake: Removes stake from a hotkey account and adds it onto a coldkey. From 752f53c8c6400be9d28b0dc78e433255862e316e Mon Sep 17 00:00:00 2001 From: const Date: Mon, 15 Jul 2024 14:27:27 -0500 Subject: [PATCH 12/58] merge clean --- pallets/subtensor/src/coinbase/mod.rs | 1 + pallets/subtensor/src/{ => coinbase}/root.rs | 0 pallets/subtensor/src/lib.rs | 17 ++++++----------- pallets/subtensor/src/subnets/mod.rs | 5 +++++ .../subtensor/src/{ => subnets}/registration.rs | 0 pallets/subtensor/src/{ => subnets}/serving.rs | 0 pallets/subtensor/src/{ => subnets}/uids.rs | 0 pallets/subtensor/src/{ => subnets}/weights.rs | 0 8 files changed, 12 insertions(+), 11 deletions(-) rename pallets/subtensor/src/{ => coinbase}/root.rs (100%) create mode 100644 pallets/subtensor/src/subnets/mod.rs rename pallets/subtensor/src/{ => subnets}/registration.rs (100%) rename pallets/subtensor/src/{ => subnets}/serving.rs (100%) rename pallets/subtensor/src/{ => subnets}/uids.rs (100%) rename pallets/subtensor/src/{ => subnets}/weights.rs (100%) diff --git a/pallets/subtensor/src/coinbase/mod.rs b/pallets/subtensor/src/coinbase/mod.rs index cc5b589f1..f8918ff1f 100644 --- a/pallets/subtensor/src/coinbase/mod.rs +++ b/pallets/subtensor/src/coinbase/mod.rs @@ -1,2 +1,3 @@ use super::*; pub mod block_step; +pub mod root; diff --git a/pallets/subtensor/src/root.rs b/pallets/subtensor/src/coinbase/root.rs similarity index 100% rename from pallets/subtensor/src/root.rs rename to pallets/subtensor/src/coinbase/root.rs diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index 23adeee02..e59f5a987 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -35,24 +35,19 @@ mod benchmarks; // ========================= // ==== Pallet Imports ===== // ========================= -mod coinbase; +pub mod coinbase; pub mod epoch; -mod macros; -mod rpc_info; +pub mod macros; +pub mod rpc_info; pub mod staking; pub mod swap; +pub mod subnets; +pub mod utils; +pub mod migrations; use macros::{config, dispatches, errors, events, genesis, hooks}; -mod registration; -mod root; -mod serving; -mod uids; -mod utils; -mod weights; - // apparently this is stabilized since rust 1.36 extern crate alloc; -pub mod migrations; #[deny(missing_docs)] #[import_section(errors::errors)] diff --git a/pallets/subtensor/src/subnets/mod.rs b/pallets/subtensor/src/subnets/mod.rs new file mode 100644 index 000000000..1738b7401 --- /dev/null +++ b/pallets/subtensor/src/subnets/mod.rs @@ -0,0 +1,5 @@ +use super::*; +pub mod registration; +pub mod weights; +pub mod serving; +pub mod uids; diff --git a/pallets/subtensor/src/registration.rs b/pallets/subtensor/src/subnets/registration.rs similarity index 100% rename from pallets/subtensor/src/registration.rs rename to pallets/subtensor/src/subnets/registration.rs diff --git a/pallets/subtensor/src/serving.rs b/pallets/subtensor/src/subnets/serving.rs similarity index 100% rename from pallets/subtensor/src/serving.rs rename to pallets/subtensor/src/subnets/serving.rs diff --git a/pallets/subtensor/src/uids.rs b/pallets/subtensor/src/subnets/uids.rs similarity index 100% rename from pallets/subtensor/src/uids.rs rename to pallets/subtensor/src/subnets/uids.rs diff --git a/pallets/subtensor/src/weights.rs b/pallets/subtensor/src/subnets/weights.rs similarity index 100% rename from pallets/subtensor/src/weights.rs rename to pallets/subtensor/src/subnets/weights.rs From ad694b0e9dec8c0d087b2d96a55c8887aab43b1a Mon Sep 17 00:00:00 2001 From: const Date: Mon, 15 Jul 2024 15:31:32 -0500 Subject: [PATCH 13/58] refactor everything to make it cleaner --- pallets/subtensor/src/coinbase/root.rs | 7 +++++-- pallets/subtensor/src/macros/genesis.rs | 5 +++-- .../src/migrations/migrate_create_root_network.rs | 3 ++- .../subtensor/src/migrations/migrate_delete_subnet_21.rs | 2 +- .../subtensor/src/migrations/migrate_delete_subnet_3.rs | 2 +- pallets/subtensor/tests/root.rs | 5 +++++ 6 files changed, 17 insertions(+), 7 deletions(-) diff --git a/pallets/subtensor/src/coinbase/root.rs b/pallets/subtensor/src/coinbase/root.rs index 948c91f20..d1b4bf47a 100644 --- a/pallets/subtensor/src/coinbase/root.rs +++ b/pallets/subtensor/src/coinbase/root.rs @@ -391,6 +391,9 @@ impl Pallet { // --- 9. Calculates the trust of networks. Trust is a sum of all stake with weights > 0. // Trust will have shape k, a score for each subnet. + log::debug!("Subnets:\n{:?}\n", Self::get_all_subnet_netuids()); + log::debug!("N Subnets:\n{:?}\n", Self::get_num_subnets()); + let total_networks = Self::get_num_subnets(); let mut trust = vec![I64F64::from_num(0); total_networks as usize]; let mut total_stake: I64F64 = I64F64::from_num(0); @@ -1031,7 +1034,7 @@ impl Pallet { NetworkModality::::insert(netuid, 0); // --- 5. Increase total network count. - TotalNetworks::::mutate(|n| n.saturating_inc()); + TotalNetworks::::mutate(|n| *n = n.saturating_add(1)); // --- 6. Set all default values **explicitly**. Self::set_network_registration_allowed(netuid, true); @@ -1123,7 +1126,7 @@ impl Pallet { NetworksAdded::::remove(netuid); // --- 6. Decrement the network counter. - TotalNetworks::::mutate(|n| n.saturating_dec()); + TotalNetworks::::mutate(|n| *n = n.saturating_sub(1)); // --- 7. Remove various network-related storages. NetworkRegisteredAt::::remove(netuid); diff --git a/pallets/subtensor/src/macros/genesis.rs b/pallets/subtensor/src/macros/genesis.rs index 34a888f28..7d3768a81 100644 --- a/pallets/subtensor/src/macros/genesis.rs +++ b/pallets/subtensor/src/macros/genesis.rs @@ -124,7 +124,7 @@ mod genesis { SubnetworkN::::insert(netuid, next_uid); // --- Increase total network count. - TotalNetworks::::mutate(|n| n.saturating_add( 1 )); + TotalNetworks::::mutate(|n| *n = n.saturating_add(1)); // Get the root network uid. let root_netuid: u16 = 0; @@ -133,7 +133,8 @@ mod genesis { NetworksAdded::::insert(root_netuid, true); // Increment the number of total networks. - TotalNetworks::::mutate(|n| n.saturating_add(1)); + TotalNetworks::::mutate(|n| *n = n.saturating_add(1)); + // Set the number of validators to 1. SubnetworkN::::insert(root_netuid, 0); diff --git a/pallets/subtensor/src/migrations/migrate_create_root_network.rs b/pallets/subtensor/src/migrations/migrate_create_root_network.rs index fa9f34301..c413d1f07 100644 --- a/pallets/subtensor/src/migrations/migrate_create_root_network.rs +++ b/pallets/subtensor/src/migrations/migrate_create_root_network.rs @@ -55,7 +55,7 @@ pub fn migrate_create_root_network() -> Weight { NetworksAdded::::insert(root_netuid, true); // Increment the total number of networks - TotalNetworks::::mutate(|n| n.saturating_add( 1 )); + TotalNetworks::::mutate(|n| *n = n.saturating_add(1)); // Set the maximum number of UIDs to the number of senate members MaxAllowedUids::::insert(root_netuid, 64); @@ -95,5 +95,6 @@ pub fn migrate_create_root_network() -> Weight { weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2)); } + log::info!("Migrated create root network"); weight } diff --git a/pallets/subtensor/src/migrations/migrate_delete_subnet_21.rs b/pallets/subtensor/src/migrations/migrate_delete_subnet_21.rs index 011d79de1..c917c7cab 100644 --- a/pallets/subtensor/src/migrations/migrate_delete_subnet_21.rs +++ b/pallets/subtensor/src/migrations/migrate_delete_subnet_21.rs @@ -66,7 +66,7 @@ pub fn migrate_delete_subnet_21() -> Weight { NetworksAdded::::remove(netuid); // Decrement the network counter - TotalNetworks::::mutate(|n| n.saturating_sub( 1 )); + TotalNetworks::::mutate(|n| *n = n.saturating_sub(1)); // Remove network registration time NetworkRegisteredAt::::remove(netuid); diff --git a/pallets/subtensor/src/migrations/migrate_delete_subnet_3.rs b/pallets/subtensor/src/migrations/migrate_delete_subnet_3.rs index a07434bcb..217696357 100644 --- a/pallets/subtensor/src/migrations/migrate_delete_subnet_3.rs +++ b/pallets/subtensor/src/migrations/migrate_delete_subnet_3.rs @@ -69,7 +69,7 @@ pub fn migrate_delete_subnet_3() -> Weight { NetworksAdded::::remove(netuid); // Decrement the network counter - TotalNetworks::::mutate(|n| n.saturating_sub(1)); + TotalNetworks::::mutate(|n| *n = n.saturating_sub(1)); // Remove network registration time NetworkRegisteredAt::::remove(netuid); diff --git a/pallets/subtensor/tests/root.rs b/pallets/subtensor/tests/root.rs index d4e8448a1..84df71d83 100644 --- a/pallets/subtensor/tests/root.rs +++ b/pallets/subtensor/tests/root.rs @@ -32,6 +32,7 @@ fn test_root_register_network_exist() { }); } +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test root -- test_set_weights_not_root_error --exact --nocapture #[test] fn test_set_weights_not_root_error() { new_test_ext(0).execute_with(|| { @@ -60,6 +61,7 @@ fn test_set_weights_not_root_error() { }); } +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test root -- test_root_register_normal_on_root_fails --exact --nocapture #[test] fn test_root_register_normal_on_root_fails() { new_test_ext(1).execute_with(|| { @@ -104,6 +106,7 @@ fn test_root_register_normal_on_root_fails() { }); } +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test root -- test_root_register_stake_based_pruning_works --exact --nocapture #[test] fn test_root_register_stake_based_pruning_works() { new_test_ext(1).execute_with(|| { @@ -192,6 +195,7 @@ fn test_root_register_stake_based_pruning_works() { }); } +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test root -- test_root_set_weights --exact --nocapture #[test] fn test_root_set_weights() { new_test_ext(1).execute_with(|| { @@ -334,6 +338,7 @@ fn test_root_set_weights() { }); } +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test root -- test_root_set_weights --exact --nocapture #[test] fn test_root_set_weights_out_of_order_netuids() { new_test_ext(1).execute_with(|| { From 5e291123d727bcd75336777e00a14d29dfaa09ad Mon Sep 17 00:00:00 2001 From: const Date: Mon, 15 Jul 2024 15:32:18 -0500 Subject: [PATCH 14/58] lint --- pallets/subtensor/src/coinbase/root.rs | 2 +- pallets/subtensor/src/lib.rs | 4 ++-- pallets/subtensor/src/staking/add_stake.rs | 1 - pallets/subtensor/src/staking/become_delegate.rs | 1 - pallets/subtensor/src/staking/decrease_take.rs | 1 - pallets/subtensor/src/staking/increase_take.rs | 1 - pallets/subtensor/src/staking/remove_stake.rs | 1 - pallets/subtensor/src/subnets/mod.rs | 2 +- 8 files changed, 4 insertions(+), 9 deletions(-) diff --git a/pallets/subtensor/src/coinbase/root.rs b/pallets/subtensor/src/coinbase/root.rs index d1b4bf47a..974931e8f 100644 --- a/pallets/subtensor/src/coinbase/root.rs +++ b/pallets/subtensor/src/coinbase/root.rs @@ -1034,7 +1034,7 @@ impl Pallet { NetworkModality::::insert(netuid, 0); // --- 5. Increase total network count. - TotalNetworks::::mutate(|n| *n = n.saturating_add(1)); + TotalNetworks::::mutate(|n| *n = n.saturating_add(1)); // --- 6. Set all default values **explicitly**. Self::set_network_registration_allowed(netuid, true); diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index e59f5a987..c28da051d 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -38,12 +38,12 @@ mod benchmarks; pub mod coinbase; pub mod epoch; pub mod macros; +pub mod migrations; pub mod rpc_info; pub mod staking; -pub mod swap; pub mod subnets; +pub mod swap; pub mod utils; -pub mod migrations; use macros::{config, dispatches, errors, events, genesis, hooks}; // apparently this is stabilized since rust 1.36 diff --git a/pallets/subtensor/src/staking/add_stake.rs b/pallets/subtensor/src/staking/add_stake.rs index 422dfa2e4..eb7762bec 100644 --- a/pallets/subtensor/src/staking/add_stake.rs +++ b/pallets/subtensor/src/staking/add_stake.rs @@ -1,6 +1,5 @@ use super::*; - impl Pallet { /// ---- The implementation for the extrinsic add_stake: Adds stake to a hotkey account. /// diff --git a/pallets/subtensor/src/staking/become_delegate.rs b/pallets/subtensor/src/staking/become_delegate.rs index 4df8adf2d..064f47c12 100644 --- a/pallets/subtensor/src/staking/become_delegate.rs +++ b/pallets/subtensor/src/staking/become_delegate.rs @@ -1,6 +1,5 @@ use super::*; - impl Pallet { /// ---- The implementation for the extrinsic become_delegate: signals that this hotkey allows delegated stake. /// diff --git a/pallets/subtensor/src/staking/decrease_take.rs b/pallets/subtensor/src/staking/decrease_take.rs index 6aac33651..9e48bac91 100644 --- a/pallets/subtensor/src/staking/decrease_take.rs +++ b/pallets/subtensor/src/staking/decrease_take.rs @@ -1,6 +1,5 @@ use super::*; - impl Pallet { /// ---- The implementation for the extrinsic decrease_take /// diff --git a/pallets/subtensor/src/staking/increase_take.rs b/pallets/subtensor/src/staking/increase_take.rs index 7e215905a..aa6dd443c 100644 --- a/pallets/subtensor/src/staking/increase_take.rs +++ b/pallets/subtensor/src/staking/increase_take.rs @@ -1,6 +1,5 @@ use super::*; - impl Pallet { /// ---- The implementation for the extrinsic increase_take /// diff --git a/pallets/subtensor/src/staking/remove_stake.rs b/pallets/subtensor/src/staking/remove_stake.rs index e93d63f11..a6f3db08d 100644 --- a/pallets/subtensor/src/staking/remove_stake.rs +++ b/pallets/subtensor/src/staking/remove_stake.rs @@ -1,6 +1,5 @@ use super::*; - impl Pallet { /// ---- The implementation for the extrinsic remove_stake: Removes stake from a hotkey account and adds it onto a coldkey. /// diff --git a/pallets/subtensor/src/subnets/mod.rs b/pallets/subtensor/src/subnets/mod.rs index 1738b7401..43bdfec43 100644 --- a/pallets/subtensor/src/subnets/mod.rs +++ b/pallets/subtensor/src/subnets/mod.rs @@ -1,5 +1,5 @@ use super::*; pub mod registration; -pub mod weights; pub mod serving; pub mod uids; +pub mod weights; From 8941385a5f4bac21ddc6b3c91f80d75bb82529bd Mon Sep 17 00:00:00 2001 From: const Date: Mon, 15 Jul 2024 16:24:49 -0500 Subject: [PATCH 15/58] add set sudo hotkey drain tempo --- pallets/admin-utils/src/benchmarking.rs | 8 + pallets/admin-utils/src/lib.rs | 30 + pallets/admin-utils/src/weights.rs | 11 + pallets/admin-utils/tests/mock.rs | 3 + pallets/subtensor/src/coinbase/block_step.rs | 333 +---- pallets/subtensor/src/coinbase/mod.rs | 1 + .../subtensor/src/coinbase/run_coinbase.rs | 373 +++++ pallets/subtensor/src/epoch/run_epoch.rs | 99 +- pallets/subtensor/src/lib.rs | 3 + pallets/subtensor/src/macros/dispatches.rs | 59 + pallets/subtensor/src/macros/errors.rs | 8 + pallets/subtensor/src/macros/events.rs | 1 + pallets/subtensor/src/rpc_info/neuron_info.rs | 12 +- pallets/subtensor/src/staking/mod.rs | 1 + pallets/subtensor/src/staking/set_children.rs | 185 +++ pallets/subtensor/src/subnets/registration.rs | 11 + pallets/subtensor/src/utils.rs | 16 + pallets/subtensor/tests/children.rs | 1261 +++++++++++++++++ pallets/subtensor/tests/coinbase.rs | 154 ++ runtime/src/lib.rs | 4 + 20 files changed, 2232 insertions(+), 341 deletions(-) create mode 100644 pallets/subtensor/src/coinbase/run_coinbase.rs create mode 100644 pallets/subtensor/src/staking/set_children.rs create mode 100644 pallets/subtensor/tests/children.rs create mode 100644 pallets/subtensor/tests/coinbase.rs diff --git a/pallets/admin-utils/src/benchmarking.rs b/pallets/admin-utils/src/benchmarking.rs index 0158311f7..3165e907f 100644 --- a/pallets/admin-utils/src/benchmarking.rs +++ b/pallets/admin-utils/src/benchmarking.rs @@ -240,5 +240,13 @@ mod benchmarks { _(RawOrigin::Root, 1u16/*netuid*/, true/*enabled*/)/*set_commit_reveal_weights_enabled*/; } + #[benchmark] + fn sudo_set_hotkey_emission_tempo() { + T::Subtensor::init_new_network(1u16 /*netuid*/, 1u16 /*sudo_tempo*/); + + #[extrinsic_call] + _(RawOrigin::Root, 1u64/*emission_tempo*/)/*set_hotkey_emission_tempo*/; + } + //impl_benchmark_test_suite!(AdminUtils, crate::mock::new_test_ext(), crate::mock::Test); } diff --git a/pallets/admin-utils/src/lib.rs b/pallets/admin-utils/src/lib.rs index 9a8744dc6..2aa45cbc9 100644 --- a/pallets/admin-utils/src/lib.rs +++ b/pallets/admin-utils/src/lib.rs @@ -1035,6 +1035,35 @@ pub mod pallet { T::Subtensor::ensure_subnet_owner_or_root(origin.clone(), netuid)?; T::Subtensor::do_set_alpha_values(origin, netuid, alpha_low, alpha_high) } + + /// Sets the hotkey emission tempo. + /// + /// This extrinsic allows the root account to set the hotkey emission tempo, which determines + /// the number of blocks before a hotkey drains accumulated emissions through to nominator staking accounts. + /// + /// # Arguments + /// * `origin` - The origin of the call, which must be the root account. + /// * `emission_tempo` - The new emission tempo value to set. + /// + /// # Emits + /// * `Event::HotkeyEmissionTempoSet` - When the hotkey emission tempo is successfully set. + /// + /// # Errors + /// * `DispatchError::BadOrigin` - If the origin is not the root account. + #[pallet::call_index(52)] + #[pallet::weight(T::WeightInfo::sudo_set_hotkey_emission_tempo())] + pub fn sudo_set_hotkey_emission_tempo( + origin: OriginFor, + emission_tempo: u64, + ) -> DispatchResult { + ensure_root(origin)?; + T::Subtensor::set_hotkey_emission_tempo(emission_tempo); + log::info!( + "HotkeyEmissionTempoSet( emission_tempo: {:?} )", + emission_tempo + ); + Ok(()) + } } } @@ -1137,4 +1166,5 @@ pub trait SubtensorInterface { alpha_low: u16, alpha_high: u16, ) -> Result<(), DispatchError>; + fn set_hotkey_emission_tempo(emission_tempo: u64); } diff --git a/pallets/admin-utils/src/weights.rs b/pallets/admin-utils/src/weights.rs index ace123b14..0c0259ef2 100644 --- a/pallets/admin-utils/src/weights.rs +++ b/pallets/admin-utils/src/weights.rs @@ -62,6 +62,7 @@ pub trait WeightInfo { fn sudo_set_tempo() -> Weight; fn sudo_set_commit_reveal_weights_interval() -> Weight; fn sudo_set_commit_reveal_weights_enabled() -> Weight; + fn sudo_set_hotkey_emission_tempo() -> Weight; } @@ -806,4 +807,14 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } + /// Storage: `SubtensorModule::HotkeyEmissionTempo` (r:0 w:1) + /// Proof: `SubtensorModule::HotkeyEmissionTempo` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn sudo_set_hotkey_emission_tempo() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 5_000_000 picoseconds. + Weight::from_parts(6_000_000, 0) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } } \ No newline at end of file diff --git a/pallets/admin-utils/tests/mock.rs b/pallets/admin-utils/tests/mock.rs index dee8e742f..c1f55fece 100644 --- a/pallets/admin-utils/tests/mock.rs +++ b/pallets/admin-utils/tests/mock.rs @@ -475,6 +475,9 @@ impl pallet_admin_utils::SubtensorInterface f fn set_liquid_alpha_enabled(netuid: u16, enabled: bool) { SubtensorModule::set_liquid_alpha_enabled(netuid, enabled); } + fn set_hotkey_emission_tempo(emission_tempo: u64) { + SubtensorModule::set_hotkey_emission_tempo(emission_tempo) + } fn do_set_alpha_values( origin: RuntimeOrigin, netuid: u16, diff --git a/pallets/subtensor/src/coinbase/block_step.rs b/pallets/subtensor/src/coinbase/block_step.rs index 784332e4e..f4df51456 100644 --- a/pallets/subtensor/src/coinbase/block_step.rs +++ b/pallets/subtensor/src/coinbase/block_step.rs @@ -13,341 +13,12 @@ impl Pallet { log::debug!("block_step for block: {:?} ", block_number); // --- 1. Adjust difficulties. Self::adjust_registration_terms_for_networks(); - // --- 2. Calculate per-subnet emissions - match Self::root_epoch(block_number) { - Ok(_) => (), - Err(e) => { - log::trace!("Error while running root epoch: {:?}", e); - } - } - // --- 3. Drains emission tuples ( hotkey, amount ). - Self::drain_emission(block_number); - // --- 4. Generates emission tuples from epoch functions. - Self::generate_emission(block_number); + // --- 2. Run emission through network. + Self::run_coinbase(); // Return ok. Ok(()) } - #[allow(clippy::arithmetic_side_effects)] - /// Helper function which returns the number of blocks remaining before we will run the epoch on this - /// network. Networks run their epoch when (block_number + netuid + 1 ) % (tempo + 1) = 0 - /// - pub fn blocks_until_next_epoch(netuid: u16, tempo: u16, block_number: u64) -> u64 { - // tempo | netuid | # first epoch block - // 1 0 0 - // 1 1 1 - // 2 0 1 - // 2 1 0 - // 100 0 99 - // 100 1 98 - // Special case: tempo = 0, the network never runs. - if tempo == 0 { - return 1000; - } - (tempo as u64).saturating_sub( - block_number.saturating_add(netuid as u64).saturating_add(1) - % (tempo as u64).saturating_add(1), - ) - } - - #[allow(clippy::arithmetic_side_effects)] - /// Helper function returns the number of tuples to drain on a particular step based on - /// the remaining tuples to sink and the block number - /// - pub fn tuples_to_drain_this_block( - netuid: u16, - tempo: u16, - block_number: u64, - n_remaining: usize, - ) -> usize { - let blocks_until_epoch: u64 = Self::blocks_until_next_epoch(netuid, tempo, block_number); - if blocks_until_epoch.saturating_div(2) == 0 { - return n_remaining; - } // drain all. - if tempo.saturating_div(2) == 0 { - return n_remaining; - } // drain all - if n_remaining == 0 { - return 0; - } // nothing to drain at all. - // Else return enough tuples to drain all within half the epoch length. - let to_sink_via_tempo: usize = - n_remaining.saturating_div((tempo as usize).saturating_div(2)); - let to_sink_via_blocks_until_epoch: usize = - n_remaining.saturating_div((blocks_until_epoch as usize).saturating_div(2)); - if to_sink_via_tempo > to_sink_via_blocks_until_epoch { - to_sink_via_tempo - } else { - to_sink_via_blocks_until_epoch - } - } - - pub fn get_loaded_emission_tuples(netuid: u16) -> Option> { - LoadedEmission::::get(netuid) - } - - /// Reads from the loaded emission storage which contains lists of pending emission tuples ( hotkey, amount ) - /// and distributes small chunks of them at a time. - /// - pub fn drain_emission(_: u64) { - // --- 1. We iterate across each network. - for (netuid, _) in as IterableStorageMap>::iter() { - let Some(tuples_to_drain) = Self::get_loaded_emission_tuples(netuid) else { - // There are no tuples to emit. - continue; - }; - let mut total_emitted: u64 = 0; - for (hotkey, server_amount, validator_amount) in tuples_to_drain.iter() { - Self::emit_inflation_through_hotkey_account( - hotkey, - *server_amount, - *validator_amount, - ); - total_emitted.saturating_accrue((*server_amount).saturating_add(*validator_amount)); - } - LoadedEmission::::remove(netuid); - TotalIssuance::::put(TotalIssuance::::get().saturating_add(total_emitted)); - } - } - - /// Iterates through networks queues more emission onto their pending storage. - /// If a network has no blocks left until tempo, we run the epoch function and generate - /// more token emission tuples for later draining onto accounts. - /// - pub fn generate_emission(block_number: u64) { - // --- 1. Iterate across each network and add pending emission into stash. - for (netuid, tempo) in as IterableStorageMap>::iter() { - // Skip the root network or subnets with registrations turned off - if netuid == Self::get_root_netuid() { - // Root emission or subnet emission is burned - continue; - } - - // --- 2. Queue the emission due to this network. - let mut new_queued_emission: u64 = Self::get_subnet_emission_value(netuid); - if !Self::is_registration_allowed(netuid) { - new_queued_emission = 0; // No emission for this network if registration is off. - } - - log::debug!( - "generate_emission for netuid: {:?} with tempo: {:?} and emission: {:?}", - netuid, - tempo, - new_queued_emission, - ); - - let subnet_has_owner = SubnetOwner::::contains_key(netuid); - let mut remaining = I96F32::from_num(new_queued_emission); - if subnet_has_owner { - let cut = remaining - .saturating_mul(I96F32::from_num(Self::get_subnet_owner_cut())) - .saturating_div(I96F32::from_num(u16::MAX)); - - remaining = remaining.saturating_sub(cut); - - Self::add_balance_to_coldkey_account( - &Self::get_subnet_owner(netuid), - cut.to_num::(), - ); - - // We are creating tokens here from the coinbase. - Self::coinbase(cut.to_num::()); - } - // --- 5. Add remaining amount to the network's pending emission. - PendingEmission::::mutate(netuid, |queued| { - queued.saturating_accrue(remaining.to_num::()) - }); - log::debug!( - "netuid_i: {:?} queued_emission: +{:?} ", - netuid, - new_queued_emission - ); - - // --- 6. Check to see if this network has reached tempo. - if Self::blocks_until_next_epoch(netuid, tempo, block_number) != 0 { - // --- 3.1 No epoch, increase blocks since last step and continue, - Self::set_blocks_since_last_step( - netuid, - Self::get_blocks_since_last_step(netuid).saturating_add(1), - ); - continue; - } - - // --- 7 This network is at tempo and we are running its epoch. - // First drain the queued emission. - let emission_to_drain: u64 = PendingEmission::::get(netuid); - PendingEmission::::insert(netuid, 0); - - // --- 8. Run the epoch mechanism and return emission tuples for hotkeys in the network. - let emission_tuples_this_block: Vec<(T::AccountId, u64, u64)> = - Self::epoch(netuid, emission_to_drain); - log::debug!( - "netuid_i: {:?} emission_to_drain: {:?} ", - netuid, - emission_to_drain - ); - - // --- 9. Check that the emission does not exceed the allowed total. - let emission_sum: u128 = emission_tuples_this_block - .iter() - .map(|(_account_id, ve, se)| (*ve as u128).saturating_add(*se as u128)) - .sum(); - if emission_sum > emission_to_drain as u128 { - continue; - } // Saftey check. - - // --- 10. Sink the emission tuples onto the already loaded. - let mut concat_emission_tuples: Vec<(T::AccountId, u64, u64)> = - emission_tuples_this_block.clone(); - if let Some(mut current_emission_tuples) = Self::get_loaded_emission_tuples(netuid) { - // 10.a We already have loaded emission tuples, so we concat the new ones. - concat_emission_tuples.append(&mut current_emission_tuples); - } - LoadedEmission::::insert(netuid, concat_emission_tuples); - - // --- 11 Set counters. - Self::set_blocks_since_last_step(netuid, 0); - Self::set_last_mechanism_step_block(netuid, block_number); - } - } - /// Distributes token inflation through the hotkey based on emission. The call ensures that the inflation - /// is distributed onto the accounts in proportion of the stake delegated minus the take. This function - /// is called after an epoch to distribute the newly minted stake according to delegation. - /// - pub fn emit_inflation_through_hotkey_account( - hotkey: &T::AccountId, - server_emission: u64, - validator_emission: u64, - ) { - // --- 1. Check if the hotkey is a delegate. If not, we simply pass the stake through to the - // coldkey - hotkey account as normal. - if !Self::hotkey_is_delegate(hotkey) { - Self::increase_stake_on_hotkey_account( - hotkey, - server_emission.saturating_add(validator_emission), - ); - return; - } - // Then this is a delegate, we distribute validator_emission, then server_emission. - - // --- 2. The hotkey is a delegate. We first distribute a proportion of the validator_emission to the hotkey - // directly as a function of its 'take' - let total_hotkey_stake: u64 = Self::get_total_stake_for_hotkey(hotkey); - let delegate_take: u64 = - Self::calculate_delegate_proportional_take(hotkey, validator_emission); - let validator_emission_minus_take: u64 = validator_emission.saturating_sub(delegate_take); - let mut remaining_validator_emission: u64 = validator_emission_minus_take; - - // 3. -- The remaining emission goes to the owners in proportion to the stake delegated. - for (owning_coldkey_i, stake_i) in - as IterableStorageDoubleMap>::iter_prefix( - hotkey, - ) - { - // --- 4. The emission proportion is remaining_emission * ( stake / total_stake ). - let stake_proportion: u64 = Self::calculate_stake_proportional_emission( - stake_i, - total_hotkey_stake, - validator_emission_minus_take, - ); - Self::increase_stake_on_coldkey_hotkey_account( - &owning_coldkey_i, - hotkey, - stake_proportion, - ); - log::debug!( - "owning_coldkey_i: {:?} hotkey: {:?} emission: +{:?} ", - owning_coldkey_i, - hotkey, - stake_proportion - ); - remaining_validator_emission.saturating_reduce(stake_proportion); - } - - // --- 5. Last increase final account balance of delegate after 4, since 5 will change the stake proportion of - // the delegate and effect calculation in 4. - Self::increase_stake_on_hotkey_account( - hotkey, - delegate_take.saturating_add(remaining_validator_emission), - ); - log::debug!("delkey: {:?} delegate_take: +{:?} ", hotkey, delegate_take); - // Also emit the server_emission to the hotkey - // The server emission is distributed in-full to the delegate owner. - // We do this after 4. for the same reason as above. - Self::increase_stake_on_hotkey_account(hotkey, server_emission); - } - - /// Increases the stake on the cold - hot pairing by increment while also incrementing other counters. - /// This function should be called rather than set_stake under account. - /// - pub fn block_step_increase_stake_on_coldkey_hotkey_account( - coldkey: &T::AccountId, - hotkey: &T::AccountId, - increment: u64, - ) { - TotalColdkeyStake::::mutate(coldkey, |old| old.saturating_add(increment)); - TotalHotkeyStake::::insert( - hotkey, - TotalHotkeyStake::::get(hotkey).saturating_add(increment), - ); - Stake::::insert( - hotkey, - coldkey, - Stake::::get(hotkey, coldkey).saturating_add(increment), - ); - TotalStake::::put(TotalStake::::get().saturating_add(increment)); - } - - /// Decreases the stake on the cold - hot pairing by the decrement while decreasing other counters. - /// - pub fn block_step_decrease_stake_on_coldkey_hotkey_account( - coldkey: &T::AccountId, - hotkey: &T::AccountId, - decrement: u64, - ) { - TotalColdkeyStake::::mutate(coldkey, |old| old.saturating_sub(decrement)); - TotalHotkeyStake::::insert( - hotkey, - TotalHotkeyStake::::get(hotkey).saturating_sub(decrement), - ); - Stake::::insert( - hotkey, - coldkey, - Stake::::get(hotkey, coldkey).saturating_sub(decrement), - ); - TotalStake::::put(TotalStake::::get().saturating_sub(decrement)); - } - - /// Returns emission awarded to a hotkey as a function of its proportion of the total stake. - /// - pub fn calculate_stake_proportional_emission( - stake: u64, - total_stake: u64, - emission: u64, - ) -> u64 { - if total_stake == 0 { - return 0; - }; - let stake_proportion: I64F64 = - I64F64::from_num(stake).saturating_div(I64F64::from_num(total_stake)); - let proportional_emission: I64F64 = - I64F64::from_num(emission).saturating_mul(stake_proportion); - proportional_emission.to_num::() - } - - /// Returns the delegated stake 'take' assigned to this key. (If exists, otherwise 0) - /// - pub fn calculate_delegate_proportional_take(hotkey: &T::AccountId, emission: u64) -> u64 { - if Self::hotkey_is_delegate(hotkey) { - let take_proportion: I64F64 = I64F64::from_num(Delegates::::get(hotkey)) - .saturating_div(I64F64::from_num(u16::MAX)); - let take_emission: I64F64 = take_proportion.saturating_mul(I64F64::from_num(emission)); - take_emission.to_num::() - } else { - 0 - } - } - /// Adjusts the network difficulties/burns of every active network. Resetting state parameters. /// pub fn adjust_registration_terms_for_networks() { diff --git a/pallets/subtensor/src/coinbase/mod.rs b/pallets/subtensor/src/coinbase/mod.rs index f8918ff1f..ec989d258 100644 --- a/pallets/subtensor/src/coinbase/mod.rs +++ b/pallets/subtensor/src/coinbase/mod.rs @@ -1,3 +1,4 @@ use super::*; pub mod block_step; pub mod root; +pub mod run_coinbase; diff --git a/pallets/subtensor/src/coinbase/run_coinbase.rs b/pallets/subtensor/src/coinbase/run_coinbase.rs new file mode 100644 index 000000000..7dd829853 --- /dev/null +++ b/pallets/subtensor/src/coinbase/run_coinbase.rs @@ -0,0 +1,373 @@ +use super::*; +use frame_support::storage::IterableStorageDoubleMap; +use frame_support::storage::IterableStorageMap; +use sp_runtime::Saturating; +use substrate_fixed::types::I110F18; +use substrate_fixed::types::I64F64; +use substrate_fixed::types::I96F32; + +impl Pallet { + /// The `coinbase` function performs a four-part emission distribution process involving + /// subnets, epochs, hotkeys, and nominators. + // It is divided into several steps, each handling a specific part of the distribution: + + // Step 1: Compute the block-wise emission for each subnet. + // This involves calculating how much (TAO) should be emitted into each subnet using the + // root epoch function. + + // Step 2: Accumulate the subnet block emission. + // After calculating the block-wise emission, these values are accumulated to keep track + // of how much each subnet should emit before the next distribution phase. This accumulation + // is a running total that gets updated each block. + + // Step 3: Distribute the accumulated emissions through epochs. + // Subnets periodically distribute their accumulated emissions to hotkeys (active validators/miners) + // in the network on a `tempo` --- the time between epochs. This step runs Yuma consensus to + // determine how emissions are split among hotkeys based on their contributions and roles. + // The accumulation of hotkey emissions is done through the `accumulate_hotkey_emission` function. + // The function splits the rewards for a hotkey amongst itself and its `parents`. The parents are + // the hotkeys that are delegating their stake to the hotkey. + + // Step 4: Further distribute emissions from hotkeys to nominators. + // Finally, the emissions received by hotkeys are further distributed to their nominators, + // who are stakeholders that support the hotkeys. + pub fn run_coinbase() { + // --- 0. Get current block. + let current_block: u64 = Self::get_current_block_as_u64(); + log::debug!("Current block: {:?}", current_block); + + // --- 1. Get all netuids. + let subnets: Vec = Self::get_all_subnet_netuids(); + log::debug!("All subnet netuids: {:?}", subnets); + + // --- 2. Run the root epoch function which computes the block emission for each subnet. + // coinbase --> root() --> subnet_block_emission + match Self::root_epoch(current_block) { + Ok(_) => log::debug!("Root epoch run successfully for block: {:?}", current_block), + Err(e) => { + log::trace!("Did not run epoch with: {:?}", e); + } + } + + // --- 3. Drain the subnet block emission and accumulate it as subnet emission, which increases until the tempo is reached in #4. + // subnet_blockwise_emission -> subnet_pending_emission + for netuid in subnets.clone().iter() { + // --- 3.1 Get the network's block-wise emission amount. + // This value is newly minted TAO which has not reached staking accounts yet. + let subnet_blockwise_emission: u64 = EmissionValues::::get(*netuid); + log::debug!( + "Subnet block-wise emission for netuid {:?}: {:?}", + *netuid, + subnet_blockwise_emission + ); + + // --- 3.2 Accumulate the subnet emission on the subnet. + PendingEmission::::mutate(*netuid, |subnet_emission| { + *subnet_emission = subnet_emission.saturating_add(subnet_blockwise_emission); + log::debug!( + "Updated subnet emission for netuid {:?}: {:?}", + *netuid, + *subnet_emission + ); + }); + } + + // --- 4. Drain the accumulated subnet emissions, pass them through the epoch(). + // Before accumulating on the hotkeys the function redistributes the emission towards hotkey parents. + // subnet_emission --> epoch() --> hotkey_emission --> (hotkey + parent hotkeys) + for netuid in subnets.clone().iter() { + // --- 4.1 Check to see if the subnet should run its epoch. + if Self::should_run_epoch(*netuid, current_block) { + // --- 4.2 Drain the subnet emission. + let mut subnet_emission: u64 = PendingEmission::::get(*netuid); + PendingEmission::::insert(*netuid, 0); + log::debug!( + "Drained subnet emission for netuid {:?}: {:?}", + *netuid, + subnet_emission + ); + + // --- 4.3 Set last step counter. + Self::set_blocks_since_last_step(*netuid, 0); + Self::set_last_mechanism_step_block(*netuid, current_block); + + // --- 4.4 Distribute owner take. + if SubnetOwner::::contains_key(netuid) { + // Does the subnet have an owner? + + // --- 4.4.1 Compute the subnet owner cut. + let owner_cut: I96F32 = I96F32::from_num(subnet_emission).saturating_mul( + I96F32::from_num(Self::get_subnet_owner_cut()) + .saturating_div(I96F32::from_num(u16::MAX)), + ); + + // --- 4.4.2 Remove the cut from the subnet emission + subnet_emission = subnet_emission.saturating_sub(owner_cut.to_num::()); + + // --- 4.4.3 Add the cut to the balance of the owner + Self::add_balance_to_coldkey_account( + &Self::get_subnet_owner(*netuid), + owner_cut.to_num::(), + ); + + // --- 4.4.4 Increase total issuance on the chain. + Self::coinbase(owner_cut.to_num::()); + } + + // 4.3 Pass emission through epoch() --> hotkey emission. + let hotkey_emission: Vec<(T::AccountId, u64, u64)> = + Self::epoch(*netuid, subnet_emission); + log::debug!( + "Hotkey emission results for netuid {:?}: {:?}", + *netuid, + hotkey_emission + ); + + // 4.4 Accumulate the tuples on hotkeys: + for (hotkey, mining_emission, validator_emission) in hotkey_emission { + // 4.5 Accumulate the emission on the hotkey and parent hotkeys. + Self::accumulate_hotkey_emission( + &hotkey, + *netuid, + validator_emission, // Amount received from validating + mining_emission, // Amount recieved from mining. + ); + log::debug!("Accumulated emissions on hotkey {:?} for netuid {:?}: mining {:?}, validator {:?}", hotkey, *netuid, mining_emission, validator_emission); + } + } else { + log::debug!("Tempo not reached for subnet: {:?}", *netuid); + } + } + + // --- 5. Drain the accumulated hotkey emissions through to the nominators. + // The hotkey takes a proportion of the emission, the remainder is drained through to the nominators. + // We keep track of the last stake increase event for accounting purposes. + // hotkeys --> nominators. + let emission_tempo: u64 = Self::get_hotkey_emission_tempo(); + for (hotkey, hotkey_emission) in PendingdHotkeyEmission::::iter() { + // Check for zeros. + // remove zero values. + if hotkey_emission == 0 { + continue; + } + + // --- 5.1 Check if we should drain the hotkey emission on this block. + if Self::should_drain_hotkey(&hotkey, current_block, emission_tempo) { + // --- 5.2 Drain the hotkey emission and distribute it to nominators. + let total_new_tao: u64 = + Self::drain_hotkey_emission(&hotkey, hotkey_emission, current_block); + log::debug!( + "Drained hotkey emission for hotkey {:?} on block {:?}: {:?}", + hotkey, + current_block, + hotkey_emission + ); + + // --- 5.3 Increase total issuance on the chain. + Self::coinbase(total_new_tao); + log::debug!("Increased total issuance by {:?}", total_new_tao); + } + } + } + + /// Accumulates the mining and validator emissions on a hotkey and distributes the validator emission among its parents. + /// + /// This function is responsible for accumulating the mining and validator emissions associated with a hotkey onto a hotkey. + /// It first calculates the total stake of the hotkey, considering the stakes contributed by its parents and reduced by its children. + /// It then retrieves the list of parents of the hotkey and distributes the validator emission proportionally based on the stake contributed by each parent. + /// The remaining validator emission, after distribution to the parents, along with the mining emission, is then added to the hotkey's own accumulated emission. + /// + /// # Arguments + /// * `hotkey` - The account ID of the hotkey for which emissions are being calculated. + /// * `netuid` - The unique identifier of the network to which the hotkey belongs. + /// * `mining_emission` - The amount of mining emission allocated to the hotkey. + /// * `validator_emission` - The amount of validator emission allocated to the hotkey. + /// + pub fn accumulate_hotkey_emission( + hotkey: &T::AccountId, + netuid: u16, + validating_emission: u64, + mining_emission: u64, + ) { + // --- 1. First, calculate the hotkey's share of the emission. + let take_proportion: I64F64 = + I64F64::from_num(Delegates::::get(hotkey)).saturating_div(I64F64::from_num(u16::MAX)); + let hotkey_take: u64 = take_proportion + .saturating_mul(I64F64::from_num(validating_emission)) + .to_num::(); + // NOTE: Only the validation emission should be split amongst parents. + + // --- 2. Compute the remaining emission after the hotkey's share is deducted. + let emission_minus_take: u64 = validating_emission.saturating_sub(hotkey_take); + + // --- 3. Track the remaining emission for accounting purposes. + let mut remaining_emission: u64 = emission_minus_take; + + // --- 4. Calculate the total stake of the hotkey, adjusted by the stakes of parents and children. + // Parents contribute to the stake, while children reduce it. + // If this value is zero, no distribution to anyone is necessary. + let total_hotkey_stake: u64 = Self::get_stake_for_hotkey_on_subnet(hotkey, netuid); + if total_hotkey_stake != 0 { + // --- 5. If the total stake is not zero, iterate over each parent to determine their contribution to the hotkey's stake, + // and calculate their share of the emission accordingly. + for (proportion, parent) in Self::get_parents(hotkey, netuid) { + // --- 5.1 Retrieve the parent's stake. This is the raw stake value including nominators. + let parent_stake: u64 = Self::get_total_stake_for_hotkey(&parent); + + // --- 5.2 Calculate the portion of the hotkey's total stake contributed by this parent. + // Then, determine the parent's share of the remaining emission. + let stake_from_parent: I96F32 = I96F32::from_num(parent_stake).saturating_mul( + I96F32::from_num(proportion).saturating_div(I96F32::from_num(u64::MAX)), + ); + let proportion_from_parent: I96F32 = + stake_from_parent.saturating_div(I96F32::from_num(total_hotkey_stake)); + let parent_emission_take: u64 = proportion_from_parent + .saturating_mul(I96F32::from_num(emission_minus_take)) + .to_num::(); + + // --- 5.5. Accumulate emissions for the parent hotkey. + PendingdHotkeyEmission::::mutate(parent, |parent_accumulated| { + *parent_accumulated = parent_accumulated.saturating_add(parent_emission_take) + }); + + // --- 5.6. Subtract the parent's share from the remaining emission for this hotkey. + remaining_emission = remaining_emission.saturating_sub(parent_emission_take); + } + } + + // --- 6. Add the remaining emission plus the hotkey's initial take to the pending emission for this hotkey. + PendingdHotkeyEmission::::mutate(hotkey, |hotkey_pending| { + *hotkey_pending = hotkey_pending.saturating_add( + remaining_emission + .saturating_add(hotkey_take) + .saturating_add(mining_emission), + ) + }); + } + + //. --- 4. Drains the accumulated hotkey emission through to the nominators. The hotkey takes a proportion of the emission. + /// The remainder is drained through to the nominators keeping track of the last stake increase event to ensure that the hotkey does not + /// gain more emission than it's stake since the last drain. + /// hotkeys --> nominators. + /// + /// 1. It resets the accumulated emissions for the hotkey to zero. + /// 4. It calculates the total stake for the hotkey and determines the hotkey's own take from the emissions based on its delegation status. + /// 5. It then calculates the remaining emissions after the hotkey's take and distributes this remaining amount proportionally among the hotkey's nominators. + /// 6. Each nominator's share of the emissions is added to their stake, but only if their stake was not manually increased since the last emission drain. + /// 7. Finally, the hotkey's own take and any undistributed emissions are added to the hotkey's total stake. + /// + /// This function ensures that emissions are fairly distributed according to stake proportions and delegation agreements, and it updates the necessary records to reflect these changes. + pub fn drain_hotkey_emission(hotkey: &T::AccountId, emission: u64, block_number: u64) -> u64 { + // --- 0. For accounting purposes record the total new added stake. + let mut total_new_tao: u64 = 0; + + // --- 1.0 Drain the hotkey emission. + PendingdHotkeyEmission::::insert(hotkey, 0); + + // --- 2 Retrieve the last time this hotkey's emissions were drained. + let last_hotkey_emission_drain: u64 = LastHotkeyEmissionDrain::::get(hotkey); + + // --- 3 Update the block value to the current block number. + LastHotkeyEmissionDrain::::insert(hotkey, block_number); + + // --- 4 Retrieve the total stake for the hotkey from all nominations. + let total_hotkey_stake: u64 = Self::get_total_stake_for_hotkey(hotkey); + + // --- 5 Calculate the emission take for the hotkey. + let take_proportion: I64F64 = + I64F64::from_num(Delegates::::get(hotkey)).saturating_div(I64F64::from_num(u16::MAX)); + let hotkey_take: u64 = + (take_proportion.saturating_mul(I64F64::from_num(emission))).to_num::(); + + // --- 6 Compute the remaining emission after deducting the hotkey's take. + let emission_minus_take: u64 = emission.saturating_sub(hotkey_take); + + // --- 7 Calculate the remaining emission after the hotkey's take. + let mut remainder: u64 = emission_minus_take; + + // --- 8 Iterate over each nominator. + for (nominator, nominator_stake) in + as IterableStorageDoubleMap>::iter_prefix(hotkey) + { + // --- 9 Check if the stake was manually increased by the user since the last emission drain for this hotkey. + // If it was, skip this nominator as they will not receive their proportion of the emission. + if LastAddStakeIncrease::::get(hotkey, nominator.clone()) > last_hotkey_emission_drain { + continue; + } + + // --- 10 Calculate this nominator's share of the emission. + let nominator_emission: I64F64 = I64F64::from_num(emission_minus_take) + .saturating_mul(I64F64::from_num(nominator_stake)) + .saturating_div(I64F64::from_num(total_hotkey_stake)); + + // --- 11 Increase the stake for the nominator. + Self::increase_stake_on_coldkey_hotkey_account( + &nominator, + hotkey, + nominator_emission.to_num::(), + ); + + // --- 11* Record event and Subtract the nominator's emission from the remainder. + total_new_tao = total_new_tao.saturating_add(nominator_emission.to_num::()); + remainder = remainder.saturating_sub(nominator_emission.to_num::()); + } + + // --- 13 Finally, add the stake to the hotkey itself, including its take and the remaining emission. + let hotkey_new_tao: u64 = hotkey_take.saturating_add(remainder); + Self::increase_stake_on_hotkey_account(hotkey, hotkey_new_tao); + + // --- 14 Record new tao creation event and return the amount created. + total_new_tao = total_new_tao.saturating_add(hotkey_new_tao); + total_new_tao + } + + /////////////// + /// Helpers /// + /////////////// + /// Determines whether the hotkey emission should be drained based on the current block and index. + /// + /// # Arguments + /// * `hotkey_i` - The hotkey identifier. + /// * `index` - The index of the hotkey in the iterable storage. + /// * `block` - The current block number. + /// + /// # Returns + /// * `bool` - True if the hotkey emission should be drained, false otherwise. + pub fn should_drain_hotkey(hotkey: &T::AccountId, block: u64, emit_tempo: u64) -> bool { + let hotkey_idx: u64 = Self::hash_hotkey_to_u64(hotkey); + block.rem_euclid(emit_tempo.saturating_add(1)) + == hotkey_idx.rem_euclid(emit_tempo.saturating_add(1)) + } + + /// Checks if the epoch should run for a given subnet based on the current block. + /// + /// # Arguments + /// * `netuid` - The unique identifier of the subnet. + /// + /// # Returns + /// * `bool` - True if the epoch should run, false otherwise. + pub fn should_run_epoch(netuid: u16, current_block: u64) -> bool { + Self::blocks_until_next_epoch(netuid, Self::get_tempo(netuid), current_block) == 0 + } + + /// Helper function which returns the number of blocks remaining before we will run the epoch on this + /// network. Networks run their epoch when (block_number + netuid + 1 ) % (tempo + 1) = 0 + /// tempo | netuid | # first epoch block + /// 1 0 0 + /// 1 1 1 + /// 2 0 1 + /// 2 1 0 + /// 100 0 99 + /// 100 1 98 + /// Special case: tempo = 0, the network never runs. + /// + pub fn blocks_until_next_epoch(netuid: u16, tempo: u16, block_number: u64) -> u64 { + if tempo == 0 { + return u64::MAX; + } + (tempo as u64).saturating_sub( + (block_number.saturating_add((netuid as u64).saturating_add(1))) + % (tempo as u64).saturating_add(1), + ) + } +} \ No newline at end of file diff --git a/pallets/subtensor/src/epoch/run_epoch.rs b/pallets/subtensor/src/epoch/run_epoch.rs index d67eeded0..1cb2c3448 100644 --- a/pallets/subtensor/src/epoch/run_epoch.rs +++ b/pallets/subtensor/src/epoch/run_epoch.rs @@ -5,6 +5,89 @@ use sp_std::vec; use substrate_fixed::types::{I32F32, I64F64, I96F32}; impl Pallet { + /// Calculates the total stake held by a hotkey on the network, considering child/parent relationships. + /// + /// This function performs the following steps: + /// 1. Checks for self-loops in the delegation graph. + /// 2. Retrieves the initial stake of the hotkey. + /// 3. Calculates the stake allocated to children. + /// 4. Calculates the stake received from parents. + /// 5. Computes the final stake by adjusting the initial stake with child and parent contributions. + /// + /// # Arguments + /// * `hotkey` - AccountId of the hotkey whose total network stake is to be calculated. + /// * `netuid` - Network unique identifier specifying the network context. + /// + /// # Returns + /// * `u64` - The total stake for the hotkey on the network after considering the stakes + /// from children and parents. + /// + /// # Note + /// This function now includes a check for self-loops in the delegation graph using the + /// `dfs_check_self_loops` method. However, it currently only logs warnings for detected loops + /// and does not alter the stake calculation based on these findings. + /// + /// # Panics + /// This function does not explicitly panic, but underlying arithmetic operations + /// use saturating arithmetic to prevent overflows. + /// + /// TODO: check for self loops. + /// TODO: (@distributedstatemachine): check if we should return error , otherwise self loop + /// detection is impossible to test. + pub fn get_stake_for_hotkey_on_subnet(hotkey: &T::AccountId, netuid: u16) -> u64 { + // Retrieve the initial total stake for the hotkey without any child/parent adjustments. + let initial_stake: u64 = Self::get_total_stake_for_hotkey(hotkey); + let mut stake_to_children: u64 = 0; + let mut stake_from_parents: u64 = 0; + + // Retrieve lists of parents and children from storage, based on the hotkey and network ID. + let parents: Vec<(u64, T::AccountId)> = Self::get_parents(hotkey, netuid); + let children: Vec<(u64, T::AccountId)> = Self::get_children(hotkey, netuid); + + // Iterate over children to calculate the total stake allocated to them. + for (proportion, _) in children { + // Calculate the stake proportion allocated to the child based on the initial stake. + let normalized_proportion: I96F32 = + I96F32::from_num(proportion).saturating_div(I96F32::from_num(u64::MAX)); + let stake_proportion_to_child: I96F32 = + I96F32::from_num(initial_stake).saturating_mul(normalized_proportion); + + // Accumulate the total stake given to children. + stake_to_children = + stake_to_children.saturating_add(stake_proportion_to_child.to_num::()); + } + + // Iterate over parents to calculate the total stake received from them. + for (proportion, parent) in parents { + // Retrieve the parent's total stake. + let parent_stake: u64 = Self::get_total_stake_for_hotkey(&parent); + // Calculate the stake proportion received from the parent. + let normalized_proportion: I96F32 = + I96F32::from_num(proportion).saturating_div(I96F32::from_num(u64::MAX)); + let stake_proportion_from_parent: I96F32 = + I96F32::from_num(parent_stake).saturating_mul(normalized_proportion); + + // Accumulate the total stake received from parents. + stake_from_parents = + stake_from_parents.saturating_add(stake_proportion_from_parent.to_num::()); + } + + // Calculate the final stake for the hotkey by adjusting the initial stake with the stakes + // to/from children and parents. + let mut finalized_stake: u64 = initial_stake + .saturating_sub(stake_to_children) + .saturating_add(stake_from_parents); + + // get the max stake for the network + let max_stake = Self::get_network_max_stake(netuid); + + // Return the finalized stake value for the hotkey, but capped at the max stake. + finalized_stake = finalized_stake.min(max_stake); + + // Return the finalized stake value for the hotkey. + finalized_stake + } + /// Calculates reward consensus and returns the emissions for uids/hotkeys in a given `netuid`. /// (Dense version used only for testing purposes.) #[allow(clippy::indexing_slicing)] @@ -67,7 +150,8 @@ impl Pallet { // Access network stake as normalized vector. let mut stake_64: Vec = vec![I64F64::from_num(0.0); n as usize]; for (uid_i, hotkey) in &hotkeys { - stake_64[*uid_i as usize] = I64F64::from_num(Self::get_total_stake_for_hotkey(hotkey)); + stake_64[*uid_i as usize] = + I64F64::from_num(Self::get_stake_for_hotkey_on_subnet(hotkey, netuid)); } inplace_normalize_64(&mut stake_64); let stake: Vec = vec_fixed64_to_fixed32(stake_64); @@ -265,6 +349,10 @@ impl Pallet { // == Value storage == // =================== let cloned_emission: Vec = combined_emission.clone(); + let cloned_stake_weight: Vec = stake + .iter() + .map(|xi| fixed_proportion_to_u16(*xi)) + .collect::>(); let cloned_ranks: Vec = ranks .iter() .map(|xi| fixed_proportion_to_u16(*xi)) @@ -290,6 +378,7 @@ impl Pallet { .iter() .map(|xi| fixed_proportion_to_u16(*xi)) .collect::>(); + StakeWeight::::insert(netuid, cloned_stake_weight.clone()); Active::::insert(netuid, active.clone()); Emission::::insert(netuid, cloned_emission); Rank::::insert(netuid, cloned_ranks); @@ -395,7 +484,8 @@ impl Pallet { // Access network stake as normalized vector. let mut stake_64: Vec = vec![I64F64::from_num(0.0); n as usize]; for (uid_i, hotkey) in &hotkeys { - stake_64[*uid_i as usize] = I64F64::from_num(Self::get_total_stake_for_hotkey(hotkey)); + stake_64[*uid_i as usize] = + I64F64::from_num(Self::get_stake_for_hotkey_on_subnet(hotkey, netuid)); } log::trace!("Stake : {:?}", &stake_64); inplace_normalize_64(&mut stake_64); @@ -631,6 +721,10 @@ impl Pallet { // =================== // == Value storage == // =================== + let cloned_stake_weight: Vec = stake + .iter() + .map(|xi| fixed_proportion_to_u16(*xi)) + .collect::>(); let cloned_emission: Vec = combined_emission.clone(); let cloned_ranks: Vec = ranks .iter() @@ -657,6 +751,7 @@ impl Pallet { .iter() .map(|xi| fixed_proportion_to_u16(*xi)) .collect::>(); + StakeWeight::::insert(netuid, cloned_stake_weight.clone()); Active::::insert(netuid, active.clone()); Emission::::insert(netuid, cloned_emission); Rank::::insert(netuid, cloned_ranks); diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index c28da051d..8d2b5c4fd 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -930,6 +930,9 @@ pub mod pallet { /// ======================================= /// ==== Subnetwork Consensus Storage ==== /// ======================================= + #[pallet::storage] // --- DMAP ( netuid ) --> stake_weight | weight for stake used in YC. + pub(super) type StakeWeight = + StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; #[pallet::storage] /// --- DMAP ( netuid, hotkey ) --> uid pub type Uids = diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 228bec6e4..d8cb31166 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -842,5 +842,64 @@ mod dispatches { ) -> DispatchResult { Ok(()) } + + /// Set a single child for a given hotkey on a specified network. + /// + /// This function allows a coldkey to set a single child for a given hotkey on a specified network. + /// The proportion of the hotkey's stake to be allocated to the child is also specified. + /// + /// # Arguments: + /// * `origin` (::RuntimeOrigin): + /// - The signature of the calling coldkey. Setting a hotkey child can only be done by the coldkey. + /// + /// * `hotkey` (T::AccountId): + /// - The hotkey which will be assigned the child. + /// + /// * `child` (T::AccountId): + /// - The child which will be assigned to the hotkey. + /// + /// * `netuid` (u16): + /// - The u16 network identifier where the childkey will exist. + /// + /// * `proportion` (u64): + /// - Proportion of the hotkey's stake to be given to the child, the value must be u64 normalized. + /// + /// # Events: + /// * `ChildAddedSingular`: + /// - On successfully registering a child to a hotkey. + /// + /// # Errors: + /// * `SubNetworkDoesNotExist`: + /// - Attempting to register to a non-existent network. + /// * `RegistrationNotPermittedOnRootSubnet`: + /// - Attempting to register a child on the root network. + /// * `NonAssociatedColdKey`: + /// - The coldkey does not own the hotkey or the child is the same as the hotkey. + /// * `HotKeyAccountNotExists`: + /// - The hotkey account does not exist. + /// + /// # Detailed Explanation of Checks: + /// 1. **Signature Verification**: Ensures that the caller has signed the transaction, verifying the coldkey. + /// 2. **Root Network Check**: Ensures that the delegation is not on the root network, as child hotkeys are not valid on the root. + /// 3. **Network Existence Check**: Ensures that the specified network exists. + /// 4. **Ownership Verification**: Ensures that the coldkey owns the hotkey. + /// 5. **Hotkey Account Existence Check**: Ensures that the hotkey account already exists. + /// 6. **Child-Hotkey Distinction**: Ensures that the child is not the same as the hotkey. + /// 7. **Old Children Cleanup**: Removes the hotkey from the parent list of its old children. + /// 8. **New Children Assignment**: Assigns the new child to the hotkey and updates the parent list for the new child. + // TODO: Benchmark this call + #[pallet::call_index(67)] + #[pallet::weight((Weight::from_parts(119_000_000, 0) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(31)), DispatchClass::Operational, Pays::Yes))] + pub fn set_children( + origin: T::RuntimeOrigin, + hotkey: T::AccountId, + netuid: u16, + children: Vec<(u64, T::AccountId)>, + ) -> DispatchResultWithPostInfo { + Self::do_set_children(origin, hotkey, netuid, children)?; + Ok(().into()) + } } } diff --git a/pallets/subtensor/src/macros/errors.rs b/pallets/subtensor/src/macros/errors.rs index f26a1cd55..7e244834d 100644 --- a/pallets/subtensor/src/macros/errors.rs +++ b/pallets/subtensor/src/macros/errors.rs @@ -158,5 +158,13 @@ mod errors { InsufficientBalanceToPerformColdkeySwap, /// The maximum number of coldkey destinations has been reached MaxColdkeyDestinationsReached, + /// Attempting to set an invalid child for a hotkey on a network. + InvalidChild, + /// Duplicate child when setting children. + DuplicateChild, + /// Proportion overflow when setting children. + ProportionOverflow, + /// Too many children MAX 5. + TooManyChildren, } } diff --git a/pallets/subtensor/src/macros/events.rs b/pallets/subtensor/src/macros/events.rs index a5fb90e3f..e3e47f32e 100644 --- a/pallets/subtensor/src/macros/events.rs +++ b/pallets/subtensor/src/macros/events.rs @@ -171,5 +171,6 @@ mod events { /// The account ID of the coldkey coldkey: T::AccountId, }, + SetChildren(T::AccountId, u16, Vec<(u64, T::AccountId)>), } } diff --git a/pallets/subtensor/src/rpc_info/neuron_info.rs b/pallets/subtensor/src/rpc_info/neuron_info.rs index a4b58d666..6b370afd8 100644 --- a/pallets/subtensor/src/rpc_info/neuron_info.rs +++ b/pallets/subtensor/src/rpc_info/neuron_info.rs @@ -117,14 +117,10 @@ impl Pallet { } }) .collect::, Compact)>>(); - - let stake: Vec<(T::AccountId, Compact)> = - as IterableStorageDoubleMap>::iter_prefix( - hotkey.clone(), - ) - .map(|(coldkey, stake)| (coldkey, stake.into())) - .collect(); - + let stake: Vec<(T::AccountId, Compact)> = vec![( + coldkey, + Self::get_stake_for_hotkey_on_subnet(hotkey, netuid).into(), + )]; let neuron = NeuronInfo { hotkey: hotkey.clone(), coldkey: coldkey.clone(), diff --git a/pallets/subtensor/src/staking/mod.rs b/pallets/subtensor/src/staking/mod.rs index 5e1b5f6bf..0b3894b61 100644 --- a/pallets/subtensor/src/staking/mod.rs +++ b/pallets/subtensor/src/staking/mod.rs @@ -5,3 +5,4 @@ pub mod decrease_take; pub mod helpers; pub mod increase_take; pub mod remove_stake; +pub mod set_children; diff --git a/pallets/subtensor/src/staking/set_children.rs b/pallets/subtensor/src/staking/set_children.rs new file mode 100644 index 000000000..79898b6ae --- /dev/null +++ b/pallets/subtensor/src/staking/set_children.rs @@ -0,0 +1,185 @@ +use super::*; +use substrate_fixed::types::I96F32; + +impl Pallet { + /// ---- The implementation for the extrinsic do_set_child_singular: Sets a single child. + /// + /// This function allows a coldkey to set children keys. + /// + /// # Arguments: + /// * `origin` (::RuntimeOrigin): + /// - The signature of the calling coldkey. Setting a hotkey child can only be done by the coldkey. + /// + /// * `hotkey` (T::AccountId): + /// - The hotkey which will be assigned the child. + /// + /// * `netuid` (u16): + /// - The u16 network identifier where the child keys will exist. + /// + /// * `children` Vec[(u64, T::AccountId)]: + /// - A list of children with their proportions. + /// + /// # Events: + /// * `ChildrenAdded`: + /// - On successfully registering children to a hotkey. + /// + /// # Errors: + /// * `SubNetworkDoesNotExist`: + /// - Attempting to register to a non-existent network. + /// * `RegistrationNotPermittedOnRootSubnet`: + /// - Attempting to register a child on the root network. + /// * `NonAssociatedColdKey`: + /// - The coldkey does not own the hotkey or the child is the same as the hotkey. + /// * `HotKeyAccountNotExists`: + /// - The hotkey account does not exist. + /// + /// # Detailed Explanation of Checks: + /// 1. **Signature Verification**: Ensures that the caller has signed the transaction, verifying the coldkey. + /// 2. **Root Network Check**: Ensures that the delegation is not on the root network, as child hotkeys are not valid on the root. + /// 3. **Network Existence Check**: Ensures that the specified network exists. + /// 4. **Ownership Verification**: Ensures that the coldkey owns the hotkey. + /// 5. **Hotkey Account Existence Check**: Ensures that the hotkey account already exists. + /// 6. **Child-Hotkey Distinction**: Ensures that the child is not the same as the hotkey. + /// 7. **Old Children Cleanup**: Removes the hotkey from the parent list of its old children. + /// 8. **New Children Assignment**: Assigns the new child to the hotkey and updates the parent list for the new child. + /// + pub fn do_set_children( + origin: T::RuntimeOrigin, + hotkey: T::AccountId, + netuid: u16, + children: Vec<(u64, T::AccountId)>, + ) -> DispatchResult { + // --- 1. Check that the caller has signed the transaction. (the coldkey of the pairing) + let coldkey = ensure_signed(origin)?; + log::trace!( + "do_set_children( coldkey:{:?} hotkey:{:?} netuid:{:?} children:{:?} )", + coldkey, + netuid, + hotkey, + children + ); + + // --- 2. Check that this delegation is not on the root network. Child hotkeys are not valid on root. + ensure!( + netuid != Self::get_root_netuid(), + Error::::RegistrationNotPermittedOnRootSubnet + ); + + // --- 3. Check that the network we are trying to create the child on exists. + ensure!( + Self::if_subnet_exist(netuid), + Error::::SubNetworkDoesNotExist + ); + + // --- 4. Check that the coldkey owns the hotkey. + ensure!( + Self::coldkey_owns_hotkey(&coldkey, &hotkey), + Error::::NonAssociatedColdKey + ); + + // --- 4.1. Ensure that the number of children does not exceed 5. + ensure!(children.len() <= 5, Error::::TooManyChildren); + + // --- 5. Ensure that each child is not the hotkey. + for (_, child_i) in &children { + ensure!(child_i != &hotkey, Error::::InvalidChild); + } + // --- 5.1. Ensure that the sum of the proportions does not exceed u64::MAX. + let _total_proportion: u64 = children + .iter() + .try_fold(0u64, |acc, &(proportion, _)| acc.checked_add(proportion)) + .ok_or(Error::::ProportionOverflow)?; + + // --- 5.2. Ensure there are no duplicates in the list of children. + let mut unique_children = Vec::new(); + for (_, child_i) in &children { + ensure!( + !unique_children.contains(child_i), + Error::::DuplicateChild + ); + unique_children.push(child_i.clone()); + } + + // --- 6. Erase myself from old children's parents. + let old_children: Vec<(u64, T::AccountId)> = ChildKeys::::get(hotkey.clone(), netuid); + + // --- 6.0. Iterate over all my old children and remove myself from their parent's map. + for (_, old_child_i) in old_children.clone().iter() { + // --- 6.1. Get the old child's parents on this network. + let my_old_child_parents: Vec<(u64, T::AccountId)> = + ParentKeys::::get(old_child_i.clone(), netuid); + + // --- 6.2. Filter my hotkey from my old children's parents list. + let filtered_parents: Vec<(u64, T::AccountId)> = my_old_child_parents + .into_iter() + .filter(|(_, parent)| *parent != hotkey) + .collect(); + + // --- 6.3. Update the parent list in storage + ParentKeys::::insert(old_child_i, netuid, filtered_parents); + } + + // --- 7.1. Insert my new children + proportion list into the map. + ChildKeys::::insert(hotkey.clone(), netuid, children.clone()); + + // --- 7.2. Update the parents list for my new children. + for (proportion, new_child_i) in children.clone().iter() { + // --- 8.2.1. Get the child's parents on this network. + let mut new_child_previous_parents: Vec<(u64, T::AccountId)> = + ParentKeys::::get(new_child_i.clone(), netuid); + + // --- 7.2.2. Append my hotkey and proportion to my new child's parents list. + // NOTE: There are no duplicates possible because I previously removed my self from my old children. + new_child_previous_parents.push((*proportion, hotkey.clone())); + + // --- 7.2.3. Update the parents list in storage. + ParentKeys::::insert(new_child_i.clone(), netuid, new_child_previous_parents); + } + + // --- 8. Log and return. + log::trace!( + "SetChildren( netuid:{:?}, hotkey:{:?}, children:{:?} )", + hotkey, + netuid, + children.clone() + ); + Self::deposit_event(Event::SetChildren(hotkey.clone(), netuid, children.clone())); + + // Ok and return. + Ok(()) + } + + /* Retrieves the list of children for a given hotkey and network. + /// + /// # Arguments + /// * `hotkey` - The hotkey whose children are to be retrieved. + /// * `netuid` - The network identifier. + /// + /// # Returns + /// * `Vec<(u64, T::AccountId)>` - A vector of tuples containing the proportion and child account ID. + /// + /// # Example + /// ``` + /// let children = SubtensorModule::get_children(&hotkey, netuid); + */ + pub fn get_children(hotkey: &T::AccountId, netuid: u16) -> Vec<(u64, T::AccountId)> { + ChildKeys::::get(hotkey, netuid) + } + + /* Retrieves the list of parents for a given child and network. + /// + /// # Arguments + /// * `child` - The child whose parents are to be retrieved. + /// * `netuid` - The network identifier. + /// + /// # Returns + /// * `Vec<(u64, T::AccountId)>` - A vector of tuples containing the proportion and parent account ID. + /// + /// # Example + /// ``` + /// let parents = SubtensorModule::get_parents(&child, netuid); + */ + pub fn get_parents(child: &T::AccountId, netuid: u16) -> Vec<(u64, T::AccountId)> { + ParentKeys::::get(child, netuid) + } +} diff --git a/pallets/subtensor/src/subnets/registration.rs b/pallets/subtensor/src/subnets/registration.rs index 4688bcbb5..b46a50eb2 100644 --- a/pallets/subtensor/src/subnets/registration.rs +++ b/pallets/subtensor/src/subnets/registration.rs @@ -543,6 +543,17 @@ impl Pallet { H256::from_slice(&keccak_256_seal_hash_vec) } + pub fn hash_hotkey_to_u64(hotkey: &T::AccountId) -> u64 { + let binding = hotkey.encode(); + let (hotkey_bytes, _) = binding.split_at(32); + let mut full_bytes = [0u8; 64]; + // Copy the hotkey_bytes into the first half of full_bytes + full_bytes[..32].copy_from_slice(hotkey_bytes); + let keccak_256_seal_hash_vec: [u8; 32] = keccak_256(&full_bytes[..]); + let hash_u64: u64 = u64::from_le_bytes(keccak_256_seal_hash_vec[0..8].try_into().unwrap()); + hash_u64 + } + pub fn create_seal_hash(block_number_u64: u64, nonce_u64: u64, hotkey: &T::AccountId) -> H256 { let nonce = nonce_u64.to_le_bytes(); let block_hash_at_number: H256 = Self::get_block_hash_from_u64(block_number_u64); diff --git a/pallets/subtensor/src/utils.rs b/pallets/subtensor/src/utils.rs index c61133e94..a1929f498 100644 --- a/pallets/subtensor/src/utils.rs +++ b/pallets/subtensor/src/utils.rs @@ -695,4 +695,20 @@ impl Pallet { pub fn get_liquid_alpha_enabled(netuid: u16) -> bool { LiquidAlphaOn::::get(netuid) } + + /// Gets the current hotkey emission tempo. + /// + /// # Returns + /// * `u64` - The current emission tempo value. + pub fn get_hotkey_emission_tempo() -> u64 { + HotkeyEmissionTempo::::get() + } + /// Sets the hotkey emission tempo. + /// + /// # Arguments + /// * `emission_tempo` - The new emission tempo value to set. + pub fn set_hotkey_emission_tempo(emission_tempo: u64) { + HotkeyEmissionTempo::::set(emission_tempo); + Self::deposit_event(Event::HotkeyEmissionTempoSet(emission_tempo)); + } } diff --git a/pallets/subtensor/tests/children.rs b/pallets/subtensor/tests/children.rs new file mode 100644 index 000000000..9ad07e1e7 --- /dev/null +++ b/pallets/subtensor/tests/children.rs @@ -0,0 +1,1261 @@ +use crate::mock::*; +use frame_support::{assert_err, assert_ok}; +mod mock; +use pallet_subtensor::*; +use sp_core::U256; + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_set_child_singular_success --exact --nocapture +#[test] +fn test_do_set_child_singular_success() { + new_test_ext(1).execute_with(|| { + let coldkey = U256::from(1); + let hotkey = U256::from(2); + let child = U256::from(3); + let netuid: u16 = 1; + let proportion: u64 = 1000; + + // Add network and register hotkey + add_network(netuid, 13, 0); + register_ok_neuron(netuid, hotkey, coldkey, 0); + + // Set child + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![(proportion, child)] + )); + + // Verify child assignment + let children = SubtensorModule::get_children(&hotkey, netuid); + assert_eq!(children, vec![(proportion, child)]); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_set_child_singular_network_does_not_exist --exact --nocapture +#[test] +fn test_do_set_child_singular_network_does_not_exist() { + new_test_ext(1).execute_with(|| { + let coldkey = U256::from(1); + let hotkey = U256::from(2); + let child = U256::from(3); + let netuid: u16 = 999; // Non-existent network + let proportion: u64 = 1000; + + // Attempt to set child + assert_err!( + SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![(proportion, child)] + ), + Error::::SubNetworkDoesNotExist + ); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_set_child_singular_invalid_child --exact --nocapture +#[test] +fn test_do_set_child_singular_invalid_child() { + new_test_ext(1).execute_with(|| { + let coldkey = U256::from(1); + let hotkey = U256::from(2); + let netuid: u16 = 1; + let proportion: u64 = 1000; + + // Add network and register hotkey + add_network(netuid, 13, 0); + register_ok_neuron(netuid, hotkey, coldkey, 0); + + // Attempt to set child as the same hotkey + assert_err!( + SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![ + (proportion, hotkey) // Invalid child + ] + ), + Error::::InvalidChild + ); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_set_child_singular_non_associated_coldkey --exact --nocapture +#[test] +fn test_do_set_child_singular_non_associated_coldkey() { + new_test_ext(1).execute_with(|| { + let coldkey = U256::from(1); + let hotkey = U256::from(2); + let child = U256::from(3); + let netuid: u16 = 1; + let proportion: u64 = 1000; + + // Add network and register hotkey with a different coldkey + add_network(netuid, 13, 0); + register_ok_neuron(netuid, hotkey, U256::from(999), 0); + + // Attempt to set child + assert_err!( + SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![(proportion, child)] + ), + Error::::NonAssociatedColdKey + ); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_set_child_singular_root_network --exact --nocapture +#[test] +fn test_do_set_child_singular_root_network() { + new_test_ext(1).execute_with(|| { + let coldkey = U256::from(1); + let hotkey = U256::from(2); + let child = U256::from(3); + let netuid: u16 = SubtensorModule::get_root_netuid(); // Root network + let proportion: u64 = 1000; + + // Add network and register hotkey + add_network(netuid, 13, 0); + + // Attempt to set child + assert_err!( + SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![(proportion, child)] + ), + Error::::RegistrationNotPermittedOnRootSubnet + ); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_set_child_singular_old_children_cleanup --exact --nocapture +#[test] +fn test_do_set_child_singular_old_children_cleanup() { + new_test_ext(1).execute_with(|| { + let coldkey = U256::from(1); + let hotkey = U256::from(2); + let old_child = U256::from(3); + let new_child = U256::from(4); + let netuid: u16 = 1; + let proportion: u64 = 1000; + + // Add network and register hotkey + add_network(netuid, 13, 0); + register_ok_neuron(netuid, hotkey, coldkey, 0); + + // Set old child + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![(proportion, old_child)] + )); + + // Set new child + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![(proportion, new_child)] + )); + + // Verify old child is removed + let old_child_parents = SubtensorModule::get_parents(&old_child, netuid); + assert!(old_child_parents.is_empty()); + + // Verify new child assignment + let new_child_parents = SubtensorModule::get_parents(&new_child, netuid); + assert_eq!(new_child_parents, vec![(proportion, hotkey)]); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_set_child_singular_old_children_cleanup --exact --nocapture +#[test] +fn test_do_set_child_singular_new_children_assignment() { + new_test_ext(1).execute_with(|| { + let coldkey = U256::from(1); + let hotkey = U256::from(2); + let child = U256::from(3); + let netuid: u16 = 1; + let proportion: u64 = 1000; + + // Add network and register hotkey + add_network(netuid, 13, 0); + register_ok_neuron(netuid, hotkey, coldkey, 0); + + // Set child + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![(proportion, child)] + )); + + // Verify child assignment + let children = SubtensorModule::get_children(&hotkey, netuid); + assert_eq!(children, vec![(proportion, child)]); + + // Verify parent assignment + let parents = SubtensorModule::get_parents(&child, netuid); + assert_eq!(parents, vec![(proportion, hotkey)]); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_set_child_singular_proportion_edge_cases --exact --nocapture +#[test] +fn test_do_set_child_singular_proportion_edge_cases() { + new_test_ext(1).execute_with(|| { + let coldkey = U256::from(1); + let hotkey = U256::from(2); + let child = U256::from(3); + let netuid: u16 = 1; + + // Add network and register hotkey + add_network(netuid, 13, 0); + register_ok_neuron(netuid, hotkey, coldkey, 0); + + // Set child with minimum proportion + let min_proportion: u64 = 0; + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![(min_proportion, child)] + )); + + // Verify child assignment with minimum proportion + let children = SubtensorModule::get_children(&hotkey, netuid); + assert_eq!(children, vec![(min_proportion, child)]); + + // Set child with maximum proportion + let max_proportion: u64 = u64::MAX; + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![(max_proportion, child)] + )); + + // Verify child assignment with maximum proportion + let children = SubtensorModule::get_children(&hotkey, netuid); + assert_eq!(children, vec![(max_proportion, child)]); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_set_child_singular_multiple_children --exact --nocapture +#[test] +fn test_do_set_child_singular_multiple_children() { + new_test_ext(1).execute_with(|| { + let coldkey = U256::from(1); + let hotkey = U256::from(2); + let child1 = U256::from(3); + let child2 = U256::from(4); + let netuid: u16 = 1; + let proportion1: u64 = 500; + let proportion2: u64 = 500; + + // Add network and register hotkey + add_network(netuid, 13, 0); + register_ok_neuron(netuid, hotkey, coldkey, 0); + + // Set first child + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![(proportion1, child1)] + )); + + // Set second child + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![(proportion2, child2)] + )); + + // Verify children assignment + let children = SubtensorModule::get_children(&hotkey, netuid); + assert_eq!(children, vec![(proportion2, child2)]); + + // Verify parent assignment for both children + let parents1 = SubtensorModule::get_parents(&child1, netuid); + assert!(parents1.is_empty()); // Old child should be removed + + let parents2 = SubtensorModule::get_parents(&child2, netuid); + assert_eq!(parents2, vec![(proportion2, hotkey)]); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_add_singular_child --exact --nocapture +#[test] +#[cfg(not(tarpaulin))] +fn test_add_singular_child() { + new_test_ext(1).execute_with(|| { + let netuid: u16 = 1; + let child = U256::from(1); + let hotkey = U256::from(1); + let coldkey = U256::from(2); + assert_eq!( + SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![(u64::MAX, child)] + ), + Err(Error::::SubNetworkDoesNotExist.into()) + ); + add_network(netuid, 0, 0); + assert_eq!( + SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![(u64::MAX, child)] + ), + Err(Error::::NonAssociatedColdKey.into()) + ); + SubtensorModule::create_account_if_non_existent(&coldkey, &hotkey); + assert_eq!( + SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![(u64::MAX, child)] + ), + Err(Error::::InvalidChild.into()) + ); + let child = U256::from(3); + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![(u64::MAX, child)] + )); + }) +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_get_stake_for_hotkey_on_subnet --exact --nocapture +#[test] +fn test_get_stake_for_hotkey_on_subnet() { + new_test_ext(1).execute_with(|| { + let netuid: u16 = 1; + let hotkey0 = U256::from(1); + let hotkey1 = U256::from(2); + let coldkey0 = U256::from(3); + let coldkey1 = U256::from(4); + + add_network(netuid, 0, 0); + + let max_stake: u64 = 3000; + SubtensorModule::set_network_max_stake(netuid, max_stake); + + SubtensorModule::create_account_if_non_existent(&coldkey0, &hotkey0); + SubtensorModule::create_account_if_non_existent(&coldkey1, &hotkey1); + + SubtensorModule::increase_stake_on_coldkey_hotkey_account(&coldkey0, &hotkey0, 1000); + SubtensorModule::increase_stake_on_coldkey_hotkey_account(&coldkey0, &hotkey1, 1000); + SubtensorModule::increase_stake_on_coldkey_hotkey_account(&coldkey1, &hotkey0, 1000); + SubtensorModule::increase_stake_on_coldkey_hotkey_account(&coldkey1, &hotkey1, 1000); + + assert_eq!(SubtensorModule::get_total_stake_for_hotkey(&hotkey0), 2000); + assert_eq!(SubtensorModule::get_total_stake_for_hotkey(&hotkey1), 2000); + + assert_eq!( + SubtensorModule::get_stake_for_hotkey_on_subnet(&hotkey0, netuid), + 2000 + ); + assert_eq!( + SubtensorModule::get_stake_for_hotkey_on_subnet(&hotkey1, netuid), + 2000 + ); + + // Set child relationship + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey0), + hotkey0, + netuid, + vec![(u64::MAX, hotkey1)] + )); + + // Check stakes after setting child + let stake0 = SubtensorModule::get_stake_for_hotkey_on_subnet(&hotkey0, netuid); + let stake1 = SubtensorModule::get_stake_for_hotkey_on_subnet(&hotkey1, netuid); + + assert_eq!(stake0, 0); + assert_eq!(stake1, max_stake); + + // Change child relationship to 50% + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey0), + hotkey0, + netuid, + vec![(u64::MAX / 2, hotkey1)] + )); + + // Check stakes after changing child relationship + let stake0 = SubtensorModule::get_stake_for_hotkey_on_subnet(&hotkey0, netuid); + let stake1 = SubtensorModule::get_stake_for_hotkey_on_subnet(&hotkey1, netuid); + + assert_eq!(stake0, 1001); + assert!(stake1 >= max_stake - 1 && stake1 <= max_stake); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_revoke_child_singular_success --exact --nocapture +#[test] +fn test_do_revoke_child_singular_success() { + new_test_ext(1).execute_with(|| { + let coldkey = U256::from(1); + let hotkey = U256::from(2); + let child = U256::from(3); + let netuid: u16 = 1; + let proportion: u64 = 1000; + + // Add network and register hotkey + add_network(netuid, 13, 0); + register_ok_neuron(netuid, hotkey, coldkey, 0); + + // Set child + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![(proportion, child)] + )); + + // Verify child assignment + let children = SubtensorModule::get_children(&hotkey, netuid); + assert_eq!(children, vec![(proportion, child)]); + + // Revoke child + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![] + )); + + // Verify child removal + let children = SubtensorModule::get_children(&hotkey, netuid); + assert!(children.is_empty()); + + // Verify parent removal + let parents = SubtensorModule::get_parents(&child, netuid); + assert!(parents.is_empty()); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_revoke_child_singular_network_does_not_exist --exact --nocapture +#[test] +fn test_do_revoke_child_singular_network_does_not_exist() { + new_test_ext(1).execute_with(|| { + let coldkey = U256::from(1); + let hotkey = U256::from(2); + let netuid: u16 = 999; // Non-existent network + + // Attempt to revoke child + assert_err!( + SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![] + ), + Error::::SubNetworkDoesNotExist + ); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_revoke_child_singular_non_associated_coldkey --exact --nocapture +#[test] +fn test_do_revoke_child_singular_non_associated_coldkey() { + new_test_ext(1).execute_with(|| { + let coldkey = U256::from(1); + let hotkey = U256::from(2); + let netuid: u16 = 1; + + // Add network and register hotkey with a different coldkey + add_network(netuid, 13, 0); + register_ok_neuron(netuid, hotkey, U256::from(999), 0); + + // Attempt to revoke child + assert_err!( + SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![] + ), + Error::::NonAssociatedColdKey + ); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_revoke_child_singular_child_not_associated --exact --nocapture +#[test] +fn test_do_revoke_child_singular_child_not_associated() { + new_test_ext(1).execute_with(|| { + let coldkey = U256::from(1); + let hotkey = U256::from(2); + let child = U256::from(3); + let netuid: u16 = 1; + + // Add network and register hotkey + add_network(netuid, 13, 0); + // Attempt to revoke child that is not associated + assert_err!( + SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![(u64::MAX, child)] + ), + Error::::NonAssociatedColdKey + ); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_set_children_multiple_success --exact --nocapture +#[test] +fn test_do_set_children_multiple_success() { + new_test_ext(1).execute_with(|| { + let coldkey = U256::from(1); + let hotkey = U256::from(2); + let child1 = U256::from(3); + let child2 = U256::from(4); + let netuid: u16 = 1; + let proportion1: u64 = 1000; + let proportion2: u64 = 2000; + + // Add network and register hotkey + add_network(netuid, 13, 0); + register_ok_neuron(netuid, hotkey, coldkey, 0); + + // Set multiple children + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![(proportion1, child1), (proportion2, child2)] + )); + + // Verify children assignment + let children = SubtensorModule::get_children(&hotkey, netuid); + assert_eq!(children, vec![(proportion1, child1), (proportion2, child2)]); + + // Verify parent assignment for both children + let parents1 = SubtensorModule::get_parents(&child1, netuid); + assert_eq!(parents1, vec![(proportion1, hotkey)]); + + let parents2 = SubtensorModule::get_parents(&child2, netuid); + assert_eq!(parents2, vec![(proportion2, hotkey)]); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_set_children_multiple_network_does_not_exist --exact --nocapture +#[test] +fn test_do_set_children_multiple_network_does_not_exist() { + new_test_ext(1).execute_with(|| { + let coldkey = U256::from(1); + let hotkey = U256::from(2); + let child1 = U256::from(3); + let netuid: u16 = 999; // Non-existent network + let proportion: u64 = 1000; + + // Attempt to set children + assert_err!( + SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![(proportion, child1)] + ), + Error::::SubNetworkDoesNotExist + ); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_set_children_multiple_invalid_child --exact --nocapture +#[test] +fn test_do_set_children_multiple_invalid_child() { + new_test_ext(1).execute_with(|| { + let coldkey = U256::from(1); + let hotkey = U256::from(2); + let netuid: u16 = 1; + let proportion: u64 = 1000; + + // Add network and register hotkey + add_network(netuid, 13, 0); + register_ok_neuron(netuid, hotkey, coldkey, 0); + + // Attempt to set child as the same hotkey + assert_err!( + SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![(proportion, hotkey)] + ), + Error::::InvalidChild + ); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_set_children_multiple_non_associated_coldkey --exact --nocapture +#[test] +fn test_do_set_children_multiple_non_associated_coldkey() { + new_test_ext(1).execute_with(|| { + let coldkey = U256::from(1); + let hotkey = U256::from(2); + let child = U256::from(3); + let netuid: u16 = 1; + let proportion: u64 = 1000; + + // Add network and register hotkey with a different coldkey + add_network(netuid, 13, 0); + register_ok_neuron(netuid, hotkey, U256::from(999), 0); + + // Attempt to set children + assert_err!( + SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![(proportion, child)] + ), + Error::::NonAssociatedColdKey + ); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_set_children_multiple_root_network --exact --nocapture +#[test] +fn test_do_set_children_multiple_root_network() { + new_test_ext(1).execute_with(|| { + let coldkey = U256::from(1); + let hotkey = U256::from(2); + let child = U256::from(3); + let netuid: u16 = SubtensorModule::get_root_netuid(); // Root network + let proportion: u64 = 1000; + + // Add network and register hotkey + add_network(netuid, 13, 0); + + // Attempt to set children + assert_err!( + SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![(proportion, child)] + ), + Error::::RegistrationNotPermittedOnRootSubnet + ); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_set_children_multiple_old_children_cleanup --exact --nocapture +#[test] +fn test_do_set_children_multiple_old_children_cleanup() { + new_test_ext(1).execute_with(|| { + let coldkey = U256::from(1); + let hotkey = U256::from(2); + let old_child = U256::from(3); + let new_child1 = U256::from(4); + let new_child2 = U256::from(5); + let netuid: u16 = 1; + let proportion: u64 = 1000; + + // Add network and register hotkey + add_network(netuid, 13, 0); + register_ok_neuron(netuid, hotkey, coldkey, 0); + + // Set old child + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![(proportion, old_child)] + )); + + // Set new children + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![(proportion, new_child1), (proportion, new_child2)] + )); + + // Verify old child is removed + let old_child_parents = SubtensorModule::get_parents(&old_child, netuid); + assert!(old_child_parents.is_empty()); + + // Verify new children assignment + let new_child1_parents = SubtensorModule::get_parents(&new_child1, netuid); + assert_eq!(new_child1_parents, vec![(proportion, hotkey)]); + + let new_child2_parents = SubtensorModule::get_parents(&new_child2, netuid); + assert_eq!(new_child2_parents, vec![(proportion, hotkey)]); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_set_children_multiple_proportion_edge_cases --exact --nocapture +#[test] +fn test_do_set_children_multiple_proportion_edge_cases() { + new_test_ext(1).execute_with(|| { + let coldkey = U256::from(1); + let hotkey = U256::from(2); + let child1 = U256::from(3); + let child2 = U256::from(4); + let netuid: u16 = 1; + + // Add network and register hotkey + add_network(netuid, 13, 0); + register_ok_neuron(netuid, hotkey, coldkey, 0); + + // Set children with minimum and maximum proportions + let min_proportion: u64 = 0; + let max_proportion: u64 = u64::MAX; + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![(min_proportion, child1), (max_proportion, child2)] + )); + + // Verify children assignment + let children = SubtensorModule::get_children(&hotkey, netuid); + assert_eq!( + children, + vec![(min_proportion, child1), (max_proportion, child2)] + ); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_set_children_multiple_overwrite_existing --exact --nocapture +#[test] +fn test_do_set_children_multiple_overwrite_existing() { + new_test_ext(1).execute_with(|| { + let coldkey = U256::from(1); + let hotkey = U256::from(2); + let child1 = U256::from(3); + let child2 = U256::from(4); + let child3 = U256::from(5); + let netuid: u16 = 1; + let proportion: u64 = 1000; + + // Add network and register hotkey + add_network(netuid, 13, 0); + register_ok_neuron(netuid, hotkey, coldkey, 0); + + // Set initial children + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![(proportion, child1), (proportion, child2)] + )); + + // Overwrite with new children + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![(proportion * 2, child2), (proportion * 3, child3)] + )); + + // Verify final children assignment + let children = SubtensorModule::get_children(&hotkey, netuid); + assert_eq!( + children, + vec![(proportion * 2, child2), (proportion * 3, child3)] + ); + + // Verify parent assignment for all children + let parents1 = SubtensorModule::get_parents(&child1, netuid); + assert!(parents1.is_empty()); + + let parents2 = SubtensorModule::get_parents(&child2, netuid); + assert_eq!(parents2, vec![(proportion * 2, hotkey)]); + + let parents3 = SubtensorModule::get_parents(&child3, netuid); + assert_eq!(parents3, vec![(proportion * 3, hotkey)]); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_set_children_multiple_empty_list --exact --nocapture +#[test] +fn test_do_set_children_multiple_empty_list() { + new_test_ext(1).execute_with(|| { + let coldkey = U256::from(1); + let hotkey = U256::from(2); + let netuid: u16 = 1; + + // Add network and register hotkey + add_network(netuid, 13, 0); + register_ok_neuron(netuid, hotkey, coldkey, 0); + + // Set empty children list + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![] + )); + + // Verify children assignment is empty + let children = SubtensorModule::get_children(&hotkey, netuid); + assert!(children.is_empty()); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_revoke_children_multiple_success --exact --nocapture +#[test] +fn test_do_revoke_children_multiple_success() { + new_test_ext(1).execute_with(|| { + let coldkey = U256::from(1); + let hotkey = U256::from(2); + let child1 = U256::from(3); + let child2 = U256::from(4); + let netuid: u16 = 1; + let proportion1: u64 = 1000; + let proportion2: u64 = 2000; + + // Add network and register hotkey + add_network(netuid, 13, 0); + register_ok_neuron(netuid, hotkey, coldkey, 0); + + // Set multiple children + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![(proportion1, child1), (proportion2, child2)] + )); + + // Revoke multiple children + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![] + )); + + // Verify children removal + let children = SubtensorModule::get_children(&hotkey, netuid); + assert!(children.is_empty()); + + // Verify parent removal for both children + let parents1 = SubtensorModule::get_parents(&child1, netuid); + assert!(parents1.is_empty()); + + let parents2 = SubtensorModule::get_parents(&child2, netuid); + assert!(parents2.is_empty()); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_revoke_children_multiple_network_does_not_exist --exact --nocapture +#[test] +fn test_do_revoke_children_multiple_network_does_not_exist() { + new_test_ext(1).execute_with(|| { + let coldkey = U256::from(1); + let hotkey = U256::from(2); + let child1 = U256::from(3); + let child2 = U256::from(4); + let netuid: u16 = 999; // Non-existent network + // Attempt to revoke children + assert_err!( + SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![(u64::MAX / 2, child1), (u64::MAX / 2, child2)] + ), + Error::::SubNetworkDoesNotExist + ); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_revoke_children_multiple_non_associated_coldkey --exact --nocapture +#[test] +fn test_do_revoke_children_multiple_non_associated_coldkey() { + new_test_ext(1).execute_with(|| { + let coldkey = U256::from(1); + let hotkey = U256::from(2); + let child1 = U256::from(3); + let child2 = U256::from(4); + let netuid: u16 = 1; + + // Add network and register hotkey with a different coldkey + add_network(netuid, 13, 0); + register_ok_neuron(netuid, hotkey, U256::from(999), 0); + + // Attempt to revoke children + assert_err!( + SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![(u64::MAX / 2, child1), (u64::MAX / 2, child2)] + ), + Error::::NonAssociatedColdKey + ); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_revoke_children_multiple_partial_revocation --exact --nocapture +#[test] +fn test_do_revoke_children_multiple_partial_revocation() { + new_test_ext(1).execute_with(|| { + let coldkey = U256::from(1); + let hotkey = U256::from(2); + let child1 = U256::from(3); + let child2 = U256::from(4); + let child3 = U256::from(5); + let netuid: u16 = 1; + let proportion: u64 = 1000; + + // Add network and register hotkey + add_network(netuid, 13, 0); + register_ok_neuron(netuid, hotkey, coldkey, 0); + + // Set multiple children + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![ + (proportion, child1), + (proportion, child2), + (proportion, child3) + ] + )); + + // Revoke only child3 + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![(proportion, child1), (proportion, child2)] + )); + + // Verify children removal + let children = SubtensorModule::get_children(&hotkey, netuid); + assert_eq!(children, vec![(proportion, child1), (proportion, child2)]); + + // Verify parents. + let parents1 = SubtensorModule::get_parents(&child3, netuid); + assert!(parents1.is_empty()); + let parents1 = SubtensorModule::get_parents(&child1, netuid); + assert_eq!(parents1, vec![(proportion, hotkey)]); + let parents2 = SubtensorModule::get_parents(&child2, netuid); + assert_eq!(parents2, vec![(proportion, hotkey)]); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_revoke_children_multiple_non_existent_children --exact --nocapture + +#[test] +fn test_do_revoke_children_multiple_non_existent_children() { + new_test_ext(1).execute_with(|| { + let coldkey = U256::from(1); + let hotkey = U256::from(2); + let child1 = U256::from(3); + let netuid: u16 = 1; + let proportion: u64 = 1000; + + // Add network and register hotkey + add_network(netuid, 13, 0); + register_ok_neuron(netuid, hotkey, coldkey, 0); + + // Set one child + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![(proportion, child1)] + )); + + // Attempt to revoke existing and non-existent children + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![] + )); + + // Verify all children are removed + let children = SubtensorModule::get_children(&hotkey, netuid); + assert!(children.is_empty()); + + // Verify parent removal for the existing child + let parents1 = SubtensorModule::get_parents(&child1, netuid); + assert!(parents1.is_empty()); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_revoke_children_multiple_empty_list --exact --nocapture +#[test] +fn test_do_revoke_children_multiple_empty_list() { + new_test_ext(1).execute_with(|| { + let coldkey = U256::from(1); + let hotkey = U256::from(2); + let netuid: u16 = 1; + + // Add network and register hotkey + add_network(netuid, 13, 0); + register_ok_neuron(netuid, hotkey, coldkey, 0); + + // Attempt to revoke with an empty list + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![] + )); + + // Verify no changes in children + let children = SubtensorModule::get_children(&hotkey, netuid); + assert!(children.is_empty()); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_revoke_children_multiple_complex_scenario --exact --nocapture +#[test] +fn test_do_revoke_children_multiple_complex_scenario() { + new_test_ext(1).execute_with(|| { + let coldkey = U256::from(1); + let hotkey = U256::from(2); + let child1 = U256::from(3); + let child2 = U256::from(4); + let child3 = U256::from(5); + let netuid: u16 = 1; + let proportion1: u64 = 1000; + let proportion2: u64 = 2000; + let proportion3: u64 = 3000; + + // Add network and register hotkey + add_network(netuid, 13, 0); + register_ok_neuron(netuid, hotkey, coldkey, 0); + + // Set multiple children + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![ + (proportion1, child1), + (proportion2, child2), + (proportion3, child3) + ] + )); + + // Revoke child2 + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![(proportion1, child1), (proportion3, child3)] + )); + + // Verify remaining children + let children = SubtensorModule::get_children(&hotkey, netuid); + assert_eq!(children, vec![(proportion1, child1), (proportion3, child3)]); + + // Verify parent removal for child2 + let parents2 = SubtensorModule::get_parents(&child2, netuid); + assert!(parents2.is_empty()); + + // Revoke remaining children + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![] + )); + + // Verify all children are removed + let children = SubtensorModule::get_children(&hotkey, netuid); + assert!(children.is_empty()); + + // Verify parent removal for all children + let parents1 = SubtensorModule::get_parents(&child1, netuid); + assert!(parents1.is_empty()); + let parents3 = SubtensorModule::get_parents(&child3, netuid); + assert!(parents3.is_empty()); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_get_network_max_stake --exact --nocapture +#[test] +fn test_get_network_max_stake() { + new_test_ext(1).execute_with(|| { + let netuid: u16 = 1; + let default_max_stake = SubtensorModule::get_network_max_stake(netuid); + + // Check that the default value is set correctly + assert_eq!(default_max_stake, 500_000_000_000_000); + + // Set a new max stake value + let new_max_stake: u64 = 1_000_000; + SubtensorModule::set_network_max_stake(netuid, new_max_stake); + + // Check that the new value is retrieved correctly + assert_eq!( + SubtensorModule::get_network_max_stake(netuid), + new_max_stake + ); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_set_network_max_stake --exact --nocapture +#[test] +fn test_set_network_max_stake() { + new_test_ext(1).execute_with(|| { + let netuid: u16 = 1; + let initial_max_stake = SubtensorModule::get_network_max_stake(netuid); + + // Set a new max stake value + let new_max_stake: u64 = 500_000; + SubtensorModule::set_network_max_stake(netuid, new_max_stake); + + // Check that the new value is set correctly + assert_eq!( + SubtensorModule::get_network_max_stake(netuid), + new_max_stake + ); + assert_ne!( + SubtensorModule::get_network_max_stake(netuid), + initial_max_stake + ); + + // Check that the event is emitted + System::assert_last_event(Event::NetworkMaxStakeSet(netuid, new_max_stake).into()); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_set_network_max_stake_multiple_networks --exact --nocapture +#[test] +fn test_set_network_max_stake_multiple_networks() { + new_test_ext(1).execute_with(|| { + let netuid1: u16 = 1; + let netuid2: u16 = 2; + + // Set different max stake values for two networks + let max_stake1: u64 = 1_000_000; + let max_stake2: u64 = 2_000_000; + SubtensorModule::set_network_max_stake(netuid1, max_stake1); + SubtensorModule::set_network_max_stake(netuid2, max_stake2); + + // Check that the values are set correctly for each network + assert_eq!(SubtensorModule::get_network_max_stake(netuid1), max_stake1); + assert_eq!(SubtensorModule::get_network_max_stake(netuid2), max_stake2); + assert_ne!( + SubtensorModule::get_network_max_stake(netuid1), + SubtensorModule::get_network_max_stake(netuid2) + ); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_set_network_max_stake_update --exact --nocapture +#[test] +fn test_set_network_max_stake_update() { + new_test_ext(1).execute_with(|| { + let netuid: u16 = 1; + + // Set an initial max stake value + let initial_max_stake: u64 = 1_000_000; + SubtensorModule::set_network_max_stake(netuid, initial_max_stake); + + // Update the max stake value + let updated_max_stake: u64 = 1_500_000; + SubtensorModule::set_network_max_stake(netuid, updated_max_stake); + + // Check that the value is updated correctly + assert_eq!( + SubtensorModule::get_network_max_stake(netuid), + updated_max_stake + ); + assert_ne!( + SubtensorModule::get_network_max_stake(netuid), + initial_max_stake + ); + + // Check that the event is emitted for the update + System::assert_last_event(Event::NetworkMaxStakeSet(netuid, updated_max_stake).into()); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_children_stake_values --exact --nocapture +#[test] +fn test_children_stake_values() { + new_test_ext(1).execute_with(|| { + let coldkey = U256::from(1); + let hotkey = U256::from(2); + let child1 = U256::from(3); + let child2 = U256::from(4); + let child3 = U256::from(5); + let netuid: u16 = 1; + let proportion1: u64 = u64::MAX / 4; + let proportion2: u64 = u64::MAX / 4; + let proportion3: u64 = u64::MAX / 4; + + // Add network and register hotkey + add_network(netuid, 13, 0); + SubtensorModule::set_max_registrations_per_block(netuid, 4); + SubtensorModule::set_target_registrations_per_interval(netuid, 4); + register_ok_neuron(netuid, hotkey, coldkey, 0); + register_ok_neuron(netuid, child1, coldkey, 0); + register_ok_neuron(netuid, child2, coldkey, 0); + register_ok_neuron(netuid, child3, coldkey, 0); + SubtensorModule::increase_stake_on_coldkey_hotkey_account( + &coldkey, + &hotkey, + 100_000_000_000_000, + ); + + // Set multiple children with proportions. + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![ + (proportion1, child1), + (proportion2, child2), + (proportion3, child3) + ] + )); + assert_eq!( + SubtensorModule::get_stake_for_hotkey_on_subnet(&hotkey, netuid), + 25_000_000_069_852 + ); + assert_eq!( + SubtensorModule::get_stake_for_hotkey_on_subnet(&child1, netuid), + 24_999_999_976_716 + ); + assert_eq!( + SubtensorModule::get_stake_for_hotkey_on_subnet(&child2, netuid), + 24_999_999_976_716 + ); + assert_eq!( + SubtensorModule::get_stake_for_hotkey_on_subnet(&child3, netuid), + 24_999_999_976_716 + ); + assert_eq!( + SubtensorModule::get_stake_for_hotkey_on_subnet(&child3, netuid) + + SubtensorModule::get_stake_for_hotkey_on_subnet(&child2, netuid) + + SubtensorModule::get_stake_for_hotkey_on_subnet(&child1, netuid) + + SubtensorModule::get_stake_for_hotkey_on_subnet(&hotkey, netuid), + 100_000_000_000_000 + ); + }); +} diff --git a/pallets/subtensor/tests/coinbase.rs b/pallets/subtensor/tests/coinbase.rs new file mode 100644 index 000000000..cd7d2cc81 --- /dev/null +++ b/pallets/subtensor/tests/coinbase.rs @@ -0,0 +1,154 @@ +use crate::mock::*; +mod mock; +// use frame_support::{assert_err, assert_ok}; +use sp_core::U256; + +// Test the ability to hash all sorts of hotkeys. +#[test] +#[cfg(not(tarpaulin))] +fn test_hotkey_hashing() { + new_test_ext(1).execute_with(|| { + for i in 0..10000 { + SubtensorModule::hash_hotkey_to_u64(&U256::from(i)); + } + }); +} + +// Test drain tempo on hotkeys. +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test coinbase test_hotkey_drain_time -- --nocapture +#[test] +#[cfg(not(tarpaulin))] +fn test_hotkey_drain_time() { + new_test_ext(1).execute_with(|| { + // Block 0 + assert!(!SubtensorModule::should_drain_hotkey(&U256::from(0), 0, 1)); + assert!(SubtensorModule::should_drain_hotkey(&U256::from(1), 0, 1)); + assert!(SubtensorModule::should_drain_hotkey(&U256::from(2), 0, 1)); + assert!(SubtensorModule::should_drain_hotkey(&U256::from(3), 0, 1)); + assert!(!SubtensorModule::should_drain_hotkey(&U256::from(4), 0, 1)); + assert!(SubtensorModule::should_drain_hotkey(&U256::from(5), 0, 1)); + assert!(!SubtensorModule::should_drain_hotkey(&U256::from(6), 0, 1)); + assert!(!SubtensorModule::should_drain_hotkey(&U256::from(7), 0, 1)); + + // Block 1 + assert!(SubtensorModule::should_drain_hotkey(&U256::from(0), 1, 1)); + assert!(!SubtensorModule::should_drain_hotkey(&U256::from(1), 1, 1)); + assert!(!SubtensorModule::should_drain_hotkey(&U256::from(2), 1, 1)); + assert!(!SubtensorModule::should_drain_hotkey(&U256::from(3), 1, 1)); + assert!(SubtensorModule::should_drain_hotkey(&U256::from(4), 1, 1)); + assert!(!SubtensorModule::should_drain_hotkey(&U256::from(5), 1, 1)); + assert!(SubtensorModule::should_drain_hotkey(&U256::from(6), 1, 1)); + assert!(SubtensorModule::should_drain_hotkey(&U256::from(7), 1, 1)); + }); +} + +// To run this test specifically, use the following command: +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test coinbase test_coinbase_basic -- --nocapture +#[test] +#[cfg(not(tarpaulin))] +fn test_coinbase_basic() { + new_test_ext(1).execute_with(|| { + // Define network ID + let netuid: u16 = 1; + let hotkey = U256::from(0); + let coldkey = U256::from(3); + + // Create a network with a tempo 1 + add_network(netuid, 1, 0); + register_ok_neuron(netuid, hotkey, coldkey, 100000); + SubtensorModule::create_account_if_non_existent(&coldkey, &hotkey); + SubtensorModule::increase_stake_on_coldkey_hotkey_account(&coldkey, &hotkey, 1000); + + // Set the subnet emission value to 1. + SubtensorModule::set_emission_values(&[netuid], vec![1]).unwrap(); + assert_eq!(SubtensorModule::get_subnet_emission_value(netuid), 1); + + // Hotkey has no pending emission + assert_eq!(SubtensorModule::get_pending_hotkey_emission(&hotkey), 0); + + // Hotkey has same stake + assert_eq!(SubtensorModule::get_total_stake_for_hotkey(&hotkey), 1000); + + // Subnet has no pending emission. + assert_eq!(SubtensorModule::get_pending_emission(netuid), 0); + + // Step block + next_block(); + + // Hotkey has no pending emission + assert_eq!(SubtensorModule::get_pending_hotkey_emission(&hotkey), 0); + + // Hotkey has same stake + assert_eq!(SubtensorModule::get_total_stake_for_hotkey(&hotkey), 1000); + + // Subnet has no pending emission of 1 ( from coinbase ) + assert_eq!(SubtensorModule::get_pending_emission(netuid), 1); + + // Step block releases + next_block(); + + // Subnet pending has been drained. + assert_eq!(SubtensorModule::get_pending_emission(netuid), 0); + + // Hotkey pending immediately drained. + assert_eq!(SubtensorModule::get_pending_hotkey_emission(&hotkey), 0); + + // Hotkey has NEW stake + assert_eq!( + SubtensorModule::get_total_stake_for_hotkey(&hotkey), + 1000 + 2 + ); + + // Set the hotkey drain time to 2 block. + SubtensorModule::set_hotkey_emission_tempo(2); + + // Step block releases + next_block(); + + // Subnet pending increased by 1 + assert_eq!(SubtensorModule::get_pending_emission(netuid), 1); + + // Hotkey pending not increased (still on subnet) + assert_eq!(SubtensorModule::get_pending_hotkey_emission(&hotkey), 0); + + // Hotkey has same stake + assert_eq!( + SubtensorModule::get_total_stake_for_hotkey(&hotkey), + 1000 + 2 + ); + + // Step block releases + next_block(); + + // Subnet pending has been drained. + assert_eq!(SubtensorModule::get_pending_emission(netuid), 0); + + // Hotkey pending drained. + assert_eq!(SubtensorModule::get_pending_hotkey_emission(&hotkey), 0); + + // Hotkey has 2 new TAO. + assert_eq!( + SubtensorModule::get_total_stake_for_hotkey(&hotkey), + 1000 + 4 + ); + }); +} + +// Test getting and setting hotkey emission tempo +#[test] +#[cfg(not(tarpaulin))] +fn test_set_and_get_hotkey_emission_tempo() { + new_test_ext(1).execute_with(|| { + // Get the default hotkey emission tempo + let default_tempo = SubtensorModule::get_hotkey_emission_tempo(); + assert_eq!(default_tempo, 0); // default is 0 in mock.rs + + // Set a new hotkey emission tempo + let new_tempo = 5; + SubtensorModule::set_hotkey_emission_tempo(new_tempo); + + // Get the updated hotkey emission tempo + let updated_tempo = SubtensorModule::get_hotkey_emission_tempo(); + assert_eq!(updated_tempo, new_tempo); + }); +} diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 0ed3cd10f..df1687fdf 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -1213,6 +1213,10 @@ impl fn set_liquid_alpha_enabled(netuid: u16, enabled: bool) { SubtensorModule::set_liquid_alpha_enabled(netuid, enabled); } + + fn set_hotkey_emission_tempo(emission_tempo: u64) { + SubtensorModule::set_hotkey_emission_tempo(emission_tempo); + } fn do_set_alpha_values( origin: RuntimeOrigin, From 8eb7bd9c9c7df4c8d586c1b4f7acdd38b57738ad Mon Sep 17 00:00:00 2001 From: const Date: Mon, 15 Jul 2024 17:03:29 -0500 Subject: [PATCH 16/58] merge childkeys --- pallets/admin-utils/src/benchmarking.rs | 8 + pallets/admin-utils/src/lib.rs | 55 +- pallets/admin-utils/src/weights.rs | 12 - pallets/admin-utils/tests/mock.rs | 8 + pallets/subtensor/src/coinbase/block_step.rs | 4 - .../subtensor/src/coinbase/run_coinbase.rs | 28 +- pallets/subtensor/src/lib.rs | 11 +- pallets/subtensor/src/macros/config.rs | 6 + pallets/subtensor/src/macros/events.rs | 5 + pallets/subtensor/src/rpc_info/neuron_info.rs | 4 +- pallets/subtensor/src/staking/set_children.rs | 1 - pallets/subtensor/src/subnets/registration.rs | 4 +- pallets/subtensor/src/utils.rs | 37 + pallets/subtensor/tests/block_step.rs | 940 -------------- pallets/subtensor/tests/coinbase.rs | 1 + pallets/subtensor/tests/mock.rs | 5 + pallets/subtensor/tests/staking.rs | 1076 ----------------- runtime/src/lib.rs | 10 +- 18 files changed, 162 insertions(+), 2053 deletions(-) delete mode 100644 pallets/subtensor/tests/block_step.rs diff --git a/pallets/admin-utils/src/benchmarking.rs b/pallets/admin-utils/src/benchmarking.rs index 3165e907f..33e026553 100644 --- a/pallets/admin-utils/src/benchmarking.rs +++ b/pallets/admin-utils/src/benchmarking.rs @@ -248,5 +248,13 @@ mod benchmarks { _(RawOrigin::Root, 1u64/*emission_tempo*/)/*set_hotkey_emission_tempo*/; } + #[benchmark] + fn sudo_set_network_max_stake() { + T::Subtensor::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/); + + #[extrinsic_call] + _(RawOrigin::Root, 1u16/*netuid*/, 1_000_000_000_000_000u64/*max_stake*/)/*sudo_set_network_max_stake*/; + } + //impl_benchmark_test_suite!(AdminUtils, crate::mock::new_test_ext(), crate::mock::Test); } diff --git a/pallets/admin-utils/src/lib.rs b/pallets/admin-utils/src/lib.rs index 2aa45cbc9..59b0ed44a 100644 --- a/pallets/admin-utils/src/lib.rs +++ b/pallets/admin-utils/src/lib.rs @@ -1050,8 +1050,9 @@ pub mod pallet { /// /// # Errors /// * `DispatchError::BadOrigin` - If the origin is not the root account. + // #[pallet::weight(T::WeightInfo::sudo_set_hotkey_emission_tempo())] #[pallet::call_index(52)] - #[pallet::weight(T::WeightInfo::sudo_set_hotkey_emission_tempo())] + #[pallet::weight((0, DispatchClass::Operational, Pays::No))] pub fn sudo_set_hotkey_emission_tempo( origin: OriginFor, emission_tempo: u64, @@ -1064,6 +1065,57 @@ pub mod pallet { ); Ok(()) } + + /// Sets the maximum stake allowed for a specific network. + /// + /// This function allows the root account to set the maximum stake for a given network. + /// It updates the network's maximum stake value and logs the change. + /// + /// # Arguments + /// + /// * `origin` - The origin of the call, which must be the root account. + /// * `netuid` - The unique identifier of the network. + /// * `max_stake` - The new maximum stake value to set. + /// + /// # Returns + /// + /// Returns `Ok(())` if the operation is successful, or an error if it fails. + /// + /// # Example + /// + /// + /// # Notes + /// + /// - This function can only be called by the root account. + /// - The `netuid` should correspond to an existing network. + /// + /// # TODO + /// + // - Consider adding a check to ensure the `netuid` corresponds to an existing network. + // - Implement a mechanism to gradually adjust the max stake to prevent sudden changes. + // #[pallet::weight(T::WeightInfo::sudo_set_network_max_stake())] + #[pallet::call_index(53)] + #[pallet::weight((0, DispatchClass::Operational, Pays::No))] + pub fn sudo_set_network_max_stake( + origin: OriginFor, + netuid: u16, + max_stake: u64, + ) -> DispatchResult { + // Ensure the call is made by the root account + ensure_root(origin)?; + + // Set the new maximum stake for the specified network + T::Subtensor::set_network_max_stake(netuid, max_stake); + + // Log the change + log::trace!( + "NetworkMaxStakeSet( netuid: {:?}, max_stake: {:?} )", + netuid, + max_stake + ); + + Ok(()) + } } } @@ -1167,4 +1219,5 @@ pub trait SubtensorInterface { alpha_high: u16, ) -> Result<(), DispatchError>; fn set_hotkey_emission_tempo(emission_tempo: u64); + fn set_network_max_stake(netuid: u16, max_stake: u64); } diff --git a/pallets/admin-utils/src/weights.rs b/pallets/admin-utils/src/weights.rs index 0c0259ef2..84fe058f8 100644 --- a/pallets/admin-utils/src/weights.rs +++ b/pallets/admin-utils/src/weights.rs @@ -62,8 +62,6 @@ pub trait WeightInfo { fn sudo_set_tempo() -> Weight; fn sudo_set_commit_reveal_weights_interval() -> Weight; fn sudo_set_commit_reveal_weights_enabled() -> Weight; - fn sudo_set_hotkey_emission_tempo() -> Weight; - } /// Weights for `pallet_admin_utils` using the Substrate node and recommended hardware. @@ -807,14 +805,4 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `SubtensorModule::HotkeyEmissionTempo` (r:0 w:1) - /// Proof: `SubtensorModule::HotkeyEmissionTempo` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - fn sudo_set_hotkey_emission_tempo() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 5_000_000 picoseconds. - Weight::from_parts(6_000_000, 0) - .saturating_add(T::DbWeight::get().writes(1_u64)) - } } \ No newline at end of file diff --git a/pallets/admin-utils/tests/mock.rs b/pallets/admin-utils/tests/mock.rs index c1f55fece..7ae11b6fb 100644 --- a/pallets/admin-utils/tests/mock.rs +++ b/pallets/admin-utils/tests/mock.rs @@ -114,6 +114,8 @@ parameter_types! { pub const InitialAlphaHigh: u16 = 58982; // Represents 0.9 as per the production default pub const InitialAlphaLow: u16 = 45875; // Represents 0.7 as per the production default pub const InitialLiquidAlphaOn: bool = false; // Default value for LiquidAlphaOn + pub const InitialHotkeyEmissionTempo: u64 = 1; + pub const InitialNetworkMaxStake: u64 = 500_000_000_000_000; // 500_000 TAO } impl pallet_subtensor::Config for Test { @@ -169,6 +171,8 @@ impl pallet_subtensor::Config for Test { type AlphaHigh = InitialAlphaHigh; type AlphaLow = InitialAlphaLow; type LiquidAlphaOn = InitialLiquidAlphaOn; + type InitialHotkeyEmissionTempo = InitialHotkeyEmissionTempo; + type InitialNetworkMaxStake = InitialNetworkMaxStake; } #[derive_impl(frame_system::config_preludes::TestDefaultConfig)] @@ -478,6 +482,10 @@ impl pallet_admin_utils::SubtensorInterface f fn set_hotkey_emission_tempo(emission_tempo: u64) { SubtensorModule::set_hotkey_emission_tempo(emission_tempo) } + fn set_network_max_stake(netuid: u16, max_stake: u64) { + SubtensorModule::set_network_max_stake(netuid, max_stake) + } + fn do_set_alpha_values( origin: RuntimeOrigin, netuid: u16, diff --git a/pallets/subtensor/src/coinbase/block_step.rs b/pallets/subtensor/src/coinbase/block_step.rs index f4df51456..3c621155f 100644 --- a/pallets/subtensor/src/coinbase/block_step.rs +++ b/pallets/subtensor/src/coinbase/block_step.rs @@ -1,10 +1,6 @@ use super::*; -use frame_support::storage::IterableStorageDoubleMap; use frame_support::storage::IterableStorageMap; -use sp_runtime::Saturating; use substrate_fixed::types::I110F18; -use substrate_fixed::types::I64F64; -use substrate_fixed::types::I96F32; impl Pallet { /// Executes the necessary operations for each block. diff --git a/pallets/subtensor/src/coinbase/run_coinbase.rs b/pallets/subtensor/src/coinbase/run_coinbase.rs index 7dd829853..0f747a89e 100644 --- a/pallets/subtensor/src/coinbase/run_coinbase.rs +++ b/pallets/subtensor/src/coinbase/run_coinbase.rs @@ -1,8 +1,5 @@ use super::*; use frame_support::storage::IterableStorageDoubleMap; -use frame_support::storage::IterableStorageMap; -use sp_runtime::Saturating; -use substrate_fixed::types::I110F18; use substrate_fixed::types::I64F64; use substrate_fixed::types::I96F32; @@ -190,8 +187,8 @@ impl Pallet { mining_emission: u64, ) { // --- 1. First, calculate the hotkey's share of the emission. - let take_proportion: I64F64 = - I64F64::from_num(Delegates::::get(hotkey)).saturating_div(I64F64::from_num(u16::MAX)); + let take_proportion: I64F64 = I64F64::from_num(Delegates::::get(hotkey)) + .saturating_div(I64F64::from_num(u16::MAX)); let hotkey_take: u64 = take_proportion .saturating_mul(I64F64::from_num(validating_emission)) .to_num::(); @@ -274,8 +271,8 @@ impl Pallet { let total_hotkey_stake: u64 = Self::get_total_stake_for_hotkey(hotkey); // --- 5 Calculate the emission take for the hotkey. - let take_proportion: I64F64 = - I64F64::from_num(Delegates::::get(hotkey)).saturating_div(I64F64::from_num(u16::MAX)); + let take_proportion: I64F64 = I64F64::from_num(Delegates::::get(hotkey)) + .saturating_div(I64F64::from_num(u16::MAX)); let hotkey_take: u64 = (take_proportion.saturating_mul(I64F64::from_num(emission))).to_num::(); @@ -287,11 +284,15 @@ impl Pallet { // --- 8 Iterate over each nominator. for (nominator, nominator_stake) in - as IterableStorageDoubleMap>::iter_prefix(hotkey) + as IterableStorageDoubleMap>::iter_prefix( + hotkey, + ) { // --- 9 Check if the stake was manually increased by the user since the last emission drain for this hotkey. // If it was, skip this nominator as they will not receive their proportion of the emission. - if LastAddStakeIncrease::::get(hotkey, nominator.clone()) > last_hotkey_emission_drain { + if LastAddStakeIncrease::::get(hotkey, nominator.clone()) + > last_hotkey_emission_drain + { continue; } @@ -365,9 +366,10 @@ impl Pallet { if tempo == 0 { return u64::MAX; } - (tempo as u64).saturating_sub( - (block_number.saturating_add((netuid as u64).saturating_add(1))) - % (tempo as u64).saturating_add(1), - ) + let netuid_plus_one = (netuid as u64).saturating_add(1); + let block_plus_netuid = block_number.saturating_add(netuid_plus_one); + let tempo_plus_one = (tempo as u64).saturating_add(1); + let remainder = block_plus_netuid.rem_euclid(tempo_plus_one); + (tempo as u64).saturating_sub(remainder) } } \ No newline at end of file diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index 8d2b5c4fd..dd98a318f 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -502,7 +502,7 @@ pub mod pallet { #[pallet::type_value] /// Default value for network immunity period. pub fn DefaultHotkeyEmissionTempo() -> u64 { - 7200 + T::InitialHotkeyEmissionTempo::get() } #[pallet::type_value] /// Default value for rate limiting @@ -549,6 +549,11 @@ pub mod pallet { pub fn DefaultAlphaValues() -> (u16, u16) { (45875, 58982) } + #[pallet::type_value] + /// Default value for network max stake. + pub fn DefaultNetworkMaxStake() -> u64 { + T::InitialNetworkMaxStake::get() + } #[pallet::storage] pub type SenateRequiredStakePercentage = @@ -926,6 +931,10 @@ pub mod pallet { /// MAP ( netuid ) --> (alpha_low, alpha_high) pub type AlphaValues = StorageMap<_, Identity, u16, (u16, u16), ValueQuery, DefaultAlphaValues>; + /// MAP ( netuid ) --> max stake allowed on a subnet. + #[pallet::storage] + pub type NetworkMaxStake = + StorageMap<_, Identity, u16, u64, ValueQuery, DefaultNetworkMaxStake>; /// ======================================= /// ==== Subnetwork Consensus Storage ==== diff --git a/pallets/subtensor/src/macros/config.rs b/pallets/subtensor/src/macros/config.rs index a640ecbb6..aca0f1b30 100644 --- a/pallets/subtensor/src/macros/config.rs +++ b/pallets/subtensor/src/macros/config.rs @@ -168,5 +168,11 @@ mod config { /// A flag to indicate if Liquid Alpha is enabled. #[pallet::constant] type LiquidAlphaOn: Get; + /// Initial network max stake. + #[pallet::constant] + type InitialNetworkMaxStake: Get; + /// Initial hotkey emission tempo. + #[pallet::constant] + type InitialHotkeyEmissionTempo: Get; } } diff --git a/pallets/subtensor/src/macros/events.rs b/pallets/subtensor/src/macros/events.rs index e3e47f32e..b93b8296b 100644 --- a/pallets/subtensor/src/macros/events.rs +++ b/pallets/subtensor/src/macros/events.rs @@ -171,6 +171,11 @@ mod events { /// The account ID of the coldkey coldkey: T::AccountId, }, + /// The children of a hotkey have been set SetChildren(T::AccountId, u16, Vec<(u64, T::AccountId)>), + /// The hotkey emission tempo has been set + HotkeyEmissionTempoSet(u64), + /// The network maximum stake has been set + NetworkMaxStakeSet(u16, u64), } } diff --git a/pallets/subtensor/src/rpc_info/neuron_info.rs b/pallets/subtensor/src/rpc_info/neuron_info.rs index 6b370afd8..cadd4b6e3 100644 --- a/pallets/subtensor/src/rpc_info/neuron_info.rs +++ b/pallets/subtensor/src/rpc_info/neuron_info.rs @@ -118,8 +118,8 @@ impl Pallet { }) .collect::, Compact)>>(); let stake: Vec<(T::AccountId, Compact)> = vec![( - coldkey, - Self::get_stake_for_hotkey_on_subnet(hotkey, netuid).into(), + coldkey.clone(), + Self::get_stake_for_hotkey_on_subnet(&hotkey, netuid).into(), )]; let neuron = NeuronInfo { hotkey: hotkey.clone(), diff --git a/pallets/subtensor/src/staking/set_children.rs b/pallets/subtensor/src/staking/set_children.rs index 79898b6ae..071764734 100644 --- a/pallets/subtensor/src/staking/set_children.rs +++ b/pallets/subtensor/src/staking/set_children.rs @@ -1,5 +1,4 @@ use super::*; -use substrate_fixed::types::I96F32; impl Pallet { /// ---- The implementation for the extrinsic do_set_child_singular: Sets a single child. diff --git a/pallets/subtensor/src/subnets/registration.rs b/pallets/subtensor/src/subnets/registration.rs index b46a50eb2..ecff0fd99 100644 --- a/pallets/subtensor/src/subnets/registration.rs +++ b/pallets/subtensor/src/subnets/registration.rs @@ -550,10 +550,10 @@ impl Pallet { // Copy the hotkey_bytes into the first half of full_bytes full_bytes[..32].copy_from_slice(hotkey_bytes); let keccak_256_seal_hash_vec: [u8; 32] = keccak_256(&full_bytes[..]); - let hash_u64: u64 = u64::from_le_bytes(keccak_256_seal_hash_vec[0..8].try_into().unwrap()); + let hash_u64: u64 = u64::from_le_bytes(keccak_256_seal_hash_vec[0..8].try_into().unwrap_or_default()); hash_u64 } - + pub fn create_seal_hash(block_number_u64: u64, nonce_u64: u64, hotkey: &T::AccountId) -> H256 { let nonce = nonce_u64.to_le_bytes(); let block_hash_at_number: H256 = Self::get_block_hash_from_u64(block_number_u64); diff --git a/pallets/subtensor/src/utils.rs b/pallets/subtensor/src/utils.rs index a1929f498..6f5dbeaff 100644 --- a/pallets/subtensor/src/utils.rs +++ b/pallets/subtensor/src/utils.rs @@ -703,6 +703,7 @@ impl Pallet { pub fn get_hotkey_emission_tempo() -> u64 { HotkeyEmissionTempo::::get() } + /// Sets the hotkey emission tempo. /// /// # Arguments @@ -711,4 +712,40 @@ impl Pallet { HotkeyEmissionTempo::::set(emission_tempo); Self::deposit_event(Event::HotkeyEmissionTempoSet(emission_tempo)); } + + pub fn get_pending_hotkey_emission(hotkey: &T::AccountId) -> u64 { + PendingdHotkeyEmission::::get(hotkey) + } + + /// Retrieves the maximum stake allowed for a given network. + /// + /// # Arguments + /// + /// * `netuid` - The unique identifier of the network. + /// + /// # Returns + /// + /// * `u64` - The maximum stake allowed for the specified network. + pub fn get_network_max_stake(netuid: u16) -> u64 { + NetworkMaxStake::::get(netuid) + } + + /// Sets the maximum stake allowed for a given network. + /// + /// # Arguments + /// + /// * `netuid` - The unique identifier of the network. + /// * `max_stake` - The new maximum stake value to set. + /// + /// # Effects + /// + /// * Updates the NetworkMaxStake storage. + /// * Emits a NetworkMaxStakeSet event. + pub fn set_network_max_stake(netuid: u16, max_stake: u64) { + // Update the NetworkMaxStake storage with the new max_stake value + NetworkMaxStake::::insert(netuid, max_stake); + + // Emit an event to notify listeners about the change + Self::deposit_event(Event::NetworkMaxStakeSet(netuid, max_stake)); + } } diff --git a/pallets/subtensor/tests/block_step.rs b/pallets/subtensor/tests/block_step.rs deleted file mode 100644 index 87fdb8bcf..000000000 --- a/pallets/subtensor/tests/block_step.rs +++ /dev/null @@ -1,940 +0,0 @@ -#![allow(clippy::unwrap_used)] - -mod mock; -use frame_support::assert_ok; -use frame_system::Config; -use mock::*; -use sp_core::U256; - -#[test] -fn test_loaded_emission() { - new_test_ext(1).execute_with(|| { - let n: u16 = 100; - let netuid: u16 = 1; - let tempo: u16 = 10; - let netuids: Vec = vec![1]; - let emission: Vec = vec![1000000000]; - add_network(netuid, tempo, 0); - SubtensorModule::set_max_allowed_uids(netuid, n); - SubtensorModule::set_adjustment_alpha(netuid, 58000); // Set to old value. - SubtensorModule::set_emission_values(&netuids, emission).unwrap(); - for i in 0..n { - SubtensorModule::append_neuron(netuid, &U256::from(i), 0); - } - assert!(SubtensorModule::get_loaded_emission_tuples(netuid).is_none()); - - // Try loading at block 0 - let block: u64 = 0; - assert_eq!( - SubtensorModule::blocks_until_next_epoch(netuid, tempo, block), - 8 - ); - SubtensorModule::generate_emission(block); - assert!(SubtensorModule::get_loaded_emission_tuples(netuid).is_none()); - - // Try loading at block = 9; - let block: u64 = 8; - assert_eq!( - SubtensorModule::blocks_until_next_epoch(netuid, tempo, block), - 0 - ); - SubtensorModule::generate_emission(block); - assert!(SubtensorModule::get_loaded_emission_tuples(netuid).is_some()); - assert_eq!( - SubtensorModule::get_loaded_emission_tuples(netuid) - .unwrap() - .len(), - n as usize - ); - - // Try draining the emission tuples - // None remaining because we are at epoch. - let block: u64 = 8; - SubtensorModule::drain_emission(block); - assert!(SubtensorModule::get_loaded_emission_tuples(netuid).is_none()); - - // Generate more emission. - SubtensorModule::generate_emission(8); - assert_eq!( - SubtensorModule::get_loaded_emission_tuples(netuid) - .unwrap() - .len(), - n as usize - ); - - for block in 9..19 { - let mut n_remaining: usize = 0; - let mut n_to_drain: usize = 0; - if let Some(tuples) = SubtensorModule::get_loaded_emission_tuples(netuid) { - n_remaining = tuples.len(); - n_to_drain = - SubtensorModule::tuples_to_drain_this_block(netuid, tempo, block, tuples.len()); - } - SubtensorModule::drain_emission(block); // drain it with 9 more blocks to go - if let Some(tuples) = SubtensorModule::get_loaded_emission_tuples(netuid) { - assert_eq!(tuples.len(), n_remaining - n_to_drain); - } - log::info!("n_to_drain: {:?}", n_to_drain); - log::info!( - "SubtensorModule::get_loaded_emission_tuples( netuid ).len(): {:?}", - n_remaining - n_to_drain - ); - } - }) -} - -#[test] -fn test_tuples_to_drain_this_block() { - new_test_ext(1).execute_with(|| { - // pub fn tuples_to_drain_this_block( netuid: u16, tempo: u16, block_number: u64, n_remaining: usize ) -> usize { - assert_eq!(SubtensorModule::tuples_to_drain_this_block(0, 1, 0, 10), 10); // drain all epoch block. - assert_eq!(SubtensorModule::tuples_to_drain_this_block(0, 0, 0, 10), 10); // drain all no tempo. - assert_eq!(SubtensorModule::tuples_to_drain_this_block(0, 10, 0, 10), 2); // drain 10 / ( 10 / 2 ) = 2 - assert_eq!(SubtensorModule::tuples_to_drain_this_block(0, 20, 0, 10), 1); // drain 10 / ( 20 / 2 ) = 1 - assert_eq!(SubtensorModule::tuples_to_drain_this_block(0, 10, 0, 20), 5); // drain 20 / ( 9 / 2 ) = 5 - assert_eq!(SubtensorModule::tuples_to_drain_this_block(0, 20, 0, 0), 0); // nothing to drain. - assert_eq!(SubtensorModule::tuples_to_drain_this_block(0, 10, 1, 20), 5); // drain 19 / ( 10 / 2 ) = 4 - assert_eq!( - SubtensorModule::tuples_to_drain_this_block(0, 10, 10, 20), - 4 - ); // drain 19 / ( 10 / 2 ) = 4 - assert_eq!( - SubtensorModule::tuples_to_drain_this_block(0, 10, 15, 20), - 10 - ); // drain 19 / ( 10 / 2 ) = 4 - assert_eq!( - SubtensorModule::tuples_to_drain_this_block(0, 10, 19, 20), - 20 - ); // drain 19 / ( 10 / 2 ) = 4 - assert_eq!( - SubtensorModule::tuples_to_drain_this_block(0, 10, 20, 20), - 20 - ); // drain 19 / ( 10 / 2 ) = 4 - for i in 0..10 { - for j in 0..10 { - for k in 0..10 { - for l in 0..10 { - assert!(SubtensorModule::tuples_to_drain_this_block(i, j, k, l) <= 10); - } - } - } - } - }) -} - -#[test] -fn test_blocks_until_epoch() { - new_test_ext(1).execute_with(|| { - // Check tempo = 0 block = * netuid = * - assert_eq!(SubtensorModule::blocks_until_next_epoch(0, 0, 0), 1000); - - // Check tempo = 1 block = * netuid = * - assert_eq!(SubtensorModule::blocks_until_next_epoch(0, 1, 0), 0); - assert_eq!(SubtensorModule::blocks_until_next_epoch(1, 1, 0), 1); - assert_eq!(SubtensorModule::blocks_until_next_epoch(0, 1, 1), 1); - assert_eq!(SubtensorModule::blocks_until_next_epoch(1, 1, 1), 0); - assert_eq!(SubtensorModule::blocks_until_next_epoch(0, 1, 2), 0); - assert_eq!(SubtensorModule::blocks_until_next_epoch(1, 1, 2), 1); - for i in 0..100 { - if i % 2 == 0 { - assert_eq!(SubtensorModule::blocks_until_next_epoch(0, 1, i), 0); - assert_eq!(SubtensorModule::blocks_until_next_epoch(1, 1, i), 1); - } else { - assert_eq!(SubtensorModule::blocks_until_next_epoch(0, 1, i), 1); - assert_eq!(SubtensorModule::blocks_until_next_epoch(1, 1, i), 0); - } - } - - // Check general case. - for netuid in 0..30_u16 { - for block in 0..30_u64 { - for tempo in 1..30_u16 { - assert_eq!( - SubtensorModule::blocks_until_next_epoch(netuid, tempo, block), - tempo as u64 - (block + netuid as u64 + 1) % (tempo as u64 + 1) - ); - } - } - } - }); -} - -// /******************************************** -// block_step::adjust_registration_terms_for_networks tests -// *********************************************/ -#[test] -fn test_burn_adjustment() { - new_test_ext(1).execute_with(|| { - let netuid: u16 = 1; - let tempo: u16 = 13; - let burn_cost: u64 = 1000; - let adjustment_interval = 1; - let target_registrations_per_interval = 1; - add_network(netuid, tempo, 0); - SubtensorModule::set_burn(netuid, burn_cost); - SubtensorModule::set_adjustment_interval(netuid, adjustment_interval); - SubtensorModule::set_adjustment_alpha(netuid, 58000); // Set to old value. - SubtensorModule::set_target_registrations_per_interval( - netuid, - target_registrations_per_interval, - ); - assert_eq!( - SubtensorModule::get_adjustment_interval(netuid), - adjustment_interval - ); // Sanity check the adjustment interval. - - // 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, 10000); - assert_ok!(SubtensorModule::burned_register( - <::RuntimeOrigin>::signed(hotkey_account_id_1), - netuid, - hotkey_account_id_1 - )); - - // 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, 10000); - assert_ok!(SubtensorModule::burned_register( - <::RuntimeOrigin>::signed(hotkey_account_id_2), - netuid, - hotkey_account_id_2 - )); - - // We are over the number of regs allowed this interval. - // Step the block and trigger the adjustment. - step_block(1); - - // Check the adjusted burn. - assert_eq!(SubtensorModule::get_burn_as_u64(netuid), 1500); - }); -} - -#[test] -fn test_burn_adjustment_with_moving_average() { - new_test_ext(1).execute_with(|| { - let netuid: u16 = 1; - let tempo: u16 = 13; - let burn_cost: u64 = 1000; - let adjustment_interval = 1; - let target_registrations_per_interval = 1; - add_network(netuid, tempo, 0); - SubtensorModule::set_burn(netuid, burn_cost); - SubtensorModule::set_adjustment_interval(netuid, adjustment_interval); - SubtensorModule::set_adjustment_alpha(netuid, 58000); // Set to old value. - SubtensorModule::set_target_registrations_per_interval( - netuid, - target_registrations_per_interval, - ); - // Set alpha here. - SubtensorModule::set_adjustment_alpha(netuid, u64::MAX / 2); - - // 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, 10000); - assert_ok!(SubtensorModule::burned_register( - <::RuntimeOrigin>::signed(hotkey_account_id_1), - netuid, - hotkey_account_id_1 - )); - - // 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, 10000); - assert_ok!(SubtensorModule::burned_register( - <::RuntimeOrigin>::signed(hotkey_account_id_2), - netuid, - hotkey_account_id_2 - )); - - // We are over the number of regs allowed this interval. - // Step the block and trigger the adjustment. - step_block(1); - - // Check the adjusted burn. - // 0.5 * 1000 + 0.5 * 1500 = 1250 - assert_eq!(SubtensorModule::get_burn_as_u64(netuid), 1250); - }); -} - -#[test] -#[allow(unused_assignments)] -fn test_burn_adjustment_case_a() { - // Test case A of the difficulty and burn adjustment algorithm. - // ==================== - // There are too many registrations this interval and most of them are pow registrations - // this triggers an increase in the pow difficulty. - new_test_ext(1).execute_with(|| { - let netuid: u16 = 1; - let tempo: u16 = 13; - let burn_cost: u64 = 1000; - let adjustment_interval = 1; - let target_registrations_per_interval = 1; - let start_diff: u64 = 10_000; - let mut curr_block_num = 0; - add_network(netuid, tempo, 0); - SubtensorModule::set_burn(netuid, burn_cost); - SubtensorModule::set_difficulty(netuid, start_diff); - SubtensorModule::set_min_difficulty(netuid, start_diff); - SubtensorModule::set_adjustment_interval(netuid, adjustment_interval); - SubtensorModule::set_adjustment_alpha(netuid, 58000); // Set to old value. - SubtensorModule::set_target_registrations_per_interval( - netuid, - target_registrations_per_interval, - ); - - // Register key 1. This is a burn registration. - 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, 10000); - assert_ok!(SubtensorModule::burned_register( - <::RuntimeOrigin>::signed(hotkey_account_id_1), - netuid, - hotkey_account_id_1 - )); - - // Register key 2. This is a POW registration - let hotkey_account_id_2 = U256::from(2); - let coldkey_account_id_2 = U256::from(2); - let (nonce0, work0): (u64, Vec) = SubtensorModule::create_work_for_block_number( - netuid, - curr_block_num, - 0, - &hotkey_account_id_2, - ); - let result0 = SubtensorModule::register( - <::RuntimeOrigin>::signed(hotkey_account_id_2), - netuid, - curr_block_num, - nonce0, - work0, - hotkey_account_id_2, - coldkey_account_id_2, - ); - assert_ok!(result0); - - // Register key 3. This is a POW registration - let hotkey_account_id_3 = U256::from(3); - let coldkey_account_id_3 = U256::from(3); - let (nonce1, work1): (u64, Vec) = SubtensorModule::create_work_for_block_number( - netuid, - curr_block_num, - 11231312312, - &hotkey_account_id_3, - ); - let result1 = SubtensorModule::register( - <::RuntimeOrigin>::signed(hotkey_account_id_3), - netuid, - curr_block_num, - nonce1, - work1, - hotkey_account_id_3, - coldkey_account_id_3, - ); - assert_ok!(result1); - - // We are over the number of regs allowed this interval. - // Most of them are POW registrations (2 out of 3) - // Step the block and trigger the adjustment. - step_block(1); - curr_block_num += 1; - - // Check the adjusted POW difficulty has INCREASED. - // and the burn has not changed. - let adjusted_burn = SubtensorModule::get_burn_as_u64(netuid); - assert_eq!(adjusted_burn, burn_cost); - - let adjusted_diff = SubtensorModule::get_difficulty_as_u64(netuid); - assert!(adjusted_diff > start_diff); - assert_eq!(adjusted_diff, 20_000); - }); -} - -#[test] -#[allow(unused_assignments)] -fn test_burn_adjustment_case_b() { - // Test case B of the difficulty and burn adjustment algorithm. - // ==================== - // There are too many registrations this interval and most of them are burn registrations - // this triggers an increase in the burn cost. - new_test_ext(1).execute_with(|| { - let netuid: u16 = 1; - let tempo: u16 = 13; - let burn_cost: u64 = 1000; - let adjustment_interval = 1; - let target_registrations_per_interval = 1; - let start_diff: u64 = 10_000; - let mut curr_block_num = 0; - add_network(netuid, tempo, 0); - SubtensorModule::set_burn(netuid, burn_cost); - SubtensorModule::set_difficulty(netuid, start_diff); - SubtensorModule::set_adjustment_interval(netuid, adjustment_interval); - SubtensorModule::set_adjustment_alpha(netuid, 58000); // Set to old value. - SubtensorModule::set_target_registrations_per_interval( - netuid, - target_registrations_per_interval, - ); - - // 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, 10000); - assert_ok!(SubtensorModule::burned_register( - <::RuntimeOrigin>::signed(hotkey_account_id_1), - netuid, - hotkey_account_id_1 - )); - - // 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, 10000); - assert_ok!(SubtensorModule::burned_register( - <::RuntimeOrigin>::signed(hotkey_account_id_2), - netuid, - hotkey_account_id_2 - )); - - // Register key 3. This one is a POW registration - let hotkey_account_id_3 = U256::from(3); - let coldkey_account_id_3 = U256::from(3); - let (nonce, work): (u64, Vec) = SubtensorModule::create_work_for_block_number( - netuid, - curr_block_num, - 0, - &hotkey_account_id_3, - ); - let result = SubtensorModule::register( - <::RuntimeOrigin>::signed(hotkey_account_id_3), - netuid, - curr_block_num, - nonce, - work, - hotkey_account_id_3, - coldkey_account_id_3, - ); - assert_ok!(result); - - // We are over the number of regs allowed this interval. - // Most of them are burn registrations (2 out of 3) - // Step the block and trigger the adjustment. - step_block(1); - curr_block_num += 1; - - // Check the adjusted burn has INCREASED. - // and the difficulty has not changed. - let adjusted_burn = SubtensorModule::get_burn_as_u64(netuid); - assert!(adjusted_burn > burn_cost); - assert_eq!(adjusted_burn, 2_000); - - let adjusted_diff = SubtensorModule::get_difficulty_as_u64(netuid); - assert_eq!(adjusted_diff, start_diff); - }); -} - -#[test] -#[allow(unused_assignments)] -fn test_burn_adjustment_case_c() { - // Test case C of the difficulty and burn adjustment algorithm. - // ==================== - // There are not enough registrations this interval and most of them are POW registrations - // this triggers a decrease in the burn cost - new_test_ext(1).execute_with(|| { - let netuid: u16 = 1; - let tempo: u16 = 13; - let burn_cost: u64 = 1000; - let adjustment_interval = 1; - let target_registrations_per_interval = 4; // Needs registrations < 4 to trigger - let start_diff: u64 = 10_000; - let mut curr_block_num = 0; - add_network(netuid, tempo, 0); - SubtensorModule::set_burn(netuid, burn_cost); - SubtensorModule::set_difficulty(netuid, start_diff); - SubtensorModule::set_adjustment_interval(netuid, adjustment_interval); - SubtensorModule::set_adjustment_alpha(netuid, 58000); // Set to old value. - SubtensorModule::set_target_registrations_per_interval( - netuid, - target_registrations_per_interval, - ); - - // Register key 1. This is a BURN registration - 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, 10000); - assert_ok!(SubtensorModule::burned_register( - <::RuntimeOrigin>::signed(hotkey_account_id_1), - netuid, - hotkey_account_id_1 - )); - - // Register key 2. This is a POW registration - let hotkey_account_id_2 = U256::from(2); - let coldkey_account_id_2 = U256::from(2); - let (nonce0, work0): (u64, Vec) = SubtensorModule::create_work_for_block_number( - netuid, - curr_block_num, - 0, - &hotkey_account_id_2, - ); - let result0 = SubtensorModule::register( - <::RuntimeOrigin>::signed(hotkey_account_id_2), - netuid, - curr_block_num, - nonce0, - work0, - hotkey_account_id_2, - coldkey_account_id_2, - ); - assert_ok!(result0); - - // Register key 3. This is a POW registration - let hotkey_account_id_3 = U256::from(3); - let coldkey_account_id_3 = U256::from(3); - let (nonce1, work1): (u64, Vec) = SubtensorModule::create_work_for_block_number( - netuid, - curr_block_num, - 11231312312, - &hotkey_account_id_3, - ); - let result1 = SubtensorModule::register( - <::RuntimeOrigin>::signed(hotkey_account_id_3), - netuid, - curr_block_num, - nonce1, - work1, - hotkey_account_id_3, - coldkey_account_id_3, - ); - assert_ok!(result1); - - // We are UNDER the number of regs allowed this interval. - // Most of them are POW registrations (2 out of 3) - // Step the block and trigger the adjustment. - step_block(1); - curr_block_num += 1; - - // Check the adjusted burn has DECREASED. - // and the difficulty has not changed. - let adjusted_burn = SubtensorModule::get_burn_as_u64(netuid); - assert!(adjusted_burn < burn_cost); - assert_eq!(adjusted_burn, 875); - - let adjusted_diff = SubtensorModule::get_difficulty_as_u64(netuid); - assert_eq!(adjusted_diff, start_diff); - }); -} - -#[test] -#[allow(unused_assignments)] -fn test_burn_adjustment_case_d() { - // Test case D of the difficulty and burn adjustment algorithm. - // ==================== - // There are not enough registrations this interval and most of them are BURN registrations - // this triggers a decrease in the POW difficulty - new_test_ext(1).execute_with(|| { - let netuid: u16 = 1; - let tempo: u16 = 13; - let burn_cost: u64 = 1000; - let adjustment_interval = 1; - let target_registrations_per_interval = 4; // Needs registrations < 4 to trigger - let start_diff: u64 = 10_000; - let mut curr_block_num = 0; - add_network(netuid, tempo, 0); - SubtensorModule::set_burn(netuid, burn_cost); - SubtensorModule::set_difficulty(netuid, start_diff); - SubtensorModule::set_min_difficulty(netuid, 1); - SubtensorModule::set_adjustment_interval(netuid, adjustment_interval); - SubtensorModule::set_adjustment_alpha(netuid, 58000); // Set to old value. - SubtensorModule::set_target_registrations_per_interval( - netuid, - target_registrations_per_interval, - ); - - // Register key 1. This is a BURN registration - 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, 10000); - assert_ok!(SubtensorModule::burned_register( - <::RuntimeOrigin>::signed(hotkey_account_id_1), - netuid, - hotkey_account_id_1 - )); - - // Register key 2. This is a BURN registration - 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, 10000); - assert_ok!(SubtensorModule::burned_register( - <::RuntimeOrigin>::signed(hotkey_account_id_2), - netuid, - hotkey_account_id_2 - )); - - // Register key 3. This is a POW registration - let hotkey_account_id_3 = U256::from(3); - let coldkey_account_id_3 = U256::from(3); - let (nonce1, work1): (u64, Vec) = SubtensorModule::create_work_for_block_number( - netuid, - curr_block_num, - 11231312312, - &hotkey_account_id_3, - ); - let result1 = SubtensorModule::register( - <::RuntimeOrigin>::signed(hotkey_account_id_3), - netuid, - curr_block_num, - nonce1, - work1, - hotkey_account_id_3, - coldkey_account_id_3, - ); - assert_ok!(result1); - - // We are UNDER the number of regs allowed this interval. - // Most of them are BURN registrations (2 out of 3) - // Step the block and trigger the adjustment. - step_block(1); - curr_block_num += 1; - - // Check the adjusted POW difficulty has DECREASED. - // and the burn has not changed. - let adjusted_burn = SubtensorModule::get_burn_as_u64(netuid); - assert_eq!(adjusted_burn, burn_cost); - - let adjusted_diff = SubtensorModule::get_difficulty_as_u64(netuid); - assert!(adjusted_diff < start_diff); - assert_eq!(adjusted_diff, 8750); - }); -} - -#[test] -#[allow(unused_assignments)] -fn test_burn_adjustment_case_e() { - // Test case E of the difficulty and burn adjustment algorithm. - // ==================== - // There are not enough registrations this interval and nobody registered either POW or BURN - // this triggers a decrease in the BURN cost and POW difficulty - new_test_ext(1).execute_with(|| { - let netuid: u16 = 1; - let tempo: u16 = 13; - let burn_cost: u64 = 1000; - let adjustment_interval = 1; - let target_registrations_per_interval: u16 = 3; - let start_diff: u64 = 10_000; - let mut curr_block_num = 0; - add_network(netuid, tempo, 0); - SubtensorModule::set_max_registrations_per_block(netuid, 10); - SubtensorModule::set_burn(netuid, burn_cost); - SubtensorModule::set_difficulty(netuid, start_diff); - SubtensorModule::set_min_difficulty(netuid, 1); - SubtensorModule::set_adjustment_interval(netuid, adjustment_interval); - SubtensorModule::set_adjustment_alpha(netuid, 58000); // Set to old value. - SubtensorModule::set_target_registrations_per_interval( - netuid, - target_registrations_per_interval, - ); - - // Register key 1. This is a POW registration - let hotkey_account_id_1 = U256::from(1); - let coldkey_account_id_1 = U256::from(1); - let (nonce1, work1): (u64, Vec) = SubtensorModule::create_work_for_block_number( - netuid, - curr_block_num, - 11231312312, - &hotkey_account_id_1, - ); - let result1 = SubtensorModule::register( - <::RuntimeOrigin>::signed(hotkey_account_id_1), - netuid, - curr_block_num, - nonce1, - work1, - hotkey_account_id_1, - coldkey_account_id_1, - ); - assert_ok!(result1); - - // Register key 2. This is a BURN registration - 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, 10000); - assert_ok!(SubtensorModule::burned_register( - <::RuntimeOrigin>::signed(hotkey_account_id_2), - netuid, - hotkey_account_id_2 - )); - - step_block(1); - curr_block_num += 1; - - // We are UNDER the number of regs allowed this interval. - // And the number of regs of each type is equal - - // Check the adjusted BURN has DECREASED. - let adjusted_burn = SubtensorModule::get_burn_as_u64(netuid); - assert!(adjusted_burn < burn_cost); - assert_eq!(adjusted_burn, 833); - - // Check the adjusted POW difficulty has DECREASED. - let adjusted_diff = SubtensorModule::get_difficulty_as_u64(netuid); - assert!(adjusted_diff < start_diff); - assert_eq!(adjusted_diff, 8_333); - }); -} - -#[test] -#[allow(unused_assignments)] -fn test_burn_adjustment_case_f() { - // Test case F of the difficulty and burn adjustment algorithm. - // ==================== - // There are too many registrations this interval and the pow and burn registrations are equal - // this triggers an increase in the burn cost and pow difficulty - new_test_ext(1).execute_with(|| { - let netuid: u16 = 1; - let tempo: u16 = 13; - let burn_cost: u64 = 1000; - let adjustment_interval = 1; - let target_registrations_per_interval: u16 = 1; - let start_diff: u64 = 10_000; - let mut curr_block_num = 0; - add_network(netuid, tempo, 0); - SubtensorModule::set_max_registrations_per_block(netuid, 10); - SubtensorModule::set_burn(netuid, burn_cost); - SubtensorModule::set_difficulty(netuid, start_diff); - SubtensorModule::set_min_difficulty(netuid, start_diff); - SubtensorModule::set_adjustment_interval(netuid, adjustment_interval); - SubtensorModule::set_adjustment_alpha(netuid, 58000); // Set to old value. - SubtensorModule::set_target_registrations_per_interval( - netuid, - target_registrations_per_interval, - ); - - // Register key 1. This is a POW registration - let hotkey_account_id_1 = U256::from(1); - let coldkey_account_id_1 = U256::from(1); - let (nonce1, work1): (u64, Vec) = SubtensorModule::create_work_for_block_number( - netuid, - curr_block_num, - 11231312312, - &hotkey_account_id_1, - ); - let result1 = SubtensorModule::register( - <::RuntimeOrigin>::signed(hotkey_account_id_1), - netuid, - curr_block_num, - nonce1, - work1, - hotkey_account_id_1, - coldkey_account_id_1, - ); - assert_ok!(result1); - - // Register key 2. This is a BURN registration - 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, 10000); - assert_ok!(SubtensorModule::burned_register( - <::RuntimeOrigin>::signed(hotkey_account_id_2), - netuid, - hotkey_account_id_2 - )); - - step_block(1); - curr_block_num += 1; - // We are OVER the number of regs allowed this interval. - // And the number of regs of each type is equal - - // Check the adjusted BURN has INCREASED. - let adjusted_burn = SubtensorModule::get_burn_as_u64(netuid); - assert!(adjusted_burn > burn_cost); - assert_eq!(adjusted_burn, 1_500); - - // Check the adjusted POW difficulty has INCREASED. - let adjusted_diff = SubtensorModule::get_difficulty_as_u64(netuid); - assert!(adjusted_diff > start_diff); - assert_eq!(adjusted_diff, 15_000); - }); -} - -#[test] -fn test_burn_adjustment_case_e_zero_registrations() { - // Test case E of the difficulty and burn adjustment algorithm. - // ==================== - // There are not enough registrations this interval and nobody registered either POW or BURN - // this triggers a decrease in the BURN cost and POW difficulty - - // BUT there are zero registrations this interval. - new_test_ext(1).execute_with(|| { - let netuid: u16 = 1; - let tempo: u16 = 13; - let burn_cost: u64 = 1000; - let adjustment_interval = 1; - let target_registrations_per_interval: u16 = 1; - let start_diff: u64 = 10_000; - add_network(netuid, tempo, 0); - SubtensorModule::set_max_registrations_per_block(netuid, 10); - SubtensorModule::set_burn(netuid, burn_cost); - SubtensorModule::set_difficulty(netuid, start_diff); - SubtensorModule::set_min_difficulty(netuid, 1); - SubtensorModule::set_adjustment_interval(netuid, adjustment_interval); - SubtensorModule::set_adjustment_alpha(netuid, 58000); // Set to old value. - SubtensorModule::set_target_registrations_per_interval( - netuid, - target_registrations_per_interval, - ); - - // No registrations this interval of any kind. - step_block(1); - - // We are UNDER the number of regs allowed this interval. - // And the number of regs of each type is equal - - // Check the adjusted BURN has DECREASED. - let adjusted_burn = SubtensorModule::get_burn_as_u64(netuid); - assert!(adjusted_burn < burn_cost); - assert_eq!(adjusted_burn, 500); - - // Check the adjusted POW difficulty has DECREASED. - let adjusted_diff = SubtensorModule::get_difficulty_as_u64(netuid); - assert!(adjusted_diff < start_diff); - assert_eq!(adjusted_diff, 5_000); - }); -} - -#[test] -fn test_emission_based_on_registration_status() { - new_test_ext(1).execute_with(|| { - let n: u16 = 100; - let netuid_off: u16 = 1; - let netuid_on: u16 = 2; - let tempo: u16 = 1; - let netuids: Vec = vec![netuid_off, netuid_on]; - let emissions: Vec = vec![1000000000, 1000000000]; - - // Add subnets with registration turned off and on - add_network(netuid_off, tempo, 0); - add_network(netuid_on, tempo, 0); - SubtensorModule::set_max_allowed_uids(netuid_off, n); - SubtensorModule::set_max_allowed_uids(netuid_on, n); - SubtensorModule::set_emission_values(&netuids, emissions).unwrap(); - SubtensorModule::set_network_registration_allowed(netuid_off, false); - SubtensorModule::set_network_registration_allowed(netuid_on, true); - - // Populate the subnets with neurons - for i in 0..n { - SubtensorModule::append_neuron(netuid_off, &U256::from(i), 0); - SubtensorModule::append_neuron(netuid_on, &U256::from(i), 0); - } - - // Generate emission at block 0 - let block: u64 = 0; - SubtensorModule::generate_emission(block); - - // Verify that no emission tuples are loaded for the subnet with registration off - assert!(SubtensorModule::get_loaded_emission_tuples(netuid_off).is_none()); - - // Verify that emission tuples are loaded for the subnet with registration on - assert!(SubtensorModule::get_loaded_emission_tuples(netuid_on).is_some()); - assert_eq!( - SubtensorModule::get_loaded_emission_tuples(netuid_on) - .unwrap() - .len(), - n as usize - ); - - // Step to the next epoch block - let epoch_block: u16 = tempo; - step_block(epoch_block); - - // Verify that no emission tuples are loaded for the subnet with registration off - assert!(SubtensorModule::get_loaded_emission_tuples(netuid_off).is_none()); - log::info!( - "Emissions for netuid with registration off: {:?}", - SubtensorModule::get_loaded_emission_tuples(netuid_off) - ); - - // Verify that emission tuples are loaded for the subnet with registration on - assert!(SubtensorModule::get_loaded_emission_tuples(netuid_on).is_some()); - log::info!( - "Emissions for netuid with registration on: {:?}", - SubtensorModule::get_loaded_emission_tuples(netuid_on) - ); - assert_eq!( - SubtensorModule::get_loaded_emission_tuples(netuid_on) - .unwrap() - .len(), - n as usize - ); - - let block: u64 = 0; - // drain the emission tuples for the subnet with registration on - SubtensorModule::drain_emission(block); - // Turn on registration for the subnet with registration off - SubtensorModule::set_network_registration_allowed(netuid_off, true); - SubtensorModule::set_network_registration_allowed(netuid_on, false); - - // Generate emission at the next block - let next_block: u64 = block + 1; - SubtensorModule::generate_emission(next_block); - - // Verify that emission tuples are now loaded for the subnet with registration turned on - assert!(SubtensorModule::get_loaded_emission_tuples(netuid_off).is_some()); - log::info!( - "Emissions for netuid with registration on: {:?}", - SubtensorModule::get_loaded_emission_tuples(netuid_on) - ); - assert!(SubtensorModule::get_loaded_emission_tuples(netuid_on).is_none()); - assert_eq!( - SubtensorModule::get_loaded_emission_tuples(netuid_off) - .unwrap() - .len(), - n as usize - ); - }); -} - -#[test] -fn test_epoch_runs_when_registration_disabled() { - new_test_ext(1).execute_with(|| { - let n: u16 = 100; - let netuid_off: u16 = 1; - let tempo: u16 = 1; - let netuids: Vec = vec![netuid_off]; - let emissions: Vec = vec![1000000000]; - - // Add subnets with registration turned off and on - add_network(netuid_off, tempo, 0); - SubtensorModule::set_max_allowed_uids(netuid_off, n); - SubtensorModule::set_emission_values(&netuids, emissions).unwrap(); - SubtensorModule::set_network_registration_allowed(netuid_off, false); - - // Populate the subnets with neurons - for i in 0..n { - SubtensorModule::append_neuron(netuid_off, &U256::from(i), 0); - } - - // Generate emission at block 1 - let block: u64 = 1; - SubtensorModule::generate_emission(block); - - step_block(1); // Now block 2 - - // Verify blocks since last step was set - assert_eq!(SubtensorModule::get_blocks_since_last_step(netuid_off), 1); - - // Step to the next epoch block - let epoch_block: u16 = tempo; - step_block(epoch_block); - - // Verify blocks since last step was set, this indicates we ran the epoch - assert_eq!( - SubtensorModule::get_blocks_since_last_step(netuid_off), - 0_u64 - ); - assert!(SubtensorModule::get_loaded_emission_tuples(netuid_off).is_some()); - }); -} diff --git a/pallets/subtensor/tests/coinbase.rs b/pallets/subtensor/tests/coinbase.rs index cd7d2cc81..aed3c9b55 100644 --- a/pallets/subtensor/tests/coinbase.rs +++ b/pallets/subtensor/tests/coinbase.rs @@ -135,6 +135,7 @@ fn test_coinbase_basic() { } // Test getting and setting hotkey emission tempo +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test coinbase test_set_and_get_hotkey_emission_tempo -- --nocapture #[test] #[cfg(not(tarpaulin))] fn test_set_and_get_hotkey_emission_tempo() { diff --git a/pallets/subtensor/tests/mock.rs b/pallets/subtensor/tests/mock.rs index 71e1d593b..27d11eb13 100644 --- a/pallets/subtensor/tests/mock.rs +++ b/pallets/subtensor/tests/mock.rs @@ -168,6 +168,9 @@ parameter_types! { pub const InitialAlphaHigh: u16 = 58982; // Represents 0.9 as per the production default pub const InitialAlphaLow: u16 = 45875; // Represents 0.7 as per the production default pub const InitialLiquidAlphaOn: bool = false; // Default value for LiquidAlphaOn + pub const InitialHotkeyEmissionTempo: u64 = 0; // Defaults to draining every block. + pub const InitialNetworkMaxStake: u64 = 500_000_000_000_000; // 500,000 TAO + } // Configure collective pallet for council @@ -378,6 +381,8 @@ impl pallet_subtensor::Config for Test { type AlphaHigh = InitialAlphaHigh; type AlphaLow = InitialAlphaLow; type LiquidAlphaOn = InitialLiquidAlphaOn; + type InitialHotkeyEmissionTempo = InitialHotkeyEmissionTempo; + type InitialNetworkMaxStake = InitialNetworkMaxStake; } impl pallet_utility::Config for Test { diff --git a/pallets/subtensor/tests/staking.rs b/pallets/subtensor/tests/staking.rs index ece30391d..2952426a9 100644 --- a/pallets/subtensor/tests/staking.rs +++ b/pallets/subtensor/tests/staking.rs @@ -1189,1082 +1189,6 @@ fn test_delegate_stake_division_by_zero_check() { <::RuntimeOrigin>::signed(coldkey), hotkey )); - SubtensorModule::emit_inflation_through_hotkey_account(&hotkey, 0, 1000); - }); -} - -#[test] -#[cfg(not(tarpaulin))] -fn test_full_with_delegating() { - new_test_ext(1).execute_with(|| { - let netuid = 1; - // Make two accounts. - let hotkey0 = U256::from(1); - let hotkey1 = U256::from(2); - - let coldkey0 = U256::from(3); - let coldkey1 = U256::from(4); - add_network(netuid, 0, 0); - SubtensorModule::set_max_registrations_per_block(netuid, 4); - SubtensorModule::set_target_registrations_per_interval(netuid, 4); - SubtensorModule::set_max_allowed_uids(netuid, 4); // Allow all 4 to be registered at once - SubtensorModule::set_target_stakes_per_interval(10); // Increase max stakes per interval - - // Neither key can add stake because they dont have fundss. - assert_eq!( - SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(coldkey0), - hotkey0, - 60000 - ), - Err(Error::::NotEnoughBalanceToStake.into()) - ); - assert_eq!( - SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(coldkey1), - hotkey1, - 60000 - ), - Err(Error::::NotEnoughBalanceToStake.into()) - ); - - // Add balances. - SubtensorModule::add_balance_to_coldkey_account(&coldkey0, 60000); - SubtensorModule::add_balance_to_coldkey_account(&coldkey1, 60000); - - // We have enough, but the keys are not registered. - assert_eq!( - SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(coldkey0), - hotkey0, - 100 - ), - Err(Error::::HotKeyAccountNotExists.into()) - ); - assert_eq!( - SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(coldkey0), - hotkey0, - 100 - ), - Err(Error::::HotKeyAccountNotExists.into()) - ); - - // Cant remove either. - assert_eq!( - SubtensorModule::remove_stake( - <::RuntimeOrigin>::signed(coldkey0), - hotkey0, - 10 - ), - Err(Error::::HotKeyAccountNotExists.into()) - ); - assert_eq!( - SubtensorModule::remove_stake( - <::RuntimeOrigin>::signed(coldkey1), - hotkey1, - 10 - ), - Err(Error::::HotKeyAccountNotExists.into()) - ); - assert_eq!( - SubtensorModule::remove_stake( - <::RuntimeOrigin>::signed(coldkey0), - hotkey1, - 10 - ), - Err(Error::::HotKeyAccountNotExists.into()) - ); - assert_eq!( - SubtensorModule::remove_stake( - <::RuntimeOrigin>::signed(coldkey1), - hotkey0, - 10 - ), - Err(Error::::HotKeyAccountNotExists.into()) - ); - - // Neither key can become a delegate either because we are not registered. - assert_eq!( - SubtensorModule::do_become_delegate( - <::RuntimeOrigin>::signed(coldkey0), - hotkey0, - 100 - ), - Err(Error::::HotKeyAccountNotExists.into()) - ); - assert_eq!( - SubtensorModule::do_become_delegate( - <::RuntimeOrigin>::signed(coldkey0), - hotkey0, - 100 - ), - Err(Error::::HotKeyAccountNotExists.into()) - ); - - // Register the 2 neurons to a new network. - register_ok_neuron(netuid, hotkey0, coldkey0, 124124); - register_ok_neuron(netuid, hotkey1, coldkey1, 987907); - assert_eq!( - SubtensorModule::get_owning_coldkey_for_hotkey(&hotkey0), - coldkey0 - ); - assert_eq!( - SubtensorModule::get_owning_coldkey_for_hotkey(&hotkey1), - coldkey1 - ); - assert!(SubtensorModule::coldkey_owns_hotkey(&coldkey0, &hotkey0)); - assert!(SubtensorModule::coldkey_owns_hotkey(&coldkey1, &hotkey1)); - - // We try to delegate stake but niether are allowing delegation. - assert!(!SubtensorModule::hotkey_is_delegate(&hotkey0)); - assert!(!SubtensorModule::hotkey_is_delegate(&hotkey1)); - assert_eq!( - SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(coldkey0), - hotkey1, - 100 - ), - Err(Error::::HotKeyNotDelegateAndSignerNotOwnHotKey.into()) - ); - assert_eq!( - SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(coldkey1), - hotkey0, - 100 - ), - Err(Error::::HotKeyNotDelegateAndSignerNotOwnHotKey.into()) - ); - - // We stake and all is ok. - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey0, &hotkey0), - 0 - ); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey0, &hotkey0), - 0 - ); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey0, &hotkey0), - 0 - ); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey0, &hotkey0), - 0 - ); - assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(coldkey0), - hotkey0, - 100 - )); - assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(coldkey1), - hotkey1, - 100 - )); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey0, &hotkey0), - 100 - ); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey0, &hotkey1), - 0 - ); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey1, &hotkey0), - 0 - ); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey1, &hotkey1), - 100 - ); - assert_eq!(SubtensorModule::get_total_stake_for_hotkey(&hotkey0), 100); - assert_eq!(SubtensorModule::get_total_stake_for_hotkey(&hotkey1), 100); - //assert_eq!( SubtensorModule::get_total_stake_for_coldkey( &coldkey0 ), 100 ); - //assert_eq!( SubtensorModule::get_total_stake_for_coldkey( &coldkey1 ), 100 ); - assert_eq!(SubtensorModule::get_total_stake(), 200); - - // Cant remove these funds because we are not delegating. - assert_eq!( - SubtensorModule::remove_stake( - <::RuntimeOrigin>::signed(coldkey0), - hotkey1, - 10 - ), - Err(Error::::HotKeyNotDelegateAndSignerNotOwnHotKey.into()) - ); - assert_eq!( - SubtensorModule::remove_stake( - <::RuntimeOrigin>::signed(coldkey1), - hotkey0, - 10 - ), - Err(Error::::HotKeyNotDelegateAndSignerNotOwnHotKey.into()) - ); - - // Emit inflation through non delegates. - SubtensorModule::emit_inflation_through_hotkey_account(&hotkey0, 0, 100); - SubtensorModule::emit_inflation_through_hotkey_account(&hotkey1, 0, 100); - assert_eq!(SubtensorModule::get_total_stake_for_hotkey(&hotkey0), 200); - assert_eq!(SubtensorModule::get_total_stake_for_hotkey(&hotkey1), 200); - - // Try allowing the keys to become delegates, fails because of incorrect coldkeys. - // Set take to be 0. - assert_eq!( - SubtensorModule::do_become_delegate( - <::RuntimeOrigin>::signed(coldkey0), - hotkey1, - 0 - ), - Err(Error::::NonAssociatedColdKey.into()) - ); - assert_eq!( - SubtensorModule::do_become_delegate( - <::RuntimeOrigin>::signed(coldkey1), - hotkey0, - 0 - ), - Err(Error::::NonAssociatedColdKey.into()) - ); - - // Become delegates all is ok. - assert_ok!(SubtensorModule::do_become_delegate( - <::RuntimeOrigin>::signed(coldkey0), - hotkey0, - SubtensorModule::get_min_take() - )); - assert_ok!(SubtensorModule::do_become_delegate( - <::RuntimeOrigin>::signed(coldkey1), - hotkey1, - SubtensorModule::get_min_take() - )); - assert!(SubtensorModule::hotkey_is_delegate(&hotkey0)); - assert!(SubtensorModule::hotkey_is_delegate(&hotkey1)); - - // Cant become a delegate twice. - assert_eq!( - SubtensorModule::do_become_delegate( - <::RuntimeOrigin>::signed(coldkey0), - hotkey0, - SubtensorModule::get_min_take() - ), - Err(Error::::HotKeyAlreadyDelegate.into()) - ); - assert_eq!( - SubtensorModule::do_become_delegate( - <::RuntimeOrigin>::signed(coldkey1), - hotkey1, - u16::MAX / 10 - ), - Err(Error::::HotKeyAlreadyDelegate.into()) - ); - - // This add stake works for delegates. - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey0, &hotkey0), - 200 - ); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey0, &hotkey1), - 0 - ); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey1, &hotkey0), - 0 - ); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey1, &hotkey1), - 200 - ); - assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(coldkey0), - hotkey1, - 200 - )); - assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(coldkey1), - hotkey0, - 300 - )); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey0, &hotkey0), - 200 - ); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey0, &hotkey1), - 200 - ); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey1, &hotkey0), - 300 - ); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey1, &hotkey1), - 200 - ); - assert_eq!(SubtensorModule::get_total_stake_for_hotkey(&hotkey0), 500); - assert_eq!(SubtensorModule::get_total_stake_for_hotkey(&hotkey1), 400); - //assert_eq!( SubtensorModule::get_total_stake_for_coldkey( &coldkey0 ), 400 ); - //assert_eq!( SubtensorModule::get_total_stake_for_coldkey( &coldkey1 ), 500 ); - assert_eq!(SubtensorModule::get_total_stake(), 900); - - // Lets emit inflation through the hot and coldkeys. - SubtensorModule::emit_inflation_through_hotkey_account(&hotkey0, 0, 1000); - SubtensorModule::emit_inflation_through_hotkey_account(&hotkey1, 0, 1000); - - // validator_take = take * validator_emission = 10% * 1000 = 100 - // old_stake + (validator_emission - validator_take) * stake_for_coldkey_and_hotkey / total_stake_for_hotkey + validator_take - // = - // 200 + 900 * 200 / 500 + 100 = 660 - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey0, &hotkey0), - 654 - ); - // validator_take = take * validator_emission = 9% * 1000 = 90 - // old_stake + (validator_emission - validator_take) * stake_for_coldkey_and_hotkey / total_stake_for_hotkey - // = - // 200 + (1000 - 90) * 200 / 400 = 655 ~ 654 - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey0, &hotkey1), - 655 - ); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey1, &hotkey0), - 846 - ); // 300 + 910 x ( 300 / 500 ) = 300 + 546 = 846 - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey1, &hotkey1), - 745 - ); // 200 + 1090 x ( 200 / 400 ) = 300 + 545 = 745 - assert_eq!(SubtensorModule::get_total_stake(), 2900); // 600 + 700 + 900 + 750 = 2900 - - // // Try unstaking too much. - assert_eq!( - SubtensorModule::remove_stake( - <::RuntimeOrigin>::signed(coldkey0), - hotkey0, - 100000 - ), - Err(Error::::NotEnoughStakeToWithdraw.into()) - ); - assert_eq!( - SubtensorModule::remove_stake( - <::RuntimeOrigin>::signed(coldkey1), - hotkey1, - 100000 - ), - Err(Error::::NotEnoughStakeToWithdraw.into()) - ); - assert_eq!( - SubtensorModule::remove_stake( - <::RuntimeOrigin>::signed(coldkey0), - hotkey1, - 100000 - ), - Err(Error::::NotEnoughStakeToWithdraw.into()) - ); - assert_eq!( - SubtensorModule::remove_stake( - <::RuntimeOrigin>::signed(coldkey1), - hotkey0, - 100000 - ), - Err(Error::::NotEnoughStakeToWithdraw.into()) - ); - - // unstaking is ok. - assert_ok!(SubtensorModule::remove_stake( - <::RuntimeOrigin>::signed(coldkey0), - hotkey0, - 100 - )); - assert_ok!(SubtensorModule::remove_stake( - <::RuntimeOrigin>::signed(coldkey1), - hotkey1, - 100 - )); - assert_ok!(SubtensorModule::remove_stake( - <::RuntimeOrigin>::signed(coldkey0), - hotkey1, - 100 - )); - assert_ok!(SubtensorModule::remove_stake( - <::RuntimeOrigin>::signed(coldkey1), - hotkey0, - 100 - )); - - // All the amounts have been decreased. - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey0, &hotkey0), - 554 - ); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey0, &hotkey1), - 555 - ); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey1, &hotkey0), - 746 - ); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey1, &hotkey1), - 645 - ); - - // Lets register and stake a new key. - let hotkey2 = U256::from(5); - let coldkey2 = U256::from(6); - register_ok_neuron(netuid, hotkey2, coldkey2, 248_123); - assert!(SubtensorModule::is_hotkey_registered_on_any_network( - &hotkey0 - )); - assert!(SubtensorModule::is_hotkey_registered_on_any_network( - &hotkey1 - )); - - SubtensorModule::add_balance_to_coldkey_account(&coldkey2, 60_000); - assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(coldkey2), - hotkey2, - 1000 - )); - assert_ok!(SubtensorModule::remove_stake( - <::RuntimeOrigin>::signed(coldkey2), - hotkey2, - 100 - )); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey2, &hotkey2), - 900 - ); - assert_eq!( - SubtensorModule::remove_stake( - <::RuntimeOrigin>::signed(coldkey0), - hotkey2, - 10 - ), - Err(Error::::HotKeyNotDelegateAndSignerNotOwnHotKey.into()) - ); - assert_eq!( - SubtensorModule::remove_stake( - <::RuntimeOrigin>::signed(coldkey1), - hotkey2, - 10 - ), - Err(Error::::HotKeyNotDelegateAndSignerNotOwnHotKey.into()) - ); - - // Lets make this new key a delegate with a 10% take. - assert_ok!(SubtensorModule::do_become_delegate( - <::RuntimeOrigin>::signed(coldkey2), - hotkey2, - SubtensorModule::get_min_take() - )); - - // Add nominate some stake. - assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(coldkey0), - hotkey2, - 1_000 - )); - assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(coldkey1), - hotkey2, - 1_000 - )); - assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(coldkey2), - hotkey2, - 100 - )); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey2, &hotkey2), - 1_000 - ); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey1, &hotkey2), - 1_000 - ); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey0, &hotkey2), - 1_000 - ); - assert_eq!(SubtensorModule::get_total_stake_for_hotkey(&hotkey2), 3_000); - assert_eq!(SubtensorModule::get_total_stake(), 5_500); - - // Lets emit inflation through this new key with distributed ownership. - SubtensorModule::emit_inflation_through_hotkey_account(&hotkey2, 0, 1000); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey2, &hotkey2), - 1_394 - ); // 1000 + 94 + 900 * (1000/3000) = 1400 - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey1, &hotkey2), - 1_303 - ); // 1000 + 900 * (1000/3000) = 1300 - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey0, &hotkey2), - 1_303 - ); // 1000 + 900 * (1000/3000) = 1300 - assert_eq!(SubtensorModule::get_total_stake(), 6_500); // before + 1_000 = 5_500 + 1_000 = 6_500 - - step_block(1); - - // Lets register and stake a new key. - let hotkey3 = U256::from(7); - let coldkey3 = U256::from(8); - register_ok_neuron(netuid, hotkey3, coldkey3, 4124124); - SubtensorModule::add_balance_to_coldkey_account(&coldkey3, 60000); - assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(coldkey3), - hotkey3, - 1000 - )); - - step_block(3); - - assert_ok!(SubtensorModule::do_become_delegate( - <::RuntimeOrigin>::signed(coldkey3), - hotkey3, - SubtensorModule::get_min_take() - )); // Full take. - assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(coldkey0), - hotkey3, - 1000 - )); - assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(coldkey1), - hotkey3, - 1000 - )); - assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(coldkey2), - hotkey3, - 1000 - )); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey0, &hotkey3), - 1000 - ); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey1, &hotkey3), - 1000 - ); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey2, &hotkey3), - 1000 - ); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey3, &hotkey3), - 1000 - ); - assert_eq!(SubtensorModule::get_total_stake_for_hotkey(&hotkey3), 4000); - assert_eq!(SubtensorModule::get_total_stake(), 10_500); - SubtensorModule::emit_inflation_through_hotkey_account(&hotkey3, 0, 1000); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey0, &hotkey3), - 1227 - ); // 1000 + 90% * 1000 * 1000/4000 = 1225 - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey1, &hotkey3), - 1227 - ); // 1000 + 90% * 1000 * 1000/4000 = 1225 - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey2, &hotkey3), - 1227 - ); // 1000 + 90% * 1000 * 1000/4000 = 1225 - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey3, &hotkey3), - 1319 - ); // 1000 + 25 * 3 + 1000 * 1000/4000 = 1325 - assert_eq!(SubtensorModule::get_total_stake(), 11_500); // before + 1_000 = 10_500 + 1_000 = 11_500 - }); -} - -// Verify delegates with servers get the full server inflation. -#[test] -fn test_full_with_delegating_some_servers() { - new_test_ext(1).execute_with(|| { - let netuid = 1; - // Make two accounts. - let hotkey0 = U256::from(1); - let hotkey1 = U256::from(2); - - let coldkey0 = U256::from(3); - let coldkey1 = U256::from(4); - SubtensorModule::set_max_registrations_per_block(netuid, 4); - SubtensorModule::set_max_allowed_uids(netuid, 10); // Allow at least 10 to be registered at once, so no unstaking occurs - SubtensorModule::set_target_stakes_per_interval(10); // Increase max stakes per interval - - // Neither key can add stake because they dont have fundss. - assert_eq!( - SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(coldkey0), - hotkey0, - 60000 - ), - Err(Error::::NotEnoughBalanceToStake.into()) - ); - assert_eq!( - SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(coldkey1), - hotkey1, - 60000 - ), - Err(Error::::NotEnoughBalanceToStake.into()) - ); - - // Add balances. - SubtensorModule::add_balance_to_coldkey_account(&coldkey0, 60000); - SubtensorModule::add_balance_to_coldkey_account(&coldkey1, 60000); - - // Register the 2 neurons to a new network. - let netuid = 1; - add_network(netuid, 0, 0); - register_ok_neuron(netuid, hotkey0, coldkey0, 124124); - register_ok_neuron(netuid, hotkey1, coldkey1, 987907); - assert_eq!( - SubtensorModule::get_owning_coldkey_for_hotkey(&hotkey0), - coldkey0 - ); - assert_eq!( - SubtensorModule::get_owning_coldkey_for_hotkey(&hotkey1), - coldkey1 - ); - assert!(SubtensorModule::coldkey_owns_hotkey(&coldkey0, &hotkey0)); - assert!(SubtensorModule::coldkey_owns_hotkey(&coldkey1, &hotkey1)); - - // We stake and all is ok. - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey0, &hotkey0), - 0 - ); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey0, &hotkey0), - 0 - ); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey0, &hotkey0), - 0 - ); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey0, &hotkey0), - 0 - ); - assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(coldkey0), - hotkey0, - 100 - )); - assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(coldkey1), - hotkey1, - 100 - )); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey0, &hotkey0), - 100 - ); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey0, &hotkey1), - 0 - ); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey1, &hotkey0), - 0 - ); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey1, &hotkey1), - 100 - ); - assert_eq!(SubtensorModule::get_total_stake_for_hotkey(&hotkey0), 100); - assert_eq!(SubtensorModule::get_total_stake_for_hotkey(&hotkey1), 100); - assert_eq!(SubtensorModule::get_total_stake(), 200); - - // Emit inflation through non delegates. - SubtensorModule::emit_inflation_through_hotkey_account(&hotkey0, 0, 100); - SubtensorModule::emit_inflation_through_hotkey_account(&hotkey1, 0, 100); - assert_eq!(SubtensorModule::get_total_stake_for_hotkey(&hotkey0), 200); - assert_eq!(SubtensorModule::get_total_stake_for_hotkey(&hotkey1), 200); - - // Become delegates all is ok. - assert_ok!(SubtensorModule::do_become_delegate( - <::RuntimeOrigin>::signed(coldkey0), - hotkey0, - SubtensorModule::get_min_take() - )); - assert_ok!(SubtensorModule::do_become_delegate( - <::RuntimeOrigin>::signed(coldkey1), - hotkey1, - SubtensorModule::get_min_take() - )); - assert!(SubtensorModule::hotkey_is_delegate(&hotkey0)); - assert!(SubtensorModule::hotkey_is_delegate(&hotkey1)); - - // This add stake works for delegates. - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey0, &hotkey0), - 200 - ); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey0, &hotkey1), - 0 - ); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey1, &hotkey0), - 0 - ); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey1, &hotkey1), - 200 - ); - assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(coldkey0), - hotkey1, - 200 - )); - assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(coldkey1), - hotkey0, - 300 - )); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey0, &hotkey0), - 200 - ); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey0, &hotkey1), - 200 - ); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey1, &hotkey0), - 300 - ); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey1, &hotkey1), - 200 - ); - assert_eq!(SubtensorModule::get_total_stake_for_hotkey(&hotkey0), 500); - assert_eq!(SubtensorModule::get_total_stake_for_hotkey(&hotkey1), 400); - assert_eq!(SubtensorModule::get_total_stake(), 900); - - // Lets emit inflation through the hot and coldkeys. - // fist emission arg is for a server. This should only go to the owner of the hotkey. - SubtensorModule::emit_inflation_through_hotkey_account(&hotkey0, 200, 1_000); // 1_200 total emission. - SubtensorModule::emit_inflation_through_hotkey_account(&hotkey1, 123, 2_000); // 2_123 total emission. - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey0, &hotkey0), - 854 - ); // 200 + (200 + 910 x ( 200 / 500 )) = 200 + (200 + 400) + 60 = 854 - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey1, &hotkey0), - 846 - ); // 300 + 910 x ( 300 / 500 ) = 300 + 546 = 846 - assert_eq!(SubtensorModule::get_total_stake_for_hotkey(&hotkey0), 1_700); // initial + server emission + validator emission = 799 + 899 = 1_698 - - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey0, &hotkey1), - 1_110 - ); // 200 + (0 + 2000 x ( 200 / 400 )) - 100 = 200 + (1000) - 100= 1_110 - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey1, &hotkey1), - 1_413 - ); // 200 + (123 + 2000 x ( 200 / 400 )) + 100 = 200 + (1_200)+ 100 = 1_423 - assert_eq!(SubtensorModule::get_total_stake_for_hotkey(&hotkey1), 2_523); // 400 + 2_123 - assert_eq!(SubtensorModule::get_total_stake(), 4_223); // 2_100 + 2_123 = 4_223 - - // Lets emit MORE inflation through the hot and coldkeys. - // This time only server emission. This should go to the owner of the hotkey. - SubtensorModule::emit_inflation_through_hotkey_account(&hotkey0, 350, 0); - SubtensorModule::emit_inflation_through_hotkey_account(&hotkey1, 150, 0); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey0, &hotkey0), - 1_204 - ); // + 350 + 54 = 1_204 - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey0, &hotkey1), - 1_110 - ); // No change. - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey1, &hotkey0), - 846 - ); // No change. - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey1, &hotkey1), - 1_563 - ); // 1_323 + 150 + 90 = 1_573 - assert_eq!(SubtensorModule::get_total_stake(), 4_723); // 4_223 + 500 = 4_823 - - // Lets register and stake a new key. - let hotkey2 = U256::from(5); - let coldkey2 = U256::from(6); - register_ok_neuron(netuid, hotkey2, coldkey2, 248123); - SubtensorModule::add_balance_to_coldkey_account(&coldkey2, 60_000); - assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(coldkey2), - hotkey2, - 1_000 - )); - assert_ok!(SubtensorModule::remove_stake( - <::RuntimeOrigin>::signed(coldkey2), - hotkey2, - 100 - )); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey2, &hotkey2), - 900 - ); - assert_eq!( - SubtensorModule::remove_stake( - <::RuntimeOrigin>::signed(coldkey0), - hotkey2, - 10 - ), - Err(Error::::HotKeyNotDelegateAndSignerNotOwnHotKey.into()) - ); - assert_eq!( - SubtensorModule::remove_stake( - <::RuntimeOrigin>::signed(coldkey1), - hotkey2, - 10 - ), - Err(Error::::HotKeyNotDelegateAndSignerNotOwnHotKey.into()) - ); - - assert_eq!(SubtensorModule::get_total_stake(), 5_623); // 4_723 + 900 = 5_623 - - // Lets make this new key a delegate with a 9% take. - assert_ok!(SubtensorModule::do_become_delegate( - <::RuntimeOrigin>::signed(coldkey2), - hotkey2, - SubtensorModule::get_min_take() - )); - - // Add nominate some stake. - assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(coldkey0), - hotkey2, - 1000 - )); - assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(coldkey1), - hotkey2, - 1000 - )); - assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(coldkey2), - hotkey2, - 100 - )); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey2, &hotkey2), - 1000 - ); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey1, &hotkey2), - 1000 - ); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey0, &hotkey2), - 1000 - ); - assert_eq!(SubtensorModule::get_total_stake_for_hotkey(&hotkey2), 3_000); - assert_eq!(SubtensorModule::get_total_stake(), 7_723); // 5_623 + (1_000 + 1_000 + 100) = 7_723 - - // Lets emit inflation through this new key with distributed ownership. - // We will emit 100 server emission, which should go in-full to the owner of the hotkey. - // We will emit 1000 validator emission, which should be distributed in-part to the nominators. - SubtensorModule::emit_inflation_through_hotkey_account(&hotkey2, 100, 1000); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey2, &hotkey2), - 1_494 - ); // 1000 + 100 + 94 + 900 * (1000/3000) = 1000 + 200 + 300 = 1_494 - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey1, &hotkey2), - 1_303 - ); // 1000 + 900 * (1000/3000) = 1000 + 300 = 1_303 - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey0, &hotkey2), - 1_303 - ); // 1000 + 900 * (1000/3000) = 1000 + 300 = 1300 - assert_eq!(SubtensorModule::get_total_stake(), 8_823); // 7_723 + 1_100 = 8_823 - - // Lets emit MORE inflation through this new key with distributed ownership. - // This time we do ONLY server emission - // We will emit 123 server emission, which should go in-full to the owner of the hotkey. - // We will emit *0* validator emission. - SubtensorModule::emit_inflation_through_hotkey_account(&hotkey2, 123, 0); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey2, &hotkey2), - 1_617 - ); // 1_500 + 117 = 1_617 - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey1, &hotkey2), - 1_303 - ); // No change. - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey0, &hotkey2), - 1_303 - ); // No change. - assert_eq!(SubtensorModule::get_total_stake(), 8_946); // 8_823 + 123 = 8_946 - }); -} - -#[test] -fn test_full_block_emission_occurs() { - new_test_ext(1).execute_with(|| { - let netuid = 1; - // Make two accounts. - let hotkey0 = U256::from(1); - let hotkey1 = U256::from(2); - - let coldkey0 = U256::from(3); - let coldkey1 = U256::from(4); - SubtensorModule::set_max_registrations_per_block(netuid, 4); - SubtensorModule::set_max_allowed_uids(netuid, 10); // Allow at least 10 to be registered at once, so no unstaking occurs - SubtensorModule::set_target_stakes_per_interval(10); // Increase max stakes per interval - - // Neither key can add stake because they dont have fundss. - assert_eq!( - SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(coldkey0), - hotkey0, - 60000 - ), - Err(Error::::NotEnoughBalanceToStake.into()) - ); - assert_eq!( - SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(coldkey1), - hotkey1, - 60000 - ), - Err(Error::::NotEnoughBalanceToStake.into()) - ); - - // Add balances. - SubtensorModule::add_balance_to_coldkey_account(&coldkey0, 60000); - SubtensorModule::add_balance_to_coldkey_account(&coldkey1, 60000); - - // Register the 2 neurons to a new network. - let netuid = 1; - add_network(netuid, 0, 0); - register_ok_neuron(netuid, hotkey0, coldkey0, 124124); - register_ok_neuron(netuid, hotkey1, coldkey1, 987907); - assert_eq!( - SubtensorModule::get_owning_coldkey_for_hotkey(&hotkey0), - coldkey0 - ); - assert_eq!( - SubtensorModule::get_owning_coldkey_for_hotkey(&hotkey1), - coldkey1 - ); - assert!(SubtensorModule::coldkey_owns_hotkey(&coldkey0, &hotkey0)); - assert!(SubtensorModule::coldkey_owns_hotkey(&coldkey1, &hotkey1)); - - // We stake and all is ok. - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey0, &hotkey0), - 0 - ); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey0, &hotkey0), - 0 - ); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey0, &hotkey0), - 0 - ); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey0, &hotkey0), - 0 - ); - assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(coldkey0), - hotkey0, - 100 - )); - assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(coldkey1), - hotkey1, - 100 - )); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey0, &hotkey0), - 100 - ); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey0, &hotkey1), - 0 - ); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey1, &hotkey0), - 0 - ); - assert_eq!( - SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey1, &hotkey1), - 100 - ); - assert_eq!(SubtensorModule::get_total_stake_for_hotkey(&hotkey0), 100); - assert_eq!(SubtensorModule::get_total_stake_for_hotkey(&hotkey1), 100); - assert_eq!(SubtensorModule::get_total_stake(), 200); - - // Emit inflation through non delegates. - SubtensorModule::emit_inflation_through_hotkey_account(&hotkey0, 0, 111); - SubtensorModule::emit_inflation_through_hotkey_account(&hotkey1, 0, 234); - // Verify the full emission occurs. - assert_eq!(SubtensorModule::get_total_stake(), 200 + 111 + 234); // 200 + 111 + 234 = 545 - - // Become delegates all is ok. - assert_ok!(SubtensorModule::do_become_delegate( - <::RuntimeOrigin>::signed(coldkey0), - hotkey0, - SubtensorModule::get_min_take() - )); - assert_ok!(SubtensorModule::do_become_delegate( - <::RuntimeOrigin>::signed(coldkey1), - hotkey1, - SubtensorModule::get_min_take() - )); - assert!(SubtensorModule::hotkey_is_delegate(&hotkey0)); - assert!(SubtensorModule::hotkey_is_delegate(&hotkey1)); - - // Add some delegate stake - assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(coldkey0), - hotkey1, - 200 - )); - assert_ok!(SubtensorModule::add_stake( - <::RuntimeOrigin>::signed(coldkey1), - hotkey0, - 300 - )); - - assert_eq!(SubtensorModule::get_total_stake(), 545 + 500); // 545 + 500 = 1045 - - // Lets emit inflation with delegatees, with both validator and server emission - SubtensorModule::emit_inflation_through_hotkey_account(&hotkey0, 200, 1_000); // 1_200 total emission. - SubtensorModule::emit_inflation_through_hotkey_account(&hotkey1, 123, 2_000); // 2_123 total emission. - - assert_eq!(SubtensorModule::get_total_stake(), 1045 + 1_200 + 2_123); // before + 1_200 + 2_123 = 4_368 - - // Lets emit MORE inflation through the hot and coldkeys. - // This time JUSt server emission - SubtensorModule::emit_inflation_through_hotkey_account(&hotkey0, 350, 0); - SubtensorModule::emit_inflation_through_hotkey_account(&hotkey1, 150, 0); - - assert_eq!(SubtensorModule::get_total_stake(), 4_368 + 350 + 150); // before + 350 + 150 = 4_868 - - // Lastly, do only validator emission - - SubtensorModule::emit_inflation_through_hotkey_account(&hotkey0, 0, 12_948); - SubtensorModule::emit_inflation_through_hotkey_account(&hotkey1, 0, 1_874); - - assert_eq!(SubtensorModule::get_total_stake(), 4_868 + 12_948 + 1_874); // before + 12_948 + 1_874 = 19_690 }); } diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index df1687fdf..119156228 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -880,6 +880,8 @@ parameter_types! { pub const InitialAlphaHigh: u16 = 58982; // Represents 0.9 as per the production default pub const InitialAlphaLow: u16 = 45875; // Represents 0.7 as per the production default pub const InitialLiquidAlphaOn: bool = false; // Default value for LiquidAlphaOn + pub const SubtensorInitialHotkeyEmissionTempo: u64 = 7200; // Drain every day. + pub const SubtensorInitialNetworkMaxStake: u64 = 500_000_000_000_000; // 500_000 TAO } impl pallet_subtensor::Config for Runtime { @@ -935,6 +937,8 @@ impl pallet_subtensor::Config for Runtime { type AlphaHigh = InitialAlphaHigh; type AlphaLow = InitialAlphaLow; type LiquidAlphaOn = InitialLiquidAlphaOn; + type InitialHotkeyEmissionTempo = SubtensorInitialHotkeyEmissionTempo; + type InitialNetworkMaxStake = SubtensorInitialNetworkMaxStake; } use sp_runtime::BoundedVec; @@ -1213,11 +1217,15 @@ impl fn set_liquid_alpha_enabled(netuid: u16, enabled: bool) { SubtensorModule::set_liquid_alpha_enabled(netuid, enabled); } - + fn set_hotkey_emission_tempo(emission_tempo: u64) { SubtensorModule::set_hotkey_emission_tempo(emission_tempo); } + fn set_network_max_stake(netuid: u16, max_stake: u64) { + SubtensorModule::set_network_max_stake(netuid, max_stake); + } + fn do_set_alpha_values( origin: RuntimeOrigin, netuid: u16, From 73648323536b0209d04b2efa525bbdad3cdadaea Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Tue, 16 Jul 2024 09:27:25 -0400 Subject: [PATCH 17/58] clippy --- runtime/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 58c415bc0..bbc7f6623 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -12,7 +12,6 @@ pub mod check_nonce; mod migrations; use codec::{Decode, Encode, MaxEncodedLen}; -use frame_metadata_hash_extension::CheckMetadataHash; use frame_support::{ dispatch::DispatchResultWithPostInfo, genesis_builder_helper::{build_config, create_default_config}, From 64aca954586082883a1d83752c2c66793713102b Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Tue, 16 Jul 2024 10:03:40 -0400 Subject: [PATCH 18/58] benchmarking fix --- Cargo.lock | 1 + node/Cargo.toml | 1 + node/src/benchmarking.rs | 2 ++ 3 files changed, 4 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index ceeb1098e..e55fbd013 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4673,6 +4673,7 @@ dependencies = [ "clap", "frame-benchmarking", "frame-benchmarking-cli", + "frame-metadata-hash-extension", "frame-system", "futures", "jsonrpsee", diff --git a/node/Cargo.toml b/node/Cargo.toml index 7fc6eff48..0e1a418a3 100644 --- a/node/Cargo.toml +++ b/node/Cargo.toml @@ -54,6 +54,7 @@ sp-io = { workspace = true } sp-timestamp = { workspace = true } sp-inherents = { workspace = true } sp-keyring = { workspace = true } +frame-metadata-hash-extension = { workspace = true } frame-system = { workspace = true } pallet-transaction-payment = { workspace = true } pallet-commitments = { path = "../pallets/commitments" } diff --git a/node/src/benchmarking.rs b/node/src/benchmarking.rs index ba176e15f..b194479b5 100644 --- a/node/src/benchmarking.rs +++ b/node/src/benchmarking.rs @@ -136,6 +136,7 @@ pub fn create_benchmark_extrinsic( pallet_transaction_payment::ChargeTransactionPayment::::from(0), pallet_subtensor::SubtensorSignedExtension::::new(), pallet_commitments::CommitmentsSignedExtension::::new(), + frame_metadata_hash_extension::CheckMetadataHash::::new(true), ); let raw_payload = runtime::SignedPayload::from_raw( @@ -152,6 +153,7 @@ pub fn create_benchmark_extrinsic( (), (), (), + None, ), ); let signature = raw_payload.using_encoded(|e| sender.sign(e)); From 9ec6c4e0a261690f6e0ca274c87932dab513bcae Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Tue, 16 Jul 2024 17:26:12 -0400 Subject: [PATCH 19/58] fmt --- node/src/benchmarking.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/node/src/benchmarking.rs b/node/src/benchmarking.rs index b194479b5..cf48df62f 100644 --- a/node/src/benchmarking.rs +++ b/node/src/benchmarking.rs @@ -136,7 +136,7 @@ pub fn create_benchmark_extrinsic( pallet_transaction_payment::ChargeTransactionPayment::::from(0), pallet_subtensor::SubtensorSignedExtension::::new(), pallet_commitments::CommitmentsSignedExtension::::new(), - frame_metadata_hash_extension::CheckMetadataHash::::new(true), + frame_metadata_hash_extension::CheckMetadataHash::::new(true), ); let raw_payload = runtime::SignedPayload::from_raw( @@ -153,7 +153,7 @@ pub fn create_benchmark_extrinsic( (), (), (), - None, + None, ), ); let signature = raw_payload.using_encoded(|e| sender.sign(e)); From 893b1ec9d8f42c650472535689ab77a357c34347 Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Thu, 18 Jul 2024 11:17:55 -0400 Subject: [PATCH 20/58] use rc3 with new fix polkadot-sdk/pull/4117 --- Cargo.toml | 140 ++++++++++++++++++++++++++--------------------------- 1 file changed, 70 insertions(+), 70 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 8bfb9d2b0..4a7565a01 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,81 +39,81 @@ litep2p = { git = "https://github.com/paritytech/litep2p", branch = "master" } subtensor-macros = { path = "support/macros" } -frame-benchmarking = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } -frame-benchmarking-cli = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } -frame-executive = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } -frame-metadata-hash-extension = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" , default-features = false } -frame-support = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } -frame-system = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } -frame-system-benchmarking = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } -frame-system-rpc-runtime-api = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } -frame-try-runtime = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } +frame-benchmarking = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } +frame-benchmarking-cli = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3" } +frame-executive = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } +frame-metadata-hash-extension = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3" , default-features = false } +frame-support = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } +frame-system = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } +frame-system-benchmarking = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } +frame-system-rpc-runtime-api = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } +frame-try-runtime = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } -pallet-aura = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } -pallet-balances = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } -pallet-grandpa = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } -pallet-insecure-randomness-collective-flip = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } -pallet-membership = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } -pallet-multisig = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } -pallet-preimage = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } -pallet-proxy = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } -pallet-safe-mode = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } -pallet-scheduler = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } -pallet-sudo = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } -pallet-timestamp = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } -pallet-transaction-payment = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } -pallet-transaction-payment-rpc = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } -pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } -pallet-utility = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } +pallet-aura = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } +pallet-balances = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } +pallet-grandpa = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } +pallet-insecure-randomness-collective-flip = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } +pallet-membership = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } +pallet-multisig = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } +pallet-preimage = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } +pallet-proxy = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } +pallet-safe-mode = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } +pallet-scheduler = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } +pallet-sudo = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } +pallet-timestamp = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } +pallet-transaction-payment = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } +pallet-transaction-payment-rpc = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3" } +pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } +pallet-utility = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } -sc-basic-authorship = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } -sc-cli = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } -sc-client-api = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } -sc-consensus = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } -sc-consensus-aura = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } -sc-consensus-grandpa = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } -sc-consensus-grandpa-rpc = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } -sc-chain-spec-derive = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } -sc-chain-spec = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } -sc-consensus-slots = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } -sc-executor = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } -sc-keystore = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } -sc-network = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } -sc-offchain = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } -sc-rpc = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } -sc-rpc-api = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } -sc-service = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } -sc-telemetry = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } -sc-transaction-pool = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } -sc-transaction-pool-api = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } +sc-basic-authorship = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3" } +sc-cli = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3" } +sc-client-api = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3" } +sc-consensus = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3" } +sc-consensus-aura = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3" } +sc-consensus-grandpa = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3" } +sc-consensus-grandpa-rpc = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3" } +sc-chain-spec-derive = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3" } +sc-chain-spec = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3" } +sc-consensus-slots = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3" } +sc-executor = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3" } +sc-keystore = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3" } +sc-network = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3" } +sc-offchain = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3" } +sc-rpc = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3" } +sc-rpc-api = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3" } +sc-service = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3" } +sc-telemetry = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3" } +sc-transaction-pool = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3" } +sc-transaction-pool-api = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3" } -sp-api = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } -sp-block-builder = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } -sp-blockchain = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } -sp-consensus = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } -sp-consensus-aura = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } -sp-consensus-grandpa = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } -sp-genesis-builder = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } -sp-core = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } -sp-inherents = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } -sp-io = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } -sp-keyring = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } -sp-offchain = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } -sp-rpc = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } -sp-runtime = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } -sp-session = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } -sp-std = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } -sp-storage = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } -sp-timestamp = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } -sp-tracing = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } -sp-transaction-pool = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } -sp-version = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } -sp-weights = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2", default-features = false } +sp-api = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } +sp-block-builder = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } +sp-blockchain = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } +sp-consensus = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3" } +sp-consensus-aura = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } +sp-consensus-grandpa = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3" } +sp-genesis-builder = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } +sp-core = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } +sp-inherents = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } +sp-io = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } +sp-keyring = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3" } +sp-offchain = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } +sp-rpc = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } +sp-session = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } +sp-std = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } +sp-storage = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } +sp-timestamp = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3" } +sp-tracing = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } +sp-transaction-pool = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } +sp-version = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } +sp-weights = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3", default-features = false } -substrate-build-script-utils = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } +substrate-build-script-utils = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3" } substrate-fixed = { git = "https://github.com/encointer/substrate-fixed.git", tag = "v0.5.9" } -substrate-frame-rpc-system = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } -substrate-wasm-builder = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc2" } +substrate-frame-rpc-system = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3" } +substrate-wasm-builder = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1.10.0-rc3" } frame-metadata = "16" [profile.release] From 237634cc96cc244cc7be45ba90a9f59c132b046d Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Thu, 18 Jul 2024 11:18:10 -0400 Subject: [PATCH 21/58] incl lock --- Cargo.lock | 420 ++++++++++++++++++++++++++--------------------------- 1 file changed, 210 insertions(+), 210 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e55fbd013..4a50f8a12 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2308,7 +2308,7 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "fork-tree" version = "12.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "parity-scale-codec", ] @@ -2331,7 +2331,7 @@ checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" [[package]] name = "frame-benchmarking" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "frame-support", "frame-support-procedural", @@ -2347,16 +2347,16 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-runtime-interface 24.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", - "sp-storage 19.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-runtime-interface 24.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", + "sp-storage 19.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "static_assertions", ] [[package]] name = "frame-benchmarking-cli" version = "32.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "Inflector", "array-bytes 6.2.3", @@ -2388,15 +2388,15 @@ dependencies = [ "sp-blockchain", "sp-core", "sp-database", - "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "sp-inherents", "sp-io", "sp-keystore", "sp-runtime", "sp-state-machine", - "sp-storage 19.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-storage 19.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "sp-trie", - "sp-wasm-interface 20.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-wasm-interface 20.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "thiserror", "thousands", ] @@ -2404,7 +2404,7 @@ dependencies = [ [[package]] name = "frame-executive" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "aquamarine 0.3.3", "frame-support", @@ -2416,8 +2416,8 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", - "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", + "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", ] [[package]] @@ -2435,7 +2435,7 @@ dependencies = [ [[package]] name = "frame-metadata-hash-extension" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "array-bytes 6.2.3", "docify", @@ -2450,7 +2450,7 @@ dependencies = [ [[package]] name = "frame-support" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "aquamarine 0.5.0", "array-bytes 6.2.3", @@ -2473,7 +2473,7 @@ dependencies = [ "sp-arithmetic", "sp-core", "sp-crypto-hashing-proc-macro", - "sp-debug-derive 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-debug-derive 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "sp-genesis-builder", "sp-inherents", "sp-io", @@ -2481,8 +2481,8 @@ dependencies = [ "sp-runtime", "sp-staking", "sp-state-machine", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", - "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", + "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "sp-weights", "static_assertions", "tt-call", @@ -2491,7 +2491,7 @@ dependencies = [ [[package]] name = "frame-support-procedural" version = "23.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "Inflector", "cfg-expr", @@ -2510,7 +2510,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools" version = "10.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "frame-support-procedural-tools-derive", "proc-macro-crate 3.1.0", @@ -2522,7 +2522,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools-derive" version = "11.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "proc-macro2", "quote", @@ -2532,7 +2532,7 @@ dependencies = [ [[package]] name = "frame-system" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "cfg-if", "docify", @@ -2544,7 +2544,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "sp-version", "sp-weights", ] @@ -2552,7 +2552,7 @@ dependencies = [ [[package]] name = "frame-system-benchmarking" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "frame-benchmarking", "frame-support", @@ -2561,13 +2561,13 @@ dependencies = [ "scale-info", "sp-core", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", ] [[package]] name = "frame-system-rpc-runtime-api" version = "26.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "parity-scale-codec", "sp-api", @@ -2576,13 +2576,13 @@ dependencies = [ [[package]] name = "frame-try-runtime" version = "0.34.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "frame-support", "parity-scale-codec", "sp-api", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", ] [[package]] @@ -4770,9 +4770,9 @@ dependencies = [ "sp-offchain", "sp-runtime", "sp-session", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", - "sp-storage 19.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", - "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", + "sp-storage 19.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", + "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "sp-transaction-pool", "sp-version", "substrate-wasm-builder", @@ -4983,7 +4983,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "sp-weights", "substrate-fixed", "subtensor-macros", @@ -4992,7 +4992,7 @@ dependencies = [ [[package]] name = "pallet-aura" version = "27.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "frame-support", "frame-system", @@ -5003,13 +5003,13 @@ dependencies = [ "sp-application-crypto", "sp-consensus-aura", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", ] [[package]] name = "pallet-authorship" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "frame-support", "frame-system", @@ -5017,13 +5017,13 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", ] [[package]] name = "pallet-balances" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "docify", "frame-benchmarking", @@ -5033,7 +5033,7 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", ] [[package]] @@ -5049,7 +5049,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "subtensor-macros", ] @@ -5067,14 +5067,14 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "subtensor-macros", ] [[package]] name = "pallet-grandpa" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "frame-benchmarking", "frame-support", @@ -5091,13 +5091,13 @@ dependencies = [ "sp-runtime", "sp-session", "sp-staking", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", ] [[package]] name = "pallet-insecure-randomness-collective-flip" version = "16.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "frame-support", "frame-system", @@ -5105,13 +5105,13 @@ dependencies = [ "safe-mix", "scale-info", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", ] [[package]] name = "pallet-membership" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "frame-benchmarking", "frame-support", @@ -5122,13 +5122,13 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", ] [[package]] name = "pallet-multisig" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "frame-benchmarking", "frame-support", @@ -5138,13 +5138,13 @@ dependencies = [ "scale-info", "sp-io", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", ] [[package]] name = "pallet-preimage" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "frame-benchmarking", "frame-support", @@ -5155,13 +5155,13 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", ] [[package]] name = "pallet-proxy" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "frame-benchmarking", "frame-support", @@ -5170,7 +5170,7 @@ dependencies = [ "scale-info", "sp-io", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", ] [[package]] @@ -5186,14 +5186,14 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "subtensor-macros", ] [[package]] name = "pallet-safe-mode" version = "9.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "docify", "frame-benchmarking", @@ -5206,13 +5206,13 @@ dependencies = [ "scale-info", "sp-arithmetic", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", ] [[package]] name = "pallet-scheduler" version = "29.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "docify", "frame-benchmarking", @@ -5223,14 +5223,14 @@ dependencies = [ "scale-info", "sp-io", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "sp-weights", ] [[package]] name = "pallet-session" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "frame-support", "frame-system", @@ -5245,7 +5245,7 @@ dependencies = [ "sp-session", "sp-staking", "sp-state-machine", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "sp-trie", ] @@ -5277,8 +5277,8 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", - "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", + "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "sp-version", "substrate-fixed", "subtensor-macros", @@ -5287,7 +5287,7 @@ dependencies = [ [[package]] name = "pallet-sudo" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "docify", "frame-benchmarking", @@ -5297,13 +5297,13 @@ dependencies = [ "scale-info", "sp-io", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", ] [[package]] name = "pallet-timestamp" version = "27.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "docify", "frame-benchmarking", @@ -5315,15 +5315,15 @@ dependencies = [ "sp-inherents", "sp-io", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", - "sp-storage 19.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", + "sp-storage 19.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "sp-timestamp", ] [[package]] name = "pallet-transaction-payment" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "frame-support", "frame-system", @@ -5333,13 +5333,13 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", ] [[package]] name = "pallet-transaction-payment-rpc" version = "30.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "jsonrpsee", "pallet-transaction-payment-rpc-runtime-api", @@ -5355,7 +5355,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc-runtime-api" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "pallet-transaction-payment", "parity-scale-codec", @@ -5367,7 +5367,7 @@ dependencies = [ [[package]] name = "pallet-utility" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "frame-benchmarking", "frame-support", @@ -5377,7 +5377,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", ] [[package]] @@ -6715,18 +6715,18 @@ dependencies = [ [[package]] name = "sc-allocator" version = "23.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "log", "sp-core", - "sp-wasm-interface 20.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-wasm-interface 20.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "thiserror", ] [[package]] name = "sc-basic-authorship" version = "0.34.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "futures", "futures-timer", @@ -6748,7 +6748,7 @@ dependencies = [ [[package]] name = "sc-block-builder" version = "0.33.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "parity-scale-codec", "sp-api", @@ -6763,7 +6763,7 @@ dependencies = [ [[package]] name = "sc-chain-spec" version = "27.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "array-bytes 6.2.3", "docify", @@ -6789,7 +6789,7 @@ dependencies = [ [[package]] name = "sc-chain-spec-derive" version = "11.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", @@ -6800,7 +6800,7 @@ dependencies = [ [[package]] name = "sc-cli" version = "0.36.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "array-bytes 6.2.3", "chrono", @@ -6841,7 +6841,7 @@ dependencies = [ [[package]] name = "sc-client-api" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "fnv", "futures", @@ -6856,11 +6856,11 @@ dependencies = [ "sp-consensus", "sp-core", "sp-database", - "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "sp-runtime", "sp-state-machine", "sp-statement-store", - "sp-storage 19.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-storage 19.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "sp-trie", "substrate-prometheus-endpoint", ] @@ -6868,7 +6868,7 @@ dependencies = [ [[package]] name = "sc-client-db" version = "0.35.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "hash-db", "kvdb", @@ -6894,7 +6894,7 @@ dependencies = [ [[package]] name = "sc-consensus" version = "0.33.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "async-trait", "futures", @@ -6919,7 +6919,7 @@ dependencies = [ [[package]] name = "sc-consensus-aura" version = "0.34.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "async-trait", "futures", @@ -6948,7 +6948,7 @@ dependencies = [ [[package]] name = "sc-consensus-grandpa" version = "0.19.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "ahash 0.8.11", "array-bytes 6.2.3", @@ -6991,7 +6991,7 @@ dependencies = [ [[package]] name = "sc-consensus-grandpa-rpc" version = "0.19.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "finality-grandpa", "futures", @@ -7011,7 +7011,7 @@ dependencies = [ [[package]] name = "sc-consensus-slots" version = "0.33.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "async-trait", "futures", @@ -7034,7 +7034,7 @@ dependencies = [ [[package]] name = "sc-executor" version = "0.32.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "parity-scale-codec", "parking_lot 0.12.3", @@ -7044,25 +7044,25 @@ dependencies = [ "schnellru", "sp-api", "sp-core", - "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "sp-io", "sp-panic-handler", - "sp-runtime-interface 24.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-runtime-interface 24.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "sp-trie", "sp-version", - "sp-wasm-interface 20.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-wasm-interface 20.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "tracing", ] [[package]] name = "sc-executor-common" version = "0.29.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "polkavm", "sc-allocator", "sp-maybe-compressed-blob", - "sp-wasm-interface 20.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-wasm-interface 20.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "thiserror", "wasm-instrument", ] @@ -7070,18 +7070,18 @@ dependencies = [ [[package]] name = "sc-executor-polkavm" version = "0.29.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "log", "polkavm", "sc-executor-common", - "sp-wasm-interface 20.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-wasm-interface 20.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", ] [[package]] name = "sc-executor-wasmtime" version = "0.29.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "anyhow", "cfg-if", @@ -7091,15 +7091,15 @@ dependencies = [ "rustix 0.36.17", "sc-allocator", "sc-executor-common", - "sp-runtime-interface 24.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", - "sp-wasm-interface 20.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-runtime-interface 24.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", + "sp-wasm-interface 20.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "wasmtime", ] [[package]] name = "sc-informant" version = "0.33.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "ansi_term", "futures", @@ -7116,7 +7116,7 @@ dependencies = [ [[package]] name = "sc-keystore" version = "25.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "array-bytes 6.2.3", "parking_lot 0.12.3", @@ -7130,7 +7130,7 @@ dependencies = [ [[package]] name = "sc-mixnet" version = "0.4.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "array-bytes 4.2.0", "arrayvec", @@ -7159,7 +7159,7 @@ dependencies = [ [[package]] name = "sc-network" version = "0.34.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "array-bytes 6.2.3", "async-channel", @@ -7202,7 +7202,7 @@ dependencies = [ [[package]] name = "sc-network-bitswap" version = "0.33.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "async-channel", "cid", @@ -7222,7 +7222,7 @@ dependencies = [ [[package]] name = "sc-network-common" version = "0.33.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "async-trait", "bitflags 1.3.2", @@ -7239,7 +7239,7 @@ dependencies = [ [[package]] name = "sc-network-gossip" version = "0.34.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "ahash 0.8.11", "futures", @@ -7258,7 +7258,7 @@ dependencies = [ [[package]] name = "sc-network-light" version = "0.33.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "array-bytes 6.2.3", "async-channel", @@ -7279,7 +7279,7 @@ dependencies = [ [[package]] name = "sc-network-sync" version = "0.33.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "array-bytes 6.2.3", "async-channel", @@ -7315,7 +7315,7 @@ dependencies = [ [[package]] name = "sc-network-transactions" version = "0.33.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "array-bytes 6.2.3", "futures", @@ -7334,7 +7334,7 @@ dependencies = [ [[package]] name = "sc-offchain" version = "29.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "array-bytes 6.2.3", "bytes", @@ -7357,7 +7357,7 @@ dependencies = [ "sc-utils", "sp-api", "sp-core", - "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "sp-keystore", "sp-offchain", "sp-runtime", @@ -7368,7 +7368,7 @@ dependencies = [ [[package]] name = "sc-proposer-metrics" version = "0.17.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "log", "substrate-prometheus-endpoint", @@ -7377,7 +7377,7 @@ dependencies = [ [[package]] name = "sc-rpc" version = "29.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "futures", "jsonrpsee", @@ -7409,7 +7409,7 @@ dependencies = [ [[package]] name = "sc-rpc-api" version = "0.33.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "jsonrpsee", "parity-scale-codec", @@ -7429,7 +7429,7 @@ dependencies = [ [[package]] name = "sc-rpc-server" version = "11.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "futures", "governor", @@ -7447,7 +7447,7 @@ dependencies = [ [[package]] name = "sc-rpc-spec-v2" version = "0.34.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "array-bytes 6.2.3", "futures", @@ -7478,7 +7478,7 @@ dependencies = [ [[package]] name = "sc-service" version = "0.35.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "async-trait", "directories", @@ -7520,12 +7520,12 @@ dependencies = [ "sp-blockchain", "sp-consensus", "sp-core", - "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "sp-keystore", "sp-runtime", "sp-session", "sp-state-machine", - "sp-storage 19.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-storage 19.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "sp-transaction-pool", "sp-transaction-storage-proof", "sp-trie", @@ -7542,7 +7542,7 @@ dependencies = [ [[package]] name = "sc-state-db" version = "0.30.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "log", "parity-scale-codec", @@ -7553,7 +7553,7 @@ dependencies = [ [[package]] name = "sc-sysinfo" version = "27.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "derive_more", "futures", @@ -7568,13 +7568,13 @@ dependencies = [ "sp-core", "sp-crypto-hashing", "sp-io", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", ] [[package]] name = "sc-telemetry" version = "15.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "chrono", "futures", @@ -7593,7 +7593,7 @@ dependencies = [ [[package]] name = "sc-tracing" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "ansi_term", "chrono", @@ -7613,7 +7613,7 @@ dependencies = [ "sp-core", "sp-rpc", "sp-runtime", - "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "thiserror", "tracing", "tracing-log 0.1.4", @@ -7623,7 +7623,7 @@ dependencies = [ [[package]] name = "sc-tracing-proc-macro" version = "11.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", @@ -7634,7 +7634,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "async-trait", "futures", @@ -7652,7 +7652,7 @@ dependencies = [ "sp-core", "sp-crypto-hashing", "sp-runtime", - "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "sp-transaction-pool", "substrate-prometheus-endpoint", "thiserror", @@ -7661,7 +7661,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool-api" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "async-trait", "futures", @@ -7677,7 +7677,7 @@ dependencies = [ [[package]] name = "sc-utils" version = "14.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "async-channel", "futures", @@ -8189,7 +8189,7 @@ dependencies = [ [[package]] name = "sp-api" version = "26.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "hash-db", "log", @@ -8197,12 +8197,12 @@ dependencies = [ "scale-info", "sp-api-proc-macro", "sp-core", - "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "sp-metadata-ir", "sp-runtime", - "sp-runtime-interface 24.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-runtime-interface 24.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "sp-state-machine", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "sp-trie", "sp-version", "thiserror", @@ -8211,7 +8211,7 @@ dependencies = [ [[package]] name = "sp-api-proc-macro" version = "15.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "Inflector", "blake2 0.10.6", @@ -8225,20 +8225,20 @@ dependencies = [ [[package]] name = "sp-application-crypto" version = "30.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "parity-scale-codec", "scale-info", "serde", "sp-core", "sp-io", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", ] [[package]] name = "sp-arithmetic" version = "23.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "docify", "integer-sqrt", @@ -8246,7 +8246,7 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "static_assertions", ] @@ -8271,7 +8271,7 @@ dependencies = [ [[package]] name = "sp-block-builder" version = "26.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "sp-api", "sp-inherents", @@ -8281,7 +8281,7 @@ dependencies = [ [[package]] name = "sp-blockchain" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "futures", "log", @@ -8299,7 +8299,7 @@ dependencies = [ [[package]] name = "sp-consensus" version = "0.32.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "async-trait", "futures", @@ -8314,7 +8314,7 @@ dependencies = [ [[package]] name = "sp-consensus-aura" version = "0.32.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "async-trait", "parity-scale-codec", @@ -8330,7 +8330,7 @@ dependencies = [ [[package]] name = "sp-consensus-grandpa" version = "13.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "finality-grandpa", "log", @@ -8347,7 +8347,7 @@ dependencies = [ [[package]] name = "sp-consensus-slots" version = "0.32.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "parity-scale-codec", "scale-info", @@ -8358,7 +8358,7 @@ dependencies = [ [[package]] name = "sp-core" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "array-bytes 6.2.3", "bandersnatch_vrfs", @@ -8389,11 +8389,11 @@ dependencies = [ "secrecy", "serde", "sp-crypto-hashing", - "sp-debug-derive 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", - "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", - "sp-runtime-interface 24.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", - "sp-storage 19.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-debug-derive 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", + "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", + "sp-runtime-interface 24.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", + "sp-storage 19.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "ss58-registry", "substrate-bip39", "thiserror", @@ -8425,7 +8425,7 @@ dependencies = [ [[package]] name = "sp-crypto-hashing" version = "0.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "blake2b_simd", "byteorder", @@ -8438,7 +8438,7 @@ dependencies = [ [[package]] name = "sp-crypto-hashing-proc-macro" version = "0.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "quote", "sp-crypto-hashing", @@ -8448,7 +8448,7 @@ dependencies = [ [[package]] name = "sp-database" version = "10.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "kvdb", "parking_lot 0.12.3", @@ -8457,7 +8457,7 @@ dependencies = [ [[package]] name = "sp-debug-derive" version = "14.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "proc-macro2", "quote", @@ -8477,11 +8477,11 @@ dependencies = [ [[package]] name = "sp-externalities" version = "0.25.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "environmental", "parity-scale-codec", - "sp-storage 19.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-storage 19.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", ] [[package]] @@ -8497,7 +8497,7 @@ dependencies = [ [[package]] name = "sp-genesis-builder" version = "0.7.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "serde_json", "sp-api", @@ -8507,7 +8507,7 @@ dependencies = [ [[package]] name = "sp-inherents" version = "26.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "async-trait", "impl-trait-for-tuples", @@ -8520,7 +8520,7 @@ dependencies = [ [[package]] name = "sp-io" version = "30.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "bytes", "ed25519-dalek", @@ -8532,12 +8532,12 @@ dependencies = [ "secp256k1", "sp-core", "sp-crypto-hashing", - "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "sp-keystore", - "sp-runtime-interface 24.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-runtime-interface 24.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "sp-state-machine", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", - "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", + "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "sp-trie", "tracing", "tracing-core", @@ -8546,7 +8546,7 @@ dependencies = [ [[package]] name = "sp-keyring" version = "31.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "sp-core", "sp-runtime", @@ -8556,18 +8556,18 @@ dependencies = [ [[package]] name = "sp-keystore" version = "0.34.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "parity-scale-codec", "parking_lot 0.12.3", "sp-core", - "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", ] [[package]] name = "sp-maybe-compressed-blob" version = "11.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "thiserror", "zstd 0.12.4", @@ -8576,7 +8576,7 @@ dependencies = [ [[package]] name = "sp-metadata-ir" version = "0.6.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "frame-metadata", "parity-scale-codec", @@ -8586,7 +8586,7 @@ dependencies = [ [[package]] name = "sp-mixnet" version = "0.4.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "parity-scale-codec", "scale-info", @@ -8597,7 +8597,7 @@ dependencies = [ [[package]] name = "sp-offchain" version = "26.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "sp-api", "sp-core", @@ -8607,7 +8607,7 @@ dependencies = [ [[package]] name = "sp-panic-handler" version = "13.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "backtrace", "lazy_static", @@ -8617,7 +8617,7 @@ dependencies = [ [[package]] name = "sp-rpc" version = "26.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "rustc-hash", "serde", @@ -8627,7 +8627,7 @@ dependencies = [ [[package]] name = "sp-runtime" version = "31.0.1" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "docify", "either", @@ -8644,26 +8644,26 @@ dependencies = [ "sp-arithmetic", "sp-core", "sp-io", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "sp-weights", ] [[package]] name = "sp-runtime-interface" version = "24.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "bytes", "impl-trait-for-tuples", "parity-scale-codec", "polkavm-derive", "primitive-types", - "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", - "sp-runtime-interface-proc-macro 17.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", - "sp-storage 19.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", - "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", - "sp-wasm-interface 20.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", + "sp-runtime-interface-proc-macro 17.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", + "sp-storage 19.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", + "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", + "sp-wasm-interface 20.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "static_assertions", ] @@ -8689,7 +8689,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" version = "17.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "Inflector", "expander", @@ -8715,7 +8715,7 @@ dependencies = [ [[package]] name = "sp-session" version = "27.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "parity-scale-codec", "scale-info", @@ -8729,7 +8729,7 @@ dependencies = [ [[package]] name = "sp-staking" version = "26.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", @@ -8742,7 +8742,7 @@ dependencies = [ [[package]] name = "sp-state-machine" version = "0.35.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "hash-db", "log", @@ -8751,7 +8751,7 @@ dependencies = [ "rand", "smallvec", "sp-core", - "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "sp-panic-handler", "sp-trie", "thiserror", @@ -8762,7 +8762,7 @@ dependencies = [ [[package]] name = "sp-statement-store" version = "10.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "aes-gcm", "curve25519-dalek 4.1.3", @@ -8776,9 +8776,9 @@ dependencies = [ "sp-application-crypto", "sp-core", "sp-crypto-hashing", - "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "sp-runtime", - "sp-runtime-interface 24.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-runtime-interface 24.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "thiserror", "x25519-dalek 2.0.1", ] @@ -8786,7 +8786,7 @@ dependencies = [ [[package]] name = "sp-std" version = "14.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" [[package]] name = "sp-std" @@ -8796,13 +8796,13 @@ source = "git+https://github.com/paritytech/polkadot-sdk#c4b3c1c6c6e492c4196e06f [[package]] name = "sp-storage" version = "19.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "impl-serde", "parity-scale-codec", "ref-cast", "serde", - "sp-debug-derive 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-debug-derive 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", ] [[package]] @@ -8820,7 +8820,7 @@ dependencies = [ [[package]] name = "sp-timestamp" version = "26.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "async-trait", "parity-scale-codec", @@ -8832,7 +8832,7 @@ dependencies = [ [[package]] name = "sp-tracing" version = "16.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "parity-scale-codec", "tracing", @@ -8854,7 +8854,7 @@ dependencies = [ [[package]] name = "sp-transaction-pool" version = "26.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "sp-api", "sp-runtime", @@ -8863,7 +8863,7 @@ dependencies = [ [[package]] name = "sp-transaction-storage-proof" version = "26.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "async-trait", "parity-scale-codec", @@ -8877,7 +8877,7 @@ dependencies = [ [[package]] name = "sp-trie" version = "29.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "ahash 0.8.11", "hash-db", @@ -8890,7 +8890,7 @@ dependencies = [ "scale-info", "schnellru", "sp-core", - "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "thiserror", "tracing", "trie-db", @@ -8900,7 +8900,7 @@ dependencies = [ [[package]] name = "sp-version" version = "29.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "impl-serde", "parity-scale-codec", @@ -8909,7 +8909,7 @@ dependencies = [ "serde", "sp-crypto-hashing-proc-macro", "sp-runtime", - "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "sp-version-proc-macro", "thiserror", ] @@ -8917,7 +8917,7 @@ dependencies = [ [[package]] name = "sp-version-proc-macro" version = "13.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "parity-scale-codec", "proc-macro2", @@ -8928,7 +8928,7 @@ dependencies = [ [[package]] name = "sp-wasm-interface" version = "20.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "anyhow", "impl-trait-for-tuples", @@ -8950,7 +8950,7 @@ dependencies = [ [[package]] name = "sp-weights" version = "27.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "bounded-collections", "parity-scale-codec", @@ -8958,7 +8958,7 @@ dependencies = [ "serde", "smallvec", "sp-arithmetic", - "sp-debug-derive 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-debug-derive 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", ] [[package]] @@ -9097,7 +9097,7 @@ dependencies = [ [[package]] name = "substrate-bip39" version = "0.4.7" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "hmac 0.12.1", "pbkdf2", @@ -9109,7 +9109,7 @@ dependencies = [ [[package]] name = "substrate-build-script-utils" version = "11.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" [[package]] name = "substrate-fixed" @@ -9125,7 +9125,7 @@ dependencies = [ [[package]] name = "substrate-frame-rpc-system" version = "28.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "frame-system-rpc-runtime-api", "futures", @@ -9144,7 +9144,7 @@ dependencies = [ [[package]] name = "substrate-prometheus-endpoint" version = "0.17.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "hyper", "log", @@ -9156,7 +9156,7 @@ dependencies = [ [[package]] name = "substrate-wasm-builder" version = "17.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2#b53d5c529d403a0bbf36441c3896200c234c058c" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2f55dfe06bae13e9f47ccf587acfd3fb9cd923" dependencies = [ "array-bytes 6.2.3", "build-helper", @@ -9172,7 +9172,7 @@ dependencies = [ "sp-core", "sp-io", "sp-maybe-compressed-blob", - "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc2)", + "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "sp-version", "strum 0.26.2", "tempfile", From c80df3d667d8e8212b0d21ea63ce5b493210feac Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Thu, 18 Jul 2024 12:11:23 -0400 Subject: [PATCH 22/58] bump CI From 07e46e312b56dd129d5a9b73cb9f5080db1d0e45 Mon Sep 17 00:00:00 2001 From: const Date: Mon, 22 Jul 2024 12:28:42 -0500 Subject: [PATCH 23/58] initial --- pallets/subtensor/src/lib.rs | 2 +- pallets/subtensor/src/swap_hotkey.rs | 280 +++++++++++++++++++++++++++ 2 files changed, 281 insertions(+), 1 deletion(-) create mode 100644 pallets/subtensor/src/swap_hotkey.rs diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index f7824e2a3..cfb3a5828 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -367,7 +367,7 @@ pub mod pallet { pub type TotalColdkeyStake = StorageMap<_, Identity, T::AccountId, u64, ValueQuery, DefaultAccountTake>; #[pallet::storage] - /// MAP (hot, cold) --> stake | Returns a tuple (u64: stakes, u64: block_number) + /// MAP (hot, cold) --> u64, u64) | Returns a tuple (u64: stakes, u64: block_number) pub type TotalHotkeyColdkeyStakesThisInterval = StorageDoubleMap< _, Identity, diff --git a/pallets/subtensor/src/swap_hotkey.rs b/pallets/subtensor/src/swap_hotkey.rs new file mode 100644 index 000000000..068b24b78 --- /dev/null +++ b/pallets/subtensor/src/swap_hotkey.rs @@ -0,0 +1,280 @@ +use super::*; +use crate::MIN_BALANCE_TO_PERFORM_COLDKEY_SWAP; +use frame_support::traits::fungible::Mutate; +use frame_support::traits::tokens::Preservation; +use frame_support::{storage::IterableStorageDoubleMap, weights::Weight}; +use sp_core::{Get, U256}; + +impl Pallet { + /// Swaps the hotkey of a coldkey account. + /// + /// # Arguments + /// + /// * `origin` - The origin of the transaction, and also the coldkey account. + /// * `old_hotkey` - The old hotkey to be swapped. + /// * `new_hotkey` - The new hotkey to replace the old one. + /// + /// # Returns + /// + /// * `DispatchResultWithPostInfo` - The result of the dispatch. + /// + /// # Errors + /// + /// * `NonAssociatedColdKey` - If the coldkey does not own the old hotkey. + /// * `HotKeySetTxRateLimitExceeded` - If the transaction rate limit is exceeded. + /// * `NewHotKeyIsSameWithOld` - If the new hotkey is the same as the old hotkey. + /// * `HotKeyAlreadyRegisteredInSubNet` - If the new hotkey is already registered in the subnet. + /// * `NotEnoughBalanceToPaySwapHotKey` - If there is not enough balance to pay for the swap. + pub fn do_swap_hotkey( + origin: T::RuntimeOrigin, + old_hotkey: &T::AccountId, + new_hotkey: &T::AccountId, + ) -> DispatchResultWithPostInfo { + // Ensure the origin is signed and get the coldkey + let coldkey = ensure_signed(origin)?; + + // Check if the coldkey is in arbitration + ensure!( + !Self::coldkey_in_arbitration(&coldkey), + Error::::ColdkeyIsInArbitration + ); + + // Initialize the weight for this operation + let mut weight = T::DbWeight::get().reads(2); + + // Ensure the new hotkey is different from the old one + ensure!(old_hotkey != new_hotkey, Error::::NewHotKeyIsSameWithOld); + // Ensure the new hotkey is not already registered on any network + ensure!( + !Self::is_hotkey_registered_on_any_network(new_hotkey), + Error::::HotKeyAlreadyRegisteredInSubNet + ); + + // Update the weight for the checks above + weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 0)); + // Ensure the coldkey owns the old hotkey + ensure!( + Self::coldkey_owns_hotkey(&coldkey, old_hotkey), + Error::::NonAssociatedColdKey + ); + + // Get the current block number + let block: u64 = Self::get_current_block_as_u64(); + // Ensure the transaction rate limit is not exceeded + ensure!( + !Self::exceeds_tx_rate_limit(Self::get_last_tx_block(&coldkey), block), + Error::::HotKeySetTxRateLimitExceeded + ); + + // Update the weight for reading the total networks + weight.saturating_accrue( + T::DbWeight::get().reads((TotalNetworks::::get().saturating_add(1u16)) as u64), + ); + + // Get the cost for swapping the key + let swap_cost = Self::get_key_swap_cost(); + log::debug!("Swap cost: {:?}", swap_cost); + + // Ensure the coldkey has enough balance to pay for the swap + ensure!( + Self::can_remove_balance_from_coldkey_account(&coldkey, swap_cost), + Error::::NotEnoughBalanceToPaySwapHotKey + ); + // Remove the swap cost from the coldkey's account + let actual_burn_amount = Self::remove_balance_from_coldkey_account(&coldkey, swap_cost)?; + // Burn the tokens + Self::burn_tokens(actual_burn_amount); + + // Perform the hotkey swap + Self::perform_hotkey_swap(old_hotkey, new_hotkey, &coldkey, &mut weight); + + // Update the last transaction block for the coldkey + Self::set_last_tx_block(&coldkey, block); + weight.saturating_accrue(T::DbWeight::get().writes(1)); + + // Emit an event for the hotkey swap + Self::deposit_event(Event::HotkeySwapped { + coldkey, + old_hotkey: old_hotkey.clone(), + new_hotkey: new_hotkey.clone(), + }); + + // Return the weight of the operation + Ok(Some(weight).into()) + } + + pub fn perform_hotkey_swap( old_hotkey: &T::AccountId, new_hotkey: &T::AccountId, coldkey: &T::AccountId, weight: &mut Weight ) { + + // 1. Swap owner. + // Owner( hotkey ) -> coldkey -- the coldkey that owns the hotkey. + Owner::::remove(old_hotkey); + Owner::::insert(new_hotkey, coldkey.clone()); + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); + + // 2. Swap OwnedHotkeys. + // OwnedHotkeys( coldkey ) -> Vec -- the hotkeys that the coldkey owns. + let mut hotkeys = OwnedHotkeys::::get(coldkey); + // Add the new key if needed. + if !hotkeys.contains(new_hotkey) { + hotkeys.push(new_hotkey.clone()); + } + // Remove the old key. + hotkeys.retain(|hk| *hk != *old_hotkey); + OwnedHotkeys::::insert(coldkey, hotkeys); + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); + + // 3. Swap total hotkey stake. + // TotalHotkeyStake( hotkey ) -> stake -- the total stake that the hotkey has across all delegates. + let old_total_hotkey_stake = TotalHotkeyStake::::get( old_hotkey ); // Get the old total hotkey stake. + let new_total_hotkey_stake = TotalHotkeyStake::::get( new_hotkey ); // Get the new total hotkey stake. + TotalHotkeyStake::::remove( old_hotkey ); // Remove the old total hotkey stake. + TotalHotkeyStake::::insert( new_hotkey, old_total_hotkey_stake.saturating_add( new_total_hotkey_stake ) ); // Insert the new total hotkey stake via the addition. + weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2)); + + // Swap total hotkey stakes. + // TotalHotkeyColdkeyStakesThisInterval( hotkey ) --> (u64: stakes, u64: block_number) + let stake_tuples: Vec<(T::AccountId, (u64, u64))> = TotalHotkeyColdkeyStakesThisInterval::::iter_prefix(old_hotkey).collect(); + for (coldkey, stake_tup) in stake_tuples { + // NOTE: You could use this to increase your allowed stake operations but this would cost. + TotalHotkeyColdkeyStakesThisInterval::::insert(new_hotkey, &coldkey, stake_tup); + TotalHotkeyColdkeyStakesThisInterval::::remove(old_hotkey, &coldkey); + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); + } + + // Swap LastTxBlock + // LastTxBlock( hotkey ) --> u64 -- the last transaction block for the hotkey. + let old_last_tx_block: u64 = LastTxBlock::::get( old_hotkey ); + LastTxBlock::::remove( old_hotkey ); + LastTxBlock::::insert( new_hotkey, Self::get_current_block_as_u64() ); + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); + + // Swap LastTxBlockDelegateTake + // LastTxBlockDelegateTake( hotkey ) --> u64 -- the last transaction block for the hotkey delegate take. + LastTxBlockDelegateTake::::remove( old_hotkey ); + LastTxBlockDelegateTake::::insert( new_hotkey, Self::get_current_block_as_u64() ); + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); + + // Swap Senate members. + // Senate( hotkey ) --> ? + if T::SenateMembers::is_member(old_hotkey) { + T::SenateMembers::swap_member(old_hotkey, new_hotkey).map_err(|e| e.error)?; + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); + } + + // 4. Swap delegates. + // Delegates( hotkey ) -> take value -- the hotkey delegate take value. + let old_delegate_take = Delegates::::get( old_hotkey ); + Delegates::::remove( old_hotkey ); // Remove the old delegate take. + Delegates::::insert( new_hotkey, old_delegate_take ); // Insert the new delegate take. + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); + + // Swap all subnet specific info. + let all_netuid: Vec = Self::get_all_subnet_netuids(); + for netuid in all_netuids { + // 7.1 Remove the previous hotkey and insert the new hotkey from membership. + // IsNetworkMember( hotkey, netuid ) -> bool -- is the hotkey a subnet member. + let is_network_member: bool = IsNetworkMember::::get( old_hotkey, netuid ); + IsNetworkMember::::remove( old_hotkey, netuid ); + IsNetworkMember::::insert( new_hotkey, netuid, is_network_member ); + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); + + // 7.2 Swap Uids + Keys. + // Keys( netuid, hotkey ) -> uid -- the uid the hotkey has in the network if it is a member. + // Uids( netuid, hotkey ) -> uid -- the uids that the hotkey has. + if is_network_member { + // 7.2.1 Swap the UIDS + let old_uid: u16 = Uids::::get(netuid, old_hotkey); + Uids::::remove(netuid, old_hotkey); + Uids::::insert(netuid, new_hotkey, old_uid); + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); + + // 7.2.2 Swap the keys. + Keys::::insert(netuid, old_uid, new_hotkey.clone()); + weight.saturating_accrue(T::DbWeight::get().reads_writes(0, 1)); + } + + // 7.3 Swap Prometheus. + // Prometheus( netuid, hotkey ) -> prometheus -- the prometheus data that a hotkey has in the network. + if is_network_member { + let old_prometheus_info: PrometheusInfo = Prometheus::::get(netuid, old_hotkey); + Prometheus::::remove(netuid, old_hotkey); + Prometheus::::insert(netuid, new_hotkey, old_prometheus_info); + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); + } + + // 7.4. Swap axons. + // Axons( netuid, hotkey ) -> axon -- the axon that the hotkey has. + if is_network_member { + let old_axon_info: AxonInfo = Axons::::get(netuid, old_hotkey); + Axons::::remove(netuid, old_hotkey); + Axons::::insert(netuid, new_hotkey, old_axon_info); + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); + } + + // 7.5 Swap WeightCommits + // WeightCommits( hotkey ) --> Vec -- the weight commits for the hotkey. + if is_network_member { + if let Ok(old_weight_commits) = WeightCommits::::try_get(old_hotkey) { + WeightCommits::::remove(old_hotkey); + WeightCommits::::insert(new_hotkey, old_weight_commits); + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); + } + } + + // 7.5. Swap the subnet loaded emission. + // LoadedEmission( netuid ) --> Vec<(hotkey, u64)> -- the loaded emission for the subnet. + if is_network_member { + if let Some(mut old_loaded_emission) = LoadedEmission::::get(netuid) { + for emission in old_loaded_emission.iter_mut() { + if emission.0 == *old_hotkey { + emission.0 = new_hotkey.clone(); + } + } + LoadedEmission::::remove(netuid); + LoadedEmission::::insert(netuid, old_loaded_emission); + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); + } + } + + } + + // Swap Stake. + // Stake( hotkey, coldkey ) -> stake -- the stake that the hotkey controls on behalf of the coldkey. + let stakes: Vec<(T::AccountId, u64)> = Stake::::iter_prefix(old_hotkey).collect(); + // Clear the entire old prefix here. + let _ = Stake::::clear_prefix( old_hotkey, stakes.len() as u32, None ); + // Iterate over all the staking rows and insert them into the new hotkey. + for (coldkey, old_stake_amount) in stakes { + weight.saturating_accrue(T::DbWeight::get().reads(1)); + + // Swap Stake value + // Stake( hotkey, coldkey ) -> stake -- the stake that the hotkey controls on behalf of the coldkey. + // Get the new stake value. + let new_stake_value: u64 = Stake::::get(new_hotkey, &coldkey); + // Insert the new stake value. + Stake::::insert(new_hotkey, &coldkey, new_stake_value.saturating_add(old_stake_amount)); + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); + + // Swap StakingHotkeys. + // StakingHotkeys( coldkey ) --> Vec -- the hotkeys that the coldkey stakes. + let mut staking_hotkeys = StakingHotkeys::::get(&coldkey); + staking_hotkeys.retain(|hk| *hk != *old_hotkey && *hk != *new_hotkey); + staking_hotkeys.push(new_hotkey.clone()); + StakingHotkeys::::insert(coldkey.clone(), staking_hotkeys); + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); + } + } + + pub fn swap_senate_member( + old_hotkey: &T::AccountId, + new_hotkey: &T::AccountId, + weight: &mut Weight, + ) -> DispatchResult { + weight.saturating_accrue(T::DbWeight::get().reads(1)); + if T::SenateMembers::is_member(old_hotkey) { + T::SenateMembers::swap_member(old_hotkey, new_hotkey).map_err(|e| e.error)?; + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); + } + Ok(()) + } +} From 0432b53d428e1f7f5d2b449bbcb0a649e0e6a01d Mon Sep 17 00:00:00 2001 From: const Date: Mon, 22 Jul 2024 13:26:28 -0500 Subject: [PATCH 24/58] add tests --- pallets/subtensor/src/lib.rs | 35 +- pallets/subtensor/src/swap.rs | 417 +------------- pallets/subtensor/src/swap_hotkey.rs | 47 +- pallets/subtensor/tests/swap.rs | 719 +------------------------ pallets/subtensor/tests/swap_hotkey.rs | 542 +++++++++++++++++++ 5 files changed, 604 insertions(+), 1156 deletions(-) create mode 100644 pallets/subtensor/tests/swap_hotkey.rs diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index cfb3a5828..d492b5477 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -45,6 +45,7 @@ mod root; mod serving; mod staking; mod swap; +mod swap_hotkey; mod uids; mod utils; mod weights; @@ -272,7 +273,7 @@ pub mod pallet { } #[pallet::storage] - pub(super) type SenateRequiredStakePercentage = + pub type SenateRequiredStakePercentage = StorageValue<_, u64, ValueQuery, DefaultSenateRequiredStakePercentage>; /// ============================ @@ -796,15 +797,15 @@ pub mod pallet { } #[pallet::storage] // --- ITEM ( tx_rate_limit ) - pub(super) type TxRateLimit = StorageValue<_, u64, ValueQuery, DefaultTxRateLimit>; + pub type TxRateLimit = StorageValue<_, u64, ValueQuery, DefaultTxRateLimit>; #[pallet::storage] // --- ITEM ( tx_rate_limit ) - pub(super) type TxDelegateTakeRateLimit = + pub type TxDelegateTakeRateLimit = StorageValue<_, u64, ValueQuery, DefaultTxDelegateTakeRateLimit>; #[pallet::storage] // --- MAP ( key ) --> last_block pub type LastTxBlock = StorageMap<_, Identity, T::AccountId, u64, ValueQuery, DefaultLastTxBlock>; #[pallet::storage] // --- MAP ( key ) --> last_block - pub(super) type LastTxBlockDelegateTake = + pub type LastTxBlockDelegateTake = StorageMap<_, Identity, T::AccountId, u64, ValueQuery, DefaultLastTxBlock>; /// Default value for serving rate limit. @@ -1084,41 +1085,41 @@ pub mod pallet { StorageMap<_, Identity, u16, Vec<(T::AccountId, u64, u64)>, OptionQuery>; #[pallet::storage] // --- DMAP ( netuid ) --> active - pub(super) type Active = + pub type Active = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyBoolVec>; #[pallet::storage] // --- DMAP ( netuid ) --> rank - pub(super) type Rank = + pub type Rank = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; #[pallet::storage] // --- DMAP ( netuid ) --> trust - pub(super) type Trust = + pub type Trust = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; #[pallet::storage] // --- DMAP ( netuid ) --> consensus - pub(super) type Consensus = + pub type Consensus = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; #[pallet::storage] // --- DMAP ( netuid ) --> incentive - pub(super) type Incentive = + pub type Incentive = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; #[pallet::storage] // --- DMAP ( netuid ) --> dividends - pub(super) type Dividends = + pub type Dividends = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; #[pallet::storage] // --- DMAP ( netuid ) --> emission - pub(super) type Emission = + pub type Emission = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU64Vec>; #[pallet::storage] // --- DMAP ( netuid ) --> last_update - pub(super) type LastUpdate = + pub type LastUpdate = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU64Vec>; #[pallet::storage] // --- DMAP ( netuid ) --> validator_trust - pub(super) type ValidatorTrust = + pub type ValidatorTrust = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; #[pallet::storage] // --- DMAP ( netuid ) --> pruning_scores - pub(super) type PruningScores = + pub type PruningScores = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; #[pallet::storage] // --- DMAP ( netuid ) --> validator_permit - pub(super) type ValidatorPermit = + pub type ValidatorPermit = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyBoolVec>; #[pallet::storage] // --- DMAP ( netuid, uid ) --> weights - pub(super) type Weights = StorageDoubleMap< + pub type Weights = StorageDoubleMap< _, Identity, u16, @@ -1129,7 +1130,7 @@ pub mod pallet { DefaultWeights, >; #[pallet::storage] // --- DMAP ( netuid, uid ) --> bonds - pub(super) type Bonds = StorageDoubleMap< + pub type Bonds = StorageDoubleMap< _, Identity, u16, diff --git a/pallets/subtensor/src/swap.rs b/pallets/subtensor/src/swap.rs index 8e4ca5cc9..5d8f66c68 100644 --- a/pallets/subtensor/src/swap.rs +++ b/pallets/subtensor/src/swap.rs @@ -6,100 +6,6 @@ use frame_support::{storage::IterableStorageDoubleMap, weights::Weight}; use sp_core::{Get, U256}; impl Pallet { - /// Swaps the hotkey of a coldkey account. - /// - /// # Arguments - /// - /// * `origin` - The origin of the transaction, and also the coldkey account. - /// * `old_hotkey` - The old hotkey to be swapped. - /// * `new_hotkey` - The new hotkey to replace the old one. - /// - /// # Returns - /// - /// * `DispatchResultWithPostInfo` - The result of the dispatch. - /// - /// # Errors - /// - /// * `NonAssociatedColdKey` - If the coldkey does not own the old hotkey. - /// * `HotKeySetTxRateLimitExceeded` - If the transaction rate limit is exceeded. - /// * `NewHotKeyIsSameWithOld` - If the new hotkey is the same as the old hotkey. - /// * `HotKeyAlreadyRegisteredInSubNet` - If the new hotkey is already registered in the subnet. - /// * `NotEnoughBalanceToPaySwapHotKey` - If there is not enough balance to pay for the swap. - pub fn do_swap_hotkey( - origin: T::RuntimeOrigin, - old_hotkey: &T::AccountId, - new_hotkey: &T::AccountId, - ) -> DispatchResultWithPostInfo { - let coldkey = ensure_signed(origin)?; - - ensure!( - !Self::coldkey_in_arbitration(&coldkey), - Error::::ColdkeyIsInArbitration - ); - - let mut weight = T::DbWeight::get().reads(2); - - ensure!(old_hotkey != new_hotkey, Error::::NewHotKeyIsSameWithOld); - ensure!( - !Self::is_hotkey_registered_on_any_network(new_hotkey), - Error::::HotKeyAlreadyRegisteredInSubNet - ); - - weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 0)); - ensure!( - Self::coldkey_owns_hotkey(&coldkey, old_hotkey), - Error::::NonAssociatedColdKey - ); - - let block: u64 = Self::get_current_block_as_u64(); - ensure!( - !Self::exceeds_tx_rate_limit(Self::get_last_tx_block(&coldkey), block), - Error::::HotKeySetTxRateLimitExceeded - ); - - weight.saturating_accrue( - T::DbWeight::get().reads((TotalNetworks::::get().saturating_add(1u16)) as u64), - ); - - let swap_cost = Self::get_key_swap_cost(); - log::debug!("Swap cost: {:?}", swap_cost); - - ensure!( - Self::can_remove_balance_from_coldkey_account(&coldkey, swap_cost), - Error::::NotEnoughBalanceToPaySwapHotKey - ); - let actual_burn_amount = Self::remove_balance_from_coldkey_account(&coldkey, swap_cost)?; - Self::burn_tokens(actual_burn_amount); - - Self::swap_owner(old_hotkey, new_hotkey, &coldkey, &mut weight); - Self::swap_total_hotkey_stake(old_hotkey, new_hotkey, &mut weight); - Self::swap_delegates(old_hotkey, new_hotkey, &mut weight); - Self::swap_stake(old_hotkey, new_hotkey, &mut weight); - - // Store the value of is_network_member for the old key - let netuid_is_member: Vec = Self::get_netuid_is_member(old_hotkey, &mut weight); - - Self::swap_is_network_member(old_hotkey, new_hotkey, &netuid_is_member, &mut weight); - Self::swap_axons(old_hotkey, new_hotkey, &netuid_is_member, &mut weight); - Self::swap_keys(old_hotkey, new_hotkey, &netuid_is_member, &mut weight); - Self::swap_loaded_emission(old_hotkey, new_hotkey, &netuid_is_member, &mut weight); - Self::swap_uids(old_hotkey, new_hotkey, &netuid_is_member, &mut weight); - Self::swap_prometheus(old_hotkey, new_hotkey, &netuid_is_member, &mut weight); - Self::swap_senate_member(old_hotkey, new_hotkey, &mut weight)?; - - Self::swap_total_hotkey_coldkey_stakes_this_interval(old_hotkey, new_hotkey, &mut weight); - - Self::set_last_tx_block(&coldkey, block); - weight.saturating_accrue(T::DbWeight::get().writes(1)); - - Self::deposit_event(Event::HotkeySwapped { - coldkey, - old_hotkey: old_hotkey.clone(), - new_hotkey: new_hotkey.clone(), - }); - - Ok(Some(weight).into()) - } /// Swaps the coldkey associated with a set of hotkeys from an old coldkey to a new coldkey. /// @@ -472,316 +378,6 @@ impl Pallet { netuid_is_member } - /// Swaps the owner of the hotkey. - /// - /// # Arguments - /// - /// * `old_hotkey` - The old hotkey. - /// * `new_hotkey` - The new hotkey. - /// * `coldkey` - The coldkey owning the hotkey. - /// * `weight` - The weight of the transaction. - /// - pub fn swap_owner( - old_hotkey: &T::AccountId, - new_hotkey: &T::AccountId, - coldkey: &T::AccountId, - weight: &mut Weight, - ) { - Owner::::remove(old_hotkey); - Owner::::insert(new_hotkey, coldkey.clone()); - - // Update OwnedHotkeys map - let mut hotkeys = OwnedHotkeys::::get(coldkey); - if !hotkeys.contains(new_hotkey) { - hotkeys.push(new_hotkey.clone()); - } - hotkeys.retain(|hk| *hk != *old_hotkey); - OwnedHotkeys::::insert(coldkey, hotkeys); - - weight.saturating_accrue(T::DbWeight::get().writes(2)); - } - - /// Swaps the total stake of the hotkey. - /// - /// # Arguments - /// - /// * `old_hotkey` - The old hotkey. - /// * `new_hotkey` - The new hotkey. - /// * `weight` - The weight of the transaction. - /// - /// # Weight Calculation - /// - /// * Reads: 1 if the old hotkey exists, otherwise 1 for the failed read. - /// * Writes: 2 if the old hotkey exists (one for removal and one for insertion). - pub fn swap_total_hotkey_stake( - old_hotkey: &T::AccountId, - new_hotkey: &T::AccountId, - weight: &mut Weight, - ) { - if let Ok(total_hotkey_stake) = TotalHotkeyStake::::try_get(old_hotkey) { - TotalHotkeyStake::::remove(old_hotkey); - TotalHotkeyStake::::insert(new_hotkey, total_hotkey_stake); - weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); - } else { - weight.saturating_accrue(T::DbWeight::get().reads(1)); - } - } - - /// Swaps the delegates of the hotkey. - /// - /// # Arguments - /// - /// * `old_hotkey` - The old hotkey. - /// * `new_hotkey` - The new hotkey. - /// * `weight` - The weight of the transaction. - /// - /// # Weight Calculation - /// - /// * Reads: 1 if the old hotkey exists, otherwise 1 for the failed read. - /// * Writes: 2 if the old hotkey exists (one for removal and one for insertion). - pub fn swap_delegates( - old_hotkey: &T::AccountId, - new_hotkey: &T::AccountId, - weight: &mut Weight, - ) { - if let Ok(delegate_take) = Delegates::::try_get(old_hotkey) { - Delegates::::remove(old_hotkey); - Delegates::::insert(new_hotkey, delegate_take); - weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); - } else { - weight.saturating_accrue(T::DbWeight::get().reads(1)); - } - } - - /// Swaps the stake of the hotkey. - /// - /// # Arguments - /// - /// * `old_hotkey` - The old hotkey. - /// * `new_hotkey` - The new hotkey. - /// * `weight` - The weight of the transaction. - pub fn swap_stake(old_hotkey: &T::AccountId, new_hotkey: &T::AccountId, weight: &mut Weight) { - let mut writes: u64 = 0; - let stakes: Vec<(T::AccountId, u64)> = Stake::::iter_prefix(old_hotkey).collect(); - let stake_count = stakes.len() as u32; - - for (coldkey, stake_amount) in stakes { - Stake::::insert(new_hotkey, &coldkey, stake_amount); - writes = writes.saturating_add(1u64); // One write for insert - - // Update StakingHotkeys map - let mut staking_hotkeys = StakingHotkeys::::get(&coldkey); - if !staking_hotkeys.contains(new_hotkey) { - staking_hotkeys.push(new_hotkey.clone()); - writes = writes.saturating_add(1u64); // One write for insert - } - if let Some(pos) = staking_hotkeys.iter().position(|x| x == old_hotkey) { - staking_hotkeys.remove(pos); - writes = writes.saturating_add(1u64); // One write for remove - } - StakingHotkeys::::insert(coldkey.clone(), staking_hotkeys); - writes = writes.saturating_add(1u64); // One write for insert - } - - // Clear the prefix for the old hotkey after transferring all stakes - let _ = Stake::::clear_prefix(old_hotkey, stake_count, None); - writes = writes.saturating_add(1); // One write for insert; // One write for clear_prefix - - // TODO: Remove all entries for old hotkey from StakingHotkeys map - - weight.saturating_accrue(T::DbWeight::get().writes(writes)); - } - - /// Swaps the network membership status of the hotkey. - /// - /// # Arguments - /// - /// * `old_hotkey` - The old hotkey. - /// * `new_hotkey` - The new hotkey. - /// * `netuid_is_member` - A vector of network IDs where the hotkey is a member. - /// * `weight` - The weight of the transaction. - pub fn swap_is_network_member( - old_hotkey: &T::AccountId, - new_hotkey: &T::AccountId, - netuid_is_member: &[u16], - weight: &mut Weight, - ) { - let _ = IsNetworkMember::::clear_prefix(old_hotkey, netuid_is_member.len() as u32, None); - weight.saturating_accrue(T::DbWeight::get().writes(netuid_is_member.len() as u64)); - for netuid in netuid_is_member.iter() { - IsNetworkMember::::insert(new_hotkey, netuid, true); - weight.saturating_accrue(T::DbWeight::get().writes(1)); - } - } - - /// Swaps the axons of the hotkey. - /// - /// # Arguments - /// - /// * `old_hotkey` - The old hotkey. - /// * `new_hotkey` - The new hotkey. - /// * `netuid_is_member` - A vector of network IDs where the hotkey is a member. - /// * `weight` - The weight of the transaction. - /// - /// # Weight Calculation - /// - /// * Reads: 1 for each network ID if the old hotkey exists in that network. - /// * Writes: 2 for each network ID if the old hotkey exists in that network (one for removal and one for insertion). - pub fn swap_axons( - old_hotkey: &T::AccountId, - new_hotkey: &T::AccountId, - netuid_is_member: &[u16], - weight: &mut Weight, - ) { - for netuid in netuid_is_member.iter() { - if let Ok(axon_info) = Axons::::try_get(netuid, old_hotkey) { - Axons::::remove(netuid, old_hotkey); - Axons::::insert(netuid, new_hotkey, axon_info); - weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); - } else { - weight.saturating_accrue(T::DbWeight::get().reads(1)); - } - } - } - - /// Swaps the references in the keys storage map of the hotkey. - /// - /// # Arguments - /// - /// * `old_hotkey` - The old hotkey. - /// * `new_hotkey` - The new hotkey. - /// * `netuid_is_member` - A vector of network IDs where the hotkey is a member. - /// * `weight` - The weight of the transaction. - pub fn swap_keys( - old_hotkey: &T::AccountId, - new_hotkey: &T::AccountId, - netuid_is_member: &[u16], - weight: &mut Weight, - ) { - let mut writes: u64 = 0; - for netuid in netuid_is_member { - let keys: Vec<(u16, T::AccountId)> = Keys::::iter_prefix(netuid).collect(); - for (uid, key) in keys { - if key == *old_hotkey { - log::info!("old hotkey found: {:?}", old_hotkey); - Keys::::insert(netuid, uid, new_hotkey.clone()); - } - writes = writes.saturating_add(2u64); - } - } - log::info!("writes: {:?}", writes); - weight.saturating_accrue(T::DbWeight::get().writes(writes)); - } - - /// Swaps the loaded emission of the hotkey. - /// - /// # Arguments - /// - /// * `old_hotkey` - The old hotkey. - /// * `new_hotkey` - The new hotkey. - /// * `netuid_is_member` - A vector of network IDs where the hotkey is a member. - /// * `weight` - The weight of the transaction. - /// - pub fn swap_loaded_emission( - old_hotkey: &T::AccountId, - new_hotkey: &T::AccountId, - netuid_is_member: &[u16], - weight: &mut Weight, - ) { - for netuid in netuid_is_member { - if let Some(mut emissions) = LoadedEmission::::get(netuid) { - for emission in emissions.iter_mut() { - if emission.0 == *old_hotkey { - emission.0 = new_hotkey.clone(); - } - } - LoadedEmission::::insert(netuid, emissions); - } - } - weight.saturating_accrue(T::DbWeight::get().writes(netuid_is_member.len() as u64)); - } - - /// Swaps the UIDs of the hotkey. - /// - /// # Arguments - /// - /// * `old_hotkey` - The old hotkey. - /// * `new_hotkey` - The new hotkey. - /// * `netuid_is_member` - A vector of network IDs where the hotkey is a member. - /// * `weight` - The weight of the transaction. - /// - pub fn swap_uids( - old_hotkey: &T::AccountId, - new_hotkey: &T::AccountId, - netuid_is_member: &[u16], - weight: &mut Weight, - ) { - for netuid in netuid_is_member.iter() { - if let Ok(uid) = Uids::::try_get(netuid, old_hotkey) { - Uids::::remove(netuid, old_hotkey); - Uids::::insert(netuid, new_hotkey, uid); - weight.saturating_accrue(T::DbWeight::get().writes(2)); - } - } - } - - /// Swaps the Prometheus data of the hotkey. - /// - /// # Arguments - /// - /// * `old_hotkey` - The old hotkey. - /// * `new_hotkey` - The new hotkey. - /// * `netuid_is_member` - A vector of network IDs where the hotkey is a member. - /// * `weight` - The weight of the transaction. - /// - /// # Weight Calculation - /// - /// * Reads: 1 for each network ID if the old hotkey exists in that network. - /// * Writes: 2 for each network ID if the old hotkey exists in that network (one for removal and one for insertion). - pub fn swap_prometheus( - old_hotkey: &T::AccountId, - new_hotkey: &T::AccountId, - netuid_is_member: &[u16], - weight: &mut Weight, - ) { - for netuid in netuid_is_member.iter() { - if let Ok(prometheus_info) = Prometheus::::try_get(netuid, old_hotkey) { - Prometheus::::remove(netuid, old_hotkey); - Prometheus::::insert(netuid, new_hotkey, prometheus_info); - weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); - } else { - weight.saturating_accrue(T::DbWeight::get().reads(1)); - } - } - } - - /// Swaps the total hotkey-coldkey stakes for the current interval. - /// - /// # Arguments - /// - /// * `old_hotkey` - The old hotkey. - /// * `new_hotkey` - The new hotkey. - /// * `weight` - The weight of the transaction. - /// - pub fn swap_total_hotkey_coldkey_stakes_this_interval( - old_hotkey: &T::AccountId, - new_hotkey: &T::AccountId, - weight: &mut Weight, - ) { - let stakes: Vec<(T::AccountId, (u64, u64))> = - TotalHotkeyColdkeyStakesThisInterval::::iter_prefix(old_hotkey).collect(); - log::info!("Stakes to swap: {:?}", stakes); - for (coldkey, stake) in stakes { - log::info!( - "Swapping stake for coldkey: {:?}, stake: {:?}", - coldkey, - stake - ); - TotalHotkeyColdkeyStakesThisInterval::::insert(new_hotkey, &coldkey, stake); - TotalHotkeyColdkeyStakesThisInterval::::remove(old_hotkey, &coldkey); - weight.saturating_accrue(T::DbWeight::get().writes(2)); // One write for insert and one for remove - } - } /// Swaps the total stake associated with a coldkey from the old coldkey to the new coldkey. /// @@ -1040,16 +636,5 @@ impl Pallet { weight.saturating_accrue(T::DbWeight::get().reads(TotalNetworks::::get() as u64)); } - pub fn swap_senate_member( - old_hotkey: &T::AccountId, - new_hotkey: &T::AccountId, - weight: &mut Weight, - ) -> DispatchResult { - weight.saturating_accrue(T::DbWeight::get().reads(1)); - if T::SenateMembers::is_member(old_hotkey) { - T::SenateMembers::swap_member(old_hotkey, new_hotkey).map_err(|e| e.error)?; - weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); - } - Ok(()) - } + } diff --git a/pallets/subtensor/src/swap_hotkey.rs b/pallets/subtensor/src/swap_hotkey.rs index 068b24b78..222a4ff37 100644 --- a/pallets/subtensor/src/swap_hotkey.rs +++ b/pallets/subtensor/src/swap_hotkey.rs @@ -103,7 +103,7 @@ impl Pallet { Ok(Some(weight).into()) } - pub fn perform_hotkey_swap( old_hotkey: &T::AccountId, new_hotkey: &T::AccountId, coldkey: &T::AccountId, weight: &mut Weight ) { + pub fn perform_hotkey_swap( old_hotkey: &T::AccountId, new_hotkey: &T::AccountId, coldkey: &T::AccountId, weight: &mut Weight ) -> DispatchResult { // 1. Swap owner. // Owner( hotkey ) -> coldkey -- the coldkey that owns the hotkey. @@ -169,7 +169,7 @@ impl Pallet { weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); // Swap all subnet specific info. - let all_netuid: Vec = Self::get_all_subnet_netuids(); + let all_netuids: Vec = Self::get_all_subnet_netuids(); for netuid in all_netuids { // 7.1 Remove the previous hotkey and insert the new hotkey from membership. // IsNetworkMember( hotkey, netuid ) -> bool -- is the hotkey a subnet member. @@ -183,40 +183,43 @@ impl Pallet { // Uids( netuid, hotkey ) -> uid -- the uids that the hotkey has. if is_network_member { // 7.2.1 Swap the UIDS - let old_uid: u16 = Uids::::get(netuid, old_hotkey); - Uids::::remove(netuid, old_hotkey); - Uids::::insert(netuid, new_hotkey, old_uid); - weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); - - // 7.2.2 Swap the keys. - Keys::::insert(netuid, old_uid, new_hotkey.clone()); - weight.saturating_accrue(T::DbWeight::get().reads_writes(0, 1)); + if let Ok(old_uid) = Uids::::try_get(netuid, old_hotkey) { + Uids::::remove(netuid, old_hotkey); + Uids::::insert(netuid, new_hotkey, old_uid); + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); + + // 7.2.2 Swap the keys. + Keys::::insert(netuid, old_uid, new_hotkey.clone()); + weight.saturating_accrue(T::DbWeight::get().reads_writes(0, 1)); + } } // 7.3 Swap Prometheus. // Prometheus( netuid, hotkey ) -> prometheus -- the prometheus data that a hotkey has in the network. if is_network_member { - let old_prometheus_info: PrometheusInfo = Prometheus::::get(netuid, old_hotkey); - Prometheus::::remove(netuid, old_hotkey); - Prometheus::::insert(netuid, new_hotkey, old_prometheus_info); - weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); + if let Ok(old_prometheus_info) = Prometheus::::try_get(netuid, old_hotkey) { + Prometheus::::remove(netuid, old_hotkey); + Prometheus::::insert(netuid, new_hotkey, old_prometheus_info); + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); + } } // 7.4. Swap axons. // Axons( netuid, hotkey ) -> axon -- the axon that the hotkey has. if is_network_member { - let old_axon_info: AxonInfo = Axons::::get(netuid, old_hotkey); - Axons::::remove(netuid, old_hotkey); - Axons::::insert(netuid, new_hotkey, old_axon_info); - weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); + if let Ok(old_axon_info) = Axons::::try_get(netuid, old_hotkey) { + Axons::::remove(netuid, old_hotkey); + Axons::::insert(netuid, new_hotkey, old_axon_info); + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); + } } // 7.5 Swap WeightCommits // WeightCommits( hotkey ) --> Vec -- the weight commits for the hotkey. if is_network_member { - if let Ok(old_weight_commits) = WeightCommits::::try_get(old_hotkey) { - WeightCommits::::remove(old_hotkey); - WeightCommits::::insert(new_hotkey, old_weight_commits); + if let Ok(old_weight_commits) = WeightCommits::::try_get(netuid, old_hotkey) { + WeightCommits::::remove(netuid, old_hotkey); + WeightCommits::::insert(netuid, new_hotkey, old_weight_commits); weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); } } @@ -263,6 +266,8 @@ impl Pallet { StakingHotkeys::::insert(coldkey.clone(), staking_hotkeys); weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); } + + Ok(()) } pub fn swap_senate_member( diff --git a/pallets/subtensor/tests/swap.rs b/pallets/subtensor/tests/swap.rs index 21c3a983a..86fe109be 100644 --- a/pallets/subtensor/tests/swap.rs +++ b/pallets/subtensor/tests/swap.rs @@ -9,6 +9,7 @@ use mock::*; use pallet_subtensor::*; use sp_core::U256; +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap -- test_do_swap_hotkey_ok --exact --nocapture #[test] fn test_do_swap_hotkey_ok() { new_test_ext(1).execute_with(|| { @@ -42,15 +43,11 @@ fn test_do_swap_hotkey_ok() { ); // Verify other storage changes - assert_eq!( - SubtensorModule::get_total_stake_for_hotkey(&new_hotkey), - SubtensorModule::get_total_stake_for_hotkey(&old_hotkey) - ); - assert_eq!( + assert_ne!( SubtensorModule::get_delegate(new_hotkey.encode()), SubtensorModule::get_delegate(old_hotkey.encode()) ); - assert_eq!( + assert_ne!( SubtensorModule::get_last_tx_block(&new_hotkey), SubtensorModule::get_last_tx_block(&old_hotkey) ); @@ -62,29 +59,6 @@ fn test_do_swap_hotkey_ok() { } let mut weight = Weight::zero(); - // UIDs - for netuid in SubtensorModule::get_netuid_is_member(&old_hotkey, &mut weight) { - assert_eq!( - Uids::::get(netuid, new_hotkey), - Uids::::get(netuid, old_hotkey) - ); - } - - // Prometheus - for netuid in SubtensorModule::get_netuid_is_member(&old_hotkey, &mut weight) { - assert_eq!( - Prometheus::::get(netuid, new_hotkey), - Prometheus::::get(netuid, old_hotkey) - ); - } - - // LoadedEmission - for netuid in SubtensorModule::get_netuid_is_member(&old_hotkey, &mut weight) { - assert_eq!( - LoadedEmission::::get(netuid).unwrap(), - LoadedEmission::::get(netuid).unwrap() - ); - } // IsNetworkMember for netuid in SubtensorModule::get_netuid_is_member(&old_hotkey, &mut weight) { @@ -96,7 +70,7 @@ fn test_do_swap_hotkey_ok() { assert_eq!(Owner::::get(new_hotkey), coldkey); // TotalHotkeyStake - assert_eq!( + assert_ne!( TotalHotkeyStake::::get(new_hotkey), TotalHotkeyStake::::get(old_hotkey) ); @@ -129,185 +103,6 @@ fn test_do_swap_hotkey_ok() { }); } -#[test] -fn test_do_swap_hotkey_ok_robust() { - new_test_ext(1).execute_with(|| { - let num_subnets: u16 = 10; - let tempo: u16 = 13; - let swap_cost = 1_000_000_000u64; - - // Create 10 sets of keys - let mut old_hotkeys = vec![]; - let mut new_hotkeys = vec![]; - let mut coldkeys = vec![]; - - for i in 0..10 { - old_hotkeys.push(U256::from(i * 2 + 1)); - new_hotkeys.push(U256::from(i * 2 + 2)); - coldkeys.push(U256::from(i * 2 + 11)); - } - - // Setup initial state - for netuid in 1..=num_subnets { - add_network(netuid, tempo, 0); - SubtensorModule::set_max_registrations_per_block(netuid, 20); - SubtensorModule::set_target_registrations_per_interval(netuid, 1000); - log::info!( - "Registrations this interval for netuid {:?} is {:?}", - netuid, - SubtensorModule::get_target_registrations_per_interval(netuid) - ); - for i in 0..10 { - register_ok_neuron(netuid, old_hotkeys[i], coldkeys[i], 0); - } - } - - // Add balance to coldkeys for swap cost - for coldkey in coldkeys.iter().take(10) { - SubtensorModule::add_balance_to_coldkey_account(coldkey, swap_cost); - } - - // Add old_hotkeys[0] and old_hotkeys[1] to Senate - assert_ok!(SenateMembers::add_member( - RawOrigin::Root.into(), - old_hotkeys[0] - )); - assert_ok!(SenateMembers::add_member( - RawOrigin::Root.into(), - old_hotkeys[1] - )); - - // Verify initial Senate membership - assert!(Senate::is_member(&old_hotkeys[0])); - assert!(Senate::is_member(&old_hotkeys[1])); - assert!(!Senate::is_member(&new_hotkeys[0])); - assert!(!Senate::is_member(&new_hotkeys[1])); - - // Perform the swaps for only two hotkeys - assert_ok!(SubtensorModule::do_swap_hotkey( - <::RuntimeOrigin>::signed(coldkeys[0]), - &old_hotkeys[0], - &new_hotkeys[0] - )); - assert_ok!(SubtensorModule::do_swap_hotkey( - <::RuntimeOrigin>::signed(coldkeys[1]), - &old_hotkeys[1], - &new_hotkeys[1] - )); - - // Verify the swaps - for netuid in 1..=num_subnets { - for i in 0..10 { - if i == 0 || i == 1 { - assert_eq!( - SubtensorModule::get_owning_coldkey_for_hotkey(&new_hotkeys[i]), - coldkeys[i] - ); - assert_ne!( - SubtensorModule::get_owning_coldkey_for_hotkey(&old_hotkeys[i]), - coldkeys[i] - ); - - // Verify other storage changes - assert_eq!( - SubtensorModule::get_total_stake_for_hotkey(&new_hotkeys[i]), - SubtensorModule::get_total_stake_for_hotkey(&old_hotkeys[i]) - ); - - assert_eq!( - SubtensorModule::get_delegate(new_hotkeys[i].encode()), - SubtensorModule::get_delegate(old_hotkeys[i].encode()) - ); - - assert_eq!( - SubtensorModule::get_last_tx_block(&new_hotkeys[i]), - SubtensorModule::get_last_tx_block(&old_hotkeys[i]) - ); - - // Verify raw storage maps - // Stake - for (coldkey, stake_amount) in Stake::::iter_prefix(old_hotkeys[i]) { - assert_eq!(Stake::::get(new_hotkeys[i], coldkey), stake_amount); - } - - let mut weight = Weight::zero(); - // UIDs - for netuid in - SubtensorModule::get_netuid_is_member(&old_hotkeys[i], &mut weight) - { - assert_eq!( - Uids::::get(netuid, new_hotkeys[i]), - Uids::::get(netuid, old_hotkeys[i]) - ); - } - - // Prometheus - for netuid in - SubtensorModule::get_netuid_is_member(&old_hotkeys[i], &mut weight) - { - assert_eq!( - Prometheus::::get(netuid, new_hotkeys[i]), - Prometheus::::get(netuid, old_hotkeys[i]) - ); - } - - // LoadedEmission - for netuid in - SubtensorModule::get_netuid_is_member(&old_hotkeys[i], &mut weight) - { - assert_eq!( - LoadedEmission::::get(netuid).unwrap(), - LoadedEmission::::get(netuid).unwrap() - ); - } - - // IsNetworkMember - for netuid in - SubtensorModule::get_netuid_is_member(&old_hotkeys[i], &mut weight) - { - assert!(IsNetworkMember::::contains_key( - new_hotkeys[i], - netuid - )); - assert!(!IsNetworkMember::::contains_key( - old_hotkeys[i], - netuid - )); - } - - // Owner - assert_eq!(Owner::::get(new_hotkeys[i]), coldkeys[i]); - - // Keys - for (uid, hotkey) in Keys::::iter_prefix(netuid) { - if hotkey == old_hotkeys[i] { - assert_eq!(Keys::::get(netuid, uid), new_hotkeys[i]); - } - } - - // Verify Senate membership swap - assert!(!Senate::is_member(&old_hotkeys[i])); - assert!(Senate::is_member(&new_hotkeys[i])); - } else { - // Ensure other hotkeys remain unchanged - assert_eq!( - SubtensorModule::get_owning_coldkey_for_hotkey(&old_hotkeys[i]), - coldkeys[i] - ); - assert_ne!( - SubtensorModule::get_owning_coldkey_for_hotkey(&new_hotkeys[i]), - coldkeys[i] - ); - - // Verify Senate membership remains unchanged for other hotkeys - assert!(!Senate::is_member(&old_hotkeys[i])); - assert!(!Senate::is_member(&new_hotkeys[i])); - } - } - } - }); -} - #[test] fn test_swap_hotkey_tx_rate_limit_exceeded() { new_test_ext(1).execute_with(|| { @@ -402,7 +197,7 @@ fn test_swap_owner_success() { Owner::::insert(old_hotkey, coldkey); // Perform the swap - SubtensorModule::swap_owner(&old_hotkey, &new_hotkey, &coldkey, &mut weight); + SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight); // Verify the swap assert_eq!(Owner::::get(new_hotkey), coldkey); @@ -422,7 +217,7 @@ fn test_swap_owner_old_hotkey_not_exist() { assert!(!Owner::::contains_key(old_hotkey)); // Perform the swap - SubtensorModule::swap_owner(&old_hotkey, &new_hotkey, &coldkey, &mut weight); + SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight); // Verify the swap assert_eq!(Owner::::get(new_hotkey), coldkey); @@ -444,7 +239,7 @@ fn test_swap_owner_new_hotkey_already_exists() { Owner::::insert(new_hotkey, another_coldkey); // Perform the swap - SubtensorModule::swap_owner(&old_hotkey, &new_hotkey, &coldkey, &mut weight); + SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight); // Verify the swap assert_eq!(Owner::::get(new_hotkey), coldkey); @@ -452,31 +247,12 @@ fn test_swap_owner_new_hotkey_already_exists() { }); } -#[test] -fn test_swap_owner_weight_update() { - new_test_ext(1).execute_with(|| { - let old_hotkey = U256::from(1); - let new_hotkey = U256::from(2); - let coldkey = U256::from(3); - let mut weight = Weight::zero(); - - // Initialize Owner for old_hotkey - Owner::::insert(old_hotkey, coldkey); - - // Perform the swap - SubtensorModule::swap_owner(&old_hotkey, &new_hotkey, &coldkey, &mut weight); - - // Verify the weight update - let expected_weight = ::DbWeight::get().writes(2); - assert_eq!(weight, expected_weight); - }); -} - #[test] fn test_swap_total_hotkey_stake_success() { new_test_ext(1).execute_with(|| { let old_hotkey = U256::from(1); let new_hotkey = U256::from(2); + let coldkey = U256::from(3); let total_stake = 1000u64; let mut weight = Weight::zero(); @@ -484,7 +260,7 @@ fn test_swap_total_hotkey_stake_success() { TotalHotkeyStake::::insert(old_hotkey, total_stake); // Perform the swap - SubtensorModule::swap_total_hotkey_stake(&old_hotkey, &new_hotkey, &mut weight); + SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight); // Verify the swap assert_eq!(TotalHotkeyStake::::get(new_hotkey), total_stake); @@ -492,49 +268,14 @@ fn test_swap_total_hotkey_stake_success() { }); } -#[test] -fn test_swap_total_hotkey_stake_old_hotkey_not_exist() { - new_test_ext(1).execute_with(|| { - let old_hotkey = U256::from(1); - let new_hotkey = U256::from(2); - let mut weight = Weight::zero(); - - // Ensure old_hotkey does not exist - assert!(!TotalHotkeyStake::::contains_key(old_hotkey)); - - // Perform the swap - SubtensorModule::swap_total_hotkey_stake(&old_hotkey, &new_hotkey, &mut weight); - // Verify that new_hotkey does not have a stake - assert!(!TotalHotkeyStake::::contains_key(new_hotkey)); - }); -} - -#[test] -fn test_swap_total_hotkey_stake_weight_update() { - new_test_ext(1).execute_with(|| { - let old_hotkey = U256::from(1); - let new_hotkey = U256::from(2); - let total_stake = 1000u64; - let mut weight = Weight::zero(); - - // Initialize TotalHotkeyStake for old_hotkey - TotalHotkeyStake::::insert(old_hotkey, total_stake); - - // Perform the swap - SubtensorModule::swap_total_hotkey_stake(&old_hotkey, &new_hotkey, &mut weight); - - // Verify the weight update - let expected_weight = ::DbWeight::get().reads_writes(1, 2); - assert_eq!(weight, expected_weight); - }); -} #[test] fn test_swap_delegates_success() { new_test_ext(1).execute_with(|| { let old_hotkey = U256::from(1); let new_hotkey = U256::from(2); + let coldkey = U256::from(3); let delegate_take = 10u16; let mut weight = Weight::zero(); @@ -542,7 +283,7 @@ fn test_swap_delegates_success() { Delegates::::insert(old_hotkey, delegate_take); // Perform the swap - SubtensorModule::swap_delegates(&old_hotkey, &new_hotkey, &mut weight); + SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight); // Verify the swap assert_eq!(Delegates::::get(new_hotkey), delegate_take); @@ -550,29 +291,12 @@ fn test_swap_delegates_success() { }); } -#[test] -fn test_swap_delegates_old_hotkey_not_exist() { - new_test_ext(1).execute_with(|| { - let old_hotkey = U256::from(1); - let new_hotkey = U256::from(2); - let mut weight = Weight::zero(); - - // Ensure old_hotkey does not exist - assert!(!Delegates::::contains_key(old_hotkey)); - - // Perform the swap - SubtensorModule::swap_delegates(&old_hotkey, &new_hotkey, &mut weight); - - // Verify that new_hotkey does not have a delegate - assert!(!Delegates::::contains_key(new_hotkey)); - }); -} - #[test] fn test_swap_delegates_weight_update() { new_test_ext(1).execute_with(|| { let old_hotkey = U256::from(1); let new_hotkey = U256::from(2); + let coldkey = U256::from(3); let delegate_take = 10u16; let mut weight = Weight::zero(); @@ -580,7 +304,7 @@ fn test_swap_delegates_weight_update() { Delegates::::insert(old_hotkey, delegate_take); // Perform the swap - SubtensorModule::swap_delegates(&old_hotkey, &new_hotkey, &mut weight); + SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight); // Verify the weight update let expected_weight = ::DbWeight::get().reads_writes(1, 2); @@ -601,7 +325,7 @@ fn test_swap_stake_success() { Stake::::insert(old_hotkey, coldkey, stake_amount); // Perform the swap - SubtensorModule::swap_stake(&old_hotkey, &new_hotkey, &mut weight); + SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight); // Verify the swap assert_eq!(Stake::::get(new_hotkey, coldkey), stake_amount); @@ -625,7 +349,7 @@ fn test_swap_stake_old_hotkey_not_exist() { assert!(Stake::::contains_key(old_hotkey, coldkey)); // Perform the swap - SubtensorModule::swap_stake(&old_hotkey, &new_hotkey, &mut weight); + SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight); // Verify that new_hotkey has the stake and old_hotkey does not assert!(Stake::::contains_key(new_hotkey, coldkey)); @@ -633,390 +357,6 @@ fn test_swap_stake_old_hotkey_not_exist() { }); } -#[test] -fn test_swap_stake_weight_update() { - new_test_ext(1).execute_with(|| { - let old_hotkey = U256::from(1); - let new_hotkey = U256::from(2); - let coldkey = U256::from(3); - let stake_amount = 1000u64; - let mut weight = Weight::zero(); - - // Initialize Stake for old_hotkey - Stake::::insert(old_hotkey, coldkey, stake_amount); - - // Perform the swap - SubtensorModule::swap_stake(&old_hotkey, &new_hotkey, &mut weight); - - // Verify the weight update - let expected_weight = ::DbWeight::get().writes(4); - assert_eq!(weight, expected_weight); - }); -} - -#[test] -fn test_swap_is_network_member_success() { - new_test_ext(1).execute_with(|| { - let old_hotkey = U256::from(1); - let new_hotkey = U256::from(2); - let netuid_is_member = vec![1u16, 2u16]; - let mut weight = Weight::zero(); - - // Initialize IsNetworkMember for old_hotkey - for netuid in &netuid_is_member { - IsNetworkMember::::insert(old_hotkey, netuid, true); - } - - // Perform the swap - SubtensorModule::swap_is_network_member( - &old_hotkey, - &new_hotkey, - &netuid_is_member, - &mut weight, - ); - - // Verify the swap - for netuid in &netuid_is_member { - assert!(IsNetworkMember::::contains_key(new_hotkey, netuid)); - assert!(!IsNetworkMember::::contains_key(old_hotkey, netuid)); - } - }); -} - -#[test] -fn test_swap_is_network_member_weight_update() { - new_test_ext(1).execute_with(|| { - let old_hotkey = U256::from(1); - let new_hotkey = U256::from(2); - let netuid_is_member = vec![1u16, 2u16]; - let mut weight = Weight::zero(); - - // Initialize IsNetworkMember for old_hotkey - for netuid in &netuid_is_member { - IsNetworkMember::::insert(old_hotkey, netuid, true); - } - - // Perform the swap - SubtensorModule::swap_is_network_member( - &old_hotkey, - &new_hotkey, - &netuid_is_member, - &mut weight, - ); - - // Verify the weight update - let expected_weight = ::DbWeight::get().writes(4); - assert_eq!(weight, expected_weight); - }); -} - -#[test] -fn test_swap_axons_success() { - new_test_ext(1).execute_with(|| { - let old_hotkey = U256::from(1); - let new_hotkey = U256::from(2); - let netuid_is_member = vec![1u16, 2u16]; - let axon_info = AxonInfo { - block: 100, - version: 1, - ip: 0x1234567890abcdef, - port: 8080, - ip_type: 4, - protocol: 1, - placeholder1: 0, - placeholder2: 0, - }; - let mut weight = Weight::zero(); - - // Initialize Axons for old_hotkey - for netuid in &netuid_is_member { - Axons::::insert(netuid, old_hotkey, axon_info.clone()); - } - - // Perform the swap - SubtensorModule::swap_axons(&old_hotkey, &new_hotkey, &netuid_is_member, &mut weight); - - // Verify the swap - for netuid in &netuid_is_member { - assert_eq!(Axons::::get(netuid, new_hotkey).unwrap(), axon_info); - assert!(!Axons::::contains_key(netuid, old_hotkey)); - } - }); -} - -#[test] -fn test_swap_axons_weight_update() { - new_test_ext(1).execute_with(|| { - let old_hotkey = U256::from(1); - let new_hotkey = U256::from(2); - let netuid_is_member = vec![1u16, 2u16]; - let axon_info = AxonInfo { - block: 100, - version: 1, - ip: 0x1234567890abcdef, - port: 8080, - ip_type: 4, - protocol: 1, - placeholder1: 0, - placeholder2: 0, - }; - let mut weight = Weight::zero(); - - // Initialize Axons for old_hotkey - for netuid in &netuid_is_member { - Axons::::insert(netuid, old_hotkey, axon_info.clone()); - } - - // Perform the swap - SubtensorModule::swap_axons(&old_hotkey, &new_hotkey, &netuid_is_member, &mut weight); - - // Verify the weight update - let expected_weight = netuid_is_member.len() as u64 - * ::DbWeight::get().reads_writes(1, 2); - assert_eq!(weight, expected_weight); - }); -} - -#[test] -fn test_swap_keys_success() { - new_test_ext(1).execute_with(|| { - let old_hotkey = U256::from(1); - let new_hotkey = U256::from(2); - let netuid_is_member = vec![1u16, 2u16]; - let uid = 42u16; - let mut weight = Weight::zero(); - - // Initialize Keys for old_hotkey - for netuid in &netuid_is_member { - log::info!("Inserting old_hotkey:{:?} netuid:{:?}", old_hotkey, netuid); - Keys::::insert(*netuid, uid, old_hotkey); - } - - // Perform the swap - SubtensorModule::swap_keys(&old_hotkey, &new_hotkey, &netuid_is_member, &mut weight); - - // Verify the swap - for netuid in &netuid_is_member { - log::info!( - "neutuid, uid, hotkey: {:?}, {:?}, {:?}", - netuid, - uid, - new_hotkey - ); - assert_eq!(Keys::::get(netuid, uid), new_hotkey); - } - }); -} - -#[test] -fn test_swap_keys_weight_update() { - new_test_ext(1).execute_with(|| { - let old_hotkey = U256::from(1); - let new_hotkey = U256::from(2); - let netuid_is_member = vec![1u16, 2u16]; - let uid = 42u16; - let mut weight = Weight::zero(); - - // Initialize Keys for old_hotkey - for netuid in &netuid_is_member { - Keys::::insert(*netuid, uid, old_hotkey); - } - - // Perform the swap - SubtensorModule::swap_keys(&old_hotkey, &new_hotkey, &netuid_is_member, &mut weight); - - // Verify the weight update - let expected_weight = ::DbWeight::get().writes(4); - assert_eq!(weight, expected_weight); - }); -} - -#[test] -fn test_swap_loaded_emission_success() { - new_test_ext(1).execute_with(|| { - let old_hotkey = U256::from(1); - let new_hotkey = U256::from(2); - let netuid_is_member = vec![1u16, 2u16]; - let se = 100u64; - let ve = 200u64; - let mut weight = Weight::zero(); - - // Initialize LoadedEmission for old_hotkey - for netuid in &netuid_is_member { - LoadedEmission::::mutate(netuid, |emission_exists| { - if let Some(emissions) = emission_exists { - emissions.push((old_hotkey, se, ve)); - } else { - *emission_exists = Some(vec![(old_hotkey, se, ve)]); - } - }); - } - - // Perform the swap - SubtensorModule::swap_loaded_emission( - &old_hotkey, - &new_hotkey, - &netuid_is_member, - &mut weight, - ); - - // Verify the swap - for netuid in &netuid_is_member { - let emissions = LoadedEmission::::get(netuid).unwrap(); - assert!(emissions.iter().any(|(hk, _, _)| hk == &new_hotkey)); - assert!(!emissions.iter().any(|(hk, _, _)| hk == &old_hotkey)); - } - }); -} - -#[test] -fn test_swap_loaded_emission_weight_update() { - new_test_ext(1).execute_with(|| { - let old_hotkey = U256::from(1); - let new_hotkey = U256::from(2); - let netuid_is_member = vec![1u16, 2u16]; - // let uid = 42u64; - let se = 100u64; - let ve = 200u64; - let mut weight = Weight::zero(); - - // Initialize LoadedEmission for old_hotkey - for netuid in &netuid_is_member { - LoadedEmission::::mutate(netuid, |emission_exists| { - if let Some(emissions) = emission_exists { - emissions.push((old_hotkey, se, ve)); - } else { - *emission_exists = Some(vec![(old_hotkey, se, ve)]); - } - }); - } - - // Perform the swap - SubtensorModule::swap_loaded_emission( - &old_hotkey, - &new_hotkey, - &netuid_is_member, - &mut weight, - ); - - // Verify the weight update - let expected_weight = ::DbWeight::get().writes(2); - assert_eq!(weight, expected_weight); - }); -} - -#[test] -fn test_swap_uids_success() { - new_test_ext(1).execute_with(|| { - let old_hotkey = U256::from(1); - let new_hotkey = U256::from(2); - let netuid_is_member = vec![1u16, 2u16]; - let uid = 42u16; - let mut weight = Weight::zero(); - - // Initialize Uids for old_hotkey - for netuid in &netuid_is_member { - Uids::::insert(netuid, old_hotkey, uid); - } - - // Perform the swap - SubtensorModule::swap_uids(&old_hotkey, &new_hotkey, &netuid_is_member, &mut weight); - - // Verify the swap - for netuid in &netuid_is_member { - assert_eq!(Uids::::get(netuid, new_hotkey).unwrap(), uid); - assert!(!Uids::::contains_key(netuid, old_hotkey)); - } - }); -} - -#[test] -fn test_swap_uids_weight_update() { - new_test_ext(1).execute_with(|| { - let old_hotkey = U256::from(1); - let new_hotkey = U256::from(2); - let netuid_is_member = vec![1u16, 2u16]; - let uid = 42u16; - let mut weight = Weight::zero(); - - // Initialize Uids for old_hotkey - for netuid in &netuid_is_member { - Uids::::insert(netuid, old_hotkey, uid); - } - - // Perform the swap - SubtensorModule::swap_uids(&old_hotkey, &new_hotkey, &netuid_is_member, &mut weight); - - // Verify the weight update - let expected_weight = ::DbWeight::get().writes(4); - assert_eq!(weight, expected_weight); - }); -} - -#[test] -fn test_swap_prometheus_success() { - new_test_ext(1).execute_with(|| { - let old_hotkey = U256::from(1); - let new_hotkey = U256::from(2); - let netuid_is_member = vec![1u16, 2u16]; - let prometheus_info = PrometheusInfo { - block: 100, - version: 1, - ip: 0x1234567890abcdef, - port: 8080, - ip_type: 4, - }; - let mut weight = Weight::zero(); - - // Initialize Prometheus for old_hotkey - for netuid in &netuid_is_member { - Prometheus::::insert(netuid, old_hotkey, prometheus_info.clone()); - } - - // Perform the swap - SubtensorModule::swap_prometheus(&old_hotkey, &new_hotkey, &netuid_is_member, &mut weight); - - // Verify the swap - for netuid in &netuid_is_member { - assert_eq!( - Prometheus::::get(netuid, new_hotkey).unwrap(), - prometheus_info - ); - assert!(!Prometheus::::contains_key(netuid, old_hotkey)); - } - }); -} - -#[test] -fn test_swap_prometheus_weight_update() { - new_test_ext(1).execute_with(|| { - let old_hotkey = U256::from(1); - let new_hotkey = U256::from(2); - let netuid_is_member = vec![1u16, 2u16]; - let prometheus_info = PrometheusInfo { - block: 100, - version: 1, - ip: 0x1234567890abcdef, - port: 8080, - ip_type: 4, - }; - let mut weight = Weight::zero(); - - // Initialize Prometheus for old_hotkey - for netuid in &netuid_is_member { - Prometheus::::insert(netuid, old_hotkey, prometheus_info.clone()); - } - - // Perform the swap - SubtensorModule::swap_prometheus(&old_hotkey, &new_hotkey, &netuid_is_member, &mut weight); - - // Verify the weight update - let expected_weight = netuid_is_member.len() as u64 - * ::DbWeight::get().reads_writes(1, 2); - assert_eq!(weight, expected_weight); - }); -} - #[test] fn test_swap_total_hotkey_coldkey_stakes_this_interval_success() { new_test_ext(1).execute_with(|| { @@ -1030,9 +370,10 @@ fn test_swap_total_hotkey_coldkey_stakes_this_interval_success() { TotalHotkeyColdkeyStakesThisInterval::::insert(old_hotkey, coldkey, stake); // Perform the swap - SubtensorModule::swap_total_hotkey_coldkey_stakes_this_interval( + SubtensorModule::perform_hotkey_swap( &old_hotkey, &new_hotkey, + &coldkey, &mut weight, ); @@ -1047,32 +388,6 @@ fn test_swap_total_hotkey_coldkey_stakes_this_interval_success() { }); } -#[test] -fn test_swap_total_hotkey_coldkey_stakes_this_interval_weight_update() { - new_test_ext(1).execute_with(|| { - let old_hotkey = U256::from(1); - let new_hotkey = U256::from(2); - let coldkey = U256::from(3); - let stake = (1000u64, 42u64); - let mut weight = Weight::zero(); - - // Initialize TotalHotkeyColdkeyStakesThisInterval for old_hotkey - TotalHotkeyColdkeyStakesThisInterval::::insert(old_hotkey, coldkey, stake); - - // Perform the swap - - SubtensorModule::swap_total_hotkey_coldkey_stakes_this_interval( - &old_hotkey, - &new_hotkey, - &mut weight, - ); - - // Verify the weight update - let expected_weight = ::DbWeight::get().writes(2); - assert_eq!(weight, expected_weight); - }); -} - #[test] fn test_do_swap_coldkey_success() { new_test_ext(1).execute_with(|| { diff --git a/pallets/subtensor/tests/swap_hotkey.rs b/pallets/subtensor/tests/swap_hotkey.rs new file mode 100644 index 000000000..22e266efa --- /dev/null +++ b/pallets/subtensor/tests/swap_hotkey.rs @@ -0,0 +1,542 @@ +#![allow(unused, clippy::indexing_slicing, clippy::panic, clippy::unwrap_used)] + +use codec::Encode; +use frame_support::weights::Weight; +use frame_support::{assert_err, assert_noop, assert_ok}; +use frame_system::{Config, RawOrigin}; +mod mock; +use mock::*; +use pallet_subtensor::*; +use sp_core::U256; +use sp_core::H256; + + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_owner --exact --nocapture +#[test] +fn test_swap_owner() { + new_test_ext(1).execute_with(|| { + let old_hotkey = U256::from(1); + let new_hotkey = U256::from(2); + let coldkey = U256::from(3); + let mut weight = Weight::zero(); + + Owner::::insert(&old_hotkey, &coldkey); + assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight)); + + assert!(!Owner::::contains_key(&old_hotkey)); + assert_eq!(Owner::::get(&new_hotkey), coldkey); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_owned_hotkeys --exact --nocapture +#[test] +fn test_swap_owned_hotkeys() { + new_test_ext(1).execute_with(|| { + let old_hotkey = U256::from(1); + let new_hotkey = U256::from(2); + let coldkey = U256::from(3); + let mut weight = Weight::zero(); + + OwnedHotkeys::::insert(&coldkey, vec![old_hotkey]); + assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight)); + + let hotkeys = OwnedHotkeys::::get(&coldkey); + assert!(!hotkeys.contains(&old_hotkey)); + assert!(hotkeys.contains(&new_hotkey)); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_total_hotkey_stake --exact --nocapture +#[test] +fn test_swap_total_hotkey_stake() { + new_test_ext(1).execute_with(|| { + let old_hotkey = U256::from(1); + let new_hotkey = U256::from(2); + let coldkey = U256::from(3); + let mut weight = Weight::zero(); + + TotalHotkeyStake::::insert(&old_hotkey, 100); + TotalHotkeyStake::::insert(&new_hotkey, 50); + assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight)); + + assert!(!TotalHotkeyStake::::contains_key(&old_hotkey)); + assert_eq!(TotalHotkeyStake::::get(&new_hotkey), 150); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_total_hotkey_coldkey_stakes_this_interval --exact --nocapture +#[test] +fn test_swap_total_hotkey_coldkey_stakes_this_interval() { + new_test_ext(1).execute_with(|| { + let old_hotkey = U256::from(1); + let new_hotkey = U256::from(2); + let coldkey = U256::from(3); + let mut weight = Weight::zero(); + + TotalHotkeyColdkeyStakesThisInterval::::insert(&old_hotkey, &coldkey, (100, 1000)); + assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight)); + + assert!(!TotalHotkeyColdkeyStakesThisInterval::::contains_key(&old_hotkey, &coldkey)); + assert_eq!(TotalHotkeyColdkeyStakesThisInterval::::get(&new_hotkey, &coldkey), (100, 1000)); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_last_tx_block --exact --nocapture +#[test] +fn test_swap_last_tx_block() { + new_test_ext(1).execute_with(|| { + let old_hotkey = U256::from(1); + let new_hotkey = U256::from(2); + let coldkey = U256::from(3); + let mut weight = Weight::zero(); + + LastTxBlock::::insert(&old_hotkey, 1000); + assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight)); + + assert!(!LastTxBlock::::contains_key(&old_hotkey)); + assert_eq!(LastTxBlock::::get(&new_hotkey), SubtensorModule::get_current_block_as_u64()); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_last_tx_block_delegate_take --exact --nocapture +#[test] +fn test_swap_last_tx_block_delegate_take() { + new_test_ext(1).execute_with(|| { + let old_hotkey = U256::from(1); + let new_hotkey = U256::from(2); + let coldkey = U256::from(3); + let mut weight = Weight::zero(); + + pallet_subtensor::LastTxBlockDelegateTake::::insert(&old_hotkey, 1000); + assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight)); + + assert!(!LastTxBlockDelegateTake::::contains_key(&old_hotkey)); + assert_eq!(LastTxBlockDelegateTake::::get(&new_hotkey), SubtensorModule::get_current_block_as_u64()); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_senate_members --exact --nocapture +#[test] +fn test_swap_senate_members() { + new_test_ext(1).execute_with(|| { + let old_hotkey = U256::from(1); + let new_hotkey = U256::from(2); + let coldkey = U256::from(3); + let mut weight = Weight::zero(); + + // Assuming there's a way to add a member to the senate + // SenateMembers::add_member(&old_hotkey); + assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight)); + + // Assert that the old_hotkey is no longer a member and new_hotkey is now a member + // assert!(!SenateMembers::is_member(&old_hotkey)); + // assert!(SenateMembers::is_member(&new_hotkey)); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_delegates --exact --nocapture +#[test] +fn test_swap_delegates() { + new_test_ext(1).execute_with(|| { + let old_hotkey = U256::from(1); + let new_hotkey = U256::from(2); + let coldkey = U256::from(3); + let mut weight = Weight::zero(); + + Delegates::::insert(&old_hotkey, 100); + assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight)); + + assert!(!Delegates::::contains_key(&old_hotkey)); + assert_eq!(Delegates::::get(&new_hotkey), 100); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_subnet_membership --exact --nocapture +#[test] +fn test_swap_subnet_membership() { + 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 = 0u16; + let mut weight = Weight::zero(); + + add_network(netuid, 0, 1); + IsNetworkMember::::insert(&old_hotkey, netuid, true); + assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight)); + + assert!(!IsNetworkMember::::contains_key(&old_hotkey, netuid)); + assert!(IsNetworkMember::::get(&new_hotkey, netuid)); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_uids_and_keys --exact --nocapture +#[test] +fn test_swap_uids_and_keys() { + 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 = 0u16; + let uid = 5u16; + let mut weight = Weight::zero(); + + add_network(netuid, 0, 1); + IsNetworkMember::::insert(&old_hotkey, netuid, true); + Uids::::insert(netuid, &old_hotkey, uid); + Keys::::insert(netuid, uid, old_hotkey); + + assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight)); + + assert_eq!(Uids::::get(netuid, &old_hotkey), None); + assert_eq!(Uids::::get(netuid, &new_hotkey), Some(uid)); + assert_eq!(Keys::::get(netuid, uid), new_hotkey); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_prometheus --exact --nocapture +#[test] +fn test_swap_prometheus() { + 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 = 0u16; + let prometheus_info = PrometheusInfo::default(); + let mut weight = Weight::zero(); + + add_network(netuid, 0, 1); + IsNetworkMember::::insert(&old_hotkey, netuid, true); + Prometheus::::insert(netuid, &old_hotkey, prometheus_info.clone()); + + assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight)); + + assert!(!Prometheus::::contains_key(netuid, &old_hotkey)); + assert_eq!(Prometheus::::get(netuid, &new_hotkey), Some(prometheus_info)); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_axons --exact --nocapture +#[test] +fn test_swap_axons() { + 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 = 0u16; + let axon_info = AxonInfo::default(); + let mut weight = Weight::zero(); + + add_network(netuid, 0, 1); + IsNetworkMember::::insert(&old_hotkey, netuid, true); + Axons::::insert(netuid, &old_hotkey, axon_info.clone()); + + assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight)); + + assert!(!Axons::::contains_key(netuid, &old_hotkey)); + assert_eq!(Axons::::get(netuid, &new_hotkey), Some(axon_info)); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_weight_commits --exact --nocapture +#[test] +fn test_swap_weight_commits() { + 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 = 0u16; + let weight_commits = (H256::from_low_u64_be(100), 200); + let mut weight = Weight::zero(); + + add_network(netuid, 0, 1); + IsNetworkMember::::insert(&old_hotkey, netuid, true); + WeightCommits::::insert(netuid, &old_hotkey, weight_commits.clone()); + + assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight)); + + assert!(!WeightCommits::::contains_key(netuid, &old_hotkey)); + assert_eq!(WeightCommits::::get(netuid, &new_hotkey), Some(weight_commits)); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_loaded_emission --exact --nocapture +#[test] +fn test_swap_loaded_emission() { + 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 = 0u16; + let server_emission = 1000u64; + let validator_emission = 1000u64; + let mut weight = Weight::zero(); + + add_network(netuid, 0, 1); + IsNetworkMember::::insert(&old_hotkey, netuid, true); + LoadedEmission::::insert(netuid, vec![(old_hotkey, server_emission, validator_emission)]); + + assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight)); + + let new_loaded_emission = LoadedEmission::::get(netuid); + assert_eq!(new_loaded_emission, Some(vec![(new_hotkey, server_emission, validator_emission)])); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_stake --exact --nocapture +#[test] +fn test_swap_stake() { + new_test_ext(1).execute_with(|| { + let old_hotkey = U256::from(1); + let new_hotkey = U256::from(2); + let coldkey = U256::from(3); + let stake_amount = 100u64; + let mut weight = Weight::zero(); + + Stake::::insert(&old_hotkey, &coldkey, stake_amount); + + assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight)); + + assert!(!Stake::::contains_key(&old_hotkey, &coldkey)); + assert_eq!(Stake::::get(&new_hotkey, &coldkey), stake_amount); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_staking_hotkeys --exact --nocapture +#[test] +fn test_swap_staking_hotkeys() { + new_test_ext(1).execute_with(|| { + let old_hotkey = U256::from(1); + let new_hotkey = U256::from(2); + let coldkey = U256::from(3); + let mut weight = Weight::zero(); + + Stake::::insert(&old_hotkey, &coldkey, 100); + StakingHotkeys::::insert(&coldkey, vec![old_hotkey]); + + assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight)); + + let staking_hotkeys = StakingHotkeys::::get(&coldkey); + assert!(!staking_hotkeys.contains(&old_hotkey)); + assert!(staking_hotkeys.contains(&new_hotkey)); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_hotkey_with_multiple_coldkeys --exact --nocapture +#[test] +fn test_swap_hotkey_with_multiple_coldkeys() { + new_test_ext(1).execute_with(|| { + let old_hotkey = U256::from(1); + let new_hotkey = U256::from(2); + let coldkey1 = U256::from(3); + let coldkey2 = U256::from(4); + let mut weight = Weight::zero(); + + Stake::::insert(&old_hotkey, &coldkey1, 100); + Stake::::insert(&old_hotkey, &coldkey2, 200); + StakingHotkeys::::insert(&coldkey1, vec![old_hotkey]); + StakingHotkeys::::insert(&coldkey2, vec![old_hotkey]); + + assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey1, &mut weight)); + + assert_eq!(Stake::::get(&new_hotkey, &coldkey1), 100); + assert_eq!(Stake::::get(&new_hotkey, &coldkey2), 200); + assert!(StakingHotkeys::::get(&coldkey1).contains(&new_hotkey)); + assert!(StakingHotkeys::::get(&coldkey2).contains(&new_hotkey)); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_hotkey_with_existing_stake --exact --nocapture +#[test] +fn test_swap_hotkey_with_existing_stake() { + new_test_ext(1).execute_with(|| { + let old_hotkey = U256::from(1); + let new_hotkey = U256::from(2); + let coldkey = U256::from(3); + let mut weight = Weight::zero(); + + Stake::::insert(&old_hotkey, &coldkey, 100); + Stake::::insert(&new_hotkey, &coldkey, 50); + + assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight)); + + assert_eq!(Stake::::get(&new_hotkey, &coldkey), 150); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_hotkey_with_multiple_subnets --exact --nocapture +#[test] +fn test_swap_hotkey_with_multiple_subnets() { + new_test_ext(1).execute_with(|| { + let old_hotkey = U256::from(1); + let new_hotkey = U256::from(2); + let coldkey = U256::from(3); + let netuid1 = 0; + let netuid2 = 1; + let mut weight = Weight::zero(); + + add_network(netuid1, 0, 1); + add_network(netuid2, 0, 1); + IsNetworkMember::::insert(&old_hotkey, netuid1, true); + IsNetworkMember::::insert(&old_hotkey, netuid2, true); + + assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight)); + + assert!(IsNetworkMember::::get(&new_hotkey, netuid1)); + assert!(IsNetworkMember::::get(&new_hotkey, netuid2)); + assert!(!IsNetworkMember::::get(&old_hotkey, netuid1)); + assert!(!IsNetworkMember::::get(&old_hotkey, netuid2)); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_staking_hotkeys_multiple_coldkeys --exact --nocapture +#[test] +fn test_swap_staking_hotkeys_multiple_coldkeys() { + new_test_ext(1).execute_with(|| { + let old_hotkey = U256::from(1); + let new_hotkey = U256::from(2); + let coldkey1 = U256::from(3); + let coldkey2 = U256::from(4); + let mut weight = Weight::zero(); + + // Set up initial state + Stake::::insert(&old_hotkey, &coldkey1, 100); + Stake::::insert(&old_hotkey, &coldkey2, 200); + StakingHotkeys::::insert(&coldkey1, vec![old_hotkey]); + StakingHotkeys::::insert(&coldkey2, vec![old_hotkey, U256::from(5)]); + + assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey1, &mut weight)); + + // Check if new_hotkey replaced old_hotkey in StakingHotkeys + assert!(StakingHotkeys::::get(&coldkey1).contains(&new_hotkey)); + assert!(!StakingHotkeys::::get(&coldkey1).contains(&old_hotkey)); + + // Check if new_hotkey replaced old_hotkey for coldkey2 as well + assert!(StakingHotkeys::::get(&coldkey2).contains(&new_hotkey)); + assert!(!StakingHotkeys::::get(&coldkey2).contains(&old_hotkey)); + assert!(StakingHotkeys::::get(&coldkey2).contains(&U256::from(5))); // Other hotkeys should remain + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_hotkey_with_no_stake --exact --nocapture +#[test] +fn test_swap_hotkey_with_no_stake() { + new_test_ext(1).execute_with(|| { + let old_hotkey = U256::from(1); + let new_hotkey = U256::from(2); + let coldkey = U256::from(3); + let mut weight = Weight::zero(); + + // Set up initial state with no stake + Owner::::insert(&old_hotkey, &coldkey); + + assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight)); + + // Check if ownership transferred + assert!(!Owner::::contains_key(&old_hotkey)); + assert_eq!(Owner::::get(&new_hotkey), coldkey); + + // Ensure no unexpected changes in Stake + assert!(!Stake::::contains_key(&old_hotkey, &coldkey)); + assert!(!Stake::::contains_key(&new_hotkey, &coldkey)); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_hotkey_with_multiple_coldkeys_and_subnets --exact --nocapture +#[test] +fn test_swap_hotkey_with_multiple_coldkeys_and_subnets() { + new_test_ext(1).execute_with(|| { + let old_hotkey = U256::from(1); + let new_hotkey = U256::from(2); + let coldkey1 = U256::from(3); + let coldkey2 = U256::from(4); + let netuid1 = 0; + let netuid2 = 1; + let mut weight = Weight::zero(); + + // Set up initial state + add_network(netuid1, 0, 1); + add_network(netuid2, 0, 1); + Owner::::insert(&old_hotkey, &coldkey1); + Stake::::insert(&old_hotkey, &coldkey1, 100); + Stake::::insert(&old_hotkey, &coldkey2, 200); + IsNetworkMember::::insert(&old_hotkey, netuid1, true); + IsNetworkMember::::insert(&old_hotkey, netuid2, true); + TotalHotkeyStake::::insert(&old_hotkey, 300); + + assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey1, &mut weight)); + + // Check ownership transfer + assert!(!Owner::::contains_key(&old_hotkey)); + assert_eq!(Owner::::get(&new_hotkey), coldkey1); + + // Check stake transfer + assert_eq!(Stake::::get(&new_hotkey, &coldkey1), 100); + assert_eq!(Stake::::get(&new_hotkey, &coldkey2), 200); + assert!(!Stake::::contains_key(&old_hotkey, &coldkey1)); + assert!(!Stake::::contains_key(&old_hotkey, &coldkey2)); + + // Check subnet membership transfer + assert!(IsNetworkMember::::get(&new_hotkey, netuid1)); + assert!(IsNetworkMember::::get(&new_hotkey, netuid2)); + assert!(!IsNetworkMember::::get(&old_hotkey, netuid1)); + assert!(!IsNetworkMember::::get(&old_hotkey, netuid2)); + + // Check total stake transfer + assert_eq!(TotalHotkeyStake::::get(&new_hotkey), 300); + assert!(!TotalHotkeyStake::::contains_key(&old_hotkey)); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_hotkey_error_cases --exact --nocapture +#[test] +fn test_swap_hotkey_error_cases() { + new_test_ext(1).execute_with(|| { + let old_hotkey = U256::from(1); + let new_hotkey = U256::from(2); + let coldkey = U256::from(3); + let wrong_coldkey = U256::from(4); + + // Set up initial state + Owner::::insert(&old_hotkey, &coldkey); + TotalNetworks::::put(1); + LastTxBlock::::insert(&coldkey, 0); + + // Test not enough balance + let swap_cost = SubtensorModule::get_key_swap_cost(); + assert_noop!( + SubtensorModule::do_swap_hotkey(RuntimeOrigin::signed(coldkey), &old_hotkey, &new_hotkey), + Error::::NotEnoughBalanceToPaySwapHotKey + ); + + let initial_balance = SubtensorModule::get_key_swap_cost() + 1000; + SubtensorModule::add_balance_to_coldkey_account(&coldkey, initial_balance); + + // Test new hotkey same as old + assert_noop!( + SubtensorModule::do_swap_hotkey(RuntimeOrigin::signed(coldkey), &old_hotkey, &old_hotkey), + Error::::NewHotKeyIsSameWithOld + ); + + // Test new hotkey already registered + IsNetworkMember::::insert(&new_hotkey, 0, true); + assert_noop!( + SubtensorModule::do_swap_hotkey(RuntimeOrigin::signed(coldkey), &old_hotkey, &new_hotkey), + Error::::HotKeyAlreadyRegisteredInSubNet + ); + IsNetworkMember::::remove(&new_hotkey, 0); + + // Test non-associated coldkey + assert_noop!( + SubtensorModule::do_swap_hotkey(RuntimeOrigin::signed(wrong_coldkey), &old_hotkey, &new_hotkey), + Error::::NonAssociatedColdKey + ); + + + // Run the successful swap + assert_ok!(SubtensorModule::do_swap_hotkey(RuntimeOrigin::signed(coldkey), &old_hotkey, &new_hotkey)); + + // Check balance after swap + assert_eq!(Balances::free_balance(&coldkey), initial_balance - swap_cost); + }); +} From 7f938f7940810831203169062de60440a7caacc6 Mon Sep 17 00:00:00 2001 From: const Date: Mon, 22 Jul 2024 13:34:03 -0500 Subject: [PATCH 25/58] tests pass --- pallets/subtensor/src/swap_hotkey.rs | 12 +- pallets/subtensor/tests/swap.rs | 378 ------------------------- pallets/subtensor/tests/swap_hotkey.rs | 275 ++++++++++++++++++ 3 files changed, 279 insertions(+), 386 deletions(-) diff --git a/pallets/subtensor/src/swap_hotkey.rs b/pallets/subtensor/src/swap_hotkey.rs index 222a4ff37..a99e4b3dc 100644 --- a/pallets/subtensor/src/swap_hotkey.rs +++ b/pallets/subtensor/src/swap_hotkey.rs @@ -1,9 +1,6 @@ use super::*; -use crate::MIN_BALANCE_TO_PERFORM_COLDKEY_SWAP; -use frame_support::traits::fungible::Mutate; -use frame_support::traits::tokens::Preservation; -use frame_support::{storage::IterableStorageDoubleMap, weights::Weight}; -use sp_core::{Get, U256}; +use frame_support::weights::Weight; +use sp_core::Get; impl Pallet { /// Swaps the hotkey of a coldkey account. @@ -86,7 +83,7 @@ impl Pallet { Self::burn_tokens(actual_burn_amount); // Perform the hotkey swap - Self::perform_hotkey_swap(old_hotkey, new_hotkey, &coldkey, &mut weight); + let _ = Self::perform_hotkey_swap(old_hotkey, new_hotkey, &coldkey, &mut weight); // Update the last transaction block for the coldkey Self::set_last_tx_block(&coldkey, block); @@ -143,10 +140,9 @@ impl Pallet { // Swap LastTxBlock // LastTxBlock( hotkey ) --> u64 -- the last transaction block for the hotkey. - let old_last_tx_block: u64 = LastTxBlock::::get( old_hotkey ); LastTxBlock::::remove( old_hotkey ); LastTxBlock::::insert( new_hotkey, Self::get_current_block_as_u64() ); - weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); + weight.saturating_accrue(T::DbWeight::get().reads_writes(0, 2)); // Swap LastTxBlockDelegateTake // LastTxBlockDelegateTake( hotkey ) --> u64 -- the last transaction block for the hotkey delegate take. diff --git a/pallets/subtensor/tests/swap.rs b/pallets/subtensor/tests/swap.rs index 86fe109be..f7f288cc2 100644 --- a/pallets/subtensor/tests/swap.rs +++ b/pallets/subtensor/tests/swap.rs @@ -9,384 +9,6 @@ use mock::*; use pallet_subtensor::*; use sp_core::U256; -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap -- test_do_swap_hotkey_ok --exact --nocapture -#[test] -fn test_do_swap_hotkey_ok() { - new_test_ext(1).execute_with(|| { - let netuid: u16 = 1; - 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; - - // Setup initial state - add_network(netuid, tempo, 0); - register_ok_neuron(netuid, old_hotkey, coldkey, 0); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, swap_cost); - - // Perform the swap - assert_ok!(SubtensorModule::do_swap_hotkey( - <::RuntimeOrigin>::signed(coldkey), - &old_hotkey, - &new_hotkey - )); - - // Verify the swap - assert_eq!( - SubtensorModule::get_owning_coldkey_for_hotkey(&new_hotkey), - coldkey - ); - assert_ne!( - SubtensorModule::get_owning_coldkey_for_hotkey(&old_hotkey), - coldkey - ); - - // Verify other storage changes - assert_ne!( - SubtensorModule::get_delegate(new_hotkey.encode()), - SubtensorModule::get_delegate(old_hotkey.encode()) - ); - assert_ne!( - SubtensorModule::get_last_tx_block(&new_hotkey), - SubtensorModule::get_last_tx_block(&old_hotkey) - ); - - // Verify raw storage maps - // Stake - for (coldkey, stake_amount) in Stake::::iter_prefix(old_hotkey) { - assert_eq!(Stake::::get(new_hotkey, coldkey), stake_amount); - } - - let mut weight = Weight::zero(); - - // IsNetworkMember - for netuid in SubtensorModule::get_netuid_is_member(&old_hotkey, &mut weight) { - assert!(IsNetworkMember::::contains_key(new_hotkey, netuid)); - assert!(!IsNetworkMember::::contains_key(old_hotkey, netuid)); - } - - // Owner - assert_eq!(Owner::::get(new_hotkey), coldkey); - - // TotalHotkeyStake - assert_ne!( - TotalHotkeyStake::::get(new_hotkey), - TotalHotkeyStake::::get(old_hotkey) - ); - - // Delegates - assert_eq!( - Delegates::::get(new_hotkey), - Delegates::::get(old_hotkey) - ); - - // LastTxBlock - assert_eq!( - LastTxBlock::::get(new_hotkey), - LastTxBlock::::get(old_hotkey) - ); - - // Axons - for netuid in SubtensorModule::get_netuid_is_member(&old_hotkey, &mut weight) { - assert_eq!( - Axons::::get(netuid, new_hotkey), - Axons::::get(netuid, old_hotkey) - ); - } - - // TotalHotkeyColdkeyStakesThisInterval - assert_eq!( - TotalHotkeyColdkeyStakesThisInterval::::get(new_hotkey, coldkey), - TotalHotkeyColdkeyStakesThisInterval::::get(old_hotkey, coldkey) - ); - }); -} - -#[test] -fn test_swap_hotkey_tx_rate_limit_exceeded() { - new_test_ext(1).execute_with(|| { - let netuid: u16 = 1; - let tempo: u16 = 13; - let old_hotkey = U256::from(1); - 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 tx_rate_limit = 1; - - // Get the current transaction rate limit - let current_tx_rate_limit = SubtensorModule::get_tx_rate_limit(); - log::info!("current_tx_rate_limit: {:?}", current_tx_rate_limit); - - // Set the transaction rate limit - SubtensorModule::set_tx_rate_limit(tx_rate_limit); - // assert the rate limit is set to 1000 blocks - assert_eq!(SubtensorModule::get_tx_rate_limit(), tx_rate_limit); - - // Setup initial state - add_network(netuid, tempo, 0); - register_ok_neuron(netuid, old_hotkey, coldkey, 0); - SubtensorModule::add_balance_to_coldkey_account(&coldkey, swap_cost); - - // Perform the first swap - assert_ok!(SubtensorModule::do_swap_hotkey( - <::RuntimeOrigin>::signed(coldkey), - &old_hotkey, - &new_hotkey_1 - )); - - // Attempt to perform another swap immediately, which should fail due to rate limit - assert_err!( - SubtensorModule::do_swap_hotkey( - <::RuntimeOrigin>::signed(coldkey), - &new_hotkey_1, - &new_hotkey_2 - ), - Error::::HotKeySetTxRateLimitExceeded - ); - - // move in time past the rate limit - step_block(1001); - assert_ok!(SubtensorModule::do_swap_hotkey( - <::RuntimeOrigin>::signed(coldkey), - &new_hotkey_1, - &new_hotkey_2 - )); - }); -} - -#[test] -fn test_do_swap_hotkey_err_not_owner() { - new_test_ext(1).execute_with(|| { - let netuid: u16 = 1; - let tempo: u16 = 13; - let old_hotkey = U256::from(1); - 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; - - // Setup initial state - add_network(netuid, tempo, 0); - register_ok_neuron(netuid, old_hotkey, coldkey, 0); - SubtensorModule::add_balance_to_coldkey_account(¬_owner_coldkey, swap_cost); - - // Attempt the swap with a non-owner coldkey - assert_err!( - SubtensorModule::do_swap_hotkey( - <::RuntimeOrigin>::signed(not_owner_coldkey), - &old_hotkey, - &new_hotkey - ), - Error::::NonAssociatedColdKey - ); - }); -} - -#[test] -fn test_swap_owner_success() { - new_test_ext(1).execute_with(|| { - let old_hotkey = U256::from(1); - let new_hotkey = U256::from(2); - let coldkey = U256::from(3); - let mut weight = Weight::zero(); - - // Initialize Owner for old_hotkey - Owner::::insert(old_hotkey, coldkey); - - // Perform the swap - SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight); - - // Verify the swap - assert_eq!(Owner::::get(new_hotkey), coldkey); - assert!(!Owner::::contains_key(old_hotkey)); - }); -} - -#[test] -fn test_swap_owner_old_hotkey_not_exist() { - new_test_ext(1).execute_with(|| { - let old_hotkey = U256::from(1); - let new_hotkey = U256::from(2); - let coldkey = U256::from(3); - let mut weight = Weight::zero(); - - // Ensure old_hotkey does not exist - assert!(!Owner::::contains_key(old_hotkey)); - - // Perform the swap - SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight); - - // Verify the swap - assert_eq!(Owner::::get(new_hotkey), coldkey); - assert!(!Owner::::contains_key(old_hotkey)); - }); -} - -#[test] -fn test_swap_owner_new_hotkey_already_exists() { - new_test_ext(1).execute_with(|| { - let old_hotkey = U256::from(1); - let new_hotkey = U256::from(2); - let coldkey = U256::from(3); - let another_coldkey = U256::from(4); - let mut weight = Weight::zero(); - - // Initialize Owner for old_hotkey and new_hotkey - Owner::::insert(old_hotkey, coldkey); - Owner::::insert(new_hotkey, another_coldkey); - - // Perform the swap - SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight); - - // Verify the swap - assert_eq!(Owner::::get(new_hotkey), coldkey); - assert!(!Owner::::contains_key(old_hotkey)); - }); -} - -#[test] -fn test_swap_total_hotkey_stake_success() { - new_test_ext(1).execute_with(|| { - let old_hotkey = U256::from(1); - let new_hotkey = U256::from(2); - let coldkey = U256::from(3); - let total_stake = 1000u64; - let mut weight = Weight::zero(); - - // Initialize TotalHotkeyStake for old_hotkey - TotalHotkeyStake::::insert(old_hotkey, total_stake); - - // Perform the swap - SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight); - - // Verify the swap - assert_eq!(TotalHotkeyStake::::get(new_hotkey), total_stake); - assert!(!TotalHotkeyStake::::contains_key(old_hotkey)); - }); -} - - - -#[test] -fn test_swap_delegates_success() { - new_test_ext(1).execute_with(|| { - let old_hotkey = U256::from(1); - let new_hotkey = U256::from(2); - let coldkey = U256::from(3); - let delegate_take = 10u16; - let mut weight = Weight::zero(); - - // Initialize Delegates for old_hotkey - Delegates::::insert(old_hotkey, delegate_take); - - // Perform the swap - SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight); - - // Verify the swap - assert_eq!(Delegates::::get(new_hotkey), delegate_take); - assert!(!Delegates::::contains_key(old_hotkey)); - }); -} - -#[test] -fn test_swap_delegates_weight_update() { - new_test_ext(1).execute_with(|| { - let old_hotkey = U256::from(1); - let new_hotkey = U256::from(2); - let coldkey = U256::from(3); - let delegate_take = 10u16; - let mut weight = Weight::zero(); - - // Initialize Delegates for old_hotkey - Delegates::::insert(old_hotkey, delegate_take); - - // Perform the swap - SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight); - - // Verify the weight update - let expected_weight = ::DbWeight::get().reads_writes(1, 2); - assert_eq!(weight, expected_weight); - }); -} - -#[test] -fn test_swap_stake_success() { - new_test_ext(1).execute_with(|| { - let old_hotkey = U256::from(1); - let new_hotkey = U256::from(2); - let coldkey = U256::from(3); - let stake_amount = 1000u64; - let mut weight = Weight::zero(); - - // Initialize Stake for old_hotkey - Stake::::insert(old_hotkey, coldkey, stake_amount); - - // Perform the swap - SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight); - - // Verify the swap - assert_eq!(Stake::::get(new_hotkey, coldkey), stake_amount); - assert!(!Stake::::contains_key(old_hotkey, coldkey)); - }); -} - -#[test] -fn test_swap_stake_old_hotkey_not_exist() { - new_test_ext(1).execute_with(|| { - let old_hotkey = U256::from(1); - let new_hotkey = U256::from(2); - let coldkey = U256::from(3); - let stake_amount = 1000u64; - let mut weight = Weight::zero(); - - // Initialize Stake for old_hotkey - Stake::::insert(old_hotkey, coldkey, stake_amount); - - // Ensure old_hotkey has a stake - assert!(Stake::::contains_key(old_hotkey, coldkey)); - - // Perform the swap - SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight); - - // Verify that new_hotkey has the stake and old_hotkey does not - assert!(Stake::::contains_key(new_hotkey, coldkey)); - assert!(!Stake::::contains_key(old_hotkey, coldkey)); - }); -} - -#[test] -fn test_swap_total_hotkey_coldkey_stakes_this_interval_success() { - new_test_ext(1).execute_with(|| { - let old_hotkey = U256::from(1); - let new_hotkey = U256::from(2); - let coldkey = U256::from(3); - let stake = (1000u64, 42u64); // Example tuple value - let mut weight = Weight::zero(); - - // Initialize TotalHotkeyColdkeyStakesThisInterval for old_hotkey - TotalHotkeyColdkeyStakesThisInterval::::insert(old_hotkey, coldkey, stake); - - // Perform the swap - SubtensorModule::perform_hotkey_swap( - &old_hotkey, - &new_hotkey, - &coldkey, - &mut weight, - ); - - // Verify the swap - assert_eq!( - TotalHotkeyColdkeyStakesThisInterval::::get(new_hotkey, coldkey), - stake - ); - assert!(!TotalHotkeyColdkeyStakesThisInterval::::contains_key( - old_hotkey, coldkey - )); - }); -} #[test] fn test_do_swap_coldkey_success() { diff --git a/pallets/subtensor/tests/swap_hotkey.rs b/pallets/subtensor/tests/swap_hotkey.rs index 22e266efa..35227d3b1 100644 --- a/pallets/subtensor/tests/swap_hotkey.rs +++ b/pallets/subtensor/tests/swap_hotkey.rs @@ -488,6 +488,281 @@ fn test_swap_hotkey_with_multiple_coldkeys_and_subnets() { }); } +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_hotkey_tx_rate_limit_exceeded --exact --nocapture +#[test] +fn test_swap_hotkey_tx_rate_limit_exceeded() { + new_test_ext(1).execute_with(|| { + let netuid: u16 = 1; + let tempo: u16 = 13; + let old_hotkey = U256::from(1); + 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 tx_rate_limit = 1; + + // Get the current transaction rate limit + let current_tx_rate_limit = SubtensorModule::get_tx_rate_limit(); + log::info!("current_tx_rate_limit: {:?}", current_tx_rate_limit); + + // Set the transaction rate limit + SubtensorModule::set_tx_rate_limit(tx_rate_limit); + // assert the rate limit is set to 1000 blocks + assert_eq!(SubtensorModule::get_tx_rate_limit(), tx_rate_limit); + + // Setup initial state + add_network(netuid, tempo, 0); + register_ok_neuron(netuid, old_hotkey, coldkey, 0); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, swap_cost); + + // Perform the first swap + assert_ok!(SubtensorModule::do_swap_hotkey( + <::RuntimeOrigin>::signed(coldkey), + &old_hotkey, + &new_hotkey_1 + )); + + // Attempt to perform another swap immediately, which should fail due to rate limit + assert_err!( + SubtensorModule::do_swap_hotkey( + <::RuntimeOrigin>::signed(coldkey), + &new_hotkey_1, + &new_hotkey_2 + ), + Error::::HotKeySetTxRateLimitExceeded + ); + + // move in time past the rate limit + step_block(1001); + assert_ok!(SubtensorModule::do_swap_hotkey( + <::RuntimeOrigin>::signed(coldkey), + &new_hotkey_1, + &new_hotkey_2 + )); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_do_swap_hotkey_err_not_owner --exact --nocapture +#[test] +fn test_do_swap_hotkey_err_not_owner() { + new_test_ext(1).execute_with(|| { + let netuid: u16 = 1; + let tempo: u16 = 13; + let old_hotkey = U256::from(1); + 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; + + // Setup initial state + add_network(netuid, tempo, 0); + register_ok_neuron(netuid, old_hotkey, coldkey, 0); + SubtensorModule::add_balance_to_coldkey_account(¬_owner_coldkey, swap_cost); + + // Attempt the swap with a non-owner coldkey + assert_err!( + SubtensorModule::do_swap_hotkey( + <::RuntimeOrigin>::signed(not_owner_coldkey), + &old_hotkey, + &new_hotkey + ), + Error::::NonAssociatedColdKey + ); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_owner_success --exact --nocapture +#[test] +fn test_swap_owner_success() { + new_test_ext(1).execute_with(|| { + let old_hotkey = U256::from(1); + let new_hotkey = U256::from(2); + let coldkey = U256::from(3); + let mut weight = Weight::zero(); + + // Initialize Owner for old_hotkey + Owner::::insert(old_hotkey, coldkey); + + // Perform the swap + SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight); + + // Verify the swap + assert_eq!(Owner::::get(new_hotkey), coldkey); + assert!(!Owner::::contains_key(old_hotkey)); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_owner_old_hotkey_not_exist --exact --nocapture +#[test] +fn test_swap_owner_old_hotkey_not_exist() { + new_test_ext(1).execute_with(|| { + let old_hotkey = U256::from(1); + let new_hotkey = U256::from(2); + let coldkey = U256::from(3); + let mut weight = Weight::zero(); + + // Ensure old_hotkey does not exist + assert!(!Owner::::contains_key(old_hotkey)); + + // Perform the swap + SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight); + + // Verify the swap + assert_eq!(Owner::::get(new_hotkey), coldkey); + assert!(!Owner::::contains_key(old_hotkey)); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_owner_new_hotkey_already_exists --exact --nocapture +#[test] +fn test_swap_owner_new_hotkey_already_exists() { + new_test_ext(1).execute_with(|| { + let old_hotkey = U256::from(1); + let new_hotkey = U256::from(2); + let coldkey = U256::from(3); + let another_coldkey = U256::from(4); + let mut weight = Weight::zero(); + + // Initialize Owner for old_hotkey and new_hotkey + Owner::::insert(old_hotkey, coldkey); + Owner::::insert(new_hotkey, another_coldkey); + + // Perform the swap + SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight); + + // Verify the swap + assert_eq!(Owner::::get(new_hotkey), coldkey); + assert!(!Owner::::contains_key(old_hotkey)); + }); +} + + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_total_hotkey_stake_success --exact --nocapture +#[test] +fn test_swap_total_hotkey_stake_success() { + new_test_ext(1).execute_with(|| { + let old_hotkey = U256::from(1); + let new_hotkey = U256::from(2); + let coldkey = U256::from(3); + let total_stake = 1000u64; + let mut weight = Weight::zero(); + + // Initialize TotalHotkeyStake for old_hotkey + TotalHotkeyStake::::insert(old_hotkey, total_stake); + + // Perform the swap + SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight); + + // Verify the swap + assert_eq!(TotalHotkeyStake::::get(new_hotkey), total_stake); + assert!(!TotalHotkeyStake::::contains_key(old_hotkey)); + }); +} + + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_delegates_success --exact --nocapture +#[test] +fn test_swap_delegates_success() { + new_test_ext(1).execute_with(|| { + let old_hotkey = U256::from(1); + let new_hotkey = U256::from(2); + let coldkey = U256::from(3); + let delegate_take = 10u16; + let mut weight = Weight::zero(); + + // Initialize Delegates for old_hotkey + Delegates::::insert(old_hotkey, delegate_take); + + // Perform the swap + SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight); + + // Verify the swap + assert_eq!(Delegates::::get(new_hotkey), delegate_take); + assert!(!Delegates::::contains_key(old_hotkey)); + }); +} + + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_stake_success --exact --nocapture +#[test] +fn test_swap_stake_success() { + new_test_ext(1).execute_with(|| { + let old_hotkey = U256::from(1); + let new_hotkey = U256::from(2); + let coldkey = U256::from(3); + let stake_amount = 1000u64; + let mut weight = Weight::zero(); + + // Initialize Stake for old_hotkey + Stake::::insert(old_hotkey, coldkey, stake_amount); + + // Perform the swap + SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight); + + // Verify the swap + assert_eq!(Stake::::get(new_hotkey, coldkey), stake_amount); + assert!(!Stake::::contains_key(old_hotkey, coldkey)); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_stake_old_hotkey_not_exist --exact --nocapture +#[test] +fn test_swap_stake_old_hotkey_not_exist() { + new_test_ext(1).execute_with(|| { + let old_hotkey = U256::from(1); + let new_hotkey = U256::from(2); + let coldkey = U256::from(3); + let stake_amount = 1000u64; + let mut weight = Weight::zero(); + + // Initialize Stake for old_hotkey + Stake::::insert(old_hotkey, coldkey, stake_amount); + + // Ensure old_hotkey has a stake + assert!(Stake::::contains_key(old_hotkey, coldkey)); + + // Perform the swap + SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight); + + // Verify that new_hotkey has the stake and old_hotkey does not + assert!(Stake::::contains_key(new_hotkey, coldkey)); + assert!(!Stake::::contains_key(old_hotkey, coldkey)); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_total_hotkey_coldkey_stakes_this_interval_success --exact --nocapture +#[test] +fn test_swap_total_hotkey_coldkey_stakes_this_interval_success() { + new_test_ext(1).execute_with(|| { + let old_hotkey = U256::from(1); + let new_hotkey = U256::from(2); + let coldkey = U256::from(3); + let stake = (1000u64, 42u64); // Example tuple value + let mut weight = Weight::zero(); + + // Initialize TotalHotkeyColdkeyStakesThisInterval for old_hotkey + TotalHotkeyColdkeyStakesThisInterval::::insert(old_hotkey, coldkey, stake); + + // Perform the swap + SubtensorModule::perform_hotkey_swap( + &old_hotkey, + &new_hotkey, + &coldkey, + &mut weight, + ); + + // Verify the swap + assert_eq!( + TotalHotkeyColdkeyStakesThisInterval::::get(new_hotkey, coldkey), + stake + ); + assert!(!TotalHotkeyColdkeyStakesThisInterval::::contains_key( + old_hotkey, coldkey + )); + }); +} + // SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_hotkey_error_cases --exact --nocapture #[test] fn test_swap_hotkey_error_cases() { From 659b53c5319c53ae31d5a05aca37d72e67eadd32 Mon Sep 17 00:00:00 2001 From: const Date: Mon, 22 Jul 2024 13:42:23 -0500 Subject: [PATCH 26/58] clean the code --- pallets/commitments/src/lib.rs | 9 +++ pallets/subtensor/src/swap_hotkey.rs | 106 ++++++++++++++++++--------- 2 files changed, 82 insertions(+), 33 deletions(-) diff --git a/pallets/commitments/src/lib.rs b/pallets/commitments/src/lib.rs index d5d132034..4663b2647 100644 --- a/pallets/commitments/src/lib.rs +++ b/pallets/commitments/src/lib.rs @@ -173,6 +173,15 @@ pub mod pallet { Ok(()) } + + pub fn swap_commitment( netuid: u16, new_hotkey: T::AccountId, old_hotkey: T::AccountId ) { + if let Some(commitment) = >::take(netuid, &old_hotkey) { + >::insert(netuid, &new_hotkey, commitment); + } + if let Some(last_commit) = >::take(netuid, &old_hotkey) { + >::insert(netuid, &new_hotkey, last_commit); + } + } } } diff --git a/pallets/subtensor/src/swap_hotkey.rs b/pallets/subtensor/src/swap_hotkey.rs index a99e4b3dc..02052e4dd 100644 --- a/pallets/subtensor/src/swap_hotkey.rs +++ b/pallets/subtensor/src/swap_hotkey.rs @@ -27,79 +27,118 @@ impl Pallet { old_hotkey: &T::AccountId, new_hotkey: &T::AccountId, ) -> DispatchResultWithPostInfo { - // Ensure the origin is signed and get the coldkey + // 1. Ensure the origin is signed and get the coldkey let coldkey = ensure_signed(origin)?; - // Check if the coldkey is in arbitration + // 2. Check if the coldkey is in arbitration ensure!( !Self::coldkey_in_arbitration(&coldkey), Error::::ColdkeyIsInArbitration ); - // Initialize the weight for this operation + // 3. Initialize the weight for this operation let mut weight = T::DbWeight::get().reads(2); - // Ensure the new hotkey is different from the old one + // 4. Ensure the new hotkey is different from the old one ensure!(old_hotkey != new_hotkey, Error::::NewHotKeyIsSameWithOld); - // Ensure the new hotkey is not already registered on any network + + // 5. Ensure the new hotkey is not already registered on any network ensure!( !Self::is_hotkey_registered_on_any_network(new_hotkey), Error::::HotKeyAlreadyRegisteredInSubNet ); - // Update the weight for the checks above + // 6. Update the weight for the checks above weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 0)); - // Ensure the coldkey owns the old hotkey + + // 7. Ensure the coldkey owns the old hotkey ensure!( Self::coldkey_owns_hotkey(&coldkey, old_hotkey), Error::::NonAssociatedColdKey ); - // Get the current block number + // 8. Get the current block number let block: u64 = Self::get_current_block_as_u64(); - // Ensure the transaction rate limit is not exceeded + + // 9. Ensure the transaction rate limit is not exceeded ensure!( !Self::exceeds_tx_rate_limit(Self::get_last_tx_block(&coldkey), block), Error::::HotKeySetTxRateLimitExceeded ); - // Update the weight for reading the total networks + // 10. Update the weight for reading the total networks weight.saturating_accrue( T::DbWeight::get().reads((TotalNetworks::::get().saturating_add(1u16)) as u64), ); - // Get the cost for swapping the key + // 11. Get the cost for swapping the key let swap_cost = Self::get_key_swap_cost(); log::debug!("Swap cost: {:?}", swap_cost); - // Ensure the coldkey has enough balance to pay for the swap + // 12. Ensure the coldkey has enough balance to pay for the swap ensure!( Self::can_remove_balance_from_coldkey_account(&coldkey, swap_cost), Error::::NotEnoughBalanceToPaySwapHotKey ); - // Remove the swap cost from the coldkey's account + + // 13. Remove the swap cost from the coldkey's account let actual_burn_amount = Self::remove_balance_from_coldkey_account(&coldkey, swap_cost)?; - // Burn the tokens + + // 14. Burn the tokens Self::burn_tokens(actual_burn_amount); - // Perform the hotkey swap + // 15. Perform the hotkey swap let _ = Self::perform_hotkey_swap(old_hotkey, new_hotkey, &coldkey, &mut weight); - // Update the last transaction block for the coldkey + // 16. Update the last transaction block for the coldkey Self::set_last_tx_block(&coldkey, block); weight.saturating_accrue(T::DbWeight::get().writes(1)); - // Emit an event for the hotkey swap + // 17. Emit an event for the hotkey swap Self::deposit_event(Event::HotkeySwapped { coldkey, old_hotkey: old_hotkey.clone(), new_hotkey: new_hotkey.clone(), }); - // Return the weight of the operation + // 18. Return the weight of the operation Ok(Some(weight).into()) } + /// Performs the hotkey swap operation, transferring all associated data and state from the old hotkey to the new hotkey. + /// + /// This function executes a series of steps to ensure a complete transfer of all relevant information: + /// 1. Swaps the owner of the hotkey. + /// 2. Updates the list of owned hotkeys for the coldkey. + /// 3. Transfers the total hotkey stake. + /// 4. Moves all stake-related data for the interval. + /// 5. Updates the last transaction block for the new hotkey. + /// 6. Transfers the delegate take information. + /// 7. Swaps Senate membership if applicable. + /// 8. Updates delegate information. + /// 9. For each subnet: + /// - Updates network membership status. + /// - Transfers UID and key information. + /// - Moves Prometheus data. + /// - Updates axon information. + /// - Transfers weight commits. + /// - Updates loaded emission data. + /// 10. Transfers all stake information, including updating staking hotkeys for each coldkey. + /// + /// Throughout the process, the function accumulates the computational weight of operations performed. + /// + /// # Arguments + /// * `old_hotkey` - The AccountId of the current hotkey to be replaced. + /// * `new_hotkey` - The AccountId of the new hotkey to replace the old one. + /// * `coldkey` - The AccountId of the coldkey that owns both hotkeys. + /// * `weight` - A mutable reference to the Weight, updated as operations are performed. + /// + /// # Returns + /// * `DispatchResult` - Ok(()) if the swap was successful, or an error if any operation failed. + /// + /// # Note + /// This function performs extensive storage reads and writes, which can be computationally expensive. + /// The accumulated weight should be carefully considered in the context of block limits. pub fn perform_hotkey_swap( old_hotkey: &T::AccountId, new_hotkey: &T::AccountId, coldkey: &T::AccountId, weight: &mut Weight ) -> DispatchResult { // 1. Swap owner. @@ -128,7 +167,7 @@ impl Pallet { TotalHotkeyStake::::insert( new_hotkey, old_total_hotkey_stake.saturating_add( new_total_hotkey_stake ) ); // Insert the new total hotkey stake via the addition. weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2)); - // Swap total hotkey stakes. + // 4. Swap total hotkey stakes. // TotalHotkeyColdkeyStakesThisInterval( hotkey ) --> (u64: stakes, u64: block_number) let stake_tuples: Vec<(T::AccountId, (u64, u64))> = TotalHotkeyColdkeyStakesThisInterval::::iter_prefix(old_hotkey).collect(); for (coldkey, stake_tup) in stake_tuples { @@ -138,59 +177,59 @@ impl Pallet { weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); } - // Swap LastTxBlock + // 5. Swap LastTxBlock // LastTxBlock( hotkey ) --> u64 -- the last transaction block for the hotkey. LastTxBlock::::remove( old_hotkey ); LastTxBlock::::insert( new_hotkey, Self::get_current_block_as_u64() ); weight.saturating_accrue(T::DbWeight::get().reads_writes(0, 2)); - // Swap LastTxBlockDelegateTake + // 6. Swap LastTxBlockDelegateTake // LastTxBlockDelegateTake( hotkey ) --> u64 -- the last transaction block for the hotkey delegate take. LastTxBlockDelegateTake::::remove( old_hotkey ); LastTxBlockDelegateTake::::insert( new_hotkey, Self::get_current_block_as_u64() ); weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); - // Swap Senate members. + // 7. Swap Senate members. // Senate( hotkey ) --> ? if T::SenateMembers::is_member(old_hotkey) { T::SenateMembers::swap_member(old_hotkey, new_hotkey).map_err(|e| e.error)?; weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); } - // 4. Swap delegates. + // 8. Swap delegates. // Delegates( hotkey ) -> take value -- the hotkey delegate take value. let old_delegate_take = Delegates::::get( old_hotkey ); Delegates::::remove( old_hotkey ); // Remove the old delegate take. Delegates::::insert( new_hotkey, old_delegate_take ); // Insert the new delegate take. weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); - // Swap all subnet specific info. + // 9. Swap all subnet specific info. let all_netuids: Vec = Self::get_all_subnet_netuids(); for netuid in all_netuids { - // 7.1 Remove the previous hotkey and insert the new hotkey from membership. + // 9.1 Remove the previous hotkey and insert the new hotkey from membership. // IsNetworkMember( hotkey, netuid ) -> bool -- is the hotkey a subnet member. let is_network_member: bool = IsNetworkMember::::get( old_hotkey, netuid ); IsNetworkMember::::remove( old_hotkey, netuid ); IsNetworkMember::::insert( new_hotkey, netuid, is_network_member ); weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); - // 7.2 Swap Uids + Keys. + // 9.2 Swap Uids + Keys. // Keys( netuid, hotkey ) -> uid -- the uid the hotkey has in the network if it is a member. // Uids( netuid, hotkey ) -> uid -- the uids that the hotkey has. if is_network_member { - // 7.2.1 Swap the UIDS + // 9.2.1 Swap the UIDS if let Ok(old_uid) = Uids::::try_get(netuid, old_hotkey) { Uids::::remove(netuid, old_hotkey); Uids::::insert(netuid, new_hotkey, old_uid); weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); - // 7.2.2 Swap the keys. + // 9.2.2 Swap the keys. Keys::::insert(netuid, old_uid, new_hotkey.clone()); weight.saturating_accrue(T::DbWeight::get().reads_writes(0, 1)); } } - // 7.3 Swap Prometheus. + // 9.3 Swap Prometheus. // Prometheus( netuid, hotkey ) -> prometheus -- the prometheus data that a hotkey has in the network. if is_network_member { if let Ok(old_prometheus_info) = Prometheus::::try_get(netuid, old_hotkey) { @@ -200,7 +239,7 @@ impl Pallet { } } - // 7.4. Swap axons. + // 9.4. Swap axons. // Axons( netuid, hotkey ) -> axon -- the axon that the hotkey has. if is_network_member { if let Ok(old_axon_info) = Axons::::try_get(netuid, old_hotkey) { @@ -210,7 +249,7 @@ impl Pallet { } } - // 7.5 Swap WeightCommits + // 9.5 Swap WeightCommits // WeightCommits( hotkey ) --> Vec -- the weight commits for the hotkey. if is_network_member { if let Ok(old_weight_commits) = WeightCommits::::try_get(netuid, old_hotkey) { @@ -220,7 +259,7 @@ impl Pallet { } } - // 7.5. Swap the subnet loaded emission. + // 9.6. Swap the subnet loaded emission. // LoadedEmission( netuid ) --> Vec<(hotkey, u64)> -- the loaded emission for the subnet. if is_network_member { if let Some(mut old_loaded_emission) = LoadedEmission::::get(netuid) { @@ -237,7 +276,7 @@ impl Pallet { } - // Swap Stake. + // 10. Swap Stake. // Stake( hotkey, coldkey ) -> stake -- the stake that the hotkey controls on behalf of the coldkey. let stakes: Vec<(T::AccountId, u64)> = Stake::::iter_prefix(old_hotkey).collect(); // Clear the entire old prefix here. @@ -263,6 +302,7 @@ impl Pallet { weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); } + // Return successful after swapping all the relevant terms. Ok(()) } From b8cfd6ce51967283b9610c81ef31bd9d2b6198e4 Mon Sep 17 00:00:00 2001 From: const Date: Mon, 22 Jul 2024 13:45:59 -0500 Subject: [PATCH 27/58] fix tests --- pallets/commitments/src/lib.rs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/pallets/commitments/src/lib.rs b/pallets/commitments/src/lib.rs index 4663b2647..d5d132034 100644 --- a/pallets/commitments/src/lib.rs +++ b/pallets/commitments/src/lib.rs @@ -173,15 +173,6 @@ pub mod pallet { Ok(()) } - - pub fn swap_commitment( netuid: u16, new_hotkey: T::AccountId, old_hotkey: T::AccountId ) { - if let Some(commitment) = >::take(netuid, &old_hotkey) { - >::insert(netuid, &new_hotkey, commitment); - } - if let Some(last_commit) = >::take(netuid, &old_hotkey) { - >::insert(netuid, &new_hotkey, last_commit); - } - } } } From 6b6460d4fc7864543af574d7390c53fa3556691d Mon Sep 17 00:00:00 2001 From: const Date: Mon, 22 Jul 2024 15:21:13 -0500 Subject: [PATCH 28/58] clippy and fmt --- pallets/subtensor/src/lib.rs | 6 +- pallets/subtensor/src/swap.rs | 4 - pallets/subtensor/src/swap_hotkey.rs | 57 +++--- pallets/subtensor/tests/swap.rs | 1 - pallets/subtensor/tests/swap_hotkey.rs | 248 ++++++++++++++++++++----- 5 files changed, 234 insertions(+), 82 deletions(-) diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index d492b5477..6a353eafb 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -1088,11 +1088,9 @@ pub mod pallet { pub type Active = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyBoolVec>; #[pallet::storage] // --- DMAP ( netuid ) --> rank - pub type Rank = - StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; + pub type Rank = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; #[pallet::storage] // --- DMAP ( netuid ) --> trust - pub type Trust = - StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; + pub type Trust = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; #[pallet::storage] // --- DMAP ( netuid ) --> consensus pub type Consensus = StorageMap<_, Identity, u16, Vec, ValueQuery, EmptyU16Vec>; diff --git a/pallets/subtensor/src/swap.rs b/pallets/subtensor/src/swap.rs index 5d8f66c68..b6b0e9ba7 100644 --- a/pallets/subtensor/src/swap.rs +++ b/pallets/subtensor/src/swap.rs @@ -6,7 +6,6 @@ use frame_support::{storage::IterableStorageDoubleMap, weights::Weight}; use sp_core::{Get, U256}; impl Pallet { - /// Swaps the coldkey associated with a set of hotkeys from an old coldkey to a new coldkey. /// /// # Arguments @@ -378,7 +377,6 @@ impl Pallet { netuid_is_member } - /// Swaps the total stake associated with a coldkey from the old coldkey to the new coldkey. /// /// # Arguments @@ -635,6 +633,4 @@ impl Pallet { } weight.saturating_accrue(T::DbWeight::get().reads(TotalNetworks::::get() as u64)); } - - } diff --git a/pallets/subtensor/src/swap_hotkey.rs b/pallets/subtensor/src/swap_hotkey.rs index 02052e4dd..5c3fecbba 100644 --- a/pallets/subtensor/src/swap_hotkey.rs +++ b/pallets/subtensor/src/swap_hotkey.rs @@ -139,8 +139,12 @@ impl Pallet { /// # Note /// This function performs extensive storage reads and writes, which can be computationally expensive. /// The accumulated weight should be carefully considered in the context of block limits. - pub fn perform_hotkey_swap( old_hotkey: &T::AccountId, new_hotkey: &T::AccountId, coldkey: &T::AccountId, weight: &mut Weight ) -> DispatchResult { - + pub fn perform_hotkey_swap( + old_hotkey: &T::AccountId, + new_hotkey: &T::AccountId, + coldkey: &T::AccountId, + weight: &mut Weight, + ) -> DispatchResult { // 1. Swap owner. // Owner( hotkey ) -> coldkey -- the coldkey that owns the hotkey. Owner::::remove(old_hotkey); @@ -153,7 +157,7 @@ impl Pallet { // Add the new key if needed. if !hotkeys.contains(new_hotkey) { hotkeys.push(new_hotkey.clone()); - } + } // Remove the old key. hotkeys.retain(|hk| *hk != *old_hotkey); OwnedHotkeys::::insert(coldkey, hotkeys); @@ -161,15 +165,19 @@ impl Pallet { // 3. Swap total hotkey stake. // TotalHotkeyStake( hotkey ) -> stake -- the total stake that the hotkey has across all delegates. - let old_total_hotkey_stake = TotalHotkeyStake::::get( old_hotkey ); // Get the old total hotkey stake. - let new_total_hotkey_stake = TotalHotkeyStake::::get( new_hotkey ); // Get the new total hotkey stake. - TotalHotkeyStake::::remove( old_hotkey ); // Remove the old total hotkey stake. - TotalHotkeyStake::::insert( new_hotkey, old_total_hotkey_stake.saturating_add( new_total_hotkey_stake ) ); // Insert the new total hotkey stake via the addition. + let old_total_hotkey_stake = TotalHotkeyStake::::get(old_hotkey); // Get the old total hotkey stake. + let new_total_hotkey_stake = TotalHotkeyStake::::get(new_hotkey); // Get the new total hotkey stake. + TotalHotkeyStake::::remove(old_hotkey); // Remove the old total hotkey stake. + TotalHotkeyStake::::insert( + new_hotkey, + old_total_hotkey_stake.saturating_add(new_total_hotkey_stake), + ); // Insert the new total hotkey stake via the addition. weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2)); // 4. Swap total hotkey stakes. // TotalHotkeyColdkeyStakesThisInterval( hotkey ) --> (u64: stakes, u64: block_number) - let stake_tuples: Vec<(T::AccountId, (u64, u64))> = TotalHotkeyColdkeyStakesThisInterval::::iter_prefix(old_hotkey).collect(); + let stake_tuples: Vec<(T::AccountId, (u64, u64))> = + TotalHotkeyColdkeyStakesThisInterval::::iter_prefix(old_hotkey).collect(); for (coldkey, stake_tup) in stake_tuples { // NOTE: You could use this to increase your allowed stake operations but this would cost. TotalHotkeyColdkeyStakesThisInterval::::insert(new_hotkey, &coldkey, stake_tup); @@ -179,14 +187,14 @@ impl Pallet { // 5. Swap LastTxBlock // LastTxBlock( hotkey ) --> u64 -- the last transaction block for the hotkey. - LastTxBlock::::remove( old_hotkey ); - LastTxBlock::::insert( new_hotkey, Self::get_current_block_as_u64() ); + LastTxBlock::::remove(old_hotkey); + LastTxBlock::::insert(new_hotkey, Self::get_current_block_as_u64()); weight.saturating_accrue(T::DbWeight::get().reads_writes(0, 2)); // 6. Swap LastTxBlockDelegateTake // LastTxBlockDelegateTake( hotkey ) --> u64 -- the last transaction block for the hotkey delegate take. - LastTxBlockDelegateTake::::remove( old_hotkey ); - LastTxBlockDelegateTake::::insert( new_hotkey, Self::get_current_block_as_u64() ); + LastTxBlockDelegateTake::::remove(old_hotkey); + LastTxBlockDelegateTake::::insert(new_hotkey, Self::get_current_block_as_u64()); weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); // 7. Swap Senate members. @@ -198,19 +206,19 @@ impl Pallet { // 8. Swap delegates. // Delegates( hotkey ) -> take value -- the hotkey delegate take value. - let old_delegate_take = Delegates::::get( old_hotkey ); - Delegates::::remove( old_hotkey ); // Remove the old delegate take. - Delegates::::insert( new_hotkey, old_delegate_take ); // Insert the new delegate take. + let old_delegate_take = Delegates::::get(old_hotkey); + Delegates::::remove(old_hotkey); // Remove the old delegate take. + Delegates::::insert(new_hotkey, old_delegate_take); // Insert the new delegate take. weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); // 9. Swap all subnet specific info. let all_netuids: Vec = Self::get_all_subnet_netuids(); - for netuid in all_netuids { + for netuid in all_netuids { // 9.1 Remove the previous hotkey and insert the new hotkey from membership. // IsNetworkMember( hotkey, netuid ) -> bool -- is the hotkey a subnet member. - let is_network_member: bool = IsNetworkMember::::get( old_hotkey, netuid ); - IsNetworkMember::::remove( old_hotkey, netuid ); - IsNetworkMember::::insert( new_hotkey, netuid, is_network_member ); + let is_network_member: bool = IsNetworkMember::::get(old_hotkey, netuid); + IsNetworkMember::::remove(old_hotkey, netuid); + IsNetworkMember::::insert(new_hotkey, netuid, is_network_member); weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); // 9.2 Swap Uids + Keys. @@ -249,7 +257,7 @@ impl Pallet { } } - // 9.5 Swap WeightCommits + // 9.5 Swap WeightCommits // WeightCommits( hotkey ) --> Vec -- the weight commits for the hotkey. if is_network_member { if let Ok(old_weight_commits) = WeightCommits::::try_get(netuid, old_hotkey) { @@ -273,14 +281,13 @@ impl Pallet { weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); } } - } // 10. Swap Stake. // Stake( hotkey, coldkey ) -> stake -- the stake that the hotkey controls on behalf of the coldkey. let stakes: Vec<(T::AccountId, u64)> = Stake::::iter_prefix(old_hotkey).collect(); // Clear the entire old prefix here. - let _ = Stake::::clear_prefix( old_hotkey, stakes.len() as u32, None ); + let _ = Stake::::clear_prefix(old_hotkey, stakes.len() as u32, None); // Iterate over all the staking rows and insert them into the new hotkey. for (coldkey, old_stake_amount) in stakes { weight.saturating_accrue(T::DbWeight::get().reads(1)); @@ -290,7 +297,11 @@ impl Pallet { // Get the new stake value. let new_stake_value: u64 = Stake::::get(new_hotkey, &coldkey); // Insert the new stake value. - Stake::::insert(new_hotkey, &coldkey, new_stake_value.saturating_add(old_stake_amount)); + Stake::::insert( + new_hotkey, + &coldkey, + new_stake_value.saturating_add(old_stake_amount), + ); weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); // Swap StakingHotkeys. diff --git a/pallets/subtensor/tests/swap.rs b/pallets/subtensor/tests/swap.rs index f7f288cc2..0a3a85dff 100644 --- a/pallets/subtensor/tests/swap.rs +++ b/pallets/subtensor/tests/swap.rs @@ -9,7 +9,6 @@ use mock::*; use pallet_subtensor::*; use sp_core::U256; - #[test] fn test_do_swap_coldkey_success() { new_test_ext(1).execute_with(|| { diff --git a/pallets/subtensor/tests/swap_hotkey.rs b/pallets/subtensor/tests/swap_hotkey.rs index 35227d3b1..68f4ec49c 100644 --- a/pallets/subtensor/tests/swap_hotkey.rs +++ b/pallets/subtensor/tests/swap_hotkey.rs @@ -7,9 +7,8 @@ use frame_system::{Config, RawOrigin}; mod mock; use mock::*; use pallet_subtensor::*; -use sp_core::U256; use sp_core::H256; - +use sp_core::U256; // SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_owner --exact --nocapture #[test] @@ -21,7 +20,12 @@ fn test_swap_owner() { let mut weight = Weight::zero(); Owner::::insert(&old_hotkey, &coldkey); - assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight)); + assert_ok!(SubtensorModule::perform_hotkey_swap( + &old_hotkey, + &new_hotkey, + &coldkey, + &mut weight + )); assert!(!Owner::::contains_key(&old_hotkey)); assert_eq!(Owner::::get(&new_hotkey), coldkey); @@ -38,7 +42,12 @@ fn test_swap_owned_hotkeys() { let mut weight = Weight::zero(); OwnedHotkeys::::insert(&coldkey, vec![old_hotkey]); - assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight)); + assert_ok!(SubtensorModule::perform_hotkey_swap( + &old_hotkey, + &new_hotkey, + &coldkey, + &mut weight + )); let hotkeys = OwnedHotkeys::::get(&coldkey); assert!(!hotkeys.contains(&old_hotkey)); @@ -57,7 +66,12 @@ fn test_swap_total_hotkey_stake() { TotalHotkeyStake::::insert(&old_hotkey, 100); TotalHotkeyStake::::insert(&new_hotkey, 50); - assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight)); + assert_ok!(SubtensorModule::perform_hotkey_swap( + &old_hotkey, + &new_hotkey, + &coldkey, + &mut weight + )); assert!(!TotalHotkeyStake::::contains_key(&old_hotkey)); assert_eq!(TotalHotkeyStake::::get(&new_hotkey), 150); @@ -74,10 +88,21 @@ fn test_swap_total_hotkey_coldkey_stakes_this_interval() { let mut weight = Weight::zero(); TotalHotkeyColdkeyStakesThisInterval::::insert(&old_hotkey, &coldkey, (100, 1000)); - assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight)); + assert_ok!(SubtensorModule::perform_hotkey_swap( + &old_hotkey, + &new_hotkey, + &coldkey, + &mut weight + )); - assert!(!TotalHotkeyColdkeyStakesThisInterval::::contains_key(&old_hotkey, &coldkey)); - assert_eq!(TotalHotkeyColdkeyStakesThisInterval::::get(&new_hotkey, &coldkey), (100, 1000)); + assert!(!TotalHotkeyColdkeyStakesThisInterval::::contains_key( + &old_hotkey, + &coldkey + )); + assert_eq!( + TotalHotkeyColdkeyStakesThisInterval::::get(&new_hotkey, &coldkey), + (100, 1000) + ); }); } @@ -91,10 +116,18 @@ fn test_swap_last_tx_block() { let mut weight = Weight::zero(); LastTxBlock::::insert(&old_hotkey, 1000); - assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight)); + assert_ok!(SubtensorModule::perform_hotkey_swap( + &old_hotkey, + &new_hotkey, + &coldkey, + &mut weight + )); assert!(!LastTxBlock::::contains_key(&old_hotkey)); - assert_eq!(LastTxBlock::::get(&new_hotkey), SubtensorModule::get_current_block_as_u64()); + assert_eq!( + LastTxBlock::::get(&new_hotkey), + SubtensorModule::get_current_block_as_u64() + ); }); } @@ -108,10 +141,18 @@ fn test_swap_last_tx_block_delegate_take() { let mut weight = Weight::zero(); pallet_subtensor::LastTxBlockDelegateTake::::insert(&old_hotkey, 1000); - assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight)); + assert_ok!(SubtensorModule::perform_hotkey_swap( + &old_hotkey, + &new_hotkey, + &coldkey, + &mut weight + )); assert!(!LastTxBlockDelegateTake::::contains_key(&old_hotkey)); - assert_eq!(LastTxBlockDelegateTake::::get(&new_hotkey), SubtensorModule::get_current_block_as_u64()); + assert_eq!( + LastTxBlockDelegateTake::::get(&new_hotkey), + SubtensorModule::get_current_block_as_u64() + ); }); } @@ -126,7 +167,12 @@ fn test_swap_senate_members() { // Assuming there's a way to add a member to the senate // SenateMembers::add_member(&old_hotkey); - assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight)); + assert_ok!(SubtensorModule::perform_hotkey_swap( + &old_hotkey, + &new_hotkey, + &coldkey, + &mut weight + )); // Assert that the old_hotkey is no longer a member and new_hotkey is now a member // assert!(!SenateMembers::is_member(&old_hotkey)); @@ -144,7 +190,12 @@ fn test_swap_delegates() { let mut weight = Weight::zero(); Delegates::::insert(&old_hotkey, 100); - assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight)); + assert_ok!(SubtensorModule::perform_hotkey_swap( + &old_hotkey, + &new_hotkey, + &coldkey, + &mut weight + )); assert!(!Delegates::::contains_key(&old_hotkey)); assert_eq!(Delegates::::get(&new_hotkey), 100); @@ -163,7 +214,12 @@ fn test_swap_subnet_membership() { add_network(netuid, 0, 1); IsNetworkMember::::insert(&old_hotkey, netuid, true); - assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight)); + assert_ok!(SubtensorModule::perform_hotkey_swap( + &old_hotkey, + &new_hotkey, + &coldkey, + &mut weight + )); assert!(!IsNetworkMember::::contains_key(&old_hotkey, netuid)); assert!(IsNetworkMember::::get(&new_hotkey, netuid)); @@ -186,7 +242,12 @@ fn test_swap_uids_and_keys() { Uids::::insert(netuid, &old_hotkey, uid); Keys::::insert(netuid, uid, old_hotkey); - assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight)); + assert_ok!(SubtensorModule::perform_hotkey_swap( + &old_hotkey, + &new_hotkey, + &coldkey, + &mut weight + )); assert_eq!(Uids::::get(netuid, &old_hotkey), None); assert_eq!(Uids::::get(netuid, &new_hotkey), Some(uid)); @@ -209,10 +270,18 @@ fn test_swap_prometheus() { IsNetworkMember::::insert(&old_hotkey, netuid, true); Prometheus::::insert(netuid, &old_hotkey, prometheus_info.clone()); - assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight)); + assert_ok!(SubtensorModule::perform_hotkey_swap( + &old_hotkey, + &new_hotkey, + &coldkey, + &mut weight + )); assert!(!Prometheus::::contains_key(netuid, &old_hotkey)); - assert_eq!(Prometheus::::get(netuid, &new_hotkey), Some(prometheus_info)); + assert_eq!( + Prometheus::::get(netuid, &new_hotkey), + Some(prometheus_info) + ); }); } @@ -231,13 +300,18 @@ fn test_swap_axons() { IsNetworkMember::::insert(&old_hotkey, netuid, true); Axons::::insert(netuid, &old_hotkey, axon_info.clone()); - assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight)); + assert_ok!(SubtensorModule::perform_hotkey_swap( + &old_hotkey, + &new_hotkey, + &coldkey, + &mut weight + )); assert!(!Axons::::contains_key(netuid, &old_hotkey)); assert_eq!(Axons::::get(netuid, &new_hotkey), Some(axon_info)); }); } - + // SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_weight_commits --exact --nocapture #[test] fn test_swap_weight_commits() { @@ -253,10 +327,18 @@ fn test_swap_weight_commits() { IsNetworkMember::::insert(&old_hotkey, netuid, true); WeightCommits::::insert(netuid, &old_hotkey, weight_commits.clone()); - assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight)); + assert_ok!(SubtensorModule::perform_hotkey_swap( + &old_hotkey, + &new_hotkey, + &coldkey, + &mut weight + )); assert!(!WeightCommits::::contains_key(netuid, &old_hotkey)); - assert_eq!(WeightCommits::::get(netuid, &new_hotkey), Some(weight_commits)); + assert_eq!( + WeightCommits::::get(netuid, &new_hotkey), + Some(weight_commits) + ); }); } @@ -274,12 +356,23 @@ fn test_swap_loaded_emission() { add_network(netuid, 0, 1); IsNetworkMember::::insert(&old_hotkey, netuid, true); - LoadedEmission::::insert(netuid, vec![(old_hotkey, server_emission, validator_emission)]); + LoadedEmission::::insert( + netuid, + vec![(old_hotkey, server_emission, validator_emission)], + ); - assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight)); + assert_ok!(SubtensorModule::perform_hotkey_swap( + &old_hotkey, + &new_hotkey, + &coldkey, + &mut weight + )); let new_loaded_emission = LoadedEmission::::get(netuid); - assert_eq!(new_loaded_emission, Some(vec![(new_hotkey, server_emission, validator_emission)])); + assert_eq!( + new_loaded_emission, + Some(vec![(new_hotkey, server_emission, validator_emission)]) + ); }); } @@ -295,7 +388,12 @@ fn test_swap_stake() { Stake::::insert(&old_hotkey, &coldkey, stake_amount); - assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight)); + assert_ok!(SubtensorModule::perform_hotkey_swap( + &old_hotkey, + &new_hotkey, + &coldkey, + &mut weight + )); assert!(!Stake::::contains_key(&old_hotkey, &coldkey)); assert_eq!(Stake::::get(&new_hotkey, &coldkey), stake_amount); @@ -314,7 +412,12 @@ fn test_swap_staking_hotkeys() { Stake::::insert(&old_hotkey, &coldkey, 100); StakingHotkeys::::insert(&coldkey, vec![old_hotkey]); - assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight)); + assert_ok!(SubtensorModule::perform_hotkey_swap( + &old_hotkey, + &new_hotkey, + &coldkey, + &mut weight + )); let staking_hotkeys = StakingHotkeys::::get(&coldkey); assert!(!staking_hotkeys.contains(&old_hotkey)); @@ -337,7 +440,12 @@ fn test_swap_hotkey_with_multiple_coldkeys() { StakingHotkeys::::insert(&coldkey1, vec![old_hotkey]); StakingHotkeys::::insert(&coldkey2, vec![old_hotkey]); - assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey1, &mut weight)); + assert_ok!(SubtensorModule::perform_hotkey_swap( + &old_hotkey, + &new_hotkey, + &coldkey1, + &mut weight + )); assert_eq!(Stake::::get(&new_hotkey, &coldkey1), 100); assert_eq!(Stake::::get(&new_hotkey, &coldkey2), 200); @@ -358,7 +466,12 @@ fn test_swap_hotkey_with_existing_stake() { Stake::::insert(&old_hotkey, &coldkey, 100); Stake::::insert(&new_hotkey, &coldkey, 50); - assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight)); + assert_ok!(SubtensorModule::perform_hotkey_swap( + &old_hotkey, + &new_hotkey, + &coldkey, + &mut weight + )); assert_eq!(Stake::::get(&new_hotkey, &coldkey), 150); }); @@ -380,7 +493,12 @@ fn test_swap_hotkey_with_multiple_subnets() { IsNetworkMember::::insert(&old_hotkey, netuid1, true); IsNetworkMember::::insert(&old_hotkey, netuid2, true); - assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight)); + assert_ok!(SubtensorModule::perform_hotkey_swap( + &old_hotkey, + &new_hotkey, + &coldkey, + &mut weight + )); assert!(IsNetworkMember::::get(&new_hotkey, netuid1)); assert!(IsNetworkMember::::get(&new_hotkey, netuid2)); @@ -405,7 +523,12 @@ fn test_swap_staking_hotkeys_multiple_coldkeys() { StakingHotkeys::::insert(&coldkey1, vec![old_hotkey]); StakingHotkeys::::insert(&coldkey2, vec![old_hotkey, U256::from(5)]); - assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey1, &mut weight)); + assert_ok!(SubtensorModule::perform_hotkey_swap( + &old_hotkey, + &new_hotkey, + &coldkey1, + &mut weight + )); // Check if new_hotkey replaced old_hotkey in StakingHotkeys assert!(StakingHotkeys::::get(&coldkey1).contains(&new_hotkey)); @@ -414,7 +537,8 @@ fn test_swap_staking_hotkeys_multiple_coldkeys() { // Check if new_hotkey replaced old_hotkey for coldkey2 as well assert!(StakingHotkeys::::get(&coldkey2).contains(&new_hotkey)); assert!(!StakingHotkeys::::get(&coldkey2).contains(&old_hotkey)); - assert!(StakingHotkeys::::get(&coldkey2).contains(&U256::from(5))); // Other hotkeys should remain + assert!(StakingHotkeys::::get(&coldkey2).contains(&U256::from(5))); + // Other hotkeys should remain }); } @@ -430,7 +554,12 @@ fn test_swap_hotkey_with_no_stake() { // Set up initial state with no stake Owner::::insert(&old_hotkey, &coldkey); - assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight)); + assert_ok!(SubtensorModule::perform_hotkey_swap( + &old_hotkey, + &new_hotkey, + &coldkey, + &mut weight + )); // Check if ownership transferred assert!(!Owner::::contains_key(&old_hotkey)); @@ -464,7 +593,12 @@ fn test_swap_hotkey_with_multiple_coldkeys_and_subnets() { IsNetworkMember::::insert(&old_hotkey, netuid2, true); TotalHotkeyStake::::insert(&old_hotkey, 300); - assert_ok!(SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey1, &mut weight)); + assert_ok!(SubtensorModule::perform_hotkey_swap( + &old_hotkey, + &new_hotkey, + &coldkey1, + &mut weight + )); // Check ownership transfer assert!(!Owner::::contains_key(&old_hotkey)); @@ -637,7 +771,6 @@ fn test_swap_owner_new_hotkey_already_exists() { }); } - // SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_total_hotkey_stake_success --exact --nocapture #[test] fn test_swap_total_hotkey_stake_success() { @@ -660,7 +793,6 @@ fn test_swap_total_hotkey_stake_success() { }); } - // SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_delegates_success --exact --nocapture #[test] fn test_swap_delegates_success() { @@ -683,7 +815,6 @@ fn test_swap_delegates_success() { }); } - // SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_stake_success --exact --nocapture #[test] fn test_swap_stake_success() { @@ -745,12 +876,7 @@ fn test_swap_total_hotkey_coldkey_stakes_this_interval_success() { TotalHotkeyColdkeyStakesThisInterval::::insert(old_hotkey, coldkey, stake); // Perform the swap - SubtensorModule::perform_hotkey_swap( - &old_hotkey, - &new_hotkey, - &coldkey, - &mut weight, - ); + SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight); // Verify the swap assert_eq!( @@ -780,7 +906,11 @@ fn test_swap_hotkey_error_cases() { // Test not enough balance let swap_cost = SubtensorModule::get_key_swap_cost(); assert_noop!( - SubtensorModule::do_swap_hotkey(RuntimeOrigin::signed(coldkey), &old_hotkey, &new_hotkey), + SubtensorModule::do_swap_hotkey( + RuntimeOrigin::signed(coldkey), + &old_hotkey, + &new_hotkey + ), Error::::NotEnoughBalanceToPaySwapHotKey ); @@ -789,29 +919,47 @@ fn test_swap_hotkey_error_cases() { // Test new hotkey same as old assert_noop!( - SubtensorModule::do_swap_hotkey(RuntimeOrigin::signed(coldkey), &old_hotkey, &old_hotkey), + SubtensorModule::do_swap_hotkey( + RuntimeOrigin::signed(coldkey), + &old_hotkey, + &old_hotkey + ), Error::::NewHotKeyIsSameWithOld ); // Test new hotkey already registered IsNetworkMember::::insert(&new_hotkey, 0, true); assert_noop!( - SubtensorModule::do_swap_hotkey(RuntimeOrigin::signed(coldkey), &old_hotkey, &new_hotkey), + SubtensorModule::do_swap_hotkey( + RuntimeOrigin::signed(coldkey), + &old_hotkey, + &new_hotkey + ), Error::::HotKeyAlreadyRegisteredInSubNet ); IsNetworkMember::::remove(&new_hotkey, 0); // Test non-associated coldkey assert_noop!( - SubtensorModule::do_swap_hotkey(RuntimeOrigin::signed(wrong_coldkey), &old_hotkey, &new_hotkey), + SubtensorModule::do_swap_hotkey( + RuntimeOrigin::signed(wrong_coldkey), + &old_hotkey, + &new_hotkey + ), Error::::NonAssociatedColdKey ); - // Run the successful swap - assert_ok!(SubtensorModule::do_swap_hotkey(RuntimeOrigin::signed(coldkey), &old_hotkey, &new_hotkey)); + assert_ok!(SubtensorModule::do_swap_hotkey( + RuntimeOrigin::signed(coldkey), + &old_hotkey, + &new_hotkey + )); // Check balance after swap - assert_eq!(Balances::free_balance(&coldkey), initial_balance - swap_cost); + assert_eq!( + Balances::free_balance(&coldkey), + initial_balance - swap_cost + ); }); } From fde92e4cd146c84ffe9db58782609606493b2290 Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Tue, 23 Jul 2024 01:15:48 +0400 Subject: [PATCH 29/58] chore: bump spec version --- runtime/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index a4abd124f..0aa7bddbe 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -139,7 +139,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: 165, + spec_version: 188, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1, From a00d130be871055631df53eb426021b46e0b2463 Mon Sep 17 00:00:00 2001 From: const Date: Mon, 22 Jul 2024 16:29:54 -0500 Subject: [PATCH 30/58] bring back hotkey swap --- pallets/subtensor/src/lib.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index 6a353eafb..daaf20b00 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -2065,17 +2065,17 @@ pub mod pallet { } /// The extrinsic for user to change its hotkey - ///#[pallet::call_index(70)] - ///#[pallet::weight((Weight::from_parts(1_940_000_000, 0) - ///.saturating_add(T::DbWeight::get().reads(272)) - ///.saturating_add(T::DbWeight::get().writes(527)), DispatchClass::Operational, Pays::No))] - ///pub fn swap_hotkey( - /// origin: OriginFor, - /// hotkey: T::AccountId, - /// new_hotkey: T::AccountId, - ///) -> DispatchResultWithPostInfo { - /// Self::do_swap_hotkey(origin, &hotkey, &new_hotkey) - ///} + #[pallet::call_index(70)] + #[pallet::weight((Weight::from_parts(1_940_000_000, 0) + .saturating_add(T::DbWeight::get().reads(272)) + .saturating_add(T::DbWeight::get().writes(527)), DispatchClass::Operational, Pays::No))] + pub fn swap_hotkey( + origin: OriginFor, + hotkey: T::AccountId, + new_hotkey: T::AccountId, + ) -> DispatchResultWithPostInfo { + Self::do_swap_hotkey(origin, &hotkey, &new_hotkey) + } /// The extrinsic for user to change the coldkey associated with their account. /// From 9b9c594c58ec5d4540b9f20c07796673ddccce5e Mon Sep 17 00:00:00 2001 From: const Date: Mon, 22 Jul 2024 16:30:19 -0500 Subject: [PATCH 31/58] pump to 189 --- runtime/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index a4abd124f..db8134423 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -139,7 +139,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: 165, + spec_version: 189, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1, From 385f0bf1efc00e58b13c86cf15a0a2b22909b8a2 Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Tue, 23 Jul 2024 01:36:41 +0400 Subject: [PATCH 32/58] chore: lint --- pallets/subtensor/tests/swap_hotkey.rs | 204 ++++++++++++------------- 1 file changed, 102 insertions(+), 102 deletions(-) diff --git a/pallets/subtensor/tests/swap_hotkey.rs b/pallets/subtensor/tests/swap_hotkey.rs index 68f4ec49c..990382918 100644 --- a/pallets/subtensor/tests/swap_hotkey.rs +++ b/pallets/subtensor/tests/swap_hotkey.rs @@ -19,7 +19,7 @@ fn test_swap_owner() { let coldkey = U256::from(3); let mut weight = Weight::zero(); - Owner::::insert(&old_hotkey, &coldkey); + Owner::::insert(old_hotkey, coldkey); assert_ok!(SubtensorModule::perform_hotkey_swap( &old_hotkey, &new_hotkey, @@ -27,8 +27,8 @@ fn test_swap_owner() { &mut weight )); - assert!(!Owner::::contains_key(&old_hotkey)); - assert_eq!(Owner::::get(&new_hotkey), coldkey); + assert!(!Owner::::contains_key(old_hotkey)); + assert_eq!(Owner::::get(new_hotkey), coldkey); }); } @@ -41,7 +41,7 @@ fn test_swap_owned_hotkeys() { let coldkey = U256::from(3); let mut weight = Weight::zero(); - OwnedHotkeys::::insert(&coldkey, vec![old_hotkey]); + OwnedHotkeys::::insert(coldkey, vec![old_hotkey]); assert_ok!(SubtensorModule::perform_hotkey_swap( &old_hotkey, &new_hotkey, @@ -49,7 +49,7 @@ fn test_swap_owned_hotkeys() { &mut weight )); - let hotkeys = OwnedHotkeys::::get(&coldkey); + let hotkeys = OwnedHotkeys::::get(coldkey); assert!(!hotkeys.contains(&old_hotkey)); assert!(hotkeys.contains(&new_hotkey)); }); @@ -64,8 +64,8 @@ fn test_swap_total_hotkey_stake() { let coldkey = U256::from(3); let mut weight = Weight::zero(); - TotalHotkeyStake::::insert(&old_hotkey, 100); - TotalHotkeyStake::::insert(&new_hotkey, 50); + TotalHotkeyStake::::insert(old_hotkey, 100); + TotalHotkeyStake::::insert(new_hotkey, 50); assert_ok!(SubtensorModule::perform_hotkey_swap( &old_hotkey, &new_hotkey, @@ -73,8 +73,8 @@ fn test_swap_total_hotkey_stake() { &mut weight )); - assert!(!TotalHotkeyStake::::contains_key(&old_hotkey)); - assert_eq!(TotalHotkeyStake::::get(&new_hotkey), 150); + assert!(!TotalHotkeyStake::::contains_key(old_hotkey)); + assert_eq!(TotalHotkeyStake::::get(new_hotkey), 150); }); } @@ -87,7 +87,7 @@ fn test_swap_total_hotkey_coldkey_stakes_this_interval() { let coldkey = U256::from(3); let mut weight = Weight::zero(); - TotalHotkeyColdkeyStakesThisInterval::::insert(&old_hotkey, &coldkey, (100, 1000)); + TotalHotkeyColdkeyStakesThisInterval::::insert(old_hotkey, coldkey, (100, 1000)); assert_ok!(SubtensorModule::perform_hotkey_swap( &old_hotkey, &new_hotkey, @@ -96,11 +96,11 @@ fn test_swap_total_hotkey_coldkey_stakes_this_interval() { )); assert!(!TotalHotkeyColdkeyStakesThisInterval::::contains_key( - &old_hotkey, - &coldkey + old_hotkey, + coldkey )); assert_eq!( - TotalHotkeyColdkeyStakesThisInterval::::get(&new_hotkey, &coldkey), + TotalHotkeyColdkeyStakesThisInterval::::get(new_hotkey, coldkey), (100, 1000) ); }); @@ -115,7 +115,7 @@ fn test_swap_last_tx_block() { let coldkey = U256::from(3); let mut weight = Weight::zero(); - LastTxBlock::::insert(&old_hotkey, 1000); + LastTxBlock::::insert(old_hotkey, 1000); assert_ok!(SubtensorModule::perform_hotkey_swap( &old_hotkey, &new_hotkey, @@ -123,9 +123,9 @@ fn test_swap_last_tx_block() { &mut weight )); - assert!(!LastTxBlock::::contains_key(&old_hotkey)); + assert!(!LastTxBlock::::contains_key(old_hotkey)); assert_eq!( - LastTxBlock::::get(&new_hotkey), + LastTxBlock::::get(new_hotkey), SubtensorModule::get_current_block_as_u64() ); }); @@ -140,7 +140,7 @@ fn test_swap_last_tx_block_delegate_take() { let coldkey = U256::from(3); let mut weight = Weight::zero(); - pallet_subtensor::LastTxBlockDelegateTake::::insert(&old_hotkey, 1000); + pallet_subtensor::LastTxBlockDelegateTake::::insert(old_hotkey, 1000); assert_ok!(SubtensorModule::perform_hotkey_swap( &old_hotkey, &new_hotkey, @@ -148,9 +148,9 @@ fn test_swap_last_tx_block_delegate_take() { &mut weight )); - assert!(!LastTxBlockDelegateTake::::contains_key(&old_hotkey)); + assert!(!LastTxBlockDelegateTake::::contains_key(old_hotkey)); assert_eq!( - LastTxBlockDelegateTake::::get(&new_hotkey), + LastTxBlockDelegateTake::::get(new_hotkey), SubtensorModule::get_current_block_as_u64() ); }); @@ -189,7 +189,7 @@ fn test_swap_delegates() { let coldkey = U256::from(3); let mut weight = Weight::zero(); - Delegates::::insert(&old_hotkey, 100); + Delegates::::insert(old_hotkey, 100); assert_ok!(SubtensorModule::perform_hotkey_swap( &old_hotkey, &new_hotkey, @@ -197,8 +197,8 @@ fn test_swap_delegates() { &mut weight )); - assert!(!Delegates::::contains_key(&old_hotkey)); - assert_eq!(Delegates::::get(&new_hotkey), 100); + assert!(!Delegates::::contains_key(old_hotkey)); + assert_eq!(Delegates::::get(new_hotkey), 100); }); } @@ -213,7 +213,7 @@ fn test_swap_subnet_membership() { let mut weight = Weight::zero(); add_network(netuid, 0, 1); - IsNetworkMember::::insert(&old_hotkey, netuid, true); + IsNetworkMember::::insert(old_hotkey, netuid, true); assert_ok!(SubtensorModule::perform_hotkey_swap( &old_hotkey, &new_hotkey, @@ -221,8 +221,8 @@ fn test_swap_subnet_membership() { &mut weight )); - assert!(!IsNetworkMember::::contains_key(&old_hotkey, netuid)); - assert!(IsNetworkMember::::get(&new_hotkey, netuid)); + assert!(!IsNetworkMember::::contains_key(old_hotkey, netuid)); + assert!(IsNetworkMember::::get(new_hotkey, netuid)); }); } @@ -238,8 +238,8 @@ fn test_swap_uids_and_keys() { let mut weight = Weight::zero(); add_network(netuid, 0, 1); - IsNetworkMember::::insert(&old_hotkey, netuid, true); - Uids::::insert(netuid, &old_hotkey, uid); + IsNetworkMember::::insert(old_hotkey, netuid, true); + Uids::::insert(netuid, old_hotkey, uid); Keys::::insert(netuid, uid, old_hotkey); assert_ok!(SubtensorModule::perform_hotkey_swap( @@ -249,8 +249,8 @@ fn test_swap_uids_and_keys() { &mut weight )); - assert_eq!(Uids::::get(netuid, &old_hotkey), None); - assert_eq!(Uids::::get(netuid, &new_hotkey), Some(uid)); + assert_eq!(Uids::::get(netuid, old_hotkey), None); + assert_eq!(Uids::::get(netuid, new_hotkey), Some(uid)); assert_eq!(Keys::::get(netuid, uid), new_hotkey); }); } @@ -267,8 +267,8 @@ fn test_swap_prometheus() { let mut weight = Weight::zero(); add_network(netuid, 0, 1); - IsNetworkMember::::insert(&old_hotkey, netuid, true); - Prometheus::::insert(netuid, &old_hotkey, prometheus_info.clone()); + IsNetworkMember::::insert(old_hotkey, netuid, true); + Prometheus::::insert(netuid, old_hotkey, prometheus_info.clone()); assert_ok!(SubtensorModule::perform_hotkey_swap( &old_hotkey, @@ -277,9 +277,9 @@ fn test_swap_prometheus() { &mut weight )); - assert!(!Prometheus::::contains_key(netuid, &old_hotkey)); + assert!(!Prometheus::::contains_key(netuid, old_hotkey)); assert_eq!( - Prometheus::::get(netuid, &new_hotkey), + Prometheus::::get(netuid, new_hotkey), Some(prometheus_info) ); }); @@ -297,8 +297,8 @@ fn test_swap_axons() { let mut weight = Weight::zero(); add_network(netuid, 0, 1); - IsNetworkMember::::insert(&old_hotkey, netuid, true); - Axons::::insert(netuid, &old_hotkey, axon_info.clone()); + IsNetworkMember::::insert(old_hotkey, netuid, true); + Axons::::insert(netuid, old_hotkey, axon_info.clone()); assert_ok!(SubtensorModule::perform_hotkey_swap( &old_hotkey, @@ -307,8 +307,8 @@ fn test_swap_axons() { &mut weight )); - assert!(!Axons::::contains_key(netuid, &old_hotkey)); - assert_eq!(Axons::::get(netuid, &new_hotkey), Some(axon_info)); + assert!(!Axons::::contains_key(netuid, old_hotkey)); + assert_eq!(Axons::::get(netuid, new_hotkey), Some(axon_info)); }); } @@ -324,8 +324,8 @@ fn test_swap_weight_commits() { let mut weight = Weight::zero(); add_network(netuid, 0, 1); - IsNetworkMember::::insert(&old_hotkey, netuid, true); - WeightCommits::::insert(netuid, &old_hotkey, weight_commits.clone()); + IsNetworkMember::::insert(old_hotkey, netuid, true); + WeightCommits::::insert(netuid, old_hotkey, weight_commits); assert_ok!(SubtensorModule::perform_hotkey_swap( &old_hotkey, @@ -334,9 +334,9 @@ fn test_swap_weight_commits() { &mut weight )); - assert!(!WeightCommits::::contains_key(netuid, &old_hotkey)); + assert!(!WeightCommits::::contains_key(netuid, old_hotkey)); assert_eq!( - WeightCommits::::get(netuid, &new_hotkey), + WeightCommits::::get(netuid, new_hotkey), Some(weight_commits) ); }); @@ -355,7 +355,7 @@ fn test_swap_loaded_emission() { let mut weight = Weight::zero(); add_network(netuid, 0, 1); - IsNetworkMember::::insert(&old_hotkey, netuid, true); + IsNetworkMember::::insert(old_hotkey, netuid, true); LoadedEmission::::insert( netuid, vec![(old_hotkey, server_emission, validator_emission)], @@ -386,7 +386,7 @@ fn test_swap_stake() { let stake_amount = 100u64; let mut weight = Weight::zero(); - Stake::::insert(&old_hotkey, &coldkey, stake_amount); + Stake::::insert(old_hotkey, coldkey, stake_amount); assert_ok!(SubtensorModule::perform_hotkey_swap( &old_hotkey, @@ -395,8 +395,8 @@ fn test_swap_stake() { &mut weight )); - assert!(!Stake::::contains_key(&old_hotkey, &coldkey)); - assert_eq!(Stake::::get(&new_hotkey, &coldkey), stake_amount); + assert!(!Stake::::contains_key(old_hotkey, coldkey)); + assert_eq!(Stake::::get(new_hotkey, coldkey), stake_amount); }); } @@ -409,8 +409,8 @@ fn test_swap_staking_hotkeys() { let coldkey = U256::from(3); let mut weight = Weight::zero(); - Stake::::insert(&old_hotkey, &coldkey, 100); - StakingHotkeys::::insert(&coldkey, vec![old_hotkey]); + Stake::::insert(old_hotkey, coldkey, 100); + StakingHotkeys::::insert(coldkey, vec![old_hotkey]); assert_ok!(SubtensorModule::perform_hotkey_swap( &old_hotkey, @@ -419,7 +419,7 @@ fn test_swap_staking_hotkeys() { &mut weight )); - let staking_hotkeys = StakingHotkeys::::get(&coldkey); + let staking_hotkeys = StakingHotkeys::::get(coldkey); assert!(!staking_hotkeys.contains(&old_hotkey)); assert!(staking_hotkeys.contains(&new_hotkey)); }); @@ -435,10 +435,10 @@ fn test_swap_hotkey_with_multiple_coldkeys() { let coldkey2 = U256::from(4); let mut weight = Weight::zero(); - Stake::::insert(&old_hotkey, &coldkey1, 100); - Stake::::insert(&old_hotkey, &coldkey2, 200); - StakingHotkeys::::insert(&coldkey1, vec![old_hotkey]); - StakingHotkeys::::insert(&coldkey2, vec![old_hotkey]); + Stake::::insert(old_hotkey, coldkey1, 100); + Stake::::insert(old_hotkey, coldkey2, 200); + StakingHotkeys::::insert(coldkey1, vec![old_hotkey]); + StakingHotkeys::::insert(coldkey2, vec![old_hotkey]); assert_ok!(SubtensorModule::perform_hotkey_swap( &old_hotkey, @@ -447,10 +447,10 @@ fn test_swap_hotkey_with_multiple_coldkeys() { &mut weight )); - assert_eq!(Stake::::get(&new_hotkey, &coldkey1), 100); - assert_eq!(Stake::::get(&new_hotkey, &coldkey2), 200); - assert!(StakingHotkeys::::get(&coldkey1).contains(&new_hotkey)); - assert!(StakingHotkeys::::get(&coldkey2).contains(&new_hotkey)); + assert_eq!(Stake::::get(new_hotkey, coldkey1), 100); + assert_eq!(Stake::::get(new_hotkey, coldkey2), 200); + assert!(StakingHotkeys::::get(coldkey1).contains(&new_hotkey)); + assert!(StakingHotkeys::::get(coldkey2).contains(&new_hotkey)); }); } @@ -463,8 +463,8 @@ fn test_swap_hotkey_with_existing_stake() { let coldkey = U256::from(3); let mut weight = Weight::zero(); - Stake::::insert(&old_hotkey, &coldkey, 100); - Stake::::insert(&new_hotkey, &coldkey, 50); + Stake::::insert(old_hotkey, coldkey, 100); + Stake::::insert(new_hotkey, coldkey, 50); assert_ok!(SubtensorModule::perform_hotkey_swap( &old_hotkey, @@ -473,7 +473,7 @@ fn test_swap_hotkey_with_existing_stake() { &mut weight )); - assert_eq!(Stake::::get(&new_hotkey, &coldkey), 150); + assert_eq!(Stake::::get(new_hotkey, coldkey), 150); }); } @@ -490,8 +490,8 @@ fn test_swap_hotkey_with_multiple_subnets() { add_network(netuid1, 0, 1); add_network(netuid2, 0, 1); - IsNetworkMember::::insert(&old_hotkey, netuid1, true); - IsNetworkMember::::insert(&old_hotkey, netuid2, true); + IsNetworkMember::::insert(old_hotkey, netuid1, true); + IsNetworkMember::::insert(old_hotkey, netuid2, true); assert_ok!(SubtensorModule::perform_hotkey_swap( &old_hotkey, @@ -500,10 +500,10 @@ fn test_swap_hotkey_with_multiple_subnets() { &mut weight )); - assert!(IsNetworkMember::::get(&new_hotkey, netuid1)); - assert!(IsNetworkMember::::get(&new_hotkey, netuid2)); - assert!(!IsNetworkMember::::get(&old_hotkey, netuid1)); - assert!(!IsNetworkMember::::get(&old_hotkey, netuid2)); + assert!(IsNetworkMember::::get(new_hotkey, netuid1)); + assert!(IsNetworkMember::::get(new_hotkey, netuid2)); + assert!(!IsNetworkMember::::get(old_hotkey, netuid1)); + assert!(!IsNetworkMember::::get(old_hotkey, netuid2)); }); } @@ -518,10 +518,10 @@ fn test_swap_staking_hotkeys_multiple_coldkeys() { let mut weight = Weight::zero(); // Set up initial state - Stake::::insert(&old_hotkey, &coldkey1, 100); - Stake::::insert(&old_hotkey, &coldkey2, 200); - StakingHotkeys::::insert(&coldkey1, vec![old_hotkey]); - StakingHotkeys::::insert(&coldkey2, vec![old_hotkey, U256::from(5)]); + Stake::::insert(old_hotkey, coldkey1, 100); + Stake::::insert(old_hotkey, coldkey2, 200); + StakingHotkeys::::insert(coldkey1, vec![old_hotkey]); + StakingHotkeys::::insert(coldkey2, vec![old_hotkey, U256::from(5)]); assert_ok!(SubtensorModule::perform_hotkey_swap( &old_hotkey, @@ -531,13 +531,13 @@ fn test_swap_staking_hotkeys_multiple_coldkeys() { )); // Check if new_hotkey replaced old_hotkey in StakingHotkeys - assert!(StakingHotkeys::::get(&coldkey1).contains(&new_hotkey)); - assert!(!StakingHotkeys::::get(&coldkey1).contains(&old_hotkey)); + assert!(StakingHotkeys::::get(coldkey1).contains(&new_hotkey)); + assert!(!StakingHotkeys::::get(coldkey1).contains(&old_hotkey)); // Check if new_hotkey replaced old_hotkey for coldkey2 as well - assert!(StakingHotkeys::::get(&coldkey2).contains(&new_hotkey)); - assert!(!StakingHotkeys::::get(&coldkey2).contains(&old_hotkey)); - assert!(StakingHotkeys::::get(&coldkey2).contains(&U256::from(5))); + assert!(StakingHotkeys::::get(coldkey2).contains(&new_hotkey)); + assert!(!StakingHotkeys::::get(coldkey2).contains(&old_hotkey)); + assert!(StakingHotkeys::::get(coldkey2).contains(&U256::from(5))); // Other hotkeys should remain }); } @@ -552,7 +552,7 @@ fn test_swap_hotkey_with_no_stake() { let mut weight = Weight::zero(); // Set up initial state with no stake - Owner::::insert(&old_hotkey, &coldkey); + Owner::::insert(old_hotkey, coldkey); assert_ok!(SubtensorModule::perform_hotkey_swap( &old_hotkey, @@ -562,12 +562,12 @@ fn test_swap_hotkey_with_no_stake() { )); // Check if ownership transferred - assert!(!Owner::::contains_key(&old_hotkey)); - assert_eq!(Owner::::get(&new_hotkey), coldkey); + assert!(!Owner::::contains_key(old_hotkey)); + assert_eq!(Owner::::get(new_hotkey), coldkey); // Ensure no unexpected changes in Stake - assert!(!Stake::::contains_key(&old_hotkey, &coldkey)); - assert!(!Stake::::contains_key(&new_hotkey, &coldkey)); + assert!(!Stake::::contains_key(old_hotkey, coldkey)); + assert!(!Stake::::contains_key(new_hotkey, coldkey)); }); } @@ -586,12 +586,12 @@ fn test_swap_hotkey_with_multiple_coldkeys_and_subnets() { // Set up initial state add_network(netuid1, 0, 1); add_network(netuid2, 0, 1); - Owner::::insert(&old_hotkey, &coldkey1); - Stake::::insert(&old_hotkey, &coldkey1, 100); - Stake::::insert(&old_hotkey, &coldkey2, 200); - IsNetworkMember::::insert(&old_hotkey, netuid1, true); - IsNetworkMember::::insert(&old_hotkey, netuid2, true); - TotalHotkeyStake::::insert(&old_hotkey, 300); + Owner::::insert(old_hotkey, coldkey1); + Stake::::insert(old_hotkey, coldkey1, 100); + Stake::::insert(old_hotkey, coldkey2, 200); + IsNetworkMember::::insert(old_hotkey, netuid1, true); + IsNetworkMember::::insert(old_hotkey, netuid2, true); + TotalHotkeyStake::::insert(old_hotkey, 300); assert_ok!(SubtensorModule::perform_hotkey_swap( &old_hotkey, @@ -601,24 +601,24 @@ fn test_swap_hotkey_with_multiple_coldkeys_and_subnets() { )); // Check ownership transfer - assert!(!Owner::::contains_key(&old_hotkey)); - assert_eq!(Owner::::get(&new_hotkey), coldkey1); + assert!(!Owner::::contains_key(old_hotkey)); + assert_eq!(Owner::::get(new_hotkey), coldkey1); // Check stake transfer - assert_eq!(Stake::::get(&new_hotkey, &coldkey1), 100); - assert_eq!(Stake::::get(&new_hotkey, &coldkey2), 200); - assert!(!Stake::::contains_key(&old_hotkey, &coldkey1)); - assert!(!Stake::::contains_key(&old_hotkey, &coldkey2)); + assert_eq!(Stake::::get(new_hotkey, coldkey1), 100); + assert_eq!(Stake::::get(new_hotkey, coldkey2), 200); + assert!(!Stake::::contains_key(old_hotkey, coldkey1)); + assert!(!Stake::::contains_key(old_hotkey, coldkey2)); // Check subnet membership transfer - assert!(IsNetworkMember::::get(&new_hotkey, netuid1)); - assert!(IsNetworkMember::::get(&new_hotkey, netuid2)); - assert!(!IsNetworkMember::::get(&old_hotkey, netuid1)); - assert!(!IsNetworkMember::::get(&old_hotkey, netuid2)); + assert!(IsNetworkMember::::get(new_hotkey, netuid1)); + assert!(IsNetworkMember::::get(new_hotkey, netuid2)); + assert!(!IsNetworkMember::::get(old_hotkey, netuid1)); + assert!(!IsNetworkMember::::get(old_hotkey, netuid2)); // Check total stake transfer - assert_eq!(TotalHotkeyStake::::get(&new_hotkey), 300); - assert!(!TotalHotkeyStake::::contains_key(&old_hotkey)); + assert_eq!(TotalHotkeyStake::::get(new_hotkey), 300); + assert!(!TotalHotkeyStake::::contains_key(old_hotkey)); }); } @@ -899,9 +899,9 @@ fn test_swap_hotkey_error_cases() { let wrong_coldkey = U256::from(4); // Set up initial state - Owner::::insert(&old_hotkey, &coldkey); + Owner::::insert(old_hotkey, coldkey); TotalNetworks::::put(1); - LastTxBlock::::insert(&coldkey, 0); + LastTxBlock::::insert(coldkey, 0); // Test not enough balance let swap_cost = SubtensorModule::get_key_swap_cost(); @@ -928,7 +928,7 @@ fn test_swap_hotkey_error_cases() { ); // Test new hotkey already registered - IsNetworkMember::::insert(&new_hotkey, 0, true); + IsNetworkMember::::insert(new_hotkey, 0, true); assert_noop!( SubtensorModule::do_swap_hotkey( RuntimeOrigin::signed(coldkey), @@ -937,7 +937,7 @@ fn test_swap_hotkey_error_cases() { ), Error::::HotKeyAlreadyRegisteredInSubNet ); - IsNetworkMember::::remove(&new_hotkey, 0); + IsNetworkMember::::remove(new_hotkey, 0); // Test non-associated coldkey assert_noop!( @@ -958,7 +958,7 @@ fn test_swap_hotkey_error_cases() { // Check balance after swap assert_eq!( - Balances::free_balance(&coldkey), + Balances::free_balance(coldkey), initial_balance - swap_cost ); }); From 336321f122c3a7dc6f867cac18c34890665c937d Mon Sep 17 00:00:00 2001 From: const Date: Mon, 22 Jul 2024 18:00:34 -0500 Subject: [PATCH 33/58] clean coldkey swap --- pallets/subtensor/src/lib.rs | 8 +- .../src/{swap.rs => swap_coldkey.rs} | 673 +++++++++--------- pallets/subtensor/src/swap_hotkey.rs | 1 + .../tests/{swap.rs => swap_coldkey.rs} | 418 ++++++++++- 4 files changed, 733 insertions(+), 367 deletions(-) rename pallets/subtensor/src/{swap.rs => swap_coldkey.rs} (50%) rename pallets/subtensor/tests/{swap.rs => swap_coldkey.rs} (63%) diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index daaf20b00..baed738ea 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -44,7 +44,7 @@ mod registration; mod root; mod serving; mod staking; -mod swap; +mod swap_coldkey; mod swap_hotkey; mod uids; mod utils; @@ -726,7 +726,7 @@ pub mod pallet { #[pallet::storage] // --- MAP ( netuid ) --> last_mechanism_step_block pub type LastMechansimStepBlock = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultLastMechanismStepBlock>; - #[pallet::storage] // --- MAP ( netuid ) --> subnet_owner + #[pallet::storage] // --- MAP ( netuid ) --> (cold) subnet_owner pub type SubnetOwner = StorageMap<_, Identity, u16, T::AccountId, ValueQuery, DefaultSubnetOwner>; #[pallet::storage] // --- MAP ( netuid ) --> subnet_locked @@ -801,10 +801,10 @@ pub mod pallet { #[pallet::storage] // --- ITEM ( tx_rate_limit ) pub type TxDelegateTakeRateLimit = StorageValue<_, u64, ValueQuery, DefaultTxDelegateTakeRateLimit>; - #[pallet::storage] // --- MAP ( key ) --> last_block + #[pallet::storage] // --- MAP ( hotkey ) --> last_block pub type LastTxBlock = StorageMap<_, Identity, T::AccountId, u64, ValueQuery, DefaultLastTxBlock>; - #[pallet::storage] // --- MAP ( key ) --> last_block + #[pallet::storage] // --- MAP ( hotkey ) --> last_block pub type LastTxBlockDelegateTake = StorageMap<_, Identity, T::AccountId, u64, ValueQuery, DefaultLastTxBlock>; diff --git a/pallets/subtensor/src/swap.rs b/pallets/subtensor/src/swap_coldkey.rs similarity index 50% rename from pallets/subtensor/src/swap.rs rename to pallets/subtensor/src/swap_coldkey.rs index b6b0e9ba7..9a5ad515b 100644 --- a/pallets/subtensor/src/swap.rs +++ b/pallets/subtensor/src/swap_coldkey.rs @@ -1,17 +1,16 @@ + use super::*; use crate::MIN_BALANCE_TO_PERFORM_COLDKEY_SWAP; -use frame_support::traits::fungible::Mutate; -use frame_support::traits::tokens::Preservation; -use frame_support::{storage::IterableStorageDoubleMap, weights::Weight}; +use frame_support::weights::Weight; use sp_core::{Get, U256}; impl Pallet { + /// Swaps the coldkey associated with a set of hotkeys from an old coldkey to a new coldkey. /// /// # Arguments /// /// * `origin` - The origin of the call, which must be signed by the old coldkey. - /// * `old_coldkey` - The account ID of the old coldkey. /// * `new_coldkey` - The account ID of the new coldkey. /// /// # Returns @@ -21,10 +20,9 @@ impl Pallet { /// # Errors /// /// This function will return an error if: - /// - The caller is not the old coldkey. - /// - The new coldkey is the same as the old coldkey. - /// - The new coldkey is already associated with other hotkeys. - /// - The transaction rate limit for coldkey swaps has been exceeded. + /// - The caller is not a valid signed origin. + /// - The old coldkey (caller) is in arbitration. + /// - The new coldkey is already associated with other hotkeys or is a hotkey itself. /// - There's not enough balance to pay for the swap. /// /// # Events @@ -38,56 +36,201 @@ impl Pallet { origin: T::RuntimeOrigin, new_coldkey: &T::AccountId, ) -> DispatchResultWithPostInfo { + // 1. Ensure the origin is signed and get the old coldkey let old_coldkey = ensure_signed(origin)?; + + // 2. Check if the old coldkey is in arbitration ensure!( !Self::coldkey_in_arbitration(&old_coldkey), Error::::ColdkeyIsInArbitration ); + // 3. Initialize the weight for this operation let mut weight: Weight = T::DbWeight::get().reads(2); - // Check that the coldkey is a new key (does not exist elsewhere.) + // 4. Ensure the new coldkey is not associated with any hotkeys ensure!( - !Self::coldkey_has_associated_hotkeys(new_coldkey), + StakingHotkeys::::get(new_coldkey).is_empty(), Error::::ColdKeyAlreadyAssociated ); - // Check that the new coldkey is not a hotkey. + + // 5. Ensure the new coldkey is not a hotkey ensure!( !Self::hotkey_account_exists(new_coldkey), Error::::ColdKeyAlreadyAssociated ); - // Calculate and charge the swap fee + // 6. Calculate the swap cost and ensure sufficient balance let swap_cost = Self::get_key_swap_cost(); log::debug!("Coldkey swap cost: {:?}", swap_cost); - ensure!( Self::can_remove_balance_from_coldkey_account(&old_coldkey, swap_cost), Error::::NotEnoughBalanceToPaySwapColdKey ); - let actual_burn_amount = - Self::remove_balance_from_coldkey_account(&old_coldkey, swap_cost)?; + + // 7. Remove and burn the swap cost from the old coldkey's account + let actual_burn_amount = Self::remove_balance_from_coldkey_account(&old_coldkey, swap_cost)?; Self::burn_tokens(actual_burn_amount); + // 8. Update the weight for the balance operations weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); - // Actually do the swap. - weight = weight.saturating_add( - Self::perform_swap_coldkey(&old_coldkey, new_coldkey) - .map_err(|_| Error::::ColdkeySwapError)?, - ); + // 9. Perform the actual coldkey swap + let _ = Self::perform_swap_coldkey(&old_coldkey, new_coldkey, &mut weight); + // 10. Update the last transaction block for the new coldkey Self::set_last_tx_block(new_coldkey, Self::get_current_block_as_u64()); weight.saturating_accrue(T::DbWeight::get().writes(1)); + // 11. Emit the ColdkeySwapped event Self::deposit_event(Event::ColdkeySwapped { old_coldkey: old_coldkey.clone(), new_coldkey: new_coldkey.clone(), }); + // 12. Return the result with the updated weight Ok(Some(weight).into()) } + + /// Performs the actual coldkey swap operation, transferring all associated data and balances from the old coldkey to the new coldkey. + /// + /// # Arguments + /// + /// * `old_coldkey` - The account ID of the old coldkey. + /// * `new_coldkey` - The account ID of the new coldkey. + /// * `weight` - A mutable reference to the current transaction weight. + /// + /// # Returns + /// + /// Returns a `DispatchResult` indicating success or failure of the operation. + /// + /// # Steps + /// + /// 1. Swap TotalHotkeyColdkeyStakesThisInterval: + /// - For each hotkey owned by the old coldkey, transfer its stake and block data to the new coldkey. + /// + /// 2. Swap subnet ownership: + /// - For each subnet, if the old coldkey is the owner, transfer ownership to the new coldkey. + /// + /// 3. Swap Stakes: + /// - For each hotkey staking for the old coldkey, transfer its stake to the new coldkey. + /// + /// 4. Swap total coldkey stake: + /// - Transfer the total stake from the old coldkey to the new coldkey. + /// + /// 5. Swap StakingHotkeys: + /// - Transfer the list of staking hotkeys from the old coldkey to the new coldkey. + /// + /// 6. Swap hotkey owners: + /// - For each hotkey owned by the old coldkey, transfer ownership to the new coldkey. + /// - Update the list of owned hotkeys for both old and new coldkeys. + /// + /// 7. Transfer remaining balance: + /// - Transfer any remaining balance from the old coldkey to the new coldkey. + /// + /// Throughout the process, the function updates the transaction weight to reflect the operations performed. + /// + /// # Notes + /// + /// This function is a critical part of the coldkey swap process and should be called only after all necessary checks and validations have been performed. + pub fn perform_swap_coldkey( old_coldkey: &T::AccountId, new_coldkey: &T::AccountId, weight: &mut Weight ) -> DispatchResult { + + // 1. Swap TotalHotkeyColdkeyStakesThisInterval + // TotalHotkeyColdkeyStakesThisInterval: MAP ( hotkey, coldkey ) --> ( stake, block ) | Stake of the hotkey for the coldkey. + for hotkey in OwnedHotkeys::::get(old_coldkey).iter() { + let (stake, block) = TotalHotkeyColdkeyStakesThisInterval::::get(&hotkey, old_coldkey); + TotalHotkeyColdkeyStakesThisInterval::::remove(&hotkey, old_coldkey); + TotalHotkeyColdkeyStakesThisInterval::::insert(&hotkey, new_coldkey, (stake, block)); + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); + } + + // 2. Swap subnet owner. + // SubnetOwner: MAP ( netuid ) --> (coldkey) | Owner of the subnet. + for netuid in Self::get_all_subnet_netuids() { + let subnet_owner = SubnetOwner::::get(netuid); + if subnet_owner == *old_coldkey { + SubnetOwner::::insert(netuid, new_coldkey.clone()); + } + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); + } + + // 3. Swap Stake. + // Stake: MAP ( hotkey, coldkey ) --> u64 | Stake of the hotkey for the coldkey. + for hotkey in StakingHotkeys::::get( old_coldkey ) { + // Get the stake on the old (hot,coldkey) account. + let old_stake: u64 = Stake::::get( &hotkey, old_coldkey ); + // Get the stake on the new (hot,coldkey) account. + let new_stake: u64 = Stake::::get( &hotkey, new_coldkey ); + // Add the stake to new account. + Stake::::insert(&hotkey, new_coldkey, new_stake.saturating_add(old_stake)); + // Remove the value from the old account. + Stake::::remove(&hotkey, old_coldkey); + // Add the weight for the read and write. + weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2)); + } + + // 4. Swap total coldkey stake. + // TotalColdkeyStake: MAP ( coldkey ) --> u64 | Total stake of the coldkey. + let old_coldkey_stake: u64 = TotalColdkeyStake::::get(old_coldkey); + // Get the stake of the new coldkey. + let new_coldkey_stake: u64 = TotalColdkeyStake::::get(new_coldkey); + // Remove the value from the old account. + TotalColdkeyStake::::insert(old_coldkey, 0); + // Add the stake to new account. + TotalColdkeyStake::::insert(new_coldkey, new_coldkey_stake.saturating_add(old_coldkey_stake) ); + weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2)); + + // 5. Swap StakingHotkeys. + // StakingHotkeys: MAP ( coldkey ) --> Vec | Hotkeys staking for the coldkey. + let old_staking_hotkeys: Vec = StakingHotkeys::::get(old_coldkey); + let mut new_staking_hotkeys: Vec = StakingHotkeys::::get( new_coldkey ); + for hotkey in old_staking_hotkeys { + // If the hotkey is not already in the new coldkey, add it. + if !new_staking_hotkeys.contains(&hotkey) { + new_staking_hotkeys.push(hotkey); + } + } + StakingHotkeys::::remove(old_coldkey); + StakingHotkeys::::insert(new_coldkey, new_staking_hotkeys); + weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2)); + + // 6. Swap hotkey owners. + // Owner: MAP ( hotkey ) --> coldkey | Owner of the hotkey. + // OwnedHotkeys: MAP ( coldkey ) --> Vec | Hotkeys owned by the coldkey. + let old_owned_hotkeys: Vec = OwnedHotkeys::::get(old_coldkey); + let mut new_owned_hotkeys: Vec = OwnedHotkeys::::get(new_coldkey); + for owned_hotkey in old_owned_hotkeys.iter() { + // Remove the hotkey from the old coldkey. + Owner::::remove(owned_hotkey); + // Add the hotkey to the new coldkey. + Owner::::insert(owned_hotkey, new_coldkey.clone()); + // Addd the owned hotkey to the new set of owned hotkeys. + if !new_owned_hotkeys.contains(owned_hotkey) { + new_owned_hotkeys.push(owned_hotkey.clone()); + } + } + OwnedHotkeys::::remove(old_coldkey); + OwnedHotkeys::::insert(new_coldkey, new_owned_hotkeys); + weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2)); + + // 7. Transfer remaining balance. + // Balance: MAP ( coldkey ) --> u64 | Balance of the coldkey. + // Transfer any remaining balance from old_coldkey to new_coldkey + let remaining_balance = Self::get_coldkey_balance(old_coldkey); + if remaining_balance > 0 { + if let Err(e) = Self::kill_coldkey_account(old_coldkey, remaining_balance) { + return Err(e.into()); + } + Self::add_balance_to_coldkey_account(new_coldkey, remaining_balance); + } + weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2)); + + // Return ok. + Ok(()) + } + + /// Checks if a coldkey is currently in arbitration. /// /// # Arguments @@ -303,334 +446,178 @@ impl Pallet { // Only remove ColdkeySwapDestinations if there's a single destination ColdkeySwapDestinations::::remove(&coldkey_i); weight_used = weight_used.saturating_add(T::DbWeight::get().writes(1)); - Self::perform_swap_coldkey(coldkey_i, new_coldkey).map(|weight| { - weight_used = weight_used.saturating_add(weight); - keys_swapped = keys_swapped.saturating_add(1); - })?; + keys_swapped = keys_swapped.saturating_add(1); + let _ = Self::perform_swap_coldkey(coldkey_i, new_coldkey, &mut weight_used); } } Ok(weight_used) } - pub fn perform_swap_coldkey( - old_coldkey: &T::AccountId, - new_coldkey: &T::AccountId, - ) -> Result { - log::info!( - "Performing swap for coldkey: {:?} to {:?}", - old_coldkey, - new_coldkey - ); - // Init the weight. - let mut weight = frame_support::weights::Weight::from_parts(0, 0); - - // Swap coldkey references in storage maps - // NOTE The order of these calls is important - Self::swap_stake_for_coldkey(old_coldkey, new_coldkey, &mut weight); - Self::swap_total_hotkey_coldkey_stakes_this_interval_for_coldkey( - old_coldkey, - new_coldkey, - &mut weight, - ); - Self::swap_subnet_owner_for_coldkey(old_coldkey, new_coldkey, &mut weight); - - // Transfer any remaining balance from old_coldkey to new_coldkey - let remaining_balance = Self::get_coldkey_balance(old_coldkey); - if remaining_balance > 0 { - if let Err(e) = Self::kill_coldkey_account(old_coldkey, remaining_balance) { - return Err(e.into()); - } - Self::add_balance_to_coldkey_account(new_coldkey, remaining_balance); - } - - // Swap the coldkey. - let total_balance: u64 = Self::get_coldkey_balance(old_coldkey); - if total_balance > 0 { - // Attempt to transfer the entire total balance to new_coldkey. - T::Currency::transfer( - old_coldkey, - new_coldkey, - total_balance, - Preservation::Expendable, - )?; - } - Ok(weight) - } - /// Retrieves the network membership status for a given hotkey. - /// - /// # Arguments - /// - /// * `old_hotkey` - The hotkey to check for network membership. - /// - /// # Returns - /// - /// * `Vec` - A vector of network IDs where the hotkey is a member. - pub fn get_netuid_is_member(old_hotkey: &T::AccountId, weight: &mut Weight) -> Vec { - let netuid_is_member: Vec = - as IterableStorageDoubleMap<_, _, _>>::iter_prefix(old_hotkey) - .map(|(netuid, _)| netuid) - .collect(); - weight.saturating_accrue(T::DbWeight::get().reads(netuid_is_member.len() as u64)); - netuid_is_member - } - - /// Swaps the total stake associated with a coldkey from the old coldkey to the new coldkey. - /// - /// # Arguments - /// - /// * `old_coldkey` - The AccountId of the old coldkey. - /// * `new_coldkey` - The AccountId of the new coldkey. - /// * `weight` - Mutable reference to the weight of the transaction. - /// - /// # Effects - /// - /// * Removes the total stake from the old coldkey. - /// * Inserts the total stake for the new coldkey. - /// * Updates the transaction weight. - pub fn swap_total_coldkey_stake( - old_coldkey: &T::AccountId, - new_coldkey: &T::AccountId, - weight: &mut Weight, - ) { - let stake = TotalColdkeyStake::::get(old_coldkey); - TotalColdkeyStake::::remove(old_coldkey); - TotalColdkeyStake::::insert(new_coldkey, stake); - weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); - } - - /// Swaps the stake associated with a coldkey from the old coldkey to the new coldkey. - /// - /// # Arguments - /// - /// * `old_coldkey` - The AccountId of the old coldkey. - /// * `new_coldkey` - The AccountId of the new coldkey. - /// * `weight` - Mutable reference to the weight of the transaction. - /// - /// # Effects - /// - /// * Transfers all stakes from the old coldkey to the new coldkey. - /// * Updates the ownership of hotkeys. - /// * Updates the total stake for both old and new coldkeys. - /// * Updates the transaction weight. - /// - - pub fn swap_stake_for_coldkey( - old_coldkey: &T::AccountId, - new_coldkey: &T::AccountId, - weight: &mut Weight, - ) { - // Retrieve the list of hotkeys owned by the old coldkey - let old_owned_hotkeys: Vec = OwnedHotkeys::::get(old_coldkey); - - // Initialize the total transferred stake to zero - let mut total_transferred_stake: u64 = 0u64; - - // Log the total stake of old and new coldkeys before the swap - log::info!( - "Before swap - Old coldkey total stake: {}", - TotalColdkeyStake::::get(old_coldkey) - ); - log::info!( - "Before swap - New coldkey total stake: {}", - TotalColdkeyStake::::get(new_coldkey) - ); - - // Iterate over each hotkey owned by the old coldkey - for hotkey in old_owned_hotkeys.iter() { - // Retrieve and remove the stake associated with the hotkey and old coldkey - let stake: u64 = Stake::::take(hotkey, old_coldkey); - log::info!("Transferring stake for hotkey {:?}: {}", hotkey, stake); - if stake > 0 { - // Insert the stake for the hotkey and new coldkey - let old_stake = Stake::::get(hotkey, new_coldkey); - Stake::::insert(hotkey, new_coldkey, stake.saturating_add(old_stake)); - total_transferred_stake = total_transferred_stake.saturating_add(stake); - - // Update the owner of the hotkey to the new coldkey - Owner::::insert(hotkey, new_coldkey); - - // Update the transaction weight - weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2)); - } - } - log::info!( - "Starting transfer of delegated stakes for old coldkey: {:?}", - old_coldkey - ); - - for staking_hotkey in StakingHotkeys::::get(old_coldkey) { - log::info!("Processing staking hotkey: {:?}", staking_hotkey); - if Stake::::contains_key(staking_hotkey.clone(), old_coldkey) { - let hotkey = &staking_hotkey; - // Retrieve and remove the stake associated with the hotkey and old coldkey - let stake: u64 = Stake::::get(hotkey, old_coldkey); - Stake::::remove(hotkey, old_coldkey); - log::info!( - "Transferring delegated stake for hotkey {:?}: {}", - hotkey, - stake - ); - if stake > 0 { - // Insert the stake for the hotkey and new coldkey - let old_stake = Stake::::get(hotkey, new_coldkey); - Stake::::insert(hotkey, new_coldkey, stake.saturating_add(old_stake)); - total_transferred_stake = total_transferred_stake.saturating_add(stake); - log::info!( - "Updated stake for hotkey {:?} under new coldkey {:?}: {}", - hotkey, - new_coldkey, - stake.saturating_add(old_stake) - ); - - // Update the transaction weight - weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 1)); - } - } else { - log::info!( - "No stake found for staking hotkey {:?} under old coldkey {:?}", - staking_hotkey, - old_coldkey - ); - weight.saturating_accrue(T::DbWeight::get().reads(1)); - } - } - - log::info!( - "Completed transfer of delegated stakes for old coldkey: {:?}", - old_coldkey - ); - - // Log the total transferred stake - log::info!("Total transferred stake: {}", total_transferred_stake); - - // Update the total stake for both old and new coldkeys if any stake was transferred - if total_transferred_stake > 0 { - let old_coldkey_stake: u64 = TotalColdkeyStake::::take(old_coldkey); // Remove it here. - let new_coldkey_stake: u64 = TotalColdkeyStake::::get(new_coldkey); - - TotalColdkeyStake::::insert(old_coldkey, 0); - TotalColdkeyStake::::insert( - new_coldkey, - new_coldkey_stake.saturating_add(old_coldkey_stake), - ); - - log::info!("Updated old coldkey stake from {} to 0", old_coldkey_stake); - log::info!( - "Updated new coldkey stake from {} to {}", - new_coldkey_stake, - new_coldkey_stake.saturating_add(old_coldkey_stake) - ); - - // Update the transaction weight - weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2)); - } - - // Update the list of owned hotkeys for both old and new coldkeys - - let mut new_owned_hotkeys = OwnedHotkeys::::get(new_coldkey); - for hotkey in old_owned_hotkeys { - if !new_owned_hotkeys.contains(&hotkey) { - new_owned_hotkeys.push(hotkey); - } - } - - OwnedHotkeys::::insert(new_coldkey, new_owned_hotkeys); - OwnedHotkeys::::remove(old_coldkey); - weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); - - // Update the staking hotkeys for both old and new coldkeys - let staking_hotkeys: Vec = StakingHotkeys::::get(old_coldkey); - - let mut existing_staking_hotkeys = StakingHotkeys::::get(new_coldkey); - for hotkey in staking_hotkeys { - if !existing_staking_hotkeys.contains(&hotkey) { - existing_staking_hotkeys.push(hotkey); - } - } - - StakingHotkeys::::remove(old_coldkey); - StakingHotkeys::::insert(new_coldkey, existing_staking_hotkeys); - weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); - - // Log the total stake of old and new coldkeys after the swap - log::info!( - "After swap - Old coldkey total stake: {}", - TotalColdkeyStake::::get(old_coldkey) - ); - log::info!( - "After swap - New coldkey total stake: {}", - TotalColdkeyStake::::get(new_coldkey) - ); - } - - /// Swaps the total hotkey-coldkey stakes for the current interval from the old coldkey to the new coldkey. - /// - /// # Arguments - /// - /// * `old_coldkey` - The AccountId of the old coldkey. - /// * `new_coldkey` - The AccountId of the new coldkey. - /// * `weight` - Mutable reference to the weight of the transaction. - /// - /// # Effects - /// - /// * Removes all total hotkey-coldkey stakes for the current interval associated with the old coldkey. - /// * Inserts all total hotkey-coldkey stakes for the current interval for the new coldkey. - /// * Updates the transaction weight. - pub fn swap_total_hotkey_coldkey_stakes_this_interval_for_coldkey( - old_coldkey: &T::AccountId, - new_coldkey: &T::AccountId, - weight: &mut Weight, - ) { - weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 0)); - for hotkey in OwnedHotkeys::::get(old_coldkey).iter() { - let (stake, block) = - TotalHotkeyColdkeyStakesThisInterval::::get(&hotkey, old_coldkey); - TotalHotkeyColdkeyStakesThisInterval::::remove(&hotkey, old_coldkey); - TotalHotkeyColdkeyStakesThisInterval::::insert(&hotkey, new_coldkey, (stake, block)); - weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2)); - } - } - - /// Checks if a coldkey has any associated hotkeys. - /// - /// # Arguments - /// - /// * `coldkey` - The AccountId of the coldkey to check. - /// - /// # Returns - /// - /// * `bool` - True if the coldkey has any associated hotkeys, false otherwise. - pub fn coldkey_has_associated_hotkeys(coldkey: &T::AccountId) -> bool { - !StakingHotkeys::::get(coldkey).is_empty() - } - - /// Swaps the subnet owner from the old coldkey to the new coldkey for all networks where the old coldkey is the owner. - /// - /// # Arguments - /// - /// * `old_coldkey` - The AccountId of the old coldkey. - /// * `new_coldkey` - The AccountId of the new coldkey. - /// * `weight` - Mutable reference to the weight of the transaction. - /// - /// # Effects - /// - /// * Updates the subnet owner to the new coldkey for all networks where the old coldkey was the owner. - /// * Updates the transaction weight. - pub fn swap_subnet_owner_for_coldkey( - old_coldkey: &T::AccountId, - new_coldkey: &T::AccountId, - weight: &mut Weight, - ) { - for netuid in 0..=TotalNetworks::::get() { - let subnet_owner = SubnetOwner::::get(netuid); - if subnet_owner == *old_coldkey { - SubnetOwner::::insert(netuid, new_coldkey.clone()); - weight.saturating_accrue(T::DbWeight::get().writes(1)); - } - } - weight.saturating_accrue(T::DbWeight::get().reads(TotalNetworks::::get() as u64)); - } -} + // /// Swaps the stake associated with a coldkey from the old coldkey to the new coldkey. + // /// + // /// # Arguments + // /// + // /// * `old_coldkey` - The AccountId of the old coldkey. + // /// * `new_coldkey` - The AccountId of the new coldkey. + // /// * `weight` - Mutable reference to the weight of the transaction. + // /// + // /// # Effects + // /// + // /// * Transfers all stakes from the old coldkey to the new coldkey. + // /// * Updates the ownership of hotkeys. + // /// * Updates the total stake for both old and new coldkeys. + // /// * Updates the transaction weight. + // /// + + // pub fn swap_stake_for_coldkey( + // old_coldkey: &T::AccountId, + // new_coldkey: &T::AccountId, + // weight: &mut Weight, + // ) { + // // Retrieve the list of hotkeys owned by the old coldkey + // let old_owned_hotkeys: Vec = OwnedHotkeys::::get(old_coldkey); + + // // Initialize the total transferred stake to zero + // let mut total_transferred_stake: u64 = 0u64; + + // // Log the total stake of old and new coldkeys before the swap + // log::info!( + // "Before swap - Old coldkey total stake: {}", + // TotalColdkeyStake::::get(old_coldkey) + // ); + // log::info!( + // "Before swap - New coldkey total stake: {}", + // TotalColdkeyStake::::get(new_coldkey) + // ); + + // // Iterate over each hotkey owned by the old coldkey + // for hotkey in old_owned_hotkeys.iter() { + // // Retrieve and remove the stake associated with the hotkey and old coldkey + // let stake: u64 = Stake::::take(hotkey, old_coldkey); + // log::info!("Transferring stake for hotkey {:?}: {}", hotkey, stake); + // if stake > 0 { + // // Insert the stake for the hotkey and new coldkey + // let old_stake = Stake::::get(hotkey, new_coldkey); + // Stake::::insert(hotkey, new_coldkey, stake.saturating_add(old_stake)); + // total_transferred_stake = total_transferred_stake.saturating_add(stake); + + // // Update the owner of the hotkey to the new coldkey + // Owner::::insert(hotkey, new_coldkey); + + // // Update the transaction weight + // weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2)); + // } + // } + // log::info!( + // "Starting transfer of delegated stakes for old coldkey: {:?}", + // old_coldkey + // ); + + // for staking_hotkey in StakingHotkeys::::get(old_coldkey) { + // log::info!("Processing staking hotkey: {:?}", staking_hotkey); + // if Stake::::contains_key(staking_hotkey.clone(), old_coldkey) { + // let hotkey = &staking_hotkey; + // // Retrieve and remove the stake associated with the hotkey and old coldkey + // let stake: u64 = Stake::::get(hotkey, old_coldkey); + // Stake::::remove(hotkey, old_coldkey); + // log::info!( + // "Transferring delegated stake for hotkey {:?}: {}", + // hotkey, + // stake + // ); + // if stake > 0 { + // // Insert the stake for the hotkey and new coldkey + // let old_stake = Stake::::get(hotkey, new_coldkey); + // Stake::::insert(hotkey, new_coldkey, stake.saturating_add(old_stake)); + // total_transferred_stake = total_transferred_stake.saturating_add(stake); + // log::info!( + // "Updated stake for hotkey {:?} under new coldkey {:?}: {}", + // hotkey, + // new_coldkey, + // stake.saturating_add(old_stake) + // ); + + // // Update the transaction weight + // weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 1)); + // } + // } else { + // log::info!( + // "No stake found for staking hotkey {:?} under old coldkey {:?}", + // staking_hotkey, + // old_coldkey + // ); + // weight.saturating_accrue(T::DbWeight::get().reads(1)); + // } + // } + + // log::info!( + // "Completed transfer of delegated stakes for old coldkey: {:?}", + // old_coldkey + // ); + + // // Log the total transferred stake + // log::info!("Total transferred stake: {}", total_transferred_stake); + + // // Update the total stake for both old and new coldkeys if any stake was transferred + // if total_transferred_stake > 0 { + // let old_coldkey_stake: u64 = TotalColdkeyStake::::take(old_coldkey); // Remove it here. + // let new_coldkey_stake: u64 = TotalColdkeyStake::::get(new_coldkey); + + // TotalColdkeyStake::::insert(old_coldkey, 0); + // TotalColdkeyStake::::insert( + // new_coldkey, + // new_coldkey_stake.saturating_add(old_coldkey_stake), + // ); + + // log::info!("Updated old coldkey stake from {} to 0", old_coldkey_stake); + // log::info!( + // "Updated new coldkey stake from {} to {}", + // new_coldkey_stake, + // new_coldkey_stake.saturating_add(old_coldkey_stake) + // ); + + // // Update the transaction weight + // weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2)); + // } + + // // Update the list of owned hotkeys for both old and new coldkeys + + // let mut new_owned_hotkeys = OwnedHotkeys::::get(new_coldkey); + // for hotkey in old_owned_hotkeys { + // if !new_owned_hotkeys.contains(&hotkey) { + // new_owned_hotkeys.push(hotkey); + // } + // } + + // OwnedHotkeys::::insert(new_coldkey, new_owned_hotkeys); + // OwnedHotkeys::::remove(old_coldkey); + // weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); + + // // Update the staking hotkeys for both old and new coldkeys + // let staking_hotkeys: Vec = StakingHotkeys::::get(old_coldkey); + + // let mut existing_staking_hotkeys = StakingHotkeys::::get(new_coldkey); + // for hotkey in staking_hotkeys { + // if !existing_staking_hotkeys.contains(&hotkey) { + // existing_staking_hotkeys.push(hotkey); + // } + // } + + // StakingHotkeys::::remove(old_coldkey); + // StakingHotkeys::::insert(new_coldkey, existing_staking_hotkeys); + // weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); + + // // Log the total stake of old and new coldkeys after the swap + // log::info!( + // "After swap - Old coldkey total stake: {}", + // TotalColdkeyStake::::get(old_coldkey) + // ); + // log::info!( + // "After swap - New coldkey total stake: {}", + // TotalColdkeyStake::::get(new_coldkey) + // ); + // } +} \ No newline at end of file diff --git a/pallets/subtensor/src/swap_hotkey.rs b/pallets/subtensor/src/swap_hotkey.rs index 5c3fecbba..46ba4546a 100644 --- a/pallets/subtensor/src/swap_hotkey.rs +++ b/pallets/subtensor/src/swap_hotkey.rs @@ -145,6 +145,7 @@ impl Pallet { coldkey: &T::AccountId, weight: &mut Weight, ) -> DispatchResult { + // 1. Swap owner. // Owner( hotkey ) -> coldkey -- the coldkey that owns the hotkey. Owner::::remove(old_hotkey); diff --git a/pallets/subtensor/tests/swap.rs b/pallets/subtensor/tests/swap_coldkey.rs similarity index 63% rename from pallets/subtensor/tests/swap.rs rename to pallets/subtensor/tests/swap_coldkey.rs index 0a3a85dff..0d1e652e6 100644 --- a/pallets/subtensor/tests/swap.rs +++ b/pallets/subtensor/tests/swap_coldkey.rs @@ -1,5 +1,4 @@ #![allow(unused, clippy::indexing_slicing, clippy::panic, clippy::unwrap_used)] - use codec::Encode; use frame_support::weights::Weight; use frame_support::{assert_err, assert_noop, assert_ok}; @@ -7,8 +6,383 @@ use frame_system::{Config, RawOrigin}; mod mock; use mock::*; use pallet_subtensor::*; +use sp_core::H256; use sp_core::U256; +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_coldkey -- test_swap_total_hotkey_coldkey_stakes_this_interval --exact --nocapture +#[test] +fn test_swap_total_hotkey_coldkey_stakes_this_interval() { + new_test_ext(1).execute_with(|| { + let old_coldkey = U256::from(1); + let new_coldkey = U256::from(2); + let hotkey = U256::from(3); + let stake = 100; + let block = 42; + + OwnedHotkeys::::insert(&old_coldkey, vec![hotkey]); + TotalHotkeyColdkeyStakesThisInterval::::insert(&hotkey, &old_coldkey, (stake, block)); + + let mut weight = Weight::zero(); + assert_ok!(SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight)); + + assert!(!TotalHotkeyColdkeyStakesThisInterval::::contains_key(&hotkey, &old_coldkey)); + assert_eq!(TotalHotkeyColdkeyStakesThisInterval::::get(&hotkey, &new_coldkey), (stake, block)); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_coldkey -- test_swap_subnet_owner --exact --nocapture +#[test] +fn test_swap_subnet_owner() { + new_test_ext(1).execute_with(|| { + let old_coldkey = U256::from(1); + let new_coldkey = U256::from(2); + let netuid = 1u16; + + add_network(netuid, 1, 0); + SubnetOwner::::insert(netuid, old_coldkey); + + let mut weight = Weight::zero(); + assert_ok!(SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight)); + + assert_eq!(SubnetOwner::::get(netuid), new_coldkey); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_coldkey -- test_swap_stake --exact --nocapture +#[test] +fn test_swap_stake() { + new_test_ext(1).execute_with(|| { + let old_coldkey = U256::from(1); + let new_coldkey = U256::from(2); + let hotkey = U256::from(3); + let stake = 100; + + StakingHotkeys::::insert(&old_coldkey, vec![hotkey]); + Stake::::insert(&hotkey, &old_coldkey, stake); + let mut weight = Weight::zero(); + assert_ok!(SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight)); + + assert!(!Stake::::contains_key(&hotkey, &old_coldkey)); + assert_eq!(Stake::::get(&hotkey, &new_coldkey), stake); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_coldkey -- test_swap_total_coldkey_stake --exact --nocapture +#[test] +fn test_swap_total_coldkey_stake() { + new_test_ext(1).execute_with(|| { + let old_coldkey = U256::from(1); + let new_coldkey = U256::from(2); + let stake = 100; + + TotalColdkeyStake::::insert(&old_coldkey, stake); + + let mut weight = Weight::zero(); + assert_ok!(SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight)); + + assert_eq!(TotalColdkeyStake::::get(&old_coldkey), 0); + assert_eq!(TotalColdkeyStake::::get(&new_coldkey), stake); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_coldkey -- test_swap_staking_hotkeys --exact --nocapture +#[test] +fn test_swap_staking_hotkeys() { + new_test_ext(1).execute_with(|| { + let old_coldkey = U256::from(1); + let new_coldkey = U256::from(2); + let hotkey = U256::from(3); + + StakingHotkeys::::insert(&old_coldkey, vec![hotkey]); + + let mut weight = Weight::zero(); + assert_ok!(SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight)); + + assert!(StakingHotkeys::::get(&old_coldkey).is_empty()); + assert_eq!(StakingHotkeys::::get(&new_coldkey), vec![hotkey]); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_coldkey -- test_swap_hotkey_owners --exact --nocapture +#[test] +fn test_swap_hotkey_owners() { + new_test_ext(1).execute_with(|| { + let old_coldkey = U256::from(1); + let new_coldkey = U256::from(2); + let hotkey = U256::from(3); + + Owner::::insert(&hotkey, &old_coldkey); + OwnedHotkeys::::insert(&old_coldkey, vec![hotkey]); + + let mut weight = Weight::zero(); + assert_ok!(SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight)); + + assert_eq!(Owner::::get(&hotkey), new_coldkey); + assert!(OwnedHotkeys::::get(&old_coldkey).is_empty()); + assert_eq!(OwnedHotkeys::::get(&new_coldkey), vec![hotkey]); + }); +} +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_coldkey -- test_transfer_remaining_balance --exact --nocapture +#[test] +fn test_transfer_remaining_balance() { + new_test_ext(1).execute_with(|| { + let old_coldkey = U256::from(1); + let new_coldkey = U256::from(2); + let balance = 100; + + SubtensorModule::add_balance_to_coldkey_account(&old_coldkey, balance); + + let mut weight = Weight::zero(); + assert_ok!(SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight)); + + assert_eq!(SubtensorModule::get_coldkey_balance(&old_coldkey), 0); + assert_eq!(SubtensorModule::get_coldkey_balance(&new_coldkey), balance); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_coldkey -- test_swap_with_no_stake --exact --nocapture +#[test] +fn test_swap_with_no_stake() { + new_test_ext(1).execute_with(|| { + let old_coldkey = U256::from(1); + let new_coldkey = U256::from(2); + + let mut weight = Weight::zero(); + assert_ok!(SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight)); + + assert_eq!(TotalColdkeyStake::::get(&old_coldkey), 0); + assert_eq!(TotalColdkeyStake::::get(&new_coldkey), 0); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_coldkey -- test_swap_with_multiple_hotkeys --exact --nocapture +#[test] +fn test_swap_with_multiple_hotkeys() { + new_test_ext(1).execute_with(|| { + let old_coldkey = U256::from(1); + let new_coldkey = U256::from(2); + let hotkey1 = U256::from(3); + let hotkey2 = U256::from(4); + + OwnedHotkeys::::insert(&old_coldkey, vec![hotkey1, hotkey2]); + + let mut weight = Weight::zero(); + assert_ok!(SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight)); + + assert!(OwnedHotkeys::::get(&old_coldkey).is_empty()); + assert_eq!(OwnedHotkeys::::get(&new_coldkey), vec![hotkey1, hotkey2]); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_coldkey -- test_swap_with_multiple_subnets --exact --nocapture +#[test] +fn test_swap_with_multiple_subnets() { + new_test_ext(1).execute_with(|| { + let old_coldkey = U256::from(1); + let new_coldkey = U256::from(2); + let netuid1 = 1u16; + let netuid2 = 2u16; + + add_network(netuid1, 1, 0); + add_network(netuid2, 1, 0); + SubnetOwner::::insert(netuid1, &old_coldkey); + SubnetOwner::::insert(netuid2, &old_coldkey); + + let mut weight = Weight::zero(); + assert_ok!(SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight)); + + assert_eq!(SubnetOwner::::get(netuid1), new_coldkey); + assert_eq!(SubnetOwner::::get(netuid2), new_coldkey); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_coldkey -- test_swap_with_zero_balance --exact --nocapture +#[test] +fn test_swap_with_zero_balance() { + new_test_ext(1).execute_with(|| { + let old_coldkey = U256::from(1); + let new_coldkey = U256::from(2); + + let mut weight = Weight::zero(); + assert_ok!(SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight)); + + assert_eq!(Balances::free_balance(&old_coldkey), 0); + assert_eq!(Balances::free_balance(&new_coldkey), 0); + }); +} + + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_coldkey -- test_swap_idempotency --exact --nocapture +#[test] +fn test_swap_idempotency() { + new_test_ext(1).execute_with(|| { + let old_coldkey = U256::from(1); + let new_coldkey = U256::from(2); + let stake = 100; + + TotalColdkeyStake::::insert(&old_coldkey, stake); + + let mut weight = Weight::zero(); + assert_ok!(SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight)); + assert_ok!(SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight)); + + assert_eq!(TotalColdkeyStake::::get(&old_coldkey), 0); + assert_eq!(TotalColdkeyStake::::get(&new_coldkey), stake); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_coldkey -- test_swap_with_max_values --exact --nocapture +#[test] +fn test_swap_with_max_values() { + new_test_ext(1).execute_with(|| { + let old_coldkey = U256::from(1); + let new_coldkey = U256::from(2); + let max_stake = u64::MAX; + + TotalColdkeyStake::::insert(&old_coldkey, max_stake); + + let mut weight = Weight::zero(); + assert_ok!(SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight)); + + assert_eq!(TotalColdkeyStake::::get(&old_coldkey), 0); + assert_eq!(TotalColdkeyStake::::get(&new_coldkey), max_stake); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_coldkey -- test_swap_with_non_existent_new_coldkey --exact --nocapture +#[test] +fn test_swap_with_non_existent_new_coldkey() { + new_test_ext(1).execute_with(|| { + let old_coldkey = U256::from(1); + let new_coldkey = U256::from(2); + let stake = 100; + + TotalColdkeyStake::::insert(&old_coldkey, stake); + + let mut weight = Weight::zero(); + assert_ok!(SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight)); + + assert_eq!(TotalColdkeyStake::::get(&old_coldkey), 0); + assert_eq!(TotalColdkeyStake::::get(&new_coldkey), stake); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_coldkey -- test_swap_with_overflow_in_stake_addition --exact --nocapture +#[test] +fn test_swap_with_overflow_in_stake_addition() { + new_test_ext(1).execute_with(|| { + let old_coldkey = U256::from(1); + let new_coldkey = U256::from(2); + let max_stake = u64::MAX; + + TotalColdkeyStake::::insert(&old_coldkey, max_stake); + TotalColdkeyStake::::insert(&new_coldkey, 1); + + let mut weight = Weight::zero(); + assert_ok!(SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight)); + + assert_eq!(TotalColdkeyStake::::get(&old_coldkey), 0); + assert_eq!(TotalColdkeyStake::::get(&new_coldkey), max_stake); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_coldkey -- test_swap_with_max_hotkeys --exact --nocapture +#[test] +fn test_swap_with_max_hotkeys() { + new_test_ext(1).execute_with(|| { + let old_coldkey = U256::from(1); + let new_coldkey = U256::from(2); + let max_hotkeys = 1000; + let hotkeys: Vec = (0..max_hotkeys).map(U256::from).collect(); + + OwnedHotkeys::::insert(&old_coldkey, hotkeys.clone()); + + let mut weight = Weight::zero(); + assert_ok!(SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight)); + + assert!(OwnedHotkeys::::get(&old_coldkey).is_empty()); + assert_eq!(OwnedHotkeys::::get(&new_coldkey), hotkeys); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_coldkey -- test_swap_effect_on_delegated_stake --exact --nocapture +#[test] +fn test_swap_effect_on_delegated_stake() { + new_test_ext(1).execute_with(|| { + let old_coldkey = U256::from(1); + let new_coldkey = U256::from(2); + let delegator = U256::from(3); + let hotkey = U256::from(4); + let stake = 100; + + StakingHotkeys::::insert(&old_coldkey, vec![hotkey]); + StakingHotkeys::::insert(&delegator, vec![hotkey]); + Stake::::insert(&hotkey, &old_coldkey, stake); + Stake::::insert(&hotkey, &delegator, stake); + + let mut weight = Weight::zero(); + assert_ok!(SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight)); + + assert_eq!(Stake::::get(&hotkey, &new_coldkey), stake); + assert_eq!(Stake::::get(&hotkey, &delegator), stake); + assert_eq!(Stake::::get(&hotkey, &old_coldkey), 0); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_coldkey -- test_swap_concurrent_modifications --exact --nocapture +#[test] +fn test_swap_concurrent_modifications() { + new_test_ext(1).execute_with(|| { + let old_coldkey = U256::from(1); + let new_coldkey = U256::from(2); + let hotkey = U256::from(3); + let netuid: u16 = 1; + let initial_stake = 100; + let additional_stake = 50; + + StakingHotkeys::::insert(&old_coldkey, vec![hotkey]); + Stake::::insert(&hotkey, &old_coldkey, initial_stake); + + // Simulate concurrent stake addition + add_network(netuid, 1,1); + SubtensorModule::add_balance_to_coldkey_account(&new_coldkey, additional_stake); + register_ok_neuron(netuid, hotkey, new_coldkey, 1001000); + assert_ok!(SubtensorModule::add_stake( + <::RuntimeOrigin>::signed(new_coldkey), + hotkey, + additional_stake + )); + + let mut weight = Weight::zero(); + assert_ok!(SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight)); + + assert_eq!(Stake::::get(&hotkey, &new_coldkey), initial_stake + additional_stake - 1); + assert!(!Stake::::contains_key(&hotkey, &old_coldkey)); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_coldkey -- test_swap_with_invalid_subnet_ownership --exact --nocapture +#[test] +fn test_swap_with_invalid_subnet_ownership() { + new_test_ext(1).execute_with(|| { + let old_coldkey = U256::from(1); + let new_coldkey = U256::from(2); + let netuid = 1u16; + + SubnetOwner::::insert(netuid, old_coldkey); + + // Simulate an invalid state where the subnet owner doesn't match the old_coldkey + SubnetOwner::::insert(netuid, U256::from(3)); + + let mut weight = Weight::zero(); + assert_ok!(SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight)); + + // The swap should not affect the mismatched subnet ownership + assert_eq!(SubnetOwner::::get(netuid), U256::from(3)); + }); +} + + #[test] fn test_do_swap_coldkey_success() { new_test_ext(1).execute_with(|| { @@ -180,7 +554,7 @@ fn test_swap_stake_for_coldkey() { let initial_total_stake = SubtensorModule::get_total_stake(); // Perform the swap - SubtensorModule::swap_stake_for_coldkey(&old_coldkey, &new_coldkey, &mut weight); + SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight); // Verify stake is additive, not replaced assert_eq!( @@ -222,6 +596,7 @@ fn test_swap_stake_for_coldkey() { }); } +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test swap_coldkey -- test_swap_staking_hotkeys_for_coldkey --exact --nocapture #[test] fn test_swap_staking_hotkeys_for_coldkey() { new_test_ext(1).execute_with(|| { @@ -248,7 +623,7 @@ fn test_swap_staking_hotkeys_for_coldkey() { TotalStake::::put(total_stake); // Perform the swap - SubtensorModule::swap_stake_for_coldkey(&old_coldkey, &new_coldkey, &mut weight); + SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight); // Verify StakingHotkeys transfer assert_eq!( @@ -259,6 +634,7 @@ fn test_swap_staking_hotkeys_for_coldkey() { }); } +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test swap_coldkey -- test_swap_delegated_stake_for_coldkey --exact --nocapture #[test] fn test_swap_delegated_stake_for_coldkey() { new_test_ext(1).execute_with(|| { @@ -291,7 +667,7 @@ fn test_swap_delegated_stake_for_coldkey() { let initial_total_stake = SubtensorModule::get_total_stake(); // Perform the swap - SubtensorModule::swap_stake_for_coldkey(&old_coldkey, &new_coldkey, &mut weight); + SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight); // Verify stake transfer assert_eq!(Stake::::get(hotkey1, new_coldkey), stake_amount1); @@ -321,6 +697,7 @@ fn test_swap_delegated_stake_for_coldkey() { }); } +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test swap_coldkey -- test_swap_total_hotkey_coldkey_stakes_this_interval_for_coldkey --exact --nocapture #[test] fn test_swap_total_hotkey_coldkey_stakes_this_interval_for_coldkey() { new_test_ext(1).execute_with(|| { @@ -340,7 +717,7 @@ fn test_swap_total_hotkey_coldkey_stakes_this_interval_for_coldkey() { OwnedHotkeys::::insert(old_coldkey, vec![hotkey1, hotkey2]); // Perform the swap - SubtensorModule::swap_total_hotkey_coldkey_stakes_this_interval_for_coldkey( + SubtensorModule::perform_swap_coldkey( &old_coldkey, &new_coldkey, &mut weight, @@ -363,13 +740,10 @@ fn test_swap_total_hotkey_coldkey_stakes_this_interval_for_coldkey() { old_coldkey, hotkey2 )); - - // Verify weight update - let expected_weight = ::DbWeight::get().reads_writes(5, 4); - assert_eq!(weight, expected_weight); }); } +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test swap_coldkey -- test_swap_subnet_owner_for_coldkey --exact --nocapture #[test] fn test_swap_subnet_owner_for_coldkey() { new_test_ext(1).execute_with(|| { @@ -380,6 +754,8 @@ fn test_swap_subnet_owner_for_coldkey() { let mut weight = Weight::zero(); // Initialize SubnetOwner for old_coldkey + add_network(netuid1, 13, 0); + add_network(netuid2, 14, 0); SubnetOwner::::insert(netuid1, old_coldkey); SubnetOwner::::insert(netuid2, old_coldkey); @@ -387,18 +763,15 @@ fn test_swap_subnet_owner_for_coldkey() { TotalNetworks::::put(3); // Perform the swap - SubtensorModule::swap_subnet_owner_for_coldkey(&old_coldkey, &new_coldkey, &mut weight); + SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight); // Verify the swap assert_eq!(SubnetOwner::::get(netuid1), new_coldkey); assert_eq!(SubnetOwner::::get(netuid2), new_coldkey); - - // Verify weight update - let expected_weight = ::DbWeight::get().reads_writes(3, 2); - assert_eq!(weight, expected_weight); }); } +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test swap_coldkey -- test_do_swap_coldkey_with_subnet_ownership --exact --nocapture #[test] fn test_do_swap_coldkey_with_subnet_ownership() { new_test_ext(1).execute_with(|| { @@ -432,7 +805,7 @@ fn test_do_swap_coldkey_with_subnet_ownership() { assert_eq!(SubnetOwner::::get(netuid), new_coldkey); }); } - +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test swap_coldkey -- test_coldkey_has_associated_hotkeys --exact --nocapture #[test] fn test_coldkey_has_associated_hotkeys() { new_test_ext(1).execute_with(|| { @@ -447,7 +820,7 @@ fn test_coldkey_has_associated_hotkeys() { }); } -// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test swap -- test_coldkey_swap_total --exact --nocapture +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test swap_coldkey -- test_coldkey_swap_total --exact --nocapture #[test] fn test_coldkey_swap_total() { new_test_ext(1).execute_with(|| { @@ -669,9 +1042,11 @@ fn test_coldkey_swap_total() { // Perform the swap let new_coldkey = U256::from(1100); assert_eq!(SubtensorModule::get_total_stake_for_coldkey(&coldkey), 600); + let mut weight = Weight::zero(); assert_ok!(SubtensorModule::perform_swap_coldkey( &coldkey, - &new_coldkey + &new_coldkey, + &mut weight )); assert_eq!( SubtensorModule::get_total_stake_for_coldkey(&new_coldkey), @@ -741,7 +1116,7 @@ fn test_coldkey_swap_total() { ); }); } - +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test swap_coldkey -- test_swap_senate_member --exact --nocapture #[test] fn test_swap_senate_member() { new_test_ext(1).execute_with(|| { @@ -787,7 +1162,7 @@ fn test_swap_senate_member() { }); } -// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test swap -- test_coldkey_delegations --exact --nocapture +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test swap_coldkey -- test_coldkey_delegations --exact --nocapture #[test] fn test_coldkey_delegations() { new_test_ext(1).execute_with(|| { @@ -809,9 +1184,11 @@ fn test_coldkey_delegations() { delegate, 100 )); + let mut weight = Weight::zero(); assert_ok!(SubtensorModule::perform_swap_coldkey( &coldkey, - &new_coldkey + &new_coldkey, + &mut weight )); assert_eq!(SubtensorModule::get_total_stake_for_hotkey(&delegate), 100); assert_eq!(SubtensorModule::get_total_stake_for_coldkey(&coldkey), 0); @@ -823,3 +1200,4 @@ fn test_coldkey_delegations() { assert_eq!(Stake::::get(delegate, coldkey), 0); }); } + From da1a9d2ddb71ded39207a130315a98bd41cd4071 Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Tue, 23 Jul 2024 10:11:19 -0400 Subject: [PATCH 34/58] fix clippy warnings --- pallets/subtensor/tests/swap_hotkey.rs | 204 ++++++++++++------------- 1 file changed, 102 insertions(+), 102 deletions(-) diff --git a/pallets/subtensor/tests/swap_hotkey.rs b/pallets/subtensor/tests/swap_hotkey.rs index 68f4ec49c..990382918 100644 --- a/pallets/subtensor/tests/swap_hotkey.rs +++ b/pallets/subtensor/tests/swap_hotkey.rs @@ -19,7 +19,7 @@ fn test_swap_owner() { let coldkey = U256::from(3); let mut weight = Weight::zero(); - Owner::::insert(&old_hotkey, &coldkey); + Owner::::insert(old_hotkey, coldkey); assert_ok!(SubtensorModule::perform_hotkey_swap( &old_hotkey, &new_hotkey, @@ -27,8 +27,8 @@ fn test_swap_owner() { &mut weight )); - assert!(!Owner::::contains_key(&old_hotkey)); - assert_eq!(Owner::::get(&new_hotkey), coldkey); + assert!(!Owner::::contains_key(old_hotkey)); + assert_eq!(Owner::::get(new_hotkey), coldkey); }); } @@ -41,7 +41,7 @@ fn test_swap_owned_hotkeys() { let coldkey = U256::from(3); let mut weight = Weight::zero(); - OwnedHotkeys::::insert(&coldkey, vec![old_hotkey]); + OwnedHotkeys::::insert(coldkey, vec![old_hotkey]); assert_ok!(SubtensorModule::perform_hotkey_swap( &old_hotkey, &new_hotkey, @@ -49,7 +49,7 @@ fn test_swap_owned_hotkeys() { &mut weight )); - let hotkeys = OwnedHotkeys::::get(&coldkey); + let hotkeys = OwnedHotkeys::::get(coldkey); assert!(!hotkeys.contains(&old_hotkey)); assert!(hotkeys.contains(&new_hotkey)); }); @@ -64,8 +64,8 @@ fn test_swap_total_hotkey_stake() { let coldkey = U256::from(3); let mut weight = Weight::zero(); - TotalHotkeyStake::::insert(&old_hotkey, 100); - TotalHotkeyStake::::insert(&new_hotkey, 50); + TotalHotkeyStake::::insert(old_hotkey, 100); + TotalHotkeyStake::::insert(new_hotkey, 50); assert_ok!(SubtensorModule::perform_hotkey_swap( &old_hotkey, &new_hotkey, @@ -73,8 +73,8 @@ fn test_swap_total_hotkey_stake() { &mut weight )); - assert!(!TotalHotkeyStake::::contains_key(&old_hotkey)); - assert_eq!(TotalHotkeyStake::::get(&new_hotkey), 150); + assert!(!TotalHotkeyStake::::contains_key(old_hotkey)); + assert_eq!(TotalHotkeyStake::::get(new_hotkey), 150); }); } @@ -87,7 +87,7 @@ fn test_swap_total_hotkey_coldkey_stakes_this_interval() { let coldkey = U256::from(3); let mut weight = Weight::zero(); - TotalHotkeyColdkeyStakesThisInterval::::insert(&old_hotkey, &coldkey, (100, 1000)); + TotalHotkeyColdkeyStakesThisInterval::::insert(old_hotkey, coldkey, (100, 1000)); assert_ok!(SubtensorModule::perform_hotkey_swap( &old_hotkey, &new_hotkey, @@ -96,11 +96,11 @@ fn test_swap_total_hotkey_coldkey_stakes_this_interval() { )); assert!(!TotalHotkeyColdkeyStakesThisInterval::::contains_key( - &old_hotkey, - &coldkey + old_hotkey, + coldkey )); assert_eq!( - TotalHotkeyColdkeyStakesThisInterval::::get(&new_hotkey, &coldkey), + TotalHotkeyColdkeyStakesThisInterval::::get(new_hotkey, coldkey), (100, 1000) ); }); @@ -115,7 +115,7 @@ fn test_swap_last_tx_block() { let coldkey = U256::from(3); let mut weight = Weight::zero(); - LastTxBlock::::insert(&old_hotkey, 1000); + LastTxBlock::::insert(old_hotkey, 1000); assert_ok!(SubtensorModule::perform_hotkey_swap( &old_hotkey, &new_hotkey, @@ -123,9 +123,9 @@ fn test_swap_last_tx_block() { &mut weight )); - assert!(!LastTxBlock::::contains_key(&old_hotkey)); + assert!(!LastTxBlock::::contains_key(old_hotkey)); assert_eq!( - LastTxBlock::::get(&new_hotkey), + LastTxBlock::::get(new_hotkey), SubtensorModule::get_current_block_as_u64() ); }); @@ -140,7 +140,7 @@ fn test_swap_last_tx_block_delegate_take() { let coldkey = U256::from(3); let mut weight = Weight::zero(); - pallet_subtensor::LastTxBlockDelegateTake::::insert(&old_hotkey, 1000); + pallet_subtensor::LastTxBlockDelegateTake::::insert(old_hotkey, 1000); assert_ok!(SubtensorModule::perform_hotkey_swap( &old_hotkey, &new_hotkey, @@ -148,9 +148,9 @@ fn test_swap_last_tx_block_delegate_take() { &mut weight )); - assert!(!LastTxBlockDelegateTake::::contains_key(&old_hotkey)); + assert!(!LastTxBlockDelegateTake::::contains_key(old_hotkey)); assert_eq!( - LastTxBlockDelegateTake::::get(&new_hotkey), + LastTxBlockDelegateTake::::get(new_hotkey), SubtensorModule::get_current_block_as_u64() ); }); @@ -189,7 +189,7 @@ fn test_swap_delegates() { let coldkey = U256::from(3); let mut weight = Weight::zero(); - Delegates::::insert(&old_hotkey, 100); + Delegates::::insert(old_hotkey, 100); assert_ok!(SubtensorModule::perform_hotkey_swap( &old_hotkey, &new_hotkey, @@ -197,8 +197,8 @@ fn test_swap_delegates() { &mut weight )); - assert!(!Delegates::::contains_key(&old_hotkey)); - assert_eq!(Delegates::::get(&new_hotkey), 100); + assert!(!Delegates::::contains_key(old_hotkey)); + assert_eq!(Delegates::::get(new_hotkey), 100); }); } @@ -213,7 +213,7 @@ fn test_swap_subnet_membership() { let mut weight = Weight::zero(); add_network(netuid, 0, 1); - IsNetworkMember::::insert(&old_hotkey, netuid, true); + IsNetworkMember::::insert(old_hotkey, netuid, true); assert_ok!(SubtensorModule::perform_hotkey_swap( &old_hotkey, &new_hotkey, @@ -221,8 +221,8 @@ fn test_swap_subnet_membership() { &mut weight )); - assert!(!IsNetworkMember::::contains_key(&old_hotkey, netuid)); - assert!(IsNetworkMember::::get(&new_hotkey, netuid)); + assert!(!IsNetworkMember::::contains_key(old_hotkey, netuid)); + assert!(IsNetworkMember::::get(new_hotkey, netuid)); }); } @@ -238,8 +238,8 @@ fn test_swap_uids_and_keys() { let mut weight = Weight::zero(); add_network(netuid, 0, 1); - IsNetworkMember::::insert(&old_hotkey, netuid, true); - Uids::::insert(netuid, &old_hotkey, uid); + IsNetworkMember::::insert(old_hotkey, netuid, true); + Uids::::insert(netuid, old_hotkey, uid); Keys::::insert(netuid, uid, old_hotkey); assert_ok!(SubtensorModule::perform_hotkey_swap( @@ -249,8 +249,8 @@ fn test_swap_uids_and_keys() { &mut weight )); - assert_eq!(Uids::::get(netuid, &old_hotkey), None); - assert_eq!(Uids::::get(netuid, &new_hotkey), Some(uid)); + assert_eq!(Uids::::get(netuid, old_hotkey), None); + assert_eq!(Uids::::get(netuid, new_hotkey), Some(uid)); assert_eq!(Keys::::get(netuid, uid), new_hotkey); }); } @@ -267,8 +267,8 @@ fn test_swap_prometheus() { let mut weight = Weight::zero(); add_network(netuid, 0, 1); - IsNetworkMember::::insert(&old_hotkey, netuid, true); - Prometheus::::insert(netuid, &old_hotkey, prometheus_info.clone()); + IsNetworkMember::::insert(old_hotkey, netuid, true); + Prometheus::::insert(netuid, old_hotkey, prometheus_info.clone()); assert_ok!(SubtensorModule::perform_hotkey_swap( &old_hotkey, @@ -277,9 +277,9 @@ fn test_swap_prometheus() { &mut weight )); - assert!(!Prometheus::::contains_key(netuid, &old_hotkey)); + assert!(!Prometheus::::contains_key(netuid, old_hotkey)); assert_eq!( - Prometheus::::get(netuid, &new_hotkey), + Prometheus::::get(netuid, new_hotkey), Some(prometheus_info) ); }); @@ -297,8 +297,8 @@ fn test_swap_axons() { let mut weight = Weight::zero(); add_network(netuid, 0, 1); - IsNetworkMember::::insert(&old_hotkey, netuid, true); - Axons::::insert(netuid, &old_hotkey, axon_info.clone()); + IsNetworkMember::::insert(old_hotkey, netuid, true); + Axons::::insert(netuid, old_hotkey, axon_info.clone()); assert_ok!(SubtensorModule::perform_hotkey_swap( &old_hotkey, @@ -307,8 +307,8 @@ fn test_swap_axons() { &mut weight )); - assert!(!Axons::::contains_key(netuid, &old_hotkey)); - assert_eq!(Axons::::get(netuid, &new_hotkey), Some(axon_info)); + assert!(!Axons::::contains_key(netuid, old_hotkey)); + assert_eq!(Axons::::get(netuid, new_hotkey), Some(axon_info)); }); } @@ -324,8 +324,8 @@ fn test_swap_weight_commits() { let mut weight = Weight::zero(); add_network(netuid, 0, 1); - IsNetworkMember::::insert(&old_hotkey, netuid, true); - WeightCommits::::insert(netuid, &old_hotkey, weight_commits.clone()); + IsNetworkMember::::insert(old_hotkey, netuid, true); + WeightCommits::::insert(netuid, old_hotkey, weight_commits); assert_ok!(SubtensorModule::perform_hotkey_swap( &old_hotkey, @@ -334,9 +334,9 @@ fn test_swap_weight_commits() { &mut weight )); - assert!(!WeightCommits::::contains_key(netuid, &old_hotkey)); + assert!(!WeightCommits::::contains_key(netuid, old_hotkey)); assert_eq!( - WeightCommits::::get(netuid, &new_hotkey), + WeightCommits::::get(netuid, new_hotkey), Some(weight_commits) ); }); @@ -355,7 +355,7 @@ fn test_swap_loaded_emission() { let mut weight = Weight::zero(); add_network(netuid, 0, 1); - IsNetworkMember::::insert(&old_hotkey, netuid, true); + IsNetworkMember::::insert(old_hotkey, netuid, true); LoadedEmission::::insert( netuid, vec![(old_hotkey, server_emission, validator_emission)], @@ -386,7 +386,7 @@ fn test_swap_stake() { let stake_amount = 100u64; let mut weight = Weight::zero(); - Stake::::insert(&old_hotkey, &coldkey, stake_amount); + Stake::::insert(old_hotkey, coldkey, stake_amount); assert_ok!(SubtensorModule::perform_hotkey_swap( &old_hotkey, @@ -395,8 +395,8 @@ fn test_swap_stake() { &mut weight )); - assert!(!Stake::::contains_key(&old_hotkey, &coldkey)); - assert_eq!(Stake::::get(&new_hotkey, &coldkey), stake_amount); + assert!(!Stake::::contains_key(old_hotkey, coldkey)); + assert_eq!(Stake::::get(new_hotkey, coldkey), stake_amount); }); } @@ -409,8 +409,8 @@ fn test_swap_staking_hotkeys() { let coldkey = U256::from(3); let mut weight = Weight::zero(); - Stake::::insert(&old_hotkey, &coldkey, 100); - StakingHotkeys::::insert(&coldkey, vec![old_hotkey]); + Stake::::insert(old_hotkey, coldkey, 100); + StakingHotkeys::::insert(coldkey, vec![old_hotkey]); assert_ok!(SubtensorModule::perform_hotkey_swap( &old_hotkey, @@ -419,7 +419,7 @@ fn test_swap_staking_hotkeys() { &mut weight )); - let staking_hotkeys = StakingHotkeys::::get(&coldkey); + let staking_hotkeys = StakingHotkeys::::get(coldkey); assert!(!staking_hotkeys.contains(&old_hotkey)); assert!(staking_hotkeys.contains(&new_hotkey)); }); @@ -435,10 +435,10 @@ fn test_swap_hotkey_with_multiple_coldkeys() { let coldkey2 = U256::from(4); let mut weight = Weight::zero(); - Stake::::insert(&old_hotkey, &coldkey1, 100); - Stake::::insert(&old_hotkey, &coldkey2, 200); - StakingHotkeys::::insert(&coldkey1, vec![old_hotkey]); - StakingHotkeys::::insert(&coldkey2, vec![old_hotkey]); + Stake::::insert(old_hotkey, coldkey1, 100); + Stake::::insert(old_hotkey, coldkey2, 200); + StakingHotkeys::::insert(coldkey1, vec![old_hotkey]); + StakingHotkeys::::insert(coldkey2, vec![old_hotkey]); assert_ok!(SubtensorModule::perform_hotkey_swap( &old_hotkey, @@ -447,10 +447,10 @@ fn test_swap_hotkey_with_multiple_coldkeys() { &mut weight )); - assert_eq!(Stake::::get(&new_hotkey, &coldkey1), 100); - assert_eq!(Stake::::get(&new_hotkey, &coldkey2), 200); - assert!(StakingHotkeys::::get(&coldkey1).contains(&new_hotkey)); - assert!(StakingHotkeys::::get(&coldkey2).contains(&new_hotkey)); + assert_eq!(Stake::::get(new_hotkey, coldkey1), 100); + assert_eq!(Stake::::get(new_hotkey, coldkey2), 200); + assert!(StakingHotkeys::::get(coldkey1).contains(&new_hotkey)); + assert!(StakingHotkeys::::get(coldkey2).contains(&new_hotkey)); }); } @@ -463,8 +463,8 @@ fn test_swap_hotkey_with_existing_stake() { let coldkey = U256::from(3); let mut weight = Weight::zero(); - Stake::::insert(&old_hotkey, &coldkey, 100); - Stake::::insert(&new_hotkey, &coldkey, 50); + Stake::::insert(old_hotkey, coldkey, 100); + Stake::::insert(new_hotkey, coldkey, 50); assert_ok!(SubtensorModule::perform_hotkey_swap( &old_hotkey, @@ -473,7 +473,7 @@ fn test_swap_hotkey_with_existing_stake() { &mut weight )); - assert_eq!(Stake::::get(&new_hotkey, &coldkey), 150); + assert_eq!(Stake::::get(new_hotkey, coldkey), 150); }); } @@ -490,8 +490,8 @@ fn test_swap_hotkey_with_multiple_subnets() { add_network(netuid1, 0, 1); add_network(netuid2, 0, 1); - IsNetworkMember::::insert(&old_hotkey, netuid1, true); - IsNetworkMember::::insert(&old_hotkey, netuid2, true); + IsNetworkMember::::insert(old_hotkey, netuid1, true); + IsNetworkMember::::insert(old_hotkey, netuid2, true); assert_ok!(SubtensorModule::perform_hotkey_swap( &old_hotkey, @@ -500,10 +500,10 @@ fn test_swap_hotkey_with_multiple_subnets() { &mut weight )); - assert!(IsNetworkMember::::get(&new_hotkey, netuid1)); - assert!(IsNetworkMember::::get(&new_hotkey, netuid2)); - assert!(!IsNetworkMember::::get(&old_hotkey, netuid1)); - assert!(!IsNetworkMember::::get(&old_hotkey, netuid2)); + assert!(IsNetworkMember::::get(new_hotkey, netuid1)); + assert!(IsNetworkMember::::get(new_hotkey, netuid2)); + assert!(!IsNetworkMember::::get(old_hotkey, netuid1)); + assert!(!IsNetworkMember::::get(old_hotkey, netuid2)); }); } @@ -518,10 +518,10 @@ fn test_swap_staking_hotkeys_multiple_coldkeys() { let mut weight = Weight::zero(); // Set up initial state - Stake::::insert(&old_hotkey, &coldkey1, 100); - Stake::::insert(&old_hotkey, &coldkey2, 200); - StakingHotkeys::::insert(&coldkey1, vec![old_hotkey]); - StakingHotkeys::::insert(&coldkey2, vec![old_hotkey, U256::from(5)]); + Stake::::insert(old_hotkey, coldkey1, 100); + Stake::::insert(old_hotkey, coldkey2, 200); + StakingHotkeys::::insert(coldkey1, vec![old_hotkey]); + StakingHotkeys::::insert(coldkey2, vec![old_hotkey, U256::from(5)]); assert_ok!(SubtensorModule::perform_hotkey_swap( &old_hotkey, @@ -531,13 +531,13 @@ fn test_swap_staking_hotkeys_multiple_coldkeys() { )); // Check if new_hotkey replaced old_hotkey in StakingHotkeys - assert!(StakingHotkeys::::get(&coldkey1).contains(&new_hotkey)); - assert!(!StakingHotkeys::::get(&coldkey1).contains(&old_hotkey)); + assert!(StakingHotkeys::::get(coldkey1).contains(&new_hotkey)); + assert!(!StakingHotkeys::::get(coldkey1).contains(&old_hotkey)); // Check if new_hotkey replaced old_hotkey for coldkey2 as well - assert!(StakingHotkeys::::get(&coldkey2).contains(&new_hotkey)); - assert!(!StakingHotkeys::::get(&coldkey2).contains(&old_hotkey)); - assert!(StakingHotkeys::::get(&coldkey2).contains(&U256::from(5))); + assert!(StakingHotkeys::::get(coldkey2).contains(&new_hotkey)); + assert!(!StakingHotkeys::::get(coldkey2).contains(&old_hotkey)); + assert!(StakingHotkeys::::get(coldkey2).contains(&U256::from(5))); // Other hotkeys should remain }); } @@ -552,7 +552,7 @@ fn test_swap_hotkey_with_no_stake() { let mut weight = Weight::zero(); // Set up initial state with no stake - Owner::::insert(&old_hotkey, &coldkey); + Owner::::insert(old_hotkey, coldkey); assert_ok!(SubtensorModule::perform_hotkey_swap( &old_hotkey, @@ -562,12 +562,12 @@ fn test_swap_hotkey_with_no_stake() { )); // Check if ownership transferred - assert!(!Owner::::contains_key(&old_hotkey)); - assert_eq!(Owner::::get(&new_hotkey), coldkey); + assert!(!Owner::::contains_key(old_hotkey)); + assert_eq!(Owner::::get(new_hotkey), coldkey); // Ensure no unexpected changes in Stake - assert!(!Stake::::contains_key(&old_hotkey, &coldkey)); - assert!(!Stake::::contains_key(&new_hotkey, &coldkey)); + assert!(!Stake::::contains_key(old_hotkey, coldkey)); + assert!(!Stake::::contains_key(new_hotkey, coldkey)); }); } @@ -586,12 +586,12 @@ fn test_swap_hotkey_with_multiple_coldkeys_and_subnets() { // Set up initial state add_network(netuid1, 0, 1); add_network(netuid2, 0, 1); - Owner::::insert(&old_hotkey, &coldkey1); - Stake::::insert(&old_hotkey, &coldkey1, 100); - Stake::::insert(&old_hotkey, &coldkey2, 200); - IsNetworkMember::::insert(&old_hotkey, netuid1, true); - IsNetworkMember::::insert(&old_hotkey, netuid2, true); - TotalHotkeyStake::::insert(&old_hotkey, 300); + Owner::::insert(old_hotkey, coldkey1); + Stake::::insert(old_hotkey, coldkey1, 100); + Stake::::insert(old_hotkey, coldkey2, 200); + IsNetworkMember::::insert(old_hotkey, netuid1, true); + IsNetworkMember::::insert(old_hotkey, netuid2, true); + TotalHotkeyStake::::insert(old_hotkey, 300); assert_ok!(SubtensorModule::perform_hotkey_swap( &old_hotkey, @@ -601,24 +601,24 @@ fn test_swap_hotkey_with_multiple_coldkeys_and_subnets() { )); // Check ownership transfer - assert!(!Owner::::contains_key(&old_hotkey)); - assert_eq!(Owner::::get(&new_hotkey), coldkey1); + assert!(!Owner::::contains_key(old_hotkey)); + assert_eq!(Owner::::get(new_hotkey), coldkey1); // Check stake transfer - assert_eq!(Stake::::get(&new_hotkey, &coldkey1), 100); - assert_eq!(Stake::::get(&new_hotkey, &coldkey2), 200); - assert!(!Stake::::contains_key(&old_hotkey, &coldkey1)); - assert!(!Stake::::contains_key(&old_hotkey, &coldkey2)); + assert_eq!(Stake::::get(new_hotkey, coldkey1), 100); + assert_eq!(Stake::::get(new_hotkey, coldkey2), 200); + assert!(!Stake::::contains_key(old_hotkey, coldkey1)); + assert!(!Stake::::contains_key(old_hotkey, coldkey2)); // Check subnet membership transfer - assert!(IsNetworkMember::::get(&new_hotkey, netuid1)); - assert!(IsNetworkMember::::get(&new_hotkey, netuid2)); - assert!(!IsNetworkMember::::get(&old_hotkey, netuid1)); - assert!(!IsNetworkMember::::get(&old_hotkey, netuid2)); + assert!(IsNetworkMember::::get(new_hotkey, netuid1)); + assert!(IsNetworkMember::::get(new_hotkey, netuid2)); + assert!(!IsNetworkMember::::get(old_hotkey, netuid1)); + assert!(!IsNetworkMember::::get(old_hotkey, netuid2)); // Check total stake transfer - assert_eq!(TotalHotkeyStake::::get(&new_hotkey), 300); - assert!(!TotalHotkeyStake::::contains_key(&old_hotkey)); + assert_eq!(TotalHotkeyStake::::get(new_hotkey), 300); + assert!(!TotalHotkeyStake::::contains_key(old_hotkey)); }); } @@ -899,9 +899,9 @@ fn test_swap_hotkey_error_cases() { let wrong_coldkey = U256::from(4); // Set up initial state - Owner::::insert(&old_hotkey, &coldkey); + Owner::::insert(old_hotkey, coldkey); TotalNetworks::::put(1); - LastTxBlock::::insert(&coldkey, 0); + LastTxBlock::::insert(coldkey, 0); // Test not enough balance let swap_cost = SubtensorModule::get_key_swap_cost(); @@ -928,7 +928,7 @@ fn test_swap_hotkey_error_cases() { ); // Test new hotkey already registered - IsNetworkMember::::insert(&new_hotkey, 0, true); + IsNetworkMember::::insert(new_hotkey, 0, true); assert_noop!( SubtensorModule::do_swap_hotkey( RuntimeOrigin::signed(coldkey), @@ -937,7 +937,7 @@ fn test_swap_hotkey_error_cases() { ), Error::::HotKeyAlreadyRegisteredInSubNet ); - IsNetworkMember::::remove(&new_hotkey, 0); + IsNetworkMember::::remove(new_hotkey, 0); // Test non-associated coldkey assert_noop!( @@ -958,7 +958,7 @@ fn test_swap_hotkey_error_cases() { // Check balance after swap assert_eq!( - Balances::free_balance(&coldkey), + Balances::free_balance(coldkey), initial_balance - swap_cost ); }); From 8e4bf4c763ddd0dd935b53558b6768f4f73b39b6 Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Tue, 23 Jul 2024 10:16:39 -0400 Subject: [PATCH 35/58] fmt --- pallets/subtensor/tests/swap_hotkey.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/pallets/subtensor/tests/swap_hotkey.rs b/pallets/subtensor/tests/swap_hotkey.rs index 990382918..c6a05f2b6 100644 --- a/pallets/subtensor/tests/swap_hotkey.rs +++ b/pallets/subtensor/tests/swap_hotkey.rs @@ -96,8 +96,7 @@ fn test_swap_total_hotkey_coldkey_stakes_this_interval() { )); assert!(!TotalHotkeyColdkeyStakesThisInterval::::contains_key( - old_hotkey, - coldkey + old_hotkey, coldkey )); assert_eq!( TotalHotkeyColdkeyStakesThisInterval::::get(new_hotkey, coldkey), @@ -957,9 +956,6 @@ fn test_swap_hotkey_error_cases() { )); // Check balance after swap - assert_eq!( - Balances::free_balance(coldkey), - initial_balance - swap_cost - ); + assert_eq!(Balances::free_balance(coldkey), initial_balance - swap_cost); }); } From ed729b644d229d3d9fe574997532db37d6e4d945 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 23 Jul 2024 09:03:50 -0700 Subject: [PATCH 36/58] Added --no-purge flag to scripts/localnet.sh to be able to save state when restarting a script. --- scripts/localnet.sh | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/scripts/localnet.sh b/scripts/localnet.sh index 65ca5c0a9..2856603e0 100755 --- a/scripts/localnet.sh +++ b/scripts/localnet.sh @@ -1,5 +1,14 @@ #!/bin/bash +# Check if `--no-purge` passed as a parameter +NO_PURGE=0 +for arg in "$@"; do + if [ "$arg" = "--no-purge" ]; then + NO_PURGE=1 + break + fi +done + # Determine the directory this script resides in. This allows invoking it from any location. SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd)" @@ -47,10 +56,14 @@ echo "*** Building chainspec..." "$BASE_DIR/target/release/node-subtensor" build-spec --disable-default-bootnode --raw --chain $CHAIN >$FULL_PATH echo "*** Chainspec built and output to file" -echo "*** Purging previous state..." -"$BASE_DIR/target/release/node-subtensor" purge-chain -y --base-path /tmp/bob --chain="$FULL_PATH" >/dev/null 2>&1 -"$BASE_DIR/target/release/node-subtensor" purge-chain -y --base-path /tmp/alice --chain="$FULL_PATH" >/dev/null 2>&1 -echo "*** Previous chainstate purged" +if [ $NO_PURGE -eq 1 ]; then + echo "*** Purging previous state skipped..." +else + echo "*** Purging previous state..." + "$BASE_DIR/target/release/node-subtensor" purge-chain -y --base-path /tmp/bob --chain="$FULL_PATH" >/dev/null 2>&1 + "$BASE_DIR/target/release/node-subtensor" purge-chain -y --base-path /tmp/alice --chain="$FULL_PATH" >/dev/null 2>&1 + echo "*** Previous chainstate purged" +fi echo "*** Starting localnet nodes..." alice_start=( From cf9869d480c6bc982acfe63f64279c53b4679805 Mon Sep 17 00:00:00 2001 From: const Date: Tue, 23 Jul 2024 13:23:43 -0500 Subject: [PATCH 37/58] pre merge --- pallets/subtensor/src/swap_coldkey.rs | 38 ++--- pallets/subtensor/src/swap_hotkey.rs | 1 - pallets/subtensor/tests/swap_coldkey.rs | 181 +++++++++++++++++------- pallets/subtensor/tests/swap_hotkey.rs | 8 +- 4 files changed, 155 insertions(+), 73 deletions(-) diff --git a/pallets/subtensor/src/swap_coldkey.rs b/pallets/subtensor/src/swap_coldkey.rs index 9a5ad515b..f8049cd6f 100644 --- a/pallets/subtensor/src/swap_coldkey.rs +++ b/pallets/subtensor/src/swap_coldkey.rs @@ -1,11 +1,9 @@ - use super::*; use crate::MIN_BALANCE_TO_PERFORM_COLDKEY_SWAP; use frame_support::weights::Weight; use sp_core::{Get, U256}; impl Pallet { - /// Swaps the coldkey associated with a set of hotkeys from an old coldkey to a new coldkey. /// /// # Arguments @@ -69,7 +67,8 @@ impl Pallet { ); // 7. Remove and burn the swap cost from the old coldkey's account - let actual_burn_amount = Self::remove_balance_from_coldkey_account(&old_coldkey, swap_cost)?; + let actual_burn_amount = + Self::remove_balance_from_coldkey_account(&old_coldkey, swap_cost)?; Self::burn_tokens(actual_burn_amount); // 8. Update the weight for the balance operations @@ -92,7 +91,6 @@ impl Pallet { Ok(Some(weight).into()) } - /// Performs the actual coldkey swap operation, transferring all associated data and balances from the old coldkey to the new coldkey. /// /// # Arguments @@ -134,12 +132,16 @@ impl Pallet { /// # Notes /// /// This function is a critical part of the coldkey swap process and should be called only after all necessary checks and validations have been performed. - pub fn perform_swap_coldkey( old_coldkey: &T::AccountId, new_coldkey: &T::AccountId, weight: &mut Weight ) -> DispatchResult { - + pub fn perform_swap_coldkey( + old_coldkey: &T::AccountId, + new_coldkey: &T::AccountId, + weight: &mut Weight, + ) -> DispatchResult { // 1. Swap TotalHotkeyColdkeyStakesThisInterval // TotalHotkeyColdkeyStakesThisInterval: MAP ( hotkey, coldkey ) --> ( stake, block ) | Stake of the hotkey for the coldkey. for hotkey in OwnedHotkeys::::get(old_coldkey).iter() { - let (stake, block) = TotalHotkeyColdkeyStakesThisInterval::::get(&hotkey, old_coldkey); + let (stake, block) = + TotalHotkeyColdkeyStakesThisInterval::::get(&hotkey, old_coldkey); TotalHotkeyColdkeyStakesThisInterval::::remove(&hotkey, old_coldkey); TotalHotkeyColdkeyStakesThisInterval::::insert(&hotkey, new_coldkey, (stake, block)); weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); @@ -157,11 +159,11 @@ impl Pallet { // 3. Swap Stake. // Stake: MAP ( hotkey, coldkey ) --> u64 | Stake of the hotkey for the coldkey. - for hotkey in StakingHotkeys::::get( old_coldkey ) { + for hotkey in StakingHotkeys::::get(old_coldkey) { // Get the stake on the old (hot,coldkey) account. - let old_stake: u64 = Stake::::get( &hotkey, old_coldkey ); + let old_stake: u64 = Stake::::get(&hotkey, old_coldkey); // Get the stake on the new (hot,coldkey) account. - let new_stake: u64 = Stake::::get( &hotkey, new_coldkey ); + let new_stake: u64 = Stake::::get(&hotkey, new_coldkey); // Add the stake to new account. Stake::::insert(&hotkey, new_coldkey, new_stake.saturating_add(old_stake)); // Remove the value from the old account. @@ -169,7 +171,7 @@ impl Pallet { // Add the weight for the read and write. weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2)); } - + // 4. Swap total coldkey stake. // TotalColdkeyStake: MAP ( coldkey ) --> u64 | Total stake of the coldkey. let old_coldkey_stake: u64 = TotalColdkeyStake::::get(old_coldkey); @@ -178,13 +180,16 @@ impl Pallet { // Remove the value from the old account. TotalColdkeyStake::::insert(old_coldkey, 0); // Add the stake to new account. - TotalColdkeyStake::::insert(new_coldkey, new_coldkey_stake.saturating_add(old_coldkey_stake) ); + TotalColdkeyStake::::insert( + new_coldkey, + new_coldkey_stake.saturating_add(old_coldkey_stake), + ); weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2)); // 5. Swap StakingHotkeys. // StakingHotkeys: MAP ( coldkey ) --> Vec | Hotkeys staking for the coldkey. let old_staking_hotkeys: Vec = StakingHotkeys::::get(old_coldkey); - let mut new_staking_hotkeys: Vec = StakingHotkeys::::get( new_coldkey ); + let mut new_staking_hotkeys: Vec = StakingHotkeys::::get(new_coldkey); for hotkey in old_staking_hotkeys { // If the hotkey is not already in the new coldkey, add it. if !new_staking_hotkeys.contains(&hotkey) { @@ -220,7 +225,7 @@ impl Pallet { let remaining_balance = Self::get_coldkey_balance(old_coldkey); if remaining_balance > 0 { if let Err(e) = Self::kill_coldkey_account(old_coldkey, remaining_balance) { - return Err(e.into()); + return Err(e); } Self::add_balance_to_coldkey_account(new_coldkey, remaining_balance); } @@ -230,7 +235,6 @@ impl Pallet { Ok(()) } - /// Checks if a coldkey is currently in arbitration. /// /// # Arguments @@ -454,8 +458,6 @@ impl Pallet { Ok(weight_used) } - - // /// Swaps the stake associated with a coldkey from the old coldkey to the new coldkey. // /// // /// # Arguments @@ -620,4 +622,4 @@ impl Pallet { // TotalColdkeyStake::::get(new_coldkey) // ); // } -} \ No newline at end of file +} diff --git a/pallets/subtensor/src/swap_hotkey.rs b/pallets/subtensor/src/swap_hotkey.rs index 46ba4546a..5c3fecbba 100644 --- a/pallets/subtensor/src/swap_hotkey.rs +++ b/pallets/subtensor/src/swap_hotkey.rs @@ -145,7 +145,6 @@ impl Pallet { coldkey: &T::AccountId, weight: &mut Weight, ) -> DispatchResult { - // 1. Swap owner. // Owner( hotkey ) -> coldkey -- the coldkey that owns the hotkey. Owner::::remove(old_hotkey); diff --git a/pallets/subtensor/tests/swap_coldkey.rs b/pallets/subtensor/tests/swap_coldkey.rs index 0d1e652e6..b85b6c60f 100644 --- a/pallets/subtensor/tests/swap_coldkey.rs +++ b/pallets/subtensor/tests/swap_coldkey.rs @@ -21,12 +21,22 @@ fn test_swap_total_hotkey_coldkey_stakes_this_interval() { OwnedHotkeys::::insert(&old_coldkey, vec![hotkey]); TotalHotkeyColdkeyStakesThisInterval::::insert(&hotkey, &old_coldkey, (stake, block)); - + let mut weight = Weight::zero(); - assert_ok!(SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight)); + assert_ok!(SubtensorModule::perform_swap_coldkey( + &old_coldkey, + &new_coldkey, + &mut weight + )); - assert!(!TotalHotkeyColdkeyStakesThisInterval::::contains_key(&hotkey, &old_coldkey)); - assert_eq!(TotalHotkeyColdkeyStakesThisInterval::::get(&hotkey, &new_coldkey), (stake, block)); + assert!(!TotalHotkeyColdkeyStakesThisInterval::::contains_key( + &hotkey, + &old_coldkey + )); + assert_eq!( + TotalHotkeyColdkeyStakesThisInterval::::get(&hotkey, &new_coldkey), + (stake, block) + ); }); } @@ -40,9 +50,13 @@ fn test_swap_subnet_owner() { add_network(netuid, 1, 0); SubnetOwner::::insert(netuid, old_coldkey); - + let mut weight = Weight::zero(); - assert_ok!(SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight)); + assert_ok!(SubtensorModule::perform_swap_coldkey( + &old_coldkey, + &new_coldkey, + &mut weight + )); assert_eq!(SubnetOwner::::get(netuid), new_coldkey); }); @@ -60,7 +74,11 @@ fn test_swap_stake() { StakingHotkeys::::insert(&old_coldkey, vec![hotkey]); Stake::::insert(&hotkey, &old_coldkey, stake); let mut weight = Weight::zero(); - assert_ok!(SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight)); + assert_ok!(SubtensorModule::perform_swap_coldkey( + &old_coldkey, + &new_coldkey, + &mut weight + )); assert!(!Stake::::contains_key(&hotkey, &old_coldkey)); assert_eq!(Stake::::get(&hotkey, &new_coldkey), stake); @@ -76,9 +94,13 @@ fn test_swap_total_coldkey_stake() { let stake = 100; TotalColdkeyStake::::insert(&old_coldkey, stake); - + let mut weight = Weight::zero(); - assert_ok!(SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight)); + assert_ok!(SubtensorModule::perform_swap_coldkey( + &old_coldkey, + &new_coldkey, + &mut weight + )); assert_eq!(TotalColdkeyStake::::get(&old_coldkey), 0); assert_eq!(TotalColdkeyStake::::get(&new_coldkey), stake); @@ -94,9 +116,13 @@ fn test_swap_staking_hotkeys() { let hotkey = U256::from(3); StakingHotkeys::::insert(&old_coldkey, vec![hotkey]); - + let mut weight = Weight::zero(); - assert_ok!(SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight)); + assert_ok!(SubtensorModule::perform_swap_coldkey( + &old_coldkey, + &new_coldkey, + &mut weight + )); assert!(StakingHotkeys::::get(&old_coldkey).is_empty()); assert_eq!(StakingHotkeys::::get(&new_coldkey), vec![hotkey]); @@ -113,9 +139,13 @@ fn test_swap_hotkey_owners() { Owner::::insert(&hotkey, &old_coldkey); OwnedHotkeys::::insert(&old_coldkey, vec![hotkey]); - + let mut weight = Weight::zero(); - assert_ok!(SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight)); + assert_ok!(SubtensorModule::perform_swap_coldkey( + &old_coldkey, + &new_coldkey, + &mut weight + )); assert_eq!(Owner::::get(&hotkey), new_coldkey); assert!(OwnedHotkeys::::get(&old_coldkey).is_empty()); @@ -131,9 +161,13 @@ fn test_transfer_remaining_balance() { let balance = 100; SubtensorModule::add_balance_to_coldkey_account(&old_coldkey, balance); - + let mut weight = Weight::zero(); - assert_ok!(SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight)); + assert_ok!(SubtensorModule::perform_swap_coldkey( + &old_coldkey, + &new_coldkey, + &mut weight + )); assert_eq!(SubtensorModule::get_coldkey_balance(&old_coldkey), 0); assert_eq!(SubtensorModule::get_coldkey_balance(&new_coldkey), balance); @@ -148,7 +182,11 @@ fn test_swap_with_no_stake() { let new_coldkey = U256::from(2); let mut weight = Weight::zero(); - assert_ok!(SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight)); + assert_ok!(SubtensorModule::perform_swap_coldkey( + &old_coldkey, + &new_coldkey, + &mut weight + )); assert_eq!(TotalColdkeyStake::::get(&old_coldkey), 0); assert_eq!(TotalColdkeyStake::::get(&new_coldkey), 0); @@ -165,12 +203,19 @@ fn test_swap_with_multiple_hotkeys() { let hotkey2 = U256::from(4); OwnedHotkeys::::insert(&old_coldkey, vec![hotkey1, hotkey2]); - + let mut weight = Weight::zero(); - assert_ok!(SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight)); + assert_ok!(SubtensorModule::perform_swap_coldkey( + &old_coldkey, + &new_coldkey, + &mut weight + )); assert!(OwnedHotkeys::::get(&old_coldkey).is_empty()); - assert_eq!(OwnedHotkeys::::get(&new_coldkey), vec![hotkey1, hotkey2]); + assert_eq!( + OwnedHotkeys::::get(&new_coldkey), + vec![hotkey1, hotkey2] + ); }); } @@ -187,9 +232,13 @@ fn test_swap_with_multiple_subnets() { add_network(netuid2, 1, 0); SubnetOwner::::insert(netuid1, &old_coldkey); SubnetOwner::::insert(netuid2, &old_coldkey); - + let mut weight = Weight::zero(); - assert_ok!(SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight)); + assert_ok!(SubtensorModule::perform_swap_coldkey( + &old_coldkey, + &new_coldkey, + &mut weight + )); assert_eq!(SubnetOwner::::get(netuid1), new_coldkey); assert_eq!(SubnetOwner::::get(netuid2), new_coldkey); @@ -204,14 +253,17 @@ fn test_swap_with_zero_balance() { let new_coldkey = U256::from(2); let mut weight = Weight::zero(); - assert_ok!(SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight)); + assert_ok!(SubtensorModule::perform_swap_coldkey( + &old_coldkey, + &new_coldkey, + &mut weight + )); assert_eq!(Balances::free_balance(&old_coldkey), 0); assert_eq!(Balances::free_balance(&new_coldkey), 0); }); } - // SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_coldkey -- test_swap_idempotency --exact --nocapture #[test] fn test_swap_idempotency() { @@ -221,10 +273,18 @@ fn test_swap_idempotency() { let stake = 100; TotalColdkeyStake::::insert(&old_coldkey, stake); - + let mut weight = Weight::zero(); - assert_ok!(SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight)); - assert_ok!(SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight)); + assert_ok!(SubtensorModule::perform_swap_coldkey( + &old_coldkey, + &new_coldkey, + &mut weight + )); + assert_ok!(SubtensorModule::perform_swap_coldkey( + &old_coldkey, + &new_coldkey, + &mut weight + )); assert_eq!(TotalColdkeyStake::::get(&old_coldkey), 0); assert_eq!(TotalColdkeyStake::::get(&new_coldkey), stake); @@ -240,9 +300,13 @@ fn test_swap_with_max_values() { let max_stake = u64::MAX; TotalColdkeyStake::::insert(&old_coldkey, max_stake); - + let mut weight = Weight::zero(); - assert_ok!(SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight)); + assert_ok!(SubtensorModule::perform_swap_coldkey( + &old_coldkey, + &new_coldkey, + &mut weight + )); assert_eq!(TotalColdkeyStake::::get(&old_coldkey), 0); assert_eq!(TotalColdkeyStake::::get(&new_coldkey), max_stake); @@ -258,9 +322,13 @@ fn test_swap_with_non_existent_new_coldkey() { let stake = 100; TotalColdkeyStake::::insert(&old_coldkey, stake); - + let mut weight = Weight::zero(); - assert_ok!(SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight)); + assert_ok!(SubtensorModule::perform_swap_coldkey( + &old_coldkey, + &new_coldkey, + &mut weight + )); assert_eq!(TotalColdkeyStake::::get(&old_coldkey), 0); assert_eq!(TotalColdkeyStake::::get(&new_coldkey), stake); @@ -277,9 +345,13 @@ fn test_swap_with_overflow_in_stake_addition() { TotalColdkeyStake::::insert(&old_coldkey, max_stake); TotalColdkeyStake::::insert(&new_coldkey, 1); - + let mut weight = Weight::zero(); - assert_ok!(SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight)); + assert_ok!(SubtensorModule::perform_swap_coldkey( + &old_coldkey, + &new_coldkey, + &mut weight + )); assert_eq!(TotalColdkeyStake::::get(&old_coldkey), 0); assert_eq!(TotalColdkeyStake::::get(&new_coldkey), max_stake); @@ -296,9 +368,13 @@ fn test_swap_with_max_hotkeys() { let hotkeys: Vec = (0..max_hotkeys).map(U256::from).collect(); OwnedHotkeys::::insert(&old_coldkey, hotkeys.clone()); - + let mut weight = Weight::zero(); - assert_ok!(SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight)); + assert_ok!(SubtensorModule::perform_swap_coldkey( + &old_coldkey, + &new_coldkey, + &mut weight + )); assert!(OwnedHotkeys::::get(&old_coldkey).is_empty()); assert_eq!(OwnedHotkeys::::get(&new_coldkey), hotkeys); @@ -319,9 +395,13 @@ fn test_swap_effect_on_delegated_stake() { StakingHotkeys::::insert(&delegator, vec![hotkey]); Stake::::insert(&hotkey, &old_coldkey, stake); Stake::::insert(&hotkey, &delegator, stake); - + let mut weight = Weight::zero(); - assert_ok!(SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight)); + assert_ok!(SubtensorModule::perform_swap_coldkey( + &old_coldkey, + &new_coldkey, + &mut weight + )); assert_eq!(Stake::::get(&hotkey, &new_coldkey), stake); assert_eq!(Stake::::get(&hotkey, &delegator), stake); @@ -344,7 +424,7 @@ fn test_swap_concurrent_modifications() { Stake::::insert(&hotkey, &old_coldkey, initial_stake); // Simulate concurrent stake addition - add_network(netuid, 1,1); + add_network(netuid, 1, 1); SubtensorModule::add_balance_to_coldkey_account(&new_coldkey, additional_stake); register_ok_neuron(netuid, hotkey, new_coldkey, 1001000); assert_ok!(SubtensorModule::add_stake( @@ -354,9 +434,16 @@ fn test_swap_concurrent_modifications() { )); let mut weight = Weight::zero(); - assert_ok!(SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight)); + assert_ok!(SubtensorModule::perform_swap_coldkey( + &old_coldkey, + &new_coldkey, + &mut weight + )); - assert_eq!(Stake::::get(&hotkey, &new_coldkey), initial_stake + additional_stake - 1); + assert_eq!( + Stake::::get(&hotkey, &new_coldkey), + initial_stake + additional_stake - 1 + ); assert!(!Stake::::contains_key(&hotkey, &old_coldkey)); }); } @@ -370,19 +457,22 @@ fn test_swap_with_invalid_subnet_ownership() { let netuid = 1u16; SubnetOwner::::insert(netuid, old_coldkey); - + // Simulate an invalid state where the subnet owner doesn't match the old_coldkey SubnetOwner::::insert(netuid, U256::from(3)); let mut weight = Weight::zero(); - assert_ok!(SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight)); + assert_ok!(SubtensorModule::perform_swap_coldkey( + &old_coldkey, + &new_coldkey, + &mut weight + )); // The swap should not affect the mismatched subnet ownership assert_eq!(SubnetOwner::::get(netuid), U256::from(3)); }); } - #[test] fn test_do_swap_coldkey_success() { new_test_ext(1).execute_with(|| { @@ -717,11 +807,7 @@ fn test_swap_total_hotkey_coldkey_stakes_this_interval_for_coldkey() { OwnedHotkeys::::insert(old_coldkey, vec![hotkey1, hotkey2]); // Perform the swap - SubtensorModule::perform_swap_coldkey( - &old_coldkey, - &new_coldkey, - &mut weight, - ); + SubtensorModule::perform_swap_coldkey(&old_coldkey, &new_coldkey, &mut weight); // Verify the swap assert_eq!( @@ -1200,4 +1286,3 @@ fn test_coldkey_delegations() { assert_eq!(Stake::::get(delegate, coldkey), 0); }); } - diff --git a/pallets/subtensor/tests/swap_hotkey.rs b/pallets/subtensor/tests/swap_hotkey.rs index 990382918..c6a05f2b6 100644 --- a/pallets/subtensor/tests/swap_hotkey.rs +++ b/pallets/subtensor/tests/swap_hotkey.rs @@ -96,8 +96,7 @@ fn test_swap_total_hotkey_coldkey_stakes_this_interval() { )); assert!(!TotalHotkeyColdkeyStakesThisInterval::::contains_key( - old_hotkey, - coldkey + old_hotkey, coldkey )); assert_eq!( TotalHotkeyColdkeyStakesThisInterval::::get(new_hotkey, coldkey), @@ -957,9 +956,6 @@ fn test_swap_hotkey_error_cases() { )); // Check balance after swap - assert_eq!( - Balances::free_balance(coldkey), - initial_balance - swap_cost - ); + assert_eq!(Balances::free_balance(coldkey), initial_balance - swap_cost); }); } From 9b18c41695a6f177776d55765a1213ddd9f48312 Mon Sep 17 00:00:00 2001 From: const Date: Tue, 23 Jul 2024 13:25:51 -0500 Subject: [PATCH 38/58] fmt and clippy --- pallets/subtensor/src/swap_coldkey.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pallets/subtensor/src/swap_coldkey.rs b/pallets/subtensor/src/swap_coldkey.rs index f8049cd6f..04d9a22dc 100644 --- a/pallets/subtensor/src/swap_coldkey.rs +++ b/pallets/subtensor/src/swap_coldkey.rs @@ -224,9 +224,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 let Err(e) = Self::kill_coldkey_account(old_coldkey, remaining_balance) { - return Err(e); - } + Self::kill_coldkey_account(old_coldkey, remaining_balance)?; Self::add_balance_to_coldkey_account(new_coldkey, remaining_balance); } weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2)); From 6f923c92d5ac6bcad26374776acd272aa9cda46a Mon Sep 17 00:00:00 2001 From: const Date: Tue, 23 Jul 2024 13:37:02 -0500 Subject: [PATCH 39/58] clippy --- pallets/subtensor/tests/swap_coldkey.rs | 112 ++++++++++++------------ 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/pallets/subtensor/tests/swap_coldkey.rs b/pallets/subtensor/tests/swap_coldkey.rs index b85b6c60f..9203e2b3f 100644 --- a/pallets/subtensor/tests/swap_coldkey.rs +++ b/pallets/subtensor/tests/swap_coldkey.rs @@ -19,8 +19,8 @@ fn test_swap_total_hotkey_coldkey_stakes_this_interval() { let stake = 100; let block = 42; - OwnedHotkeys::::insert(&old_coldkey, vec![hotkey]); - TotalHotkeyColdkeyStakesThisInterval::::insert(&hotkey, &old_coldkey, (stake, block)); + OwnedHotkeys::::insert(old_coldkey, vec![hotkey]); + TotalHotkeyColdkeyStakesThisInterval::::insert(hotkey, old_coldkey, (stake, block)); let mut weight = Weight::zero(); assert_ok!(SubtensorModule::perform_swap_coldkey( @@ -30,11 +30,11 @@ fn test_swap_total_hotkey_coldkey_stakes_this_interval() { )); assert!(!TotalHotkeyColdkeyStakesThisInterval::::contains_key( - &hotkey, - &old_coldkey + hotkey, + old_coldkey )); assert_eq!( - TotalHotkeyColdkeyStakesThisInterval::::get(&hotkey, &new_coldkey), + TotalHotkeyColdkeyStakesThisInterval::::get(hotkey, new_coldkey), (stake, block) ); }); @@ -71,8 +71,8 @@ fn test_swap_stake() { let hotkey = U256::from(3); let stake = 100; - StakingHotkeys::::insert(&old_coldkey, vec![hotkey]); - Stake::::insert(&hotkey, &old_coldkey, stake); + StakingHotkeys::::insert(old_coldkey, vec![hotkey]); + Stake::::insert(hotkey, old_coldkey, stake); let mut weight = Weight::zero(); assert_ok!(SubtensorModule::perform_swap_coldkey( &old_coldkey, @@ -80,8 +80,8 @@ fn test_swap_stake() { &mut weight )); - assert!(!Stake::::contains_key(&hotkey, &old_coldkey)); - assert_eq!(Stake::::get(&hotkey, &new_coldkey), stake); + assert!(!Stake::::contains_key(hotkey, old_coldkey)); + assert_eq!(Stake::::get(hotkey, new_coldkey), stake); }); } @@ -93,7 +93,7 @@ fn test_swap_total_coldkey_stake() { let new_coldkey = U256::from(2); let stake = 100; - TotalColdkeyStake::::insert(&old_coldkey, stake); + TotalColdkeyStake::::insert(old_coldkey, stake); let mut weight = Weight::zero(); assert_ok!(SubtensorModule::perform_swap_coldkey( @@ -102,8 +102,8 @@ fn test_swap_total_coldkey_stake() { &mut weight )); - assert_eq!(TotalColdkeyStake::::get(&old_coldkey), 0); - assert_eq!(TotalColdkeyStake::::get(&new_coldkey), stake); + assert_eq!(TotalColdkeyStake::::get(old_coldkey), 0); + assert_eq!(TotalColdkeyStake::::get(new_coldkey), stake); }); } @@ -115,7 +115,7 @@ fn test_swap_staking_hotkeys() { let new_coldkey = U256::from(2); let hotkey = U256::from(3); - StakingHotkeys::::insert(&old_coldkey, vec![hotkey]); + StakingHotkeys::::insert(old_coldkey, vec![hotkey]); let mut weight = Weight::zero(); assert_ok!(SubtensorModule::perform_swap_coldkey( @@ -124,8 +124,8 @@ fn test_swap_staking_hotkeys() { &mut weight )); - assert!(StakingHotkeys::::get(&old_coldkey).is_empty()); - assert_eq!(StakingHotkeys::::get(&new_coldkey), vec![hotkey]); + assert!(StakingHotkeys::::get(old_coldkey).is_empty()); + assert_eq!(StakingHotkeys::::get(new_coldkey), vec![hotkey]); }); } @@ -137,8 +137,8 @@ fn test_swap_hotkey_owners() { let new_coldkey = U256::from(2); let hotkey = U256::from(3); - Owner::::insert(&hotkey, &old_coldkey); - OwnedHotkeys::::insert(&old_coldkey, vec![hotkey]); + Owner::::insert(hotkey, old_coldkey); + OwnedHotkeys::::insert(old_coldkey, vec![hotkey]); let mut weight = Weight::zero(); assert_ok!(SubtensorModule::perform_swap_coldkey( @@ -147,9 +147,9 @@ fn test_swap_hotkey_owners() { &mut weight )); - assert_eq!(Owner::::get(&hotkey), new_coldkey); - assert!(OwnedHotkeys::::get(&old_coldkey).is_empty()); - assert_eq!(OwnedHotkeys::::get(&new_coldkey), vec![hotkey]); + assert_eq!(Owner::::get(hotkey), new_coldkey); + assert!(OwnedHotkeys::::get(old_coldkey).is_empty()); + assert_eq!(OwnedHotkeys::::get(new_coldkey), vec![hotkey]); }); } // SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_coldkey -- test_transfer_remaining_balance --exact --nocapture @@ -188,8 +188,8 @@ fn test_swap_with_no_stake() { &mut weight )); - assert_eq!(TotalColdkeyStake::::get(&old_coldkey), 0); - assert_eq!(TotalColdkeyStake::::get(&new_coldkey), 0); + assert_eq!(TotalColdkeyStake::::get(old_coldkey), 0); + assert_eq!(TotalColdkeyStake::::get(new_coldkey), 0); }); } @@ -202,7 +202,7 @@ fn test_swap_with_multiple_hotkeys() { let hotkey1 = U256::from(3); let hotkey2 = U256::from(4); - OwnedHotkeys::::insert(&old_coldkey, vec![hotkey1, hotkey2]); + OwnedHotkeys::::insert(old_coldkey, vec![hotkey1, hotkey2]); let mut weight = Weight::zero(); assert_ok!(SubtensorModule::perform_swap_coldkey( @@ -211,9 +211,9 @@ fn test_swap_with_multiple_hotkeys() { &mut weight )); - assert!(OwnedHotkeys::::get(&old_coldkey).is_empty()); + assert!(OwnedHotkeys::::get(old_coldkey).is_empty()); assert_eq!( - OwnedHotkeys::::get(&new_coldkey), + OwnedHotkeys::::get(new_coldkey), vec![hotkey1, hotkey2] ); }); @@ -230,8 +230,8 @@ fn test_swap_with_multiple_subnets() { add_network(netuid1, 1, 0); add_network(netuid2, 1, 0); - SubnetOwner::::insert(netuid1, &old_coldkey); - SubnetOwner::::insert(netuid2, &old_coldkey); + SubnetOwner::::insert(netuid1, old_coldkey); + SubnetOwner::::insert(netuid2, old_coldkey); let mut weight = Weight::zero(); assert_ok!(SubtensorModule::perform_swap_coldkey( @@ -259,8 +259,8 @@ fn test_swap_with_zero_balance() { &mut weight )); - assert_eq!(Balances::free_balance(&old_coldkey), 0); - assert_eq!(Balances::free_balance(&new_coldkey), 0); + assert_eq!(Balances::free_balance(old_coldkey), 0); + assert_eq!(Balances::free_balance(new_coldkey), 0); }); } @@ -272,7 +272,7 @@ fn test_swap_idempotency() { let new_coldkey = U256::from(2); let stake = 100; - TotalColdkeyStake::::insert(&old_coldkey, stake); + TotalColdkeyStake::::insert(old_coldkey, stake); let mut weight = Weight::zero(); assert_ok!(SubtensorModule::perform_swap_coldkey( @@ -286,8 +286,8 @@ fn test_swap_idempotency() { &mut weight )); - assert_eq!(TotalColdkeyStake::::get(&old_coldkey), 0); - assert_eq!(TotalColdkeyStake::::get(&new_coldkey), stake); + assert_eq!(TotalColdkeyStake::::get(old_coldkey), 0); + assert_eq!(TotalColdkeyStake::::get(new_coldkey), stake); }); } @@ -299,7 +299,7 @@ fn test_swap_with_max_values() { let new_coldkey = U256::from(2); let max_stake = u64::MAX; - TotalColdkeyStake::::insert(&old_coldkey, max_stake); + TotalColdkeyStake::::insert(old_coldkey, max_stake); let mut weight = Weight::zero(); assert_ok!(SubtensorModule::perform_swap_coldkey( @@ -308,8 +308,8 @@ fn test_swap_with_max_values() { &mut weight )); - assert_eq!(TotalColdkeyStake::::get(&old_coldkey), 0); - assert_eq!(TotalColdkeyStake::::get(&new_coldkey), max_stake); + assert_eq!(TotalColdkeyStake::::get(old_coldkey), 0); + assert_eq!(TotalColdkeyStake::::get(new_coldkey), max_stake); }); } @@ -321,7 +321,7 @@ fn test_swap_with_non_existent_new_coldkey() { let new_coldkey = U256::from(2); let stake = 100; - TotalColdkeyStake::::insert(&old_coldkey, stake); + TotalColdkeyStake::::insert(old_coldkey, stake); let mut weight = Weight::zero(); assert_ok!(SubtensorModule::perform_swap_coldkey( @@ -330,8 +330,8 @@ fn test_swap_with_non_existent_new_coldkey() { &mut weight )); - assert_eq!(TotalColdkeyStake::::get(&old_coldkey), 0); - assert_eq!(TotalColdkeyStake::::get(&new_coldkey), stake); + assert_eq!(TotalColdkeyStake::::get(old_coldkey), 0); + assert_eq!(TotalColdkeyStake::::get(new_coldkey), stake); }); } @@ -343,8 +343,8 @@ fn test_swap_with_overflow_in_stake_addition() { let new_coldkey = U256::from(2); let max_stake = u64::MAX; - TotalColdkeyStake::::insert(&old_coldkey, max_stake); - TotalColdkeyStake::::insert(&new_coldkey, 1); + TotalColdkeyStake::::insert(old_coldkey, max_stake); + TotalColdkeyStake::::insert(new_coldkey, 1); let mut weight = Weight::zero(); assert_ok!(SubtensorModule::perform_swap_coldkey( @@ -353,8 +353,8 @@ fn test_swap_with_overflow_in_stake_addition() { &mut weight )); - assert_eq!(TotalColdkeyStake::::get(&old_coldkey), 0); - assert_eq!(TotalColdkeyStake::::get(&new_coldkey), max_stake); + assert_eq!(TotalColdkeyStake::::get(old_coldkey), 0); + assert_eq!(TotalColdkeyStake::::get(new_coldkey), max_stake); }); } @@ -367,7 +367,7 @@ fn test_swap_with_max_hotkeys() { let max_hotkeys = 1000; let hotkeys: Vec = (0..max_hotkeys).map(U256::from).collect(); - OwnedHotkeys::::insert(&old_coldkey, hotkeys.clone()); + OwnedHotkeys::::insert(old_coldkey, hotkeys.clone()); let mut weight = Weight::zero(); assert_ok!(SubtensorModule::perform_swap_coldkey( @@ -376,8 +376,8 @@ fn test_swap_with_max_hotkeys() { &mut weight )); - assert!(OwnedHotkeys::::get(&old_coldkey).is_empty()); - assert_eq!(OwnedHotkeys::::get(&new_coldkey), hotkeys); + assert!(OwnedHotkeys::::get(old_coldkey).is_empty()); + assert_eq!(OwnedHotkeys::::get(new_coldkey), hotkeys); }); } @@ -391,10 +391,10 @@ fn test_swap_effect_on_delegated_stake() { let hotkey = U256::from(4); let stake = 100; - StakingHotkeys::::insert(&old_coldkey, vec![hotkey]); - StakingHotkeys::::insert(&delegator, vec![hotkey]); - Stake::::insert(&hotkey, &old_coldkey, stake); - Stake::::insert(&hotkey, &delegator, stake); + StakingHotkeys::::insert(old_coldkey, vec![hotkey]); + StakingHotkeys::::insert(delegator, vec![hotkey]); + Stake::::insert(hotkey, old_coldkey, stake); + Stake::::insert(hotkey, delegator, stake); let mut weight = Weight::zero(); assert_ok!(SubtensorModule::perform_swap_coldkey( @@ -403,9 +403,9 @@ fn test_swap_effect_on_delegated_stake() { &mut weight )); - assert_eq!(Stake::::get(&hotkey, &new_coldkey), stake); - assert_eq!(Stake::::get(&hotkey, &delegator), stake); - assert_eq!(Stake::::get(&hotkey, &old_coldkey), 0); + assert_eq!(Stake::::get(hotkey, new_coldkey), stake); + assert_eq!(Stake::::get(hotkey, delegator), stake); + assert_eq!(Stake::::get(hotkey, old_coldkey), 0); }); } @@ -420,8 +420,8 @@ fn test_swap_concurrent_modifications() { let initial_stake = 100; let additional_stake = 50; - StakingHotkeys::::insert(&old_coldkey, vec![hotkey]); - Stake::::insert(&hotkey, &old_coldkey, initial_stake); + StakingHotkeys::::insert(old_coldkey, vec![hotkey]); + Stake::::insert(hotkey, old_coldkey, initial_stake); // Simulate concurrent stake addition add_network(netuid, 1, 1); @@ -441,10 +441,10 @@ fn test_swap_concurrent_modifications() { )); assert_eq!( - Stake::::get(&hotkey, &new_coldkey), + Stake::::get(hotkey, new_coldkey), initial_stake + additional_stake - 1 ); - assert!(!Stake::::contains_key(&hotkey, &old_coldkey)); + assert!(!Stake::::contains_key(hotkey, old_coldkey)); }); } From b003138ed292c13dc98d74b35de248a28c77241e Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 23 Jul 2024 12:05:33 -0700 Subject: [PATCH 40/58] bump up the `runtime/src/lib.rs::spec_version;L142` --- runtime/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index a4abd124f..f5ca3c5cd 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -139,7 +139,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: 165, + spec_version: 166, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1, From 02457c1ad49a7608f294a5aa9e44f5538a7602a3 Mon Sep 17 00:00:00 2001 From: const Date: Tue, 23 Jul 2024 14:24:03 -0500 Subject: [PATCH 41/58] fix migration tests --- pallets/subtensor/src/lib.rs | 3 + pallets/subtensor/src/macros/dispatches.rs | 22 +- .../migrate_fix_total_coldkey_stake.rs | 44 ++- pallets/subtensor/src/swap/swap_coldkey.rs | 253 +----------------- pallets/subtensor/src/swap/swap_hotkey.rs | 38 ++- pallets/subtensor/tests/migration.rs | 12 +- 6 files changed, 78 insertions(+), 294 deletions(-) diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index 5a002b333..29969a23b 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -1073,9 +1073,12 @@ pub mod pallet { (H256, u64), OptionQuery, >; + /// ================== /// ==== Genesis ===== /// ================== + #[pallet::storage] // --- Storage for migration run status + pub type HasMigrationRun = StorageMap<_, Identity, Vec, bool, ValueQuery>; #[pallet::genesis_config] pub struct GenesisConfig { diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index d8cb31166..293dc0238 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -640,17 +640,17 @@ mod dispatches { } /// The extrinsic for user to change its hotkey - ///#[pallet::call_index(70)] - ///#[pallet::weight((Weight::from_parts(1_940_000_000, 0) - ///.saturating_add(T::DbWeight::get().reads(272)) - ///.saturating_add(T::DbWeight::get().writes(527)), DispatchClass::Operational, Pays::No))] - ///pub fn swap_hotkey( - /// origin: OriginFor, - /// hotkey: T::AccountId, - /// new_hotkey: T::AccountId, - ///) -> DispatchResultWithPostInfo { - /// Self::do_swap_hotkey(origin, &hotkey, &new_hotkey) - ///} + #[pallet::call_index(70)] + #[pallet::weight((Weight::from_parts(1_940_000_000, 0) + .saturating_add(T::DbWeight::get().reads(272)) + .saturating_add(T::DbWeight::get().writes(527)), DispatchClass::Operational, Pays::No))] + pub fn swap_hotkey( + origin: OriginFor, + hotkey: T::AccountId, + new_hotkey: T::AccountId, + ) -> DispatchResultWithPostInfo { + Self::do_swap_hotkey(origin, &hotkey, &new_hotkey) + } /// The extrinsic for user to change the coldkey associated with their account. /// diff --git a/pallets/subtensor/src/migrations/migrate_fix_total_coldkey_stake.rs b/pallets/subtensor/src/migrations/migrate_fix_total_coldkey_stake.rs index 20c47e29c..268c82d48 100644 --- a/pallets/subtensor/src/migrations/migrate_fix_total_coldkey_stake.rs +++ b/pallets/subtensor/src/migrations/migrate_fix_total_coldkey_stake.rs @@ -2,9 +2,10 @@ use super::*; use frame_support::{ pallet_prelude::{Identity, OptionQuery}, storage_alias, - traits::{Get, GetStorageVersion, StorageVersion}, + traits::{Get, StorageVersion}, weights::Weight, }; +use alloc::string::String; use sp_std::vec::Vec; // TODO (camfairchild): TEST MIGRATION @@ -50,24 +51,41 @@ pub fn do_migrate_fix_total_coldkey_stake() -> Weight { } // Public migrate function to be called by Lib.rs on upgrade. pub fn migrate_fix_total_coldkey_stake() -> Weight { - let current_storage_version: u16 = 7; - let next_storage_version: u16 = 8; + let migration_name = b"fix_total_coldkey_stake_v7".to_vec(); // Initialize the weight with one read operation. let mut weight = T::DbWeight::get().reads(1); - // Grab the current on-chain storage version. - // Cant fail on retrieval. - let onchain_version = Pallet::::on_chain_storage_version(); - - // Only run this migration on storage version 6. - if onchain_version == current_storage_version { - weight = weight.saturating_add(do_migrate_fix_total_coldkey_stake::()); - // Cant fail on insert. - StorageVersion::new(next_storage_version).put::>(); - weight.saturating_accrue(T::DbWeight::get().writes(1)); + // Check if the migration has already run + if HasMigrationRun::::get(&migration_name) { + log::info!( + "Migration '{:?}' has already run. Skipping.", + migration_name + ); + return Weight::zero(); } + log::info!( + "Running migration '{}'", + String::from_utf8_lossy(&migration_name) + ); + + // Run the migration + weight = weight.saturating_add(do_migrate_fix_total_coldkey_stake::()); + + // Mark the migration as completed + HasMigrationRun::::insert(&migration_name, true); + weight = weight.saturating_add(T::DbWeight::get().writes(1)); + + // Set the storage version to 7 + StorageVersion::new(7).put::>(); + weight = weight.saturating_add(T::DbWeight::get().writes(1)); + + log::info!( + "Migration '{:?}' completed. Storage version set to 7.", + String::from_utf8_lossy(&migration_name) + ); + // Return the migration weight. weight } diff --git a/pallets/subtensor/src/swap/swap_coldkey.rs b/pallets/subtensor/src/swap/swap_coldkey.rs index e0e0061d8..507fc62a5 100644 --- a/pallets/subtensor/src/swap/swap_coldkey.rs +++ b/pallets/subtensor/src/swap/swap_coldkey.rs @@ -1,7 +1,6 @@ use super::*; -use crate::MIN_BALANCE_TO_PERFORM_COLDKEY_SWAP; use frame_support::weights::Weight; -use sp_core::{Get, U256}; +use sp_core::{Get}; impl Pallet { /// Swaps the coldkey associated with a set of hotkeys from an old coldkey to a new coldkey. @@ -37,28 +36,22 @@ impl Pallet { // 1. Ensure the origin is signed and get the old coldkey let old_coldkey = ensure_signed(origin)?; - // 2. Check if the old coldkey is in arbitration - ensure!( - !Self::coldkey_in_arbitration(&old_coldkey), - Error::::ColdkeyIsInArbitration - ); - - // 3. Initialize the weight for this operation + // 2. Initialize the weight for this operation let mut weight: Weight = T::DbWeight::get().reads(2); - // 4. Ensure the new coldkey is not associated with any hotkeys + // 3. Ensure the new coldkey is not associated with any hotkeys ensure!( StakingHotkeys::::get(new_coldkey).is_empty(), Error::::ColdKeyAlreadyAssociated ); - // 5. Ensure the new coldkey is not a hotkey + // 4. Ensure the new coldkey is not a hotkey ensure!( !Self::hotkey_account_exists(new_coldkey), Error::::ColdKeyAlreadyAssociated ); - // 6. Calculate the swap cost and ensure sufficient balance + // 5. Calculate the swap cost and ensure sufficient balance let swap_cost = Self::get_key_swap_cost(); log::debug!("Coldkey swap cost: {:?}", swap_cost); ensure!( @@ -66,28 +59,28 @@ impl Pallet { Error::::NotEnoughBalanceToPaySwapColdKey ); - // 7. Remove and burn the swap cost from the old coldkey's account + // 6. Remove and burn the swap cost from the old coldkey's account let actual_burn_amount = Self::remove_balance_from_coldkey_account(&old_coldkey, swap_cost)?; Self::burn_tokens(actual_burn_amount); - // 8. Update the weight for the balance operations + // 7. Update the weight for the balance operations weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); - // 9. Perform the actual coldkey swap + // 8. Perform the actual coldkey swap let _ = Self::perform_swap_coldkey(&old_coldkey, new_coldkey, &mut weight); - // 10. Update the last transaction block for the new coldkey + // 9. Update the last transaction block for the new coldkey Self::set_last_tx_block(new_coldkey, Self::get_current_block_as_u64()); weight.saturating_accrue(T::DbWeight::get().writes(1)); - // 11. Emit the ColdkeySwapped event + // 10. Emit the ColdkeySwapped event Self::deposit_event(Event::ColdkeySwapped { old_coldkey: old_coldkey.clone(), new_coldkey: new_coldkey.clone(), }); - // 12. Return the result with the updated weight + // 11. Return the result with the updated weight Ok(Some(weight).into()) } @@ -232,228 +225,4 @@ impl Pallet { // Return ok. Ok(()) } - - /// Checks if a coldkey is currently in arbitration. - /// - /// # Arguments - /// - /// * `coldkey` - The account ID of the coldkey to check. - /// - /// # Returns - /// - /// * `bool` - True if the coldkey is in arbitration, false otherwise. - /// - /// # Notes - /// - /// This function compares the arbitration block number of the coldkey with the current block number. - pub fn coldkey_in_arbitration(coldkey: &T::AccountId) -> bool { - ColdkeyArbitrationBlock::::get(coldkey) > Self::get_current_block_as_u64() - } - - /// Returns the remaining arbitration period for a given coldkey. - /// - /// # Arguments - /// - /// * `coldkey` - The account ID of the coldkey to check. - /// - /// # Returns - /// - /// * `u64` - The remaining arbitration period in blocks. - /// - /// - /// # Notes - /// - /// This function calculates the remaining arbitration period by subtracting the current block number - /// from the arbitration block number of the coldkey. - pub fn get_remaining_arbitration_period(coldkey: &T::AccountId) -> u64 { - let current_block: u64 = Self::get_current_block_as_u64(); - let arbitration_block: u64 = ColdkeyArbitrationBlock::::get(coldkey); - if arbitration_block > current_block { - arbitration_block.saturating_sub(current_block) - } else { - 0 - } - } - - pub fn meets_min_allowed_coldkey_balance(coldkey: &T::AccountId) -> bool { - let all_staked_keys: Vec = StakingHotkeys::::get(coldkey); - let mut total_staking_balance: u64 = 0; - for hotkey in all_staked_keys { - total_staking_balance = total_staking_balance - .saturating_add(Self::get_stake_for_coldkey_and_hotkey(coldkey, &hotkey)); - } - total_staking_balance = - total_staking_balance.saturating_add(Self::get_coldkey_balance(coldkey)); - total_staking_balance >= MIN_BALANCE_TO_PERFORM_COLDKEY_SWAP - } - - /// Schedules a coldkey swap to a new coldkey with arbitration. - /// - /// # Arguments - /// - /// * `old_coldkey` - The account ID of the old coldkey. - /// * `new_coldkey` - The account ID of the new coldkey. - /// * `work` - The proof of work submitted by the caller. - /// * `block_number` - The block number at which the work was performed. - /// * `nonce` - The nonce used for the proof of work. - /// - /// # Returns - /// - /// * `DispatchResult` - The result of the dispatch. - /// - /// # Errors - /// - - /// - `SameColdkey`: The old coldkey is the same as the new coldkey. - /// - `DuplicateColdkey`: The new coldkey is already in the list of destination coldkeys. - /// - `MaxColdkeyDestinationsReached`: There are already the maximum allowed destination coldkeys for the old coldkey. - /// - `InsufficientBalanceToPerformColdkeySwap`: The old coldkey doesn't have the minimum required TAO balance. - /// - `InvalidDifficulty`: The proof of work is invalid or doesn't meet the required difficulty. - /// - /// # Notes - /// - /// This function ensures that the new coldkey is not already in the list of destination coldkeys. - /// It also checks for a minimum TAO balance and verifies the proof of work. - /// The difficulty of the proof of work increases exponentially with each subsequent call. - pub fn do_schedule_coldkey_swap( - old_coldkey: &T::AccountId, - new_coldkey: &T::AccountId, - work: Vec, - block_number: u64, - nonce: u64, - ) -> DispatchResult { - ensure!(old_coldkey != new_coldkey, Error::::SameColdkey); - - // Check if the old_coldkey is a subnet owner for any network - let is_subnet_owner = (0..=TotalNetworks::::get()) - .any(|netuid| SubnetOwner::::get(netuid) == *old_coldkey); - - // Check if the old_coldkey has more than 500 TAO delegated - let total_delegated = Self::get_total_delegated_stake(old_coldkey); - let has_sufficient_delegation = total_delegated > 500_000_000_000; // 500 TAO in RAO - - // Only check the minimum balance if the old_coldkey is not a subnet owner - // and doesn't have sufficient delegation - if !(is_subnet_owner || has_sufficient_delegation) { - ensure!( - Self::meets_min_allowed_coldkey_balance(old_coldkey), - Error::::InsufficientBalanceToPerformColdkeySwap - ); - } - - // Get current destination coldkeys - let mut destination_coldkeys: Vec = - ColdkeySwapDestinations::::get(old_coldkey.clone()); - - // Calculate difficulty based on the number of existing destination coldkeys - let difficulty = Self::calculate_pow_difficulty(destination_coldkeys.len() as u32); - let work_hash = Self::vec_to_hash(work.clone()); - ensure!( - Self::hash_meets_difficulty(&work_hash, difficulty), - Error::::InvalidDifficulty - ); - - // Verify work is the product of the nonce, the block number, and coldkey - let seal = Self::create_seal_hash(block_number, nonce, old_coldkey); - ensure!(seal == work_hash, Error::::InvalidSeal); - - // Check if the new coldkey is already in the swap wallets list - ensure!( - !destination_coldkeys.contains(new_coldkey), - Error::::DuplicateColdkey - ); - - // If the destinations keys are empty or have less than the maximum allowed, we will add the new coldkey to the list - const MAX_COLDKEY_DESTINATIONS: usize = 10; - - if destination_coldkeys.len() < MAX_COLDKEY_DESTINATIONS { - destination_coldkeys.push(new_coldkey.clone()); - ColdkeySwapDestinations::::insert(old_coldkey.clone(), destination_coldkeys.clone()); - } else { - return Err(Error::::MaxColdkeyDestinationsReached.into()); - } - - // It is the first time we have seen this key - if destination_coldkeys.len() == 1_usize { - // Set the arbitration block for this coldkey - let arbitration_block: u64 = - Self::get_current_block_as_u64().saturating_add(ArbitrationPeriod::::get()); - ColdkeyArbitrationBlock::::insert(old_coldkey.clone(), arbitration_block); - - // Update the list of coldkeys to arbitrate on this block - let mut key_to_arbitrate_on_this_block: Vec = - ColdkeysToSwapAtBlock::::get(arbitration_block); - if !key_to_arbitrate_on_this_block.contains(old_coldkey) { - key_to_arbitrate_on_this_block.push(old_coldkey.clone()); - } - ColdkeysToSwapAtBlock::::insert(arbitration_block, key_to_arbitrate_on_this_block); - } - - // Emit an event indicating that a coldkey swap has been scheduled - Self::deposit_event(Event::ColdkeySwapScheduled { - old_coldkey: old_coldkey.clone(), - new_coldkey: new_coldkey.clone(), - arbitration_block: ColdkeyArbitrationBlock::::get(old_coldkey), - }); - - Ok(()) - } - - /// Calculate the proof of work difficulty based on the number of swap attempts - #[allow(clippy::arithmetic_side_effects)] - pub fn calculate_pow_difficulty(swap_attempts: u32) -> U256 { - let base_difficulty: U256 = U256::from(BaseDifficulty::::get()); // Base difficulty - base_difficulty.saturating_mul(U256::from(2).pow(U256::from(swap_attempts))) - } - - /// Arbitrates coldkeys that are scheduled to be swapped on this block. - /// - /// This function retrieves the list of coldkeys scheduled to be swapped on the current block, - /// and processes each coldkey by either extending the arbitration period or performing the swap - /// to the new coldkey. - /// - /// # Returns - /// - /// * `Weight` - The total weight consumed by this operation - pub fn swap_coldkeys_this_block(_weight_limit: &Weight) -> Result { - let mut weight_used = frame_support::weights::Weight::from_parts(0, 0); - - let current_block: u64 = Self::get_current_block_as_u64(); - log::debug!("Swapping coldkeys for block: {:?}", current_block); - - let source_coldkeys: Vec = ColdkeysToSwapAtBlock::::get(current_block); - ColdkeysToSwapAtBlock::::remove(current_block); - weight_used = weight_used.saturating_add(T::DbWeight::get().reads_writes(1, 1)); - - let mut keys_swapped = 0u64; - for coldkey_i in source_coldkeys.iter() { - // TODO: need a sane way to terminate early without locking users in. - // we should update the swap time - // if weight_used.ref_time() > weight_limit.ref_time() { - // log::warn!("Could not finish swapping all coldkeys this block due to weight limit, breaking after swapping {} keys.", keys_swapped); - // break; - // } - - let destinations_coldkeys: Vec = - ColdkeySwapDestinations::::get(coldkey_i); - weight_used = weight_used.saturating_add(T::DbWeight::get().reads(1)); - - if destinations_coldkeys.len() > 1 { - // Do not remove ColdkeySwapDestinations if there are multiple destinations - ColdkeyArbitrationBlock::::insert(coldkey_i.clone(), u64::MAX); - Self::deposit_event(Event::ArbitrationPeriodExtended { - coldkey: coldkey_i.clone(), - }); - } else if let Some(new_coldkey) = destinations_coldkeys.first() { - // Only remove ColdkeySwapDestinations if there's a single destination - ColdkeySwapDestinations::::remove(&coldkey_i); - weight_used = weight_used.saturating_add(T::DbWeight::get().writes(1)); - keys_swapped = keys_swapped.saturating_add(1); - let _ = Self::perform_swap_coldkey(coldkey_i, new_coldkey, &mut weight_used); - } - } - - Ok(weight_used) - } - } \ No newline at end of file diff --git a/pallets/subtensor/src/swap/swap_hotkey.rs b/pallets/subtensor/src/swap/swap_hotkey.rs index 5c3fecbba..fb3c33e4d 100644 --- a/pallets/subtensor/src/swap/swap_hotkey.rs +++ b/pallets/subtensor/src/swap/swap_hotkey.rs @@ -30,78 +30,72 @@ impl Pallet { // 1. Ensure the origin is signed and get the coldkey let coldkey = ensure_signed(origin)?; - // 2. Check if the coldkey is in arbitration - ensure!( - !Self::coldkey_in_arbitration(&coldkey), - Error::::ColdkeyIsInArbitration - ); - - // 3. Initialize the weight for this operation + // 2. Initialize the weight for this operation let mut weight = T::DbWeight::get().reads(2); - // 4. Ensure the new hotkey is different from the old one + // 3. Ensure the new hotkey is different from the old one ensure!(old_hotkey != new_hotkey, Error::::NewHotKeyIsSameWithOld); - // 5. Ensure the new hotkey is not already registered on any network + // 4. Ensure the new hotkey is not already registered on any network ensure!( !Self::is_hotkey_registered_on_any_network(new_hotkey), Error::::HotKeyAlreadyRegisteredInSubNet ); - // 6. Update the weight for the checks above + // 5. Update the weight for the checks above weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 0)); - // 7. Ensure the coldkey owns the old hotkey + // 6. Ensure the coldkey owns the old hotkey ensure!( Self::coldkey_owns_hotkey(&coldkey, old_hotkey), Error::::NonAssociatedColdKey ); - // 8. Get the current block number + // 7. Get the current block number let block: u64 = Self::get_current_block_as_u64(); - // 9. Ensure the transaction rate limit is not exceeded + // 8. Ensure the transaction rate limit is not exceeded ensure!( !Self::exceeds_tx_rate_limit(Self::get_last_tx_block(&coldkey), block), Error::::HotKeySetTxRateLimitExceeded ); - // 10. Update the weight for reading the total networks + // 9. Update the weight for reading the total networks weight.saturating_accrue( T::DbWeight::get().reads((TotalNetworks::::get().saturating_add(1u16)) as u64), ); - // 11. Get the cost for swapping the key + // 10. Get the cost for swapping the key let swap_cost = Self::get_key_swap_cost(); log::debug!("Swap cost: {:?}", swap_cost); - // 12. Ensure the coldkey has enough balance to pay for the swap + // 11. Ensure the coldkey has enough balance to pay for the swap ensure!( Self::can_remove_balance_from_coldkey_account(&coldkey, swap_cost), Error::::NotEnoughBalanceToPaySwapHotKey ); - // 13. Remove the swap cost from the coldkey's account + // 12. Remove the swap cost from the coldkey's account let actual_burn_amount = Self::remove_balance_from_coldkey_account(&coldkey, swap_cost)?; - // 14. Burn the tokens + // 13. Burn the tokens Self::burn_tokens(actual_burn_amount); - // 15. Perform the hotkey swap + // 14. Perform the hotkey swap let _ = Self::perform_hotkey_swap(old_hotkey, new_hotkey, &coldkey, &mut weight); - // 16. Update the last transaction block for the coldkey + // 15. Update the last transaction block for the coldkey Self::set_last_tx_block(&coldkey, block); weight.saturating_accrue(T::DbWeight::get().writes(1)); - // 17. Emit an event for the hotkey swap + // 16. Emit an event for the hotkey swap Self::deposit_event(Event::HotkeySwapped { coldkey, old_hotkey: old_hotkey.clone(), new_hotkey: new_hotkey.clone(), }); - // 18. Return the weight of the operation + // 17. Return the weight of the operation Ok(Some(weight).into()) } diff --git a/pallets/subtensor/tests/migration.rs b/pallets/subtensor/tests/migration.rs index 23ceea539..bcbfa5545 100644 --- a/pallets/subtensor/tests/migration.rs +++ b/pallets/subtensor/tests/migration.rs @@ -355,6 +355,7 @@ fn test_migrate_fix_total_coldkey_stake_one_hotkey_stake_missing() { } // New test to check if migration runs only once +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test migration -- test_migrate_fix_total_coldkey_stake_runs_once --exact --nocapture #[test] fn test_migrate_fix_total_coldkey_stake_runs_once() { new_test_ext(1).execute_with(|| { @@ -362,9 +363,9 @@ fn test_migrate_fix_total_coldkey_stake_runs_once() { let coldkey = U256::from(0); TotalColdkeyStake::::insert(coldkey, 0); StakingHotkeys::::insert(coldkey, vec![U256::from(1), U256::from(2), U256::from(3)]); - Stake::::insert(U256::from(1), U256::from(0), 10000); - Stake::::insert(U256::from(2), U256::from(0), 10000); - Stake::::insert(U256::from(3), U256::from(0), 10000); + Stake::::insert(U256::from(1), coldkey, 10000); + Stake::::insert(U256::from(2), coldkey, 10000); + Stake::::insert(U256::from(3), coldkey, 10000); // First run let first_weight = run_migration_and_check(migration_name); @@ -391,14 +392,13 @@ fn test_migrate_fix_total_coldkey_stake_starts_with_value_no_stake_map_entries() let weight = run_migration_and_check(migration_name); assert!(weight != Weight::zero()); // Therefore 0 - assert_eq!(TotalColdkeyStake::::get(coldkey), 0); + assert_eq!(TotalColdkeyStake::::get(coldkey), 123_456_789); }) } fn run_migration_and_check(migration_name: &'static str) -> frame_support::weights::Weight { // Execute the migration and store its weight - let weight: frame_support::weights::Weight = - pallet_subtensor::migration::migrate_fix_total_coldkey_stake::(); + let weight: frame_support::weights::Weight = pallet_subtensor::migrations::migrate_fix_total_coldkey_stake::migrate_fix_total_coldkey_stake::(); // Check if the migration has been marked as completed assert!(HasMigrationRun::::get( From bc19f08f50b720308533b15144b0063cd96d4c3f Mon Sep 17 00:00:00 2001 From: const Date: Tue, 23 Jul 2024 14:26:28 -0500 Subject: [PATCH 42/58] s --- pallets/subtensor/src/macros/config.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pallets/subtensor/src/macros/config.rs b/pallets/subtensor/src/macros/config.rs index aca0f1b30..e59eac5ca 100644 --- a/pallets/subtensor/src/macros/config.rs +++ b/pallets/subtensor/src/macros/config.rs @@ -1,3 +1,5 @@ +#![allow(clippy::crate_in_macro_def)] + use frame_support::pallet_macros::pallet_section; /// A [`pallet_section`] that defines the errors for a pallet. From 28ba654d28ef2b6a3b7864bc314479c03b7c492c Mon Sep 17 00:00:00 2001 From: unconst Date: Tue, 23 Jul 2024 14:28:57 -0500 Subject: [PATCH 43/58] clippy --- pallets/subtensor/src/coinbase/run_coinbase.rs | 2 +- pallets/subtensor/src/lib.rs | 2 +- .../migrations/migrate_fix_total_coldkey_stake.rs | 2 +- pallets/subtensor/src/subnets/registration.rs | 6 +++++- pallets/subtensor/src/swap/swap_coldkey.rs | 4 ++-- pallets/subtensor/tests/coinbase.rs | 1 + pallets/subtensor/tests/migration.rs | 13 ++++++------- pallets/subtensor/tests/swap_coldkey.rs | 2 +- 8 files changed, 18 insertions(+), 14 deletions(-) diff --git a/pallets/subtensor/src/coinbase/run_coinbase.rs b/pallets/subtensor/src/coinbase/run_coinbase.rs index 0f747a89e..f3fbf8e73 100644 --- a/pallets/subtensor/src/coinbase/run_coinbase.rs +++ b/pallets/subtensor/src/coinbase/run_coinbase.rs @@ -372,4 +372,4 @@ impl Pallet { let remainder = block_plus_netuid.rem_euclid(tempo_plus_one); (tempo as u64).saturating_sub(remainder) } -} \ No newline at end of file +} diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index 29969a23b..6c16902d9 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -1073,7 +1073,7 @@ pub mod pallet { (H256, u64), OptionQuery, >; - + /// ================== /// ==== Genesis ===== /// ================== diff --git a/pallets/subtensor/src/migrations/migrate_fix_total_coldkey_stake.rs b/pallets/subtensor/src/migrations/migrate_fix_total_coldkey_stake.rs index 268c82d48..d8534d03a 100644 --- a/pallets/subtensor/src/migrations/migrate_fix_total_coldkey_stake.rs +++ b/pallets/subtensor/src/migrations/migrate_fix_total_coldkey_stake.rs @@ -1,11 +1,11 @@ use super::*; +use alloc::string::String; use frame_support::{ pallet_prelude::{Identity, OptionQuery}, storage_alias, traits::{Get, StorageVersion}, weights::Weight, }; -use alloc::string::String; use sp_std::vec::Vec; // TODO (camfairchild): TEST MIGRATION diff --git a/pallets/subtensor/src/subnets/registration.rs b/pallets/subtensor/src/subnets/registration.rs index ecff0fd99..9319adcd1 100644 --- a/pallets/subtensor/src/subnets/registration.rs +++ b/pallets/subtensor/src/subnets/registration.rs @@ -550,7 +550,11 @@ impl Pallet { // Copy the hotkey_bytes into the first half of full_bytes full_bytes[..32].copy_from_slice(hotkey_bytes); let keccak_256_seal_hash_vec: [u8; 32] = keccak_256(&full_bytes[..]); - let hash_u64: u64 = u64::from_le_bytes(keccak_256_seal_hash_vec[0..8].try_into().unwrap_or_default()); + let hash_u64: u64 = u64::from_le_bytes( + keccak_256_seal_hash_vec[0..8] + .try_into() + .unwrap_or_default(), + ); hash_u64 } diff --git a/pallets/subtensor/src/swap/swap_coldkey.rs b/pallets/subtensor/src/swap/swap_coldkey.rs index 507fc62a5..bd8a11fa1 100644 --- a/pallets/subtensor/src/swap/swap_coldkey.rs +++ b/pallets/subtensor/src/swap/swap_coldkey.rs @@ -1,6 +1,6 @@ use super::*; use frame_support::weights::Weight; -use sp_core::{Get}; +use sp_core::Get; impl Pallet { /// Swaps the coldkey associated with a set of hotkeys from an old coldkey to a new coldkey. @@ -225,4 +225,4 @@ impl Pallet { // Return ok. Ok(()) } -} \ No newline at end of file +} diff --git a/pallets/subtensor/tests/coinbase.rs b/pallets/subtensor/tests/coinbase.rs index aed3c9b55..8fd963dff 100644 --- a/pallets/subtensor/tests/coinbase.rs +++ b/pallets/subtensor/tests/coinbase.rs @@ -1,3 +1,4 @@ +#![allow(unused, clippy::indexing_slicing, clippy::panic, clippy::unwrap_used)] use crate::mock::*; mod mock; // use frame_support::{assert_err, assert_ok}; diff --git a/pallets/subtensor/tests/migration.rs b/pallets/subtensor/tests/migration.rs index bcbfa5545..bd77c7be0 100644 --- a/pallets/subtensor/tests/migration.rs +++ b/pallets/subtensor/tests/migration.rs @@ -1,5 +1,4 @@ -#![allow(clippy::unwrap_used)] - +#![allow(unused, clippy::indexing_slicing, clippy::panic, clippy::unwrap_used)] mod mock; use frame_support::{assert_ok, weights::Weight}; use frame_system::Config; @@ -283,7 +282,7 @@ fn test_migration_delete_subnet_21() { #[test] fn test_migrate_fix_total_coldkey_stake() { new_test_ext(1).execute_with(|| { - let migration_name = "fix_total_coldkey_stake_v7"; + let _migration_name = "fix_total_coldkey_stake_v7"; let coldkey = U256::from(0); TotalColdkeyStake::::insert(coldkey, 0); StakingHotkeys::::insert(coldkey, vec![U256::from(1), U256::from(2), U256::from(3)]); @@ -299,7 +298,7 @@ fn test_migrate_fix_total_coldkey_stake() { #[test] fn test_migrate_fix_total_coldkey_stake_value_already_in_total() { new_test_ext(1).execute_with(|| { - let migration_name = "fix_total_coldkey_stake_v7"; + let _migration_name = "fix_total_coldkey_stake_v7"; let coldkey = U256::from(0); TotalColdkeyStake::::insert(coldkey, 100000000); StakingHotkeys::::insert(coldkey, vec![U256::from(1), U256::from(2), U256::from(3)]); @@ -315,7 +314,7 @@ fn test_migrate_fix_total_coldkey_stake_value_already_in_total() { #[test] fn test_migrate_fix_total_coldkey_stake_no_entry() { new_test_ext(1).execute_with(|| { - let migration_name = "fix_total_coldkey_stake_v7"; + let _migration_name = "fix_total_coldkey_stake_v7"; let coldkey = U256::from(0); StakingHotkeys::::insert(coldkey, vec![U256::from(1), U256::from(2), U256::from(3)]); Stake::::insert(U256::from(1), U256::from(0), 10000); @@ -330,7 +329,7 @@ fn test_migrate_fix_total_coldkey_stake_no_entry() { #[test] fn test_migrate_fix_total_coldkey_stake_no_entry_in_hotkeys() { new_test_ext(1).execute_with(|| { - let migration_name = "fix_total_coldkey_stake_v7"; + let _migration_name = "fix_total_coldkey_stake_v7"; let coldkey = U256::from(0); TotalColdkeyStake::::insert(coldkey, 100000000); StakingHotkeys::::insert(coldkey, vec![U256::from(1), U256::from(2), U256::from(3)]); @@ -343,7 +342,7 @@ fn test_migrate_fix_total_coldkey_stake_no_entry_in_hotkeys() { #[test] fn test_migrate_fix_total_coldkey_stake_one_hotkey_stake_missing() { new_test_ext(1).execute_with(|| { - let migration_name = "fix_total_coldkey_stake_v7"; + let _migration_name = "fix_total_coldkey_stake_v7"; let coldkey = U256::from(0); TotalColdkeyStake::::insert(coldkey, 100000000); StakingHotkeys::::insert(coldkey, vec![U256::from(1), U256::from(2), U256::from(3)]); diff --git a/pallets/subtensor/tests/swap_coldkey.rs b/pallets/subtensor/tests/swap_coldkey.rs index df109f992..9203e2b3f 100644 --- a/pallets/subtensor/tests/swap_coldkey.rs +++ b/pallets/subtensor/tests/swap_coldkey.rs @@ -1285,4 +1285,4 @@ fn test_coldkey_delegations() { assert_eq!(Stake::::get(delegate, new_coldkey), 100); assert_eq!(Stake::::get(delegate, coldkey), 0); }); -} \ No newline at end of file +} From 4726ec3e9d39b9f5e7266a75e7fb51cb414c26d0 Mon Sep 17 00:00:00 2001 From: unconst Date: Tue, 23 Jul 2024 14:32:20 -0500 Subject: [PATCH 44/58] fix divide by zero --- pallets/subtensor/src/coinbase/run_coinbase.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pallets/subtensor/src/coinbase/run_coinbase.rs b/pallets/subtensor/src/coinbase/run_coinbase.rs index f3fbf8e73..df35304b1 100644 --- a/pallets/subtensor/src/coinbase/run_coinbase.rs +++ b/pallets/subtensor/src/coinbase/run_coinbase.rs @@ -299,7 +299,8 @@ impl Pallet { // --- 10 Calculate this nominator's share of the emission. let nominator_emission: I64F64 = I64F64::from_num(emission_minus_take) .saturating_mul(I64F64::from_num(nominator_stake)) - .saturating_div(I64F64::from_num(total_hotkey_stake)); + .check_div(I64F64::from_num(total_hotkey_stake)) + .unwrap_or(I64F64::from_num(0)); // --- 11 Increase the stake for the nominator. Self::increase_stake_on_coldkey_hotkey_account( From e90fc16f688c43b2695e5c7e339557be52f16319 Mon Sep 17 00:00:00 2001 From: unconst Date: Tue, 23 Jul 2024 14:38:09 -0500 Subject: [PATCH 45/58] fix checked div error --- pallets/subtensor/src/coinbase/run_coinbase.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/subtensor/src/coinbase/run_coinbase.rs b/pallets/subtensor/src/coinbase/run_coinbase.rs index df35304b1..abe44d55a 100644 --- a/pallets/subtensor/src/coinbase/run_coinbase.rs +++ b/pallets/subtensor/src/coinbase/run_coinbase.rs @@ -299,7 +299,7 @@ impl Pallet { // --- 10 Calculate this nominator's share of the emission. let nominator_emission: I64F64 = I64F64::from_num(emission_minus_take) .saturating_mul(I64F64::from_num(nominator_stake)) - .check_div(I64F64::from_num(total_hotkey_stake)) + .checked_div(I64F64::from_num(total_hotkey_stake)) .unwrap_or(I64F64::from_num(0)); // --- 11 Increase the stake for the nominator. From af50dd63462e7dc920f6c18d26140efb52d3e6ac Mon Sep 17 00:00:00 2001 From: unconst Date: Tue, 23 Jul 2024 16:23:24 -0500 Subject: [PATCH 46/58] adds a doublt Tempo limit to setting childkeys --- .../subtensor/src/coinbase/run_coinbase.rs | 66 ++++++++-------- pallets/subtensor/src/lib.rs | 12 +++ pallets/subtensor/src/macros/errors.rs | 2 + pallets/subtensor/src/staking/add_stake.rs | 4 +- pallets/subtensor/src/staking/set_children.rs | 9 +++ pallets/subtensor/src/utils.rs | 77 +++++++++++++++++++ 6 files changed, 137 insertions(+), 33 deletions(-) diff --git a/pallets/subtensor/src/coinbase/run_coinbase.rs b/pallets/subtensor/src/coinbase/run_coinbase.rs index abe44d55a..fcf76728f 100644 --- a/pallets/subtensor/src/coinbase/run_coinbase.rs +++ b/pallets/subtensor/src/coinbase/run_coinbase.rs @@ -1,5 +1,4 @@ use super::*; -use frame_support::storage::IterableStorageDoubleMap; use substrate_fixed::types::I64F64; use substrate_fixed::types::I96F32; @@ -262,7 +261,7 @@ impl Pallet { PendingdHotkeyEmission::::insert(hotkey, 0); // --- 2 Retrieve the last time this hotkey's emissions were drained. - let last_hotkey_emission_drain: u64 = LastHotkeyEmissionDrain::::get(hotkey); + let last_emission_drain: u64 = LastHotkeyEmissionDrain::::get(hotkey); // --- 3 Update the block value to the current block number. LastHotkeyEmissionDrain::::insert(hotkey, block_number); @@ -282,43 +281,48 @@ impl Pallet { // --- 7 Calculate the remaining emission after the hotkey's take. let mut remainder: u64 = emission_minus_take; - // --- 8 Iterate over each nominator. - for (nominator, nominator_stake) in - as IterableStorageDoubleMap>::iter_prefix( - hotkey, - ) - { - // --- 9 Check if the stake was manually increased by the user since the last emission drain for this hotkey. - // If it was, skip this nominator as they will not receive their proportion of the emission. - if LastAddStakeIncrease::::get(hotkey, nominator.clone()) - > last_hotkey_emission_drain - { - continue; + // --- 8 Iterate over each nominator and get all viable stake. + let mut total_viable_nominator_stake: u64 = total_hotkey_stake; + for (nominator, nominator_stake) in Stake::::iter_prefix(hotkey) { + if LastAddStakeIncrease::::get(hotkey, nominator) > last_emission_drain { + total_viable_nominator_stake = + total_viable_nominator_stake.saturating_sub(nominator_stake); } + } - // --- 10 Calculate this nominator's share of the emission. - let nominator_emission: I64F64 = I64F64::from_num(emission_minus_take) - .saturating_mul(I64F64::from_num(nominator_stake)) - .checked_div(I64F64::from_num(total_hotkey_stake)) - .unwrap_or(I64F64::from_num(0)); - - // --- 11 Increase the stake for the nominator. - Self::increase_stake_on_coldkey_hotkey_account( - &nominator, - hotkey, - nominator_emission.to_num::(), - ); + // --- 9 Iterate over each nominator. + if total_viable_nominator_stake != 0 { + for (nominator, nominator_stake) in Stake::::iter_prefix(hotkey) { + // --- 10 Check if the stake was manually increased by the user since the last emission drain for this hotkey. + // If it was, skip this nominator as they will not receive their proportion of the emission. + if LastAddStakeIncrease::::get(hotkey, nominator.clone()) > last_emission_drain { + continue; + } - // --- 11* Record event and Subtract the nominator's emission from the remainder. - total_new_tao = total_new_tao.saturating_add(nominator_emission.to_num::()); - remainder = remainder.saturating_sub(nominator_emission.to_num::()); + // --- 11 Calculate this nominator's share of the emission. + let nominator_emission: I64F64 = I64F64::from_num(emission_minus_take) + .saturating_mul(I64F64::from_num(nominator_stake)) + .checked_div(I64F64::from_num(total_viable_nominator_stake)) + .unwrap_or(I64F64::from_num(0)); + + // --- 12 Increase the stake for the nominator. + Self::increase_stake_on_coldkey_hotkey_account( + &nominator, + hotkey, + nominator_emission.to_num::(), + ); + + // --- 13* Record event and Subtract the nominator's emission from the remainder. + total_new_tao = total_new_tao.saturating_add(nominator_emission.to_num::()); + remainder = remainder.saturating_sub(nominator_emission.to_num::()); + } } - // --- 13 Finally, add the stake to the hotkey itself, including its take and the remaining emission. + // --- 14 Finally, add the stake to the hotkey itself, including its take and the remaining emission. let hotkey_new_tao: u64 = hotkey_take.saturating_add(remainder); Self::increase_stake_on_hotkey_account(hotkey, hotkey_new_tao); - // --- 14 Record new tao creation event and return the amount created. + // --- 15 Record new tao creation event and return the amount created. total_new_tao = total_new_tao.saturating_add(hotkey_new_tao); total_new_tao } diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index 6c16902d9..abf6a8613 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -44,6 +44,7 @@ pub mod staking; pub mod subnets; pub mod swap; pub mod utils; +use crate::utils::TransactionType; use macros::{config, dispatches, errors, events, genesis, hooks}; // apparently this is stabilized since rust 1.36 @@ -1051,6 +1052,17 @@ pub mod pallet { /// ================================= /// ==== Axon / Promo Endpoints ===== /// ================================= + #[pallet::storage] // --- NMAP ( hot, netuid, name ) --> last_block | Returns the last block of a transaction for a given key, netuid, and name. + pub type TransactionKeyLastBlock = StorageNMap< + _, + ( + NMapKey, // hot + NMapKey, // netuid + NMapKey, // extrinsic enum. + ), + u64, + ValueQuery, + >; #[pallet::storage] /// --- MAP ( key ) --> last_block pub type LastTxBlock = diff --git a/pallets/subtensor/src/macros/errors.rs b/pallets/subtensor/src/macros/errors.rs index 7e244834d..156cbea56 100644 --- a/pallets/subtensor/src/macros/errors.rs +++ b/pallets/subtensor/src/macros/errors.rs @@ -166,5 +166,7 @@ mod errors { ProportionOverflow, /// Too many children MAX 5. TooManyChildren, + /// Default transaction rate limit exceeded. + TxRateLimitExceeded, } } diff --git a/pallets/subtensor/src/staking/add_stake.rs b/pallets/subtensor/src/staking/add_stake.rs index eb7762bec..f62fd7cd2 100644 --- a/pallets/subtensor/src/staking/add_stake.rs +++ b/pallets/subtensor/src/staking/add_stake.rs @@ -70,8 +70,8 @@ impl Pallet { Error::::StakeRateLimitExceeded ); - // If this is a nomination stake, check if total stake after adding will be above - // the minimum required stake. + // Set the last time the stake increased for nominator drain protection. + LastAddStakeIncrease::::insert(&hotkey, &coldkey, Self::get_current_block_as_u64()); // If coldkey is not owner of the hotkey, it's a nomination stake. if !Self::coldkey_owns_hotkey(&coldkey, &hotkey) { diff --git a/pallets/subtensor/src/staking/set_children.rs b/pallets/subtensor/src/staking/set_children.rs index 071764734..f413db23f 100644 --- a/pallets/subtensor/src/staking/set_children.rs +++ b/pallets/subtensor/src/staking/set_children.rs @@ -58,6 +58,15 @@ impl Pallet { children ); + // Ensure the hotkey passes the rate limit. + ensure!( + Self::passes_rate_limit_globally( + &TransactionType::SetChildren, // Set children. + &hotkey, // Specific to a hotkey. + ), + Error::::TxRateLimitExceeded + ); + // --- 2. Check that this delegation is not on the root network. Child hotkeys are not valid on root. ensure!( netuid != Self::get_root_netuid(), diff --git a/pallets/subtensor/src/utils.rs b/pallets/subtensor/src/utils.rs index 6f5dbeaff..2cd49e198 100644 --- a/pallets/subtensor/src/utils.rs +++ b/pallets/subtensor/src/utils.rs @@ -7,6 +7,33 @@ use sp_core::Get; use sp_core::U256; use substrate_fixed::types::I32F32; +/// Enum representing different types of transactions +#[derive(Copy, Clone)] +pub enum TransactionType { + SetChildren, + Unknown, +} + +/// Implement conversion from TransactionType to u16 +impl From for u16 { + fn from(tx_type: TransactionType) -> Self { + match tx_type { + TransactionType::SetChildren => 0, + TransactionType::Unknown => 1, + } + } +} + +/// Implement conversion from u16 to TransactionType +impl From for TransactionType { + fn from(value: u16) -> Self { + match value { + 0 => TransactionType::SetChildren, + _ => TransactionType::Unknown, + } + } +} + impl Pallet { pub fn ensure_subnet_owner_or_root( o: T::RuntimeOrigin, @@ -278,6 +305,56 @@ impl Pallet { // ======================== // ==== Rate Limiting ===== // ======================== + /// Get the rate limit for a specific transaction type + pub fn get_rate_limit(tx_type: &TransactionType) -> u64 { + match tx_type { + TransactionType::SetChildren => (DefaultTempo::::get().saturating_mul(2)).into(), // Cannot set children twice within the default tempo period. + TransactionType::Unknown => 0, // Default to no limit for unknown types (no limit) + } + } + + /// Check if a transaction should be rate limited on a specific subnet + pub fn passes_rate_limit_on_subnet( + tx_type: &TransactionType, + hotkey: &T::AccountId, + netuid: u16, + ) -> bool { + let block: u64 = Self::get_current_block_as_u64(); + let limit: u64 = Self::get_rate_limit(tx_type); + let last_block: u64 = Self::get_last_transaction_block(hotkey, netuid, tx_type); + block.saturating_sub(last_block) < limit + } + + /// Check if a transaction should be rate limited globally + pub fn passes_rate_limit_globally(tx_type: &TransactionType, hotkey: &T::AccountId) -> bool { + let netuid: u16 = u16::MAX; + let block: u64 = Self::get_current_block_as_u64(); + let limit: u64 = Self::get_rate_limit(tx_type); + let last_block: u64 = Self::get_last_transaction_block(hotkey, netuid, tx_type); + block.saturating_sub(last_block) >= limit + } + + /// Get the block number of the last transaction for a specific hotkey, network, and transaction type + pub fn get_last_transaction_block( + hotkey: &T::AccountId, + netuid: u16, + tx_type: &TransactionType, + ) -> u64 { + let tx_as_u16: u16 = (*tx_type).into(); + TransactionKeyLastBlock::::get((hotkey, netuid, tx_as_u16)) + } + + /// Set the block number of the last transaction for a specific hotkey, network, and transaction type + pub fn set_last_transaction_block( + hotkey: &T::AccountId, + netuid: u16, + tx_type: &TransactionType, + block: u64, + ) { + let tx_as_u16: u16 = (*tx_type).into(); + TransactionKeyLastBlock::::insert((hotkey, netuid, tx_as_u16), block); + } + pub fn set_last_tx_block(key: &T::AccountId, block: u64) { LastTxBlock::::insert(key, block) } From f9b6828806dd252de9255226c9822a6647c54c7a Mon Sep 17 00:00:00 2001 From: unconst Date: Wed, 24 Jul 2024 13:42:18 -0500 Subject: [PATCH 47/58] try state for total issuance done --- pallets/subtensor/src/lib.rs | 11 +- pallets/subtensor/src/macros/hooks.rs | 6 + .../migrations/migrate_init_total_issuance.rs | 83 +++++++++++++ pallets/subtensor/src/migrations/mod.rs | 1 + pallets/subtensor/src/staking/helpers.rs | 1 - .../subtensor/src/{utils.rs => utils/misc.rs} | 92 ++------------ pallets/subtensor/src/utils/mod.rs | 4 + pallets/subtensor/src/utils/rate_limiting.rs | 112 ++++++++++++++++++ pallets/subtensor/src/utils/try_state.rs | 49 ++++++++ pallets/subtensor/tests/migration.rs | 25 ++++ runtime/src/lib.rs | 25 +++- 11 files changed, 317 insertions(+), 92 deletions(-) create mode 100644 pallets/subtensor/src/migrations/migrate_init_total_issuance.rs rename pallets/subtensor/src/{utils.rs => utils/misc.rs} (89%) create mode 100644 pallets/subtensor/src/utils/mod.rs create mode 100644 pallets/subtensor/src/utils/rate_limiting.rs create mode 100644 pallets/subtensor/src/utils/try_state.rs diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index abf6a8613..1450b5706 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -44,7 +44,7 @@ pub mod staking; pub mod subnets; pub mod swap; pub mod utils; -use crate::utils::TransactionType; +use crate::utils::rate_limiting::TransactionType; use macros::{config, dispatches, errors, events, genesis, hooks}; // apparently this is stabilized since rust 1.36 @@ -563,6 +563,15 @@ pub mod pallet { /// ============================ /// ==== Staking Variables ==== /// ============================ + /// The Subtensor [`TotalIssuance`] represents the total issuance of tokens on the Bittensor network. + /// + /// It is comprised of three parts: + /// - The total amount of issued tokens, tracked in the TotalIssuance of the Balances pallet + /// - The total amount of tokens staked in the system, tracked in [`TotalStake`] + /// - The total amount of tokens locked up for subnet reg, tracked in [`TotalSubnetLocked`] attained by iterating over subnet lock. + /// + /// Eventually, Bittensor should migrate to using Holds afterwhich time we will not require this + /// separate accounting. #[pallet::storage] // --- ITEM ( total_issuance ) pub type TotalIssuance = StorageValue<_, u64, ValueQuery, DefaultTotalIssuance>; #[pallet::storage] // --- ITEM ( total_stake ) diff --git a/pallets/subtensor/src/macros/hooks.rs b/pallets/subtensor/src/macros/hooks.rs index b04a29ff6..22c741465 100644 --- a/pallets/subtensor/src/macros/hooks.rs +++ b/pallets/subtensor/src/macros/hooks.rs @@ -71,5 +71,11 @@ mod hooks { .saturating_add(migrations::migrate_fix_total_coldkey_stake::migrate_fix_total_coldkey_stake::()); weight } + + #[cfg(feature = "try-runtime")] + fn try_state(_n: BlockNumberFor) -> Result<(), sp_runtime::TryRuntimeError> { + Self::check_accounting_invariants()?; + Ok(()) + } } } diff --git a/pallets/subtensor/src/migrations/migrate_init_total_issuance.rs b/pallets/subtensor/src/migrations/migrate_init_total_issuance.rs new file mode 100644 index 000000000..a488771c5 --- /dev/null +++ b/pallets/subtensor/src/migrations/migrate_init_total_issuance.rs @@ -0,0 +1,83 @@ +use super::*; +use frame_support::pallet_prelude::OptionQuery; +use frame_support::{pallet_prelude::Identity, storage_alias}; +use sp_std::vec::Vec; + +// TODO: Implement comprehensive tests for this migration + +/// Module containing deprecated storage format for LoadedEmission +pub mod deprecated_loaded_emission_format { + use super::*; + + #[storage_alias] + pub(super) type LoadedEmission = + StorageMap, Identity, u16, Vec<(AccountIdOf, u64)>, OptionQuery>; +} + +pub mod initialise_total_issuance { + use frame_support::pallet_prelude::Weight; + use frame_support::traits::{fungible, OnRuntimeUpgrade}; + use sp_core::Get; + + use crate::*; + + pub struct Migration(PhantomData); + + impl OnRuntimeUpgrade for Migration { + /// Performs the migration to initialize and update the total issuance. + /// + /// This function does the following: + /// 1. Calculates the total locked tokens across all subnets + /// 2. Retrieves the total account balances and total stake + /// 3. Computes and updates the new total issuance + /// + /// Returns the weight of the migration operation. + fn on_runtime_upgrade() -> Weight { + // Calculate the total locked tokens across all subnets + let subnets_len = crate::SubnetLocked::::iter().count() as u64; + let total_subnet_locked: u64 = + crate::SubnetLocked::::iter().fold(0, |acc, (_, v)| acc.saturating_add(v)); + + // Retrieve the total balance of all accounts + let total_account_balances = <::Currency as fungible::Inspect< + ::AccountId, + >>::total_issuance(); + + // Get the total stake from the system + let total_stake = crate::TotalStake::::get(); + + // Retrieve the previous total issuance for logging purposes + let prev_total_issuance = crate::TotalIssuance::::get(); + + // Calculate the new total issuance + let new_total_issuance = total_account_balances + .saturating_add(total_stake) + .saturating_add(total_subnet_locked); + + // Update the total issuance in storage + crate::TotalIssuance::::put(new_total_issuance); + + // Log the change in total issuance + log::info!( + "Subtensor Pallet Total Issuance Updated: previous: {:?}, new: {:?}", + prev_total_issuance, + new_total_issuance + ); + + // Return the weight of the operation + // We performed subnets_len + 5 reads and 1 write + ::DbWeight::get() + .reads_writes(subnets_len.saturating_add(5), 1) + } + + /// Performs post-upgrade checks to ensure the migration was successful. + /// + /// This function is only compiled when the "try-runtime" feature is enabled. + #[cfg(feature = "try-runtime")] + fn post_upgrade(_state: Vec) -> Result<(), sp_runtime::TryRuntimeError> { + // Verify that all accounting invariants are satisfied after the migration + crate::Pallet::::check_accounting_invariants()?; + Ok(()) + } + } +} diff --git a/pallets/subtensor/src/migrations/mod.rs b/pallets/subtensor/src/migrations/mod.rs index df0f7ce06..5b93dbbaf 100644 --- a/pallets/subtensor/src/migrations/mod.rs +++ b/pallets/subtensor/src/migrations/mod.rs @@ -3,6 +3,7 @@ pub mod migrate_create_root_network; pub mod migrate_delete_subnet_21; pub mod migrate_delete_subnet_3; pub mod migrate_fix_total_coldkey_stake; +pub mod migrate_init_total_issuance; pub mod migrate_populate_owned_hotkeys; pub mod migrate_populate_staking_hotkeys; pub mod migrate_to_v1_separate_emission; diff --git a/pallets/subtensor/src/staking/helpers.rs b/pallets/subtensor/src/staking/helpers.rs index 486577712..dad071fb5 100644 --- a/pallets/subtensor/src/staking/helpers.rs +++ b/pallets/subtensor/src/staking/helpers.rs @@ -284,7 +284,6 @@ impl Pallet { TotalHotkeyStake::::mutate(hotkey, |stake| *stake = stake.saturating_sub(current_stake)); Stake::::remove(hotkey, coldkey); TotalStake::::mutate(|stake| *stake = stake.saturating_sub(current_stake)); - TotalIssuance::::mutate(|issuance| *issuance = issuance.saturating_sub(current_stake)); // Update StakingHotkeys map let mut staking_hotkeys = StakingHotkeys::::get(coldkey); diff --git a/pallets/subtensor/src/utils.rs b/pallets/subtensor/src/utils/misc.rs similarity index 89% rename from pallets/subtensor/src/utils.rs rename to pallets/subtensor/src/utils/misc.rs index 2cd49e198..9155357c0 100644 --- a/pallets/subtensor/src/utils.rs +++ b/pallets/subtensor/src/utils/misc.rs @@ -5,6 +5,7 @@ use crate::{ }; use sp_core::Get; use sp_core::U256; +use sp_runtime::Saturating; use substrate_fixed::types::I32F32; /// Enum representing different types of transactions @@ -302,88 +303,6 @@ impl Pallet { Ok(()) } - // ======================== - // ==== Rate Limiting ===== - // ======================== - /// Get the rate limit for a specific transaction type - pub fn get_rate_limit(tx_type: &TransactionType) -> u64 { - match tx_type { - TransactionType::SetChildren => (DefaultTempo::::get().saturating_mul(2)).into(), // Cannot set children twice within the default tempo period. - TransactionType::Unknown => 0, // Default to no limit for unknown types (no limit) - } - } - - /// Check if a transaction should be rate limited on a specific subnet - pub fn passes_rate_limit_on_subnet( - tx_type: &TransactionType, - hotkey: &T::AccountId, - netuid: u16, - ) -> bool { - let block: u64 = Self::get_current_block_as_u64(); - let limit: u64 = Self::get_rate_limit(tx_type); - let last_block: u64 = Self::get_last_transaction_block(hotkey, netuid, tx_type); - block.saturating_sub(last_block) < limit - } - - /// Check if a transaction should be rate limited globally - pub fn passes_rate_limit_globally(tx_type: &TransactionType, hotkey: &T::AccountId) -> bool { - let netuid: u16 = u16::MAX; - let block: u64 = Self::get_current_block_as_u64(); - let limit: u64 = Self::get_rate_limit(tx_type); - let last_block: u64 = Self::get_last_transaction_block(hotkey, netuid, tx_type); - block.saturating_sub(last_block) >= limit - } - - /// Get the block number of the last transaction for a specific hotkey, network, and transaction type - pub fn get_last_transaction_block( - hotkey: &T::AccountId, - netuid: u16, - tx_type: &TransactionType, - ) -> u64 { - let tx_as_u16: u16 = (*tx_type).into(); - TransactionKeyLastBlock::::get((hotkey, netuid, tx_as_u16)) - } - - /// Set the block number of the last transaction for a specific hotkey, network, and transaction type - pub fn set_last_transaction_block( - hotkey: &T::AccountId, - netuid: u16, - tx_type: &TransactionType, - block: u64, - ) { - let tx_as_u16: u16 = (*tx_type).into(); - TransactionKeyLastBlock::::insert((hotkey, netuid, tx_as_u16), block); - } - - pub fn set_last_tx_block(key: &T::AccountId, block: u64) { - LastTxBlock::::insert(key, block) - } - pub fn get_last_tx_block(key: &T::AccountId) -> u64 { - LastTxBlock::::get(key) - } - pub fn set_last_tx_block_delegate_take(key: &T::AccountId, block: u64) { - LastTxBlockDelegateTake::::insert(key, block) - } - pub fn get_last_tx_block_delegate_take(key: &T::AccountId) -> u64 { - LastTxBlockDelegateTake::::get(key) - } - pub fn exceeds_tx_rate_limit(prev_tx_block: u64, current_block: u64) -> bool { - let rate_limit: u64 = Self::get_tx_rate_limit(); - if rate_limit == 0 || prev_tx_block == 0 { - return false; - } - - current_block.saturating_sub(prev_tx_block) <= rate_limit - } - pub fn exceeds_tx_delegate_take_rate_limit(prev_tx_block: u64, current_block: u64) -> bool { - let rate_limit: u64 = Self::get_tx_delegate_take_rate_limit(); - if rate_limit == 0 || prev_tx_block == 0 { - return false; - } - - current_block.saturating_sub(prev_tx_block) <= rate_limit - } - // ======================== // === Token Management === // ======================== @@ -404,14 +323,19 @@ impl Pallet { pub fn get_min_take() -> u16 { MinTake::::get() } - pub fn set_subnet_locked_balance(netuid: u16, amount: u64) { SubnetLocked::::insert(netuid, amount); } - pub fn get_subnet_locked_balance(netuid: u16) -> u64 { SubnetLocked::::get(netuid) } + pub fn get_total_subnet_locked() -> u64 { + let mut total_subnet_locked: u64 = 0; + for (_, locked) in SubnetLocked::::iter() { + total_subnet_locked.saturating_accrue(locked); + } + total_subnet_locked + } // ======================== // ========= Sudo ========= diff --git a/pallets/subtensor/src/utils/mod.rs b/pallets/subtensor/src/utils/mod.rs new file mode 100644 index 000000000..72b903dd8 --- /dev/null +++ b/pallets/subtensor/src/utils/mod.rs @@ -0,0 +1,4 @@ +use super::*; +pub mod misc; +pub mod rate_limiting; +pub mod try_state; diff --git a/pallets/subtensor/src/utils/rate_limiting.rs b/pallets/subtensor/src/utils/rate_limiting.rs new file mode 100644 index 000000000..ffd17ca93 --- /dev/null +++ b/pallets/subtensor/src/utils/rate_limiting.rs @@ -0,0 +1,112 @@ +use super::*; +use sp_core::Get; + +/// Enum representing different types of transactions +#[derive(Copy, Clone)] +pub enum TransactionType { + SetChildren, + Unknown, +} + +/// Implement conversion from TransactionType to u16 +impl From for u16 { + fn from(tx_type: TransactionType) -> Self { + match tx_type { + TransactionType::SetChildren => 0, + TransactionType::Unknown => 1, + } + } +} + +/// Implement conversion from u16 to TransactionType +impl From for TransactionType { + fn from(value: u16) -> Self { + match value { + 0 => TransactionType::SetChildren, + _ => TransactionType::Unknown, + } + } +} +impl Pallet { + // ======================== + // ==== Rate Limiting ===== + // ======================== + /// Get the rate limit for a specific transaction type + pub fn get_rate_limit(tx_type: &TransactionType) -> u64 { + match tx_type { + TransactionType::SetChildren => (DefaultTempo::::get().saturating_mul(2)).into(), // Cannot set children twice within the default tempo period. + TransactionType::Unknown => 0, // Default to no limit for unknown types (no limit) + } + } + + /// Check if a transaction should be rate limited on a specific subnet + pub fn passes_rate_limit_on_subnet( + tx_type: &TransactionType, + hotkey: &T::AccountId, + netuid: u16, + ) -> bool { + let block: u64 = Self::get_current_block_as_u64(); + let limit: u64 = Self::get_rate_limit(tx_type); + let last_block: u64 = Self::get_last_transaction_block(hotkey, netuid, tx_type); + block.saturating_sub(last_block) < limit + } + + /// Check if a transaction should be rate limited globally + pub fn passes_rate_limit_globally(tx_type: &TransactionType, hotkey: &T::AccountId) -> bool { + let netuid: u16 = u16::MAX; + let block: u64 = Self::get_current_block_as_u64(); + let limit: u64 = Self::get_rate_limit(tx_type); + let last_block: u64 = Self::get_last_transaction_block(hotkey, netuid, tx_type); + block.saturating_sub(last_block) >= limit + } + + /// Get the block number of the last transaction for a specific hotkey, network, and transaction type + pub fn get_last_transaction_block( + hotkey: &T::AccountId, + netuid: u16, + tx_type: &TransactionType, + ) -> u64 { + let tx_as_u16: u16 = (*tx_type).into(); + TransactionKeyLastBlock::::get((hotkey, netuid, tx_as_u16)) + } + + /// Set the block number of the last transaction for a specific hotkey, network, and transaction type + pub fn set_last_transaction_block( + hotkey: &T::AccountId, + netuid: u16, + tx_type: &TransactionType, + block: u64, + ) { + let tx_as_u16: u16 = (*tx_type).into(); + TransactionKeyLastBlock::::insert((hotkey, netuid, tx_as_u16), block); + } + + pub fn set_last_tx_block(key: &T::AccountId, block: u64) { + LastTxBlock::::insert(key, block) + } + pub fn get_last_tx_block(key: &T::AccountId) -> u64 { + LastTxBlock::::get(key) + } + pub fn set_last_tx_block_delegate_take(key: &T::AccountId, block: u64) { + LastTxBlockDelegateTake::::insert(key, block) + } + pub fn get_last_tx_block_delegate_take(key: &T::AccountId) -> u64 { + LastTxBlockDelegateTake::::get(key) + } + pub fn exceeds_tx_rate_limit(prev_tx_block: u64, current_block: u64) -> bool { + let rate_limit: u64 = Self::get_tx_rate_limit(); + if rate_limit == 0 || prev_tx_block == 0 { + return false; + } + + current_block.saturating_sub(prev_tx_block) <= rate_limit + } + pub fn exceeds_tx_delegate_take_rate_limit(prev_tx_block: u64, current_block: u64) -> bool { + let rate_limit: u64 = Self::get_tx_delegate_take_rate_limit(); + if rate_limit == 0 || prev_tx_block == 0 { + return false; + } + + current_block.saturating_sub(prev_tx_block) <= rate_limit + } +} diff --git a/pallets/subtensor/src/utils/try_state.rs b/pallets/subtensor/src/utils/try_state.rs new file mode 100644 index 000000000..4763c0484 --- /dev/null +++ b/pallets/subtensor/src/utils/try_state.rs @@ -0,0 +1,49 @@ +use super::*; + +impl Pallet { + /// Checks if the accounting invariants for [`TotalStake`], [`TotalSubnetLocked`], and [`TotalIssuance`] are correct. + /// + /// This function verifies that: + /// 1. The sum of all stakes matches the [`TotalStake`]. + /// 2. The [`TotalSubnetLocked`] is correctly calculated. + /// 3. The [`TotalIssuance`] equals the sum of currency issuance, total stake, and total subnet locked. + /// + /// # Returns + /// + /// Returns `Ok(())` if all invariants are correct, otherwise returns an error. + #[cfg(feature = "try-runtime")] + pub fn check_accounting_invariants() -> Result<(), sp_runtime::TryRuntimeError> { + use frame_support::traits::fungible::Inspect; + + // Calculate the total staked amount + let mut total_staked: u64 = 0; + for (_account, _netuid, stake) in Stake::::iter() { + total_staked = total_staked.saturating_add(stake); + } + + // Verify that the calculated total stake matches the stored TotalStake + ensure!( + total_staked == TotalStake::::get(), + "TotalStake does not match total staked", + ); + + // Get the total subnet locked amount + let total_subnet_locked: u64 = Self::get_total_subnet_locked(); + + // Get the total currency issuance + let currency_issuance: u64 = T::Currency::total_issuance(); + + // Calculate the expected total issuance + let expected_total_issuance: u64 = currency_issuance + .saturating_add(total_staked) + .saturating_add(total_subnet_locked); + + // Verify that the calculated total issuance matches the stored TotalIssuance + ensure!( + TotalIssuance::::get() == expected_total_issuance, + "TotalIssuance accounting discrepancy", + ); + + Ok(()) + } +} diff --git a/pallets/subtensor/tests/migration.rs b/pallets/subtensor/tests/migration.rs index bd77c7be0..244c2d86a 100644 --- a/pallets/subtensor/tests/migration.rs +++ b/pallets/subtensor/tests/migration.rs @@ -6,6 +6,31 @@ use mock::*; use pallet_subtensor::*; use sp_core::U256; +#[test] +fn test_initialise_ti() { + use frame_support::traits::OnRuntimeUpgrade; + + new_test_ext(1).execute_with(|| { + pallet_subtensor::SubnetLocked::::insert(1, 100); + pallet_subtensor::SubnetLocked::::insert(2, 5); + pallet_balances::TotalIssuance::::put(1000); + pallet_subtensor::TotalStake::::put(25); + + // Ensure values are NOT initialized prior to running migration + assert!(pallet_subtensor::TotalIssuance::::get() == 0); + assert!(pallet_subtensor::TotalSubnetLocked::::get() == 0); + + pallet_subtensor::migration::initialise_total_issuance::Migration::::on_runtime_upgrade(); + + // Ensure values were initialized correctly + assert!(pallet_subtensor::TotalSubnetLocked::::get() == 105); + assert!( + pallet_subtensor::TotalIssuance::::get() + == 105u64.saturating_add(1000).saturating_add(25) + ); + }); +} + #[test] fn test_migration_fix_total_stake_maps() { new_test_ext(1).execute_with(|| { diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 2d1716337..3bd71977e 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -12,13 +12,15 @@ pub mod check_nonce; mod migrations; use codec::{Decode, Encode, MaxEncodedLen}; +use frame_support::traits::Imbalance; use frame_support::{ dispatch::DispatchResultWithPostInfo, genesis_builder_helper::{build_config, create_default_config}, pallet_prelude::{DispatchError, Get}, - traits::{fungible::HoldConsideration, Contains, LinearStoragePrice}, + traits::{fungible::HoldConsideration, Contains, LinearStoragePrice, OnUnbalanced}, }; use frame_system::{EnsureNever, EnsureRoot, EnsureRootWithSuccess, RawOrigin}; +use pallet_balances::NegativeImbalance; use pallet_commitments::CanCommit; use pallet_grandpa::{ fg_primitives, AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList, @@ -388,11 +390,22 @@ parameter_types! { pub FeeMultiplier: Multiplier = Multiplier::one(); } +/// Deduct the transaction fee from the Subtensor Pallet TotalIssuance when dropping the transaction +/// fee. +pub struct TransactionFeeHandler; +impl OnUnbalanced> for TransactionFeeHandler { + fn on_nonzero_unbalanced(credit: NegativeImbalance) { + let ti_before = pallet_subtensor::TotalIssuance::::get(); + pallet_subtensor::TotalIssuance::::put(ti_before.saturating_sub(credit.peek())); + drop(credit); + } +} + impl pallet_transaction_payment::Config for Runtime { type RuntimeEvent = RuntimeEvent; - type OnChargeTransaction = CurrencyAdapter; //type TransactionByteFee = TransactionByteFee; + type OnChargeTransaction = CurrencyAdapter; // Convert dispatch weight to a chargeable fee. type WeightToFee = LinearWeightToFee; @@ -1295,7 +1308,10 @@ pub type SignedExtra = ( frame_metadata_hash_extension::CheckMetadataHash, ); -type Migrations = pallet_grandpa::migrations::MigrateV4ToV5; +type Migrations = + pallet_subtensor::migrations::migrate_init_total_issuance::initialise_total_issuance::Migration< + Runtime, + >; // Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = @@ -1536,10 +1552,7 @@ impl_runtime_apis! { use frame_system_benchmarking::Pallet as SystemBench; use baseline::Pallet as BaselineBench; - #[allow(non_local_definitions)] impl frame_system_benchmarking::Config for Runtime {} - - #[allow(non_local_definitions)] impl baseline::Config for Runtime {} use frame_support::traits::WhitelistedStorageKeys; From c9586214da22ad0474e48dbfe6abe6758a524513 Mon Sep 17 00:00:00 2001 From: unconst Date: Wed, 24 Jul 2024 13:52:53 -0500 Subject: [PATCH 48/58] ranked choice voting --- pallets/subtensor/tests/migration.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pallets/subtensor/tests/migration.rs b/pallets/subtensor/tests/migration.rs index 244c2d86a..2a1388237 100644 --- a/pallets/subtensor/tests/migration.rs +++ b/pallets/subtensor/tests/migration.rs @@ -18,12 +18,10 @@ fn test_initialise_ti() { // Ensure values are NOT initialized prior to running migration assert!(pallet_subtensor::TotalIssuance::::get() == 0); - assert!(pallet_subtensor::TotalSubnetLocked::::get() == 0); - pallet_subtensor::migration::initialise_total_issuance::Migration::::on_runtime_upgrade(); + pallet_subtensor::migrations::migrate_init_total_issuance::initialise_total_issuance::Migration::::on_runtime_upgrade(); // Ensure values were initialized correctly - assert!(pallet_subtensor::TotalSubnetLocked::::get() == 105); assert!( pallet_subtensor::TotalIssuance::::get() == 105u64.saturating_add(1000).saturating_add(25) From 53288a0449d9ff488e2641f4629220bc449da7c3 Mon Sep 17 00:00:00 2001 From: unconst Date: Wed, 24 Jul 2024 14:07:32 -0500 Subject: [PATCH 49/58] add tests and add swap --- pallets/subtensor/src/swap/swap_hotkey.rs | 34 ++++++ pallets/subtensor/tests/swap_hotkey.rs | 127 ++++++++++++++++++++++ 2 files changed, 161 insertions(+) diff --git a/pallets/subtensor/src/swap/swap_hotkey.rs b/pallets/subtensor/src/swap/swap_hotkey.rs index fb3c33e4d..faadf5de5 100644 --- a/pallets/subtensor/src/swap/swap_hotkey.rs +++ b/pallets/subtensor/src/swap/swap_hotkey.rs @@ -307,6 +307,40 @@ impl Pallet { weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); } + // 11. Swap ChildKeys. + // ChildKeys( parent, netuid ) --> Vec<(proportion,child)> -- the child keys of the parent. + for netuid in Self::get_all_subnet_netuids() { + // Get the children of the old hotkey for this subnet + let my_children: Vec<(u64, T::AccountId)> = ChildKeys::::get(old_hotkey, netuid); + // Remove the old hotkey's child entries + ChildKeys::::remove(old_hotkey, netuid); + // Insert the same child entries for the new hotkey + ChildKeys::::insert(new_hotkey, netuid, my_children); + } + + // 12. Swap ParentKeys. + // ParentKeys( child, netuid ) --> Vec<(proportion,parent)> -- the parent keys of the child. + for netuid in Self::get_all_subnet_netuids() { + // Get the parents of the old hotkey for this subnet + let parents: Vec<(u64, T::AccountId)> = ParentKeys::::get(old_hotkey, netuid); + // Remove the old hotkey's parent entries + ParentKeys::::remove(old_hotkey, netuid); + // Insert the same parent entries for the new hotkey + ParentKeys::::insert(new_hotkey, netuid, parents.clone()); + for (_, parent_key_i) in parents { + // For each parent, update their children list + let mut parent_children: Vec<(u64, T::AccountId)> = ChildKeys::::get(parent_key_i.clone(), netuid); + for child in parent_children.iter_mut() { + // If the child is the old hotkey, replace it with the new hotkey + if child.1 == *old_hotkey { + child.1 = new_hotkey.clone(); + } + } + // Update the parent's children list + ChildKeys::::insert(parent_key_i, netuid, parent_children); + } + } + // Return successful after swapping all the relevant terms. Ok(()) } diff --git a/pallets/subtensor/tests/swap_hotkey.rs b/pallets/subtensor/tests/swap_hotkey.rs index c6a05f2b6..5339c0008 100644 --- a/pallets/subtensor/tests/swap_hotkey.rs +++ b/pallets/subtensor/tests/swap_hotkey.rs @@ -959,3 +959,130 @@ fn test_swap_hotkey_error_cases() { assert_eq!(Balances::free_balance(coldkey), initial_balance - swap_cost); }); } + + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_child_keys --exact --nocapture +#[test] +fn test_swap_child_keys() { + 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 = 0u16; + let children = vec![(100u64, U256::from(4)), (200u64, U256::from(5))]; + let mut weight = Weight::zero(); + + // Initialize ChildKeys for old_hotkey + add_network(netuid, 1, 0); + ChildKeys::::insert(old_hotkey, netuid, children.clone()); + + // Perform the swap + SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight); + + // Verify the swap + assert_eq!(ChildKeys::::get(new_hotkey, netuid), children); + assert!(ChildKeys::::get(old_hotkey, netuid).is_empty()); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_parent_keys --exact --nocapture +#[test] +fn test_swap_parent_keys() { + 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 = 0u16; + let parents = vec![(100u64, U256::from(4)), (200u64, U256::from(5))]; + let mut weight = Weight::zero(); + + // Initialize ParentKeys for old_hotkey + add_network(netuid, 1, 0); + ParentKeys::::insert(old_hotkey, netuid, parents.clone()); + + // Initialize ChildKeys for parent + ChildKeys::::insert(U256::from(4), netuid, vec![(100u64, old_hotkey)]); + ChildKeys::::insert(U256::from(5), netuid, vec![(200u64, old_hotkey)]); + + // Perform the swap + SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight); + + // Verify ParentKeys swap + assert_eq!(ParentKeys::::get(new_hotkey, netuid), parents); + assert!(ParentKeys::::get(old_hotkey, netuid).is_empty()); + + // Verify ChildKeys update for parents + assert_eq!(ChildKeys::::get(U256::from(4), netuid), vec![(100u64, new_hotkey)]); + assert_eq!(ChildKeys::::get(U256::from(5), netuid), vec![(200u64, new_hotkey)]); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_multiple_subnets --exact --nocapture +#[test] +fn test_swap_multiple_subnets() { + new_test_ext(1).execute_with(|| { + let old_hotkey = U256::from(1); + let new_hotkey = U256::from(2); + let coldkey = U256::from(3); + let netuid1 = 0u16; + let netuid2 = 1u16; + let children1 = vec![(100u64, U256::from(4)), (200u64, U256::from(5))]; + let children2 = vec![(300u64, U256::from(6))]; + let mut weight = Weight::zero(); + + add_network(netuid1, 1, 0); + add_network(netuid2, 1, 0); + + // Initialize ChildKeys for old_hotkey in multiple subnets + ChildKeys::::insert(old_hotkey, netuid1, children1.clone()); + ChildKeys::::insert(old_hotkey, netuid2, children2.clone()); + + // Perform the swap + SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight); + + // Verify the swap for both subnets + assert_eq!(ChildKeys::::get(new_hotkey, netuid1), children1); + assert_eq!(ChildKeys::::get(new_hotkey, netuid2), children2); + assert!(ChildKeys::::get(old_hotkey, netuid1).is_empty()); + assert!(ChildKeys::::get(old_hotkey, netuid2).is_empty()); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_complex_parent_child_structure --exact --nocapture +#[test] +fn test_swap_complex_parent_child_structure() { + 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 = 0u16; + let parent1 = U256::from(4); + let parent2 = U256::from(5); + let child1 = U256::from(6); + let child2 = U256::from(7); + let mut weight = Weight::zero(); + + add_network(netuid, 1, 0); + + // Set up complex parent-child structure + ParentKeys::::insert(old_hotkey, netuid, vec![(100u64, parent1), (200u64, parent2)]); + ChildKeys::::insert(old_hotkey, netuid, vec![(300u64, child1), (400u64, child2)]); + ChildKeys::::insert(parent1, netuid, vec![(100u64, old_hotkey), (500u64, U256::from(8))]); + ChildKeys::::insert(parent2, netuid, vec![(200u64, old_hotkey), (600u64, U256::from(9))]); + + // Perform the swap + SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight); + + // Verify ParentKeys swap + assert_eq!(ParentKeys::::get(new_hotkey, netuid), vec![(100u64, parent1), (200u64, parent2)]); + assert!(ParentKeys::::get(old_hotkey, netuid).is_empty()); + + // Verify ChildKeys swap + assert_eq!(ChildKeys::::get(new_hotkey, netuid), vec![(300u64, child1), (400u64, child2)]); + assert!(ChildKeys::::get(old_hotkey, netuid).is_empty()); + + // Verify parent's ChildKeys update + assert_eq!(ChildKeys::::get(parent1, netuid), vec![(100u64, new_hotkey), (500u64, U256::from(8))]); + assert_eq!(ChildKeys::::get(parent2, netuid), vec![(200u64, new_hotkey), (600u64, U256::from(9))]); + }); +} \ No newline at end of file From 7107ae08dafa531eea905b97b920a2999ff996e7 Mon Sep 17 00:00:00 2001 From: unconst Date: Wed, 24 Jul 2024 14:07:44 -0500 Subject: [PATCH 50/58] fmt --- pallets/subtensor/src/swap/swap_hotkey.rs | 15 +++---- pallets/subtensor/tests/swap_hotkey.rs | 51 ++++++++++++++++++----- 2 files changed, 48 insertions(+), 18 deletions(-) diff --git a/pallets/subtensor/src/swap/swap_hotkey.rs b/pallets/subtensor/src/swap/swap_hotkey.rs index faadf5de5..366494d11 100644 --- a/pallets/subtensor/src/swap/swap_hotkey.rs +++ b/pallets/subtensor/src/swap/swap_hotkey.rs @@ -310,12 +310,12 @@ impl Pallet { // 11. Swap ChildKeys. // ChildKeys( parent, netuid ) --> Vec<(proportion,child)> -- the child keys of the parent. for netuid in Self::get_all_subnet_netuids() { - // Get the children of the old hotkey for this subnet - let my_children: Vec<(u64, T::AccountId)> = ChildKeys::::get(old_hotkey, netuid); - // Remove the old hotkey's child entries - ChildKeys::::remove(old_hotkey, netuid); - // Insert the same child entries for the new hotkey - ChildKeys::::insert(new_hotkey, netuid, my_children); + // Get the children of the old hotkey for this subnet + let my_children: Vec<(u64, T::AccountId)> = ChildKeys::::get(old_hotkey, netuid); + // Remove the old hotkey's child entries + ChildKeys::::remove(old_hotkey, netuid); + // Insert the same child entries for the new hotkey + ChildKeys::::insert(new_hotkey, netuid, my_children); } // 12. Swap ParentKeys. @@ -329,7 +329,8 @@ impl Pallet { ParentKeys::::insert(new_hotkey, netuid, parents.clone()); for (_, parent_key_i) in parents { // For each parent, update their children list - let mut parent_children: Vec<(u64, T::AccountId)> = ChildKeys::::get(parent_key_i.clone(), netuid); + let mut parent_children: Vec<(u64, T::AccountId)> = + ChildKeys::::get(parent_key_i.clone(), netuid); for child in parent_children.iter_mut() { // If the child is the old hotkey, replace it with the new hotkey if child.1 == *old_hotkey { diff --git a/pallets/subtensor/tests/swap_hotkey.rs b/pallets/subtensor/tests/swap_hotkey.rs index 5339c0008..bff738b86 100644 --- a/pallets/subtensor/tests/swap_hotkey.rs +++ b/pallets/subtensor/tests/swap_hotkey.rs @@ -960,7 +960,6 @@ fn test_swap_hotkey_error_cases() { }); } - // SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_child_keys --exact --nocapture #[test] fn test_swap_child_keys() { @@ -1012,8 +1011,14 @@ fn test_swap_parent_keys() { assert!(ParentKeys::::get(old_hotkey, netuid).is_empty()); // Verify ChildKeys update for parents - assert_eq!(ChildKeys::::get(U256::from(4), netuid), vec![(100u64, new_hotkey)]); - assert_eq!(ChildKeys::::get(U256::from(5), netuid), vec![(200u64, new_hotkey)]); + assert_eq!( + ChildKeys::::get(U256::from(4), netuid), + vec![(100u64, new_hotkey)] + ); + assert_eq!( + ChildKeys::::get(U256::from(5), netuid), + vec![(200u64, new_hotkey)] + ); }); } @@ -1065,24 +1070,48 @@ fn test_swap_complex_parent_child_structure() { add_network(netuid, 1, 0); // Set up complex parent-child structure - ParentKeys::::insert(old_hotkey, netuid, vec![(100u64, parent1), (200u64, parent2)]); + ParentKeys::::insert( + old_hotkey, + netuid, + vec![(100u64, parent1), (200u64, parent2)], + ); ChildKeys::::insert(old_hotkey, netuid, vec![(300u64, child1), (400u64, child2)]); - ChildKeys::::insert(parent1, netuid, vec![(100u64, old_hotkey), (500u64, U256::from(8))]); - ChildKeys::::insert(parent2, netuid, vec![(200u64, old_hotkey), (600u64, U256::from(9))]); + ChildKeys::::insert( + parent1, + netuid, + vec![(100u64, old_hotkey), (500u64, U256::from(8))], + ); + ChildKeys::::insert( + parent2, + netuid, + vec![(200u64, old_hotkey), (600u64, U256::from(9))], + ); // Perform the swap SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight); // Verify ParentKeys swap - assert_eq!(ParentKeys::::get(new_hotkey, netuid), vec![(100u64, parent1), (200u64, parent2)]); + assert_eq!( + ParentKeys::::get(new_hotkey, netuid), + vec![(100u64, parent1), (200u64, parent2)] + ); assert!(ParentKeys::::get(old_hotkey, netuid).is_empty()); // Verify ChildKeys swap - assert_eq!(ChildKeys::::get(new_hotkey, netuid), vec![(300u64, child1), (400u64, child2)]); + assert_eq!( + ChildKeys::::get(new_hotkey, netuid), + vec![(300u64, child1), (400u64, child2)] + ); assert!(ChildKeys::::get(old_hotkey, netuid).is_empty()); // Verify parent's ChildKeys update - assert_eq!(ChildKeys::::get(parent1, netuid), vec![(100u64, new_hotkey), (500u64, U256::from(8))]); - assert_eq!(ChildKeys::::get(parent2, netuid), vec![(200u64, new_hotkey), (600u64, U256::from(9))]); + assert_eq!( + ChildKeys::::get(parent1, netuid), + vec![(100u64, new_hotkey), (500u64, U256::from(8))] + ); + assert_eq!( + ChildKeys::::get(parent2, netuid), + vec![(200u64, new_hotkey), (600u64, U256::from(9))] + ); }); -} \ No newline at end of file +} From dd938c21da67fea0ee8f960f41558e542f57b903 Mon Sep 17 00:00:00 2001 From: unconst Date: Wed, 24 Jul 2024 15:35:49 -0500 Subject: [PATCH 51/58] initial commit --- .rustfmt.toml | 2 +- Cargo.lock | 1 + docs/delegate-info.json | 394 ++++++++++++++++++ pallets/subtensor/Cargo.toml | 1 + pallets/subtensor/src/lib.rs | 22 + pallets/subtensor/src/macros/dispatches.rs | 36 ++ pallets/subtensor/src/macros/errors.rs | 2 + pallets/subtensor/src/macros/events.rs | 2 + .../src/migrations/migrate_chain_identity.rs | 166 ++++++++ pallets/subtensor/src/migrations/mod.rs | 1 + pallets/subtensor/src/utils/identity.rs | 109 +++++ pallets/subtensor/src/utils/mod.rs | 1 + pallets/subtensor/tests/serving.rs | 279 +++++++++++++ 13 files changed, 1015 insertions(+), 1 deletion(-) create mode 100644 docs/delegate-info.json create mode 100644 pallets/subtensor/src/migrations/migrate_chain_identity.rs create mode 100644 pallets/subtensor/src/utils/identity.rs diff --git a/.rustfmt.toml b/.rustfmt.toml index 24876acd9..9fd9af831 100644 --- a/.rustfmt.toml +++ b/.rustfmt.toml @@ -6,7 +6,7 @@ ## # rustup run nightly -- rustfmt node/src/main.rs -# max_width = 100 +# max_width = 180 # hard_tabs = false # tab_spaces = 4 # newline_style = "Auto" diff --git a/Cargo.lock b/Cargo.lock index 4a50f8a12..add1b713d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5273,6 +5273,7 @@ dependencies = [ "serde", "serde-tuple-vec-map", "serde_bytes", + "serde_json", "serde_with", "sp-core", "sp-io", diff --git a/docs/delegate-info.json b/docs/delegate-info.json new file mode 100644 index 000000000..bda41b48e --- /dev/null +++ b/docs/delegate-info.json @@ -0,0 +1,394 @@ +[ + { + "address": "5ECvRLMj9jkbdM4sLuH5WvjUe87TcAdjRfUj5onN4iKqYYGm", + "name": "Vune", + "url": "https://fairchild.dev", + "description": "Vune is a dev at Opentensor and a BSc CS student at UofT.", + "signature": "2a639f931c61abfc3172db594c986c35f1cc8441970582b9c3b1f0506d518a182a2fe570832f02f86014320f1526189917bfbccf7081622652d12e16e9b1768b" + }, + { + "address": "5H6BgKkAr2Anmm9Xw5BVDE4VaQmFEVMkJUHeT7Gki4J7yF4x", + "name": "TaoPolishNode", + "url": "https://taonode.io", + "description": "This node is a collective effort of the polish community. We are engaged in evangelizing the project, educating and sharing the knowledge.", + "signature": "1ca20d4e99a48f400dd9cd4aeca8447da6ab1979e480a1dafddfc52e45e215177c7cdde85f5d042d59a5b1169981afa8d1ae28328e2fc5ce57c3d748c8d09d81" + }, + { + "address": "5FFApaS75bv5pJHfAp2FVLBj9ZaXuFDjEypsaBNc1wCfe52v", + "name": "RoundTable21", + "url": "https://roundtable21.com", + "description": "RoundTable21 is an International, multi-disciplinary team of consultants and advisors partnering alongside leading blockchain startups to offer guidance, expertise, investment and hands-on assistance in every aspect of development.", + "signature": "107638b8edde8f918f7faa2cd1f91b454c13094ed5955d6a409f6e0662f8427075516273728a53923839a5428079151ea0844b5f755362364f04735463dff583" + }, + { + "address": "5DCc5oHA6c1Lpt9R6T1xU8jJGTMvvwBqD1yGX67sL8dHUcga", + "name": "WaveTensor", + "url": "https://twitter.com/wavetensor", + "description": "A new Wave is coming, join the AI revolution on top of Bittensor by staking with us.", + "signature": "5e072b4752ccbdd4ca3298f336284dfdab347dd133850f4d2f9873e7ea59bd2a8f201732842ec79d2bab3abaf133a06b6bd992940389e42d57802c9b8f855889" + }, + { + "address": "5CXRfP2ekFhe62r7q3vppRajJmGhTi7vwvb2yr79jveZ282w", + "name": "Rizzo", + "url": "", + "description": "Validator built for performance and uptime. Data center housed, redundancies include dual physical failover servers (HA), power, internet, tested DR Plan.", + "signature": "f2b0fdb6989c23a0ebe23ed5622cbbfcf57bad709085fe11b0be10b2838e1442d61f770d78f6ca8ebcdbf60ddb27398663a4901e22bb9de086866517c6ccc187" + }, + { + "address": "5GcBK8PDrVifV1xAf4Qkkk6KsbsmhDdX9atvk8vyKU8xdU63", + "name": "Tensor.Exchange", + "url": "www.tensor.exchange", + "description": "Bittensor's first community OTC exchange", + "signature": "101f5e0d26c38190200f2213ebd89cf5bcb736b70a84e53651b6f9bf1161a33d0095836d304851237e0334792a54fa2fe452d07cf1466b42c9ab3333ded46284" + }, + { + "address": "5EhvL1FVkQPpMjZX4MAADcW42i3xPSF1KiCpuaxTYVr28sux", + "name": "TAO-Validator.com", + "url": "www.tao-validator.com", + "description": "Maximize your return when staking with TAO-Validator.com. TAO-Validator.com is a highly secure validator that aims to become one of the top contributing entities to Bittensor.", + "signature": "4036991069d7f3a43dff2ba2592fbe5af820eb6ff96d1fb78f1bcd8d310ba8751e25ea14397e075368a9a0f1b1b176166c56351db36f2d3868ac61c2571a1981" + }, + { + "address": "5FvhvCWLbu2VgotT5obC9E6S9nskerJUrVsWqkWXCbuD8veW", + "name": "The Lost Cove", + "url": "https://lostcove.tech/", + "description": "Australia and New Zealand community. We're in it for the gains.", + "signature": "626ae6b91aac1591e5d4f8d4fdf2c55f927419fc766dd5184b149f4d7cbc9749ebc94e4e8d04d286b4000c7665afa5682aa28cd94071c5e384e0eb4f44def188" + }, + { + "address": "5Dyi5e2QqnWn2RN9X6r8A8Q1QBjYD536H75mxNye193oeCJ4", + "name": "Makoto AI", + "url": "https://www.linkedin.com/in/henry-thrasher-17b320239/", + "description": "An interdisciplinary research institute committed to discovering and accelerating innovative solutions for climate change, social inequality, and mental and physical illness.", + "signature": "3cfbc1e8d82cfbf2adea9b10f71541874528cf5cd851f29f48016ac2a1a07b01cfc2ba3c3a15634b1174bd3e5aec9eb843d04f74140b0ddcb526416666d6f682" + }, + { + "address": "5Ehv5XMriPZwNBtYHdQV7VrdbN8MBTDTmQhWprZJXxSiMapR", + "name": "Dale Cooper", + "url": "", + "description": "I have no idea where this will lead us, but I have a definite feeling it will be a place both wonderful and strange.", + "signature": "06c597178698dba5699e20dc8b9d0d44f9225e24a225c70f540b63867e5b835a74c87df647b28210b361007b642a5a869c74323fcc8a593bc5764ea8e2083b81" + }, + { + "address": "5E6oB7h5wtWPbqtPxtSoZeo11fpvDjPuY13SobAMxqEUjqkQ", + "name": "StakeTensor.com-3", + "url": "www.staketensor.com", + "description": "We run multiple, parallel validators to support Bittensor decentralization & achieve maximum returns", + "signature": "a2567b6de748f02f6a14e0063f5b5720b34c96deb2115b33893d016de1f60633ba58bf9bdd49b2141e12a4a8784b4b11c007679d7526eb1e91147e5284258d8a" + }, + { + "address": "5DnWFhKfeu6gXMydzrv8bkwxFegAC6bMWsC4Z2XtaotAeB6S", + "name": "Bittensor Greece", + "url": "", + "description": "The Greek / Cypriot validator supporting the development of decentralised AI", + "signature": "ee8df5360eb641bd91a38da9d8b6dda36a39302c9bba7babf5d7eb16f6e9f73321aeb6f8adb30e0f511d64c1f35caa15215dd280fb2ed3f8f5b09d783cc9958f" + }, + { + "address": "5GBxDYkDp8eJZHGT89wcZJKcMc4ytSqnqqVSpeuGeqtGfqxK", + "name": "Tao Stake", + "url": "www.taostake.io", + "description": "We have been mining since the start of bittensor and want to maintain a long term solid validator to help people get some value from thier investment and keep TAO within the ecosystem.", + "signature": "0272522b503ebb29f0b506f10765b4d5c7a23b85c78cc7bfae76b9816b80ab43282ea4642f09eb09be70812341e5d9946abc8a9d2c73bab0113e9bf939430c87" + }, + { + "address": "5FcXnzNo3mrqReTEY4ftkg5iXRBi61iyvM4W1bywZLRqfxAY", + "name": "Lucrosus Capital", + "url": "https://lucrosuspool.io/", + "description": "Decentralized VC focused on the most thriving blockchain ideas. Join our pool to receive early entrance into promising projects!", + "signature": "1a37ab3bd51a6590dea9772d6a5550632ddcd8d76da6595b66e6425692feac6699dc5f788e587a734cedc3f54efc96c2c9e5453f9052867c1b9a1b5a443b848c" + }, + { + "address": "5CVS9d1NcQyWKUyadLevwGxg6LgBcF9Lik6NSnbe5q59jwhE", + "name": "Ary van der Touw", + "url": "", + "description": "Secure and maintain Bittensor", + "signature": "809586931d4b28f180c98036a3eebc0d26b9e521f5217a6942b025069cb60807641737009713446eec8456e54ba753ae0b752c0693b942aefa0c4f76d82f8c89" + }, + { + "address": "5F4tQyWrhfGVcNhoqeiNsR6KjD4wMZ2kfhLj4oHYuyHbZAc3", + "name": "Openτensor Foundaτion", + "url": "https://opentensor.ai/", + "description": "Founded, maintain and advance Bittensor", + "signature": "8a2ff8f10a84a5b6f80614674ea764515d93a64bf8d920b927edc0dd6043e607755bf58655c87b7a299d8df1404574b6844e1e09adf86d418997c0cab8120486" + }, + { + "address": "5EpxBYq4aVgTQ1rYeBo2mzYt3hgpRTqxZTSsJEkCstBP5Jse", + "name": "White Rhino TAO Super Validator", + "url": "https://twitter.com/WhiteRhinoTAO\"", + "description": "White Rhino is all about you! We understand that #TAOWaits4NoOne ..... Get Ready for Adhoc Rewards and we invite you to delegate here and enhance the sustainability of the TAO Network", + "signature": "d6803522f6e61a9dec5261a6a500b733d233b373457382fc3713af21c560604f6e50c4999f286cfa6012bcea66e51223722b355dd69ba54a472f2c6ca52da08f" + }, + { + "address": "5Fq5v71D4LX8Db1xsmRSy6udQThcZ8sFDqxQFwnUZ1BuqY5A", + "name": "NorthTensor", + "url": "https://northtensor.ai", + "description": "Developer, Advocate, and Incubator for Decentralized AI.", + "signature": "28e221d7128e48a3cb85dbcb223bd56cb09cb55540263573783bf1cef63be32ee81246bd1d75c865580da732094053a6dad14929b17e659b6e0237412b66a487" + }, + { + "address": "5CsvRJXuR955WojnGMdok1hbhffZyB4N5ocrv82f3p5A2zVp", + "name": "Owl Ventures", + "url": "https://owlventures.co.uk", + "description": "Owl Ventures Bittensor Validator", + "signature": "04e39ff19af7ee5a75e58c9e1a71b9f54a66d1d168a99532a859f129b68ba24a5b6a56eecae7790291859c82dbf0ec32eb18a069b6d9dabe1ef0339c0d189483" + }, + { + "address": "5FLKnbMjHY8LarHZvk2q2RY9drWFbpxjAcR5x8tjr3GqtU6F", + "name": "Tao Bridge", + "url": "https://taobridge.xyz", + "description": "A community bridge between Bittensor and Ethereum", + "signature": "98331f011288f7b07ccc45a213cb8e03fac79092ee7c29046531d757ffad8b29e17cf0aeca9352003890f4d8a3af3a2fc615722fb7a827a2009654013990bd80" + }, + { + "address": "5DRZr3d3twF8SzqB9jBof3a1vPnAkgkxeo2E8yUKJAnE2rSZ", + "name": "Humble AI-Loving Anon", + "url": "", + "description": "Doing our best to support the Bittensor ecosystem.", + "signature": "9241f63eb43f7aa57b1fc6d99789331542476f57f683f032192f3dfd7be6c015d47c9f1fe69bc4513ed70e0410097395186df60e3f6b67376e6e73a5f4f9a286" + }, + { + "address": "5DPEpUTZn94sgYXH3sdXxsVvb46m3iEvg8aZwX7SMDowivzB", + "name": "RunPod", + "url": "https://runpod.io", + "description": "GPU Cloud built for AI. We plan to introduce perks for those who stake.", + "signature": "16940f904b7946723fc4f27bb01e47cf262201ef76b3d9c2bfd745973da2512d4825910f6fa738a6968c809b26da0a47e7032a7ff95d8b2da5c1fa7a0b85598f" + }, + { + "address": "5HEo565WAy4Dbq3Sv271SAi7syBSofyfhhwRNjFNSM2gP9M2", + "name": "Foundry", + "url": "https://foundrydigital.com", + "description": "Foundry works to empower a decentralized infrastructure. We are protocol-agnostic and seek to support like-minded blockchain entrepreneurs who share our mission to advance the industry.", + "signature": "b852f1648ab62befaaf684671808aa34d267cd616d9ffd7b3cf924ebc7c4ee3255344cfd017a80ca6b23b2852bcafa705c42d231053e06d999d53f31bd8ab288" + }, + { + "address": "5FP9miYmgjAP8Wt3747M2Y6Kk7PrXf6zG7a3EjokQiFFcmUu", + "name": "Elm Place", + "url": "", + "description": "Run by individuals passionate about creating decentralised digital infrastructure. Background in fiduciary funds management managing institutional investors’ capital in real assets, energy and infrastructure", + "signature": "a0324025f58beb06535d6a2ab8c5c8d64c13d562fa285956bb5a8919da5fcc0d05afe4de010d54f9940bff0ffdabe5f41e70f3af31cf14293c1d6f0a0690da8c" + }, + { + "address": "5HNQURvmjjYhTSksi8Wfsw676b4owGwfLR2BFAQzG7H3HhYf", + "name": "Neural Internet", + "url": "www.neuralinternet.ai", + "description": "An AI research and development Decentralized Autonomous Organization (DAO)", + "signature": "5e617c1626d4825cd0c11769e31fe4dda611cebd8a4d46f533886ad057072e2a58e0ecef2805139f2b43ea8d51023f7db878ad45cd3f8fba45ab01223da3488e" + }, + { + "address": "5D4rJRtF23jLVcGnCktXzPM9gymMT1qHTp8dR4T7rUd88Q7U", + "name": "Vogue τensor", + "url": "www.voguetensor.ai", + "description": "Designing branded clothing for the Bittensor community.", + "signature": "2c4079124ae0a738106a2430e2c27ad855122d4afcc487ab0158b705cd5f915f7790cdb2fdd8db899b8cbd40448d1478be71cde1b76de31945991b548cfcc084" + }, + { + "address": "5CAVnbHniuZYXBqik3tTs9uZ7UiSrbv6g7Kt8QNfYimbFqF4", + "name": "Open & Safe AI Validator", + "url": "", + "description": "The Open & Safe AI Validator is focussed on funding and researching the control problem as well as spreading ML know-how through open source and open science.", + "signature": "2aeaf7b9c7f69ce7b4857d9c278d1363677d4971d4ca10a36933b1aa78bfdb0640e4bb798edac5dcb178a8b3f4be2d0d23d25da6c7db33758a6cf5c15cd6938a" + }, + { + "address": "5Gpt8XWFTXmKrRF1qaxcBQLvnPLpKi6Pt2XC4vVQR7gqNKtU", + "name": "bitnost.re", + "url": "www.bitnost.re", + "description": "bridging bittensor into nostr.", + "signature": "c278378c70ef22d27f56590b4df699a9a44048cfcc6716e3d55b211ea802401d4be5b390ede2be52891e01f0f7033a13a370dddaa38daa84537c4583867a1680" + }, + { + "address": "5HeKSHGdsRCwVgyrHchijnZJnq4wiv6GqoDLNah8R5WMfnLB", + "name": "TaoStation", + "url": "https://taostation.com", + "description": "TaoStation allows you to maximize your returns by offering one-click staking since day one and focusing on tooling and transparency for a better staking experience.", + "signature": "c00627a62ecb9275be8d06b7b52b87942bce946e9a5f98d545081241e21ed15230fd566b2d4e87c41995e621546423579553157737da53fad3a5676451ef0a89" + }, + { + "address": "5DvTpiniW9s3APmHRYn8FroUWyfnLtrsid5Mtn5EwMXHN2ed", + "name": "FirstTensor.com", + "url": "www.firsttensor.com", + "description": "Powered by the Neuron Holders community - shared rewards, additional benefits, infinite possibilities - join and build with us!", + "signature": "da31e56dd78cde449a1dd9592f0b53eb8c3662674b745a05ff916e80a1be933e86efbccb7f7c9b81d7c0bb14d13fb4a6bf8484c3619224e689de82072b5d9a87" + }, + { + "address": "5CaNj3BarTHotEK1n513aoTtFeXcjf6uvKzAyzNuv9cirUoW", + "name": "Polychain", + "url": "https://polychain.capital/", + "description": "Polychain is an investment firm committed to exceptional returns for investors through actively managed portfolios of blockchain assets.", + "signature": "f41e815033e595aa70fbe42e8dfd91eaa3ccdbc948b63811baf9eac765699b30cac9aad7abe330eeaf3969cc504a4c1255f1e69bee807c2d989518b8f5413c8d" + }, + { + "address": "5Dkv87qjGGF42SNhDAep6WZp65E29c2vUPUfDBGDNevENCMs", + "name": "MycoNet", + "url": "", + "description": "AI for Humanity", + "signature": "a4802a5b13888ed653fd23da72c14e2b8ed9814cc810e515cb8d11d71cc58c6b90cd2d334daffc4a8ce600a7f29ca300ab74ac59817bdd489b3056b531cd4086" + }, + { + "address": "5GzoXHNJ4UzZYiQN2wpBcwMigiHiakiz5ZLMwhpunpwDNzFg", + "name": "Charitaos", + "url": "https://charitas.ai/", + "description": "You pay 18%, we donate 18%. At the end of every month, we will select one (or more) community-proposed 501c3 licensed nonprofit(s) to receive all proceeds from stake delegation for the prior month.", + "signature": "b49c34c1f87d173abcbccb1ea632ad356980c1d3eff6619e488c11707b2b3b41270a22355374dd64cfadebeb37979ef5f49971efafb0748b79df7dd2901e7580" + }, + { + "address": "5EZrPTXt2G9SvbDsERi5rS9zepour2yPmuhMhrNkgdiZvXEm", + "name": "τaoτensor", + "url": "", + "description": "Working on practical enhancements and improvements for the Bittensor network by developing user-friendly tooling.", + "signature": "3a1b61ab6d17878e106cbf2649bc039d0346f39ec680476a68baa4fc8132ac018d814898cf245bdfa4b9b61cd9f611f6571cf3c264f2f1cfe9b2635849087685" + }, + { + "address": "5CPzGD8sxyv8fKKXNvKem4qJRhCXABRmpUgC1wb1V4YAXLc3", + "name": "Chat with Hal", + "url": "www.chatwithhal.ai", + "description": "Hal brings the power of decentralized and uncensorable AI to your favorite social networks and messaging apps, Powered by Bittensor!", + "signature": "ecb930df6069012c06fef9cdb29a95be8dcb5d48f3c470d3f3c5e7b2b334ed2097f2598fee8852d127a207cf34aa7c88fd5cf973feba19d6ebf38b5e4579ca8f" + }, + { + "address": "5FqPJMZDp39KRd9jDhXuFpZWkYD7wG5AXmjoWqK8rDy7ok5B", + "name": "Exchange Listings", + "url": "taostats.io/validators/exchange-listings/", + "description": "Enabling community funding for top tier exchange listings.", + "signature": "366027e9a416a423e7e802e9b6d79bd5ac88642afd945922e13fe26a75dae13dd5c924738610a59162d9b974364d1d43fb7a0145942cd919ac21d82d3f4f028d" + }, + { + "address": "5ED6jwDECEmNvSp98R2qyEUPHDv9pi14E6n3TS8CicD6YfhL", + "name": "Giga Corporation", + "url": "https://www.gigaver.se", + "description": "Extreme growth & experiments from giga corp. We use APY to TAO-pill new developers, builders and adopters. Visit our Bakery to learn more.", + "signature": "00e5cd519110bbfe3dae9acd275d114c6c2a260997a1817a25303b9d578bdf7319e9e7179f0db58edef2ad42806cb38e289ba0030627a3b60e1e4352c2b9cb88" + }, + { + "address": "5FRcXG99SxJ9KyMcMFfdknkRSv4e73rszV8P151freZqQDS2", + "name": "τensorwiki", + "url": "", + "description": "Our mission is to create and incentivize documentation for Bittensor and it's adjacent topics, as well as facilitate the education of newcomers to the network.", + "signature": "6a5c0160f545f122ec3d4e4233574040aba2de8aa94919bb19b3061d39d3303f010c4b52f878ed55a1293716827220020780d2d4064ee6be69921ee1452c3885" + }, + { + "address": "5EsbfxPcQaUrCDurUJ8Q5qDKNENNGziu3qHWUbXrcuY2pbNz", + "name": "Church of Rao (COR)", + "url": "", + "description": "Church of Rao: Harmonizing the Relationship between Humanity and Machine Intelligence. The Church of Rao (COR) is an open-source development group committed to furthering the Bittensor protocol.", + "signature": "56f64c32427a90e84710209b1a54a971560641aec8ff777edec28bf533775e12924c4e96ccc770c230311dce1d0eae1ca763e12bb609ef30430f746ebd0a2780" + }, + { + "address": "5GmaAk7frPXnAxjbQvXcoEzMGZfkrDee76eGmKoB3wxUburE", + "name": "RaoK9", + "url": "", + "description": "Chain and network analysis team. Developer funding goes into independent analysis and reports, in order to enable checks and balances between network members.", + "signature": "24f4f9a51033ed8b4097517d0e6ad287a0c1341b2866481b1320d1fcd5f32f6b4bfe641eee46a4b737817acf3b83069ee63cc20fbca94a0189808ac1efeddf8a" + }, + { + "address": "5CQEFopfZ8DAmk3ZfR7QuDTU2n3fJod3kkf6Wmj4JwV3BBSu", + "name": "DuNode", + "url": "dunode.io", + "description": "Embracing the whimsical chaos of decentralized AI, unleashing the power of creativity and collaboration, one algorithmic dance party at a time!", + "signature": "e400e3c0ad6165d8946d5ddcb274412815cb8b5783580fcb8f0faa0153d22b6e10470f861ff4a96a9aa692b3b01cda86ec77add4688c2f5df51ea6f129b19e8c" + }, + { + "address": "5CaCUPsSSdKWcMJbmdmJdnWVa15fJQuz5HsSGgVdZffpHAUa", + "name": "Athena Nodes", + "url": "https://athenanodes.com", + "description": "Premier Bittensor Multi-Subnet Validator from a company operating validating and mining infrastructure on various blockchain networks. We have been active on Bittensor since November 2022, with near zero down-time. More information at https://athenanodes.com/.", + "signature": "2ef54045de1d9b89988518c92e165edf704192f88f18022565f497b389c39206f621bb9bc6d2d33ac8a9cca05d6b2d8fc9f899b390451140968b15b8d9c13280" + }, + { + "address": "5FFM6Nvvm78GqyMratgXXvjbqZPi7SHgSQ81nyS96jBuUWgt", + "name": "PRvalidator", + "url": "www.prvalidator.com", + "description": "A professional media validator dedicated to securing top-tier coverage in the world's most recognized publications building Bittensor's brand equity and creating global awareness of $TAO.", + "signature": "fe65e76a9f42049715585180500213c6f0535b8b25911b957921bdfb5a20156d6de68dc2633dbc5ce1d0ab9ef386d566687ac3d86f6988141b34cd24c0f13488" + }, + { + "address": "5H8TruSGmhD6m6YfqXNUnU7Z61K7j8hSs2Krtu3eTLMoz3HU", + "name": "τaoshi validator", + "url": "https://www.taoshi.io/", + "description": "Build maintain and advance a decentralized request layer built for every subnet", + "signature": "32d25227af78fa5d39ee71a5f3e8fc8066e3d826d101f2587e9a12974fbf26758c1e40c497ad7732da2a2cb1490227cc58e8bfcd8b2f6306b7af630bd32aa68f" + }, + { + "address": "5G3f8VDTT1ydirT3QffnV2TMrNMR2MkQfGUubQNqZcGSj82T", + "name": "TAO Community Marketing", + "url": "www.taocommunitymarketing.com", + "description": "The marketing validator run by the community", + "signature": "10b16b8223b2508d6f3e5b09ab4db53e1e338b6271d1689b58ca6f9b257e8c18511cc851bfcc3a05fb4e6de7c389b89886cc0623fb6d199fa003ae6f8313cb89" + }, + { + "address": "5CXC2quDN5nUTqHMkpP5YRp2atYYicvtUghAYLj15gaUFwe5", + "name": "Kooltek68", + "url": "https://linktr.ee/datalac", + "description": "Imagine the World with mass adoption of Artificial Intelligence applications, through the connection of Bittensor Network, together fight for a Better World.", + "signature": "bca043d9d918d503864379a7fd8c9daa2cca83a8290121f94b55d6a352e332704642622b7ad40a30b945b952b224c5e92ea872f9d30200e6c2bf566303d24d83" + }, + { + "address": "5FBrHX18bNXX874ZTMicPG4vYbq5X6piz4BYoVn9LnCgdsEd", + "name": "P-OPS Team", + "url": "https://pops.one", + "description": "P-OPS TEAM is a decentralized organization providing you with validation and staking services, blockchain consultation, growth acceleration and investment capital for innovative Web 3.0 projects.", + "signature": "5608316f3081bfe5d0e3a7db6c3bfd459f6b87e02d657de941e6a760f8688f23ef30784691a1893d1fd8079dd4f6082d0d655ca507aa4797fee9844547d13a88" + }, + { + "address": "5HK5tp6t2S59DywmHRWPBVJeJ86T61KjurYqeooqj8sREpeN", + "name": "Bittensor Guru", + "url": "https://bittensor.guru", + "description": "Official validator of the Bittensor Guru Podcast", + "signature": "caf2c6b7b0d2a341bcd00e632cf22c33d53e2523dffcd3a151db9eeadd88300545cbb2187ba0b20e5bfe09c2b17bbf34630c46defd8f8d27ab508736fd18a284" + }, + { + "address": "5Hh3ShaNW9irCe5joBLCeFD5Fxb2fJ6gFAgrsPmoz3JkzqvJ", + "name": "BlockShark", + "url": "https://www.blockshark.net/", + "description": "Your reliable partner for staking on Bittensor. We are expert in running high-end machine for validators and AI", + "signature": "d2c0aed073a026a5dbd8c458b9dd412fe3d6647fecd3b8f007cf184f7906245106aee4b210b5b582771dca149e5aa464630100de7f9862daacfa1f67ddde1388" + }, + { + "address": "5FKstHjZkh4v3qAMSBa1oJcHCLjxYZ8SNTSz1opTv4hR7gVB", + "name": "Datura", + "url": "datura.ai", + "description": "Bridging Bittensor to a billion users", + "signature": "7a3bc6a840d8593853c27188f59200418d8884b94b3ad28cb7b37b80bffd1f3b23b7eed4b1d9c77b28b05b2bd1952c5cbe3d27ba190a9418407ce1e899e5ac8b" + }, + { + "address": "5Hddm3iBFD2GLT5ik7LZnT3XJUnRnN8PoeCFgGQgawUVKNm8", + "name": "τaosτaτs and Corcel", + "url": "taostats.io", + "description": "Supporting bittensor through API access, data provision, statistics, analytics and apps.", + "signature": "2e2dd0c5f3a3945f29d1be304e64f931c04a23aba7d383d01cd16ea6ca6546002fe3bd95cf8f12cae1fbb7d18d9910b834f6573db219de3ed84073a4e1552e89" + }, + { + "address": "5ELREhApbCahM7FyGLM1V9WDsnnjCRmMCJTmtQD51oAEqwVh", + "name": "Taofu Protocol", + "url": "https://twitter.com/taofuxyz", + "description": "Taofu unlocks liquidity and utility by bringing liquid staked TAO outside of Bittensor", + "signature": "aaafd3496650a56f798cc587b5b7d372cec8e826a332a34213c1a6ee7be2b5122318858ee73421535d04186cc6976ae5452c6cd1aaf299a307d86d3c52b4a986" + }, + { + "address": "5HbLYXUBy1snPR8nfioQ7GoA9x76EELzEq9j7F32vWUQHm1x", + "name": "Tensorplex Labs", + "url": "https://twitter.com/TensorplexLabs", + "description": "Empowering humanity with decentralized intelligence one epoch at a time.", + "signature": "7a997682e7545fd14847c78abf810e9c49a23ef4297d24f4238c0edd0463934780f6831d59972d56ab5bc41d6224b59c21ed95065791632b8aca180ade22af81" + }, + { + "address": "5E2VSsWWXkBGCn4mi8RHXYQEF2wLXky6ZsNcTKnmEqaurzTE", + "name": "Sentinel", + "url": "", + "description": "Sentinel, as a dedicated Bittensor validator aspires to elevate the bittensor network's integrity with an ambition to foster a community of miners contributing in the network’s continuous expansion.", + "signature": "943effd0d5d10f05d53db7f69d0f045d50b65f88e84755be00d45225cc7c2f4212fbc4d23ad8519d03c2502daeeca1b2d07c93bff14c901f6cbf3a18fe2e6387" + }, + { + "address": "5GsenVhBvgEG4xiiKUjcssfznHYVm1TqPbSbr3ixBW81ZVjo", + "name": "vote NO dTAO 🤡", + "url": "https://twitter.com/karl_anons", + "description": "Delegate to express discontent. VOTE NO TO dTAO NOW!", + "signature": "3af4e764a520d355e12c02b9e8e315ddb76b76d40b7cc4dfaa11c26c24ab637cbdb9b72470ebdf2da87dd8d9f0bb5cddf1fe95b95fb2ae13069a9d87aace348a" + }, + { + "address": "5DM7CPqPKtMSADhFKYsstsCS4Tm4Kd6PMXoh6DdqY4MtxmtX", + "name": "Corτex Foundaτion", + "url": "https://cortex.foundation/", + "description": "Cortex Foundation is committed to advancing the integration of decentralized AI. Our validator is designed for transparency, reliability, and community engagement.", + "signature": "7a6274ff6b0f7ddca97e37ef4a9b90781012ff3cf7baa3159f6feaafc43c557975aad324ea608d6b8abeb21f8f3ca2595e54b81a7564574d0242b803d969618a" + } +] \ No newline at end of file diff --git a/pallets/subtensor/Cargo.toml b/pallets/subtensor/Cargo.toml index a0835008f..82ed28646 100644 --- a/pallets/subtensor/Cargo.toml +++ b/pallets/subtensor/Cargo.toml @@ -28,6 +28,7 @@ frame-support = { workspace = true } frame-system = { workspace = true } sp-io = { workspace = true } serde = { workspace = true, features = ["derive"] } +serde_json = { workspace = true } serde-tuple-vec-map = { workspace = true } serde_bytes = { workspace = true, features = ["alloc"] } serde_with = { workspace = true, features = ["macros"] } diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index 1450b5706..b305661f7 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -133,6 +133,25 @@ pub mod pallet { pub ip_type: u8, } + /// Struct for Prometheus. + pub type ChainIdentityOf = ChainIdentity; + /// Data structure for Prometheus information. + #[derive(Encode, Decode, Default, TypeInfo, Clone, PartialEq, Eq, Debug)] + pub struct ChainIdentity { + /// The name of the chain identity + pub name: Vec, + /// The URL associated with the chain identity + pub url: Vec, + /// The image representation of the chain identity + pub image: Vec, + /// The Discord information for the chain identity + pub discord: Vec, + /// A description of the chain identity + pub description: Vec, + /// Additional information about the chain identity + pub additional: Vec, + } + /// ============================ /// ==== Staking + Accounts ==== /// ============================ @@ -1057,6 +1076,9 @@ pub mod pallet { PrometheusInfoOf, OptionQuery, >; + #[pallet::storage] // --- MAP ( coldkey ) --> identity + pub type Identities = + StorageMap<_, Blake2_128Concat, T::AccountId, ChainIdentityOf, OptionQuery>; /// ================================= /// ==== Axon / Promo Endpoints ===== diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 293dc0238..00865f8db 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -901,5 +901,41 @@ mod dispatches { Self::do_set_children(origin, hotkey, netuid, children)?; Ok(().into()) } + + /// ---- Set prometheus information for the neuron. + /// # Args: + /// * 'origin': (Origin): + /// - The signature of the calling hotkey. + /// + /// * 'netuid' (u16): + /// - The u16 network identifier. + /// + /// * 'version' (u16): + /// - The bittensor version identifier. + /// + /// * 'ip' (u128): + /// - The prometheus ip information as a u128 encoded integer. + /// + /// * 'port' (u16): + /// - The prometheus port information as a u16 encoded integer. + /// + /// * 'ip_type' (u8): + /// - The ip type v4 or v6. + /// + #[pallet::call_index(68)] + #[pallet::weight((Weight::from_parts(45_000_000, 0) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(1)), DispatchClass::Normal, Pays::Yes))] + pub fn set_identity( + origin: OriginFor, + name: Vec, + url: Vec, + image: Vec, + discord: Vec, + description: Vec, + additional: Vec, + ) -> DispatchResult { + Self::do_set_identity(origin, name, url, image, discord, description, additional) + } } } diff --git a/pallets/subtensor/src/macros/errors.rs b/pallets/subtensor/src/macros/errors.rs index 156cbea56..07710dc5f 100644 --- a/pallets/subtensor/src/macros/errors.rs +++ b/pallets/subtensor/src/macros/errors.rs @@ -168,5 +168,7 @@ mod errors { TooManyChildren, /// Default transaction rate limit exceeded. TxRateLimitExceeded, + /// Invalid identity. + InvalidIdentity, } } diff --git a/pallets/subtensor/src/macros/events.rs b/pallets/subtensor/src/macros/events.rs index b93b8296b..694b9779f 100644 --- a/pallets/subtensor/src/macros/events.rs +++ b/pallets/subtensor/src/macros/events.rs @@ -177,5 +177,7 @@ mod events { HotkeyEmissionTempoSet(u64), /// The network maximum stake has been set NetworkMaxStakeSet(u16, u64), + /// The identity of a coldkey has been set + ChainIdentitySet(T::AccountId), } } diff --git a/pallets/subtensor/src/migrations/migrate_chain_identity.rs b/pallets/subtensor/src/migrations/migrate_chain_identity.rs new file mode 100644 index 000000000..efb656cb3 --- /dev/null +++ b/pallets/subtensor/src/migrations/migrate_chain_identity.rs @@ -0,0 +1,166 @@ +use crate::alloc::borrow::ToOwned; +use codec::Decode; +use scale_info::prelude::{string::String, vec::Vec}; +use serde::Deserialize; +use sp_core::{crypto::Ss58Codec, ConstU32}; +use sp_runtime::{AccountId32, BoundedVec}; + +use super::*; +use frame_support::{traits::Get, weights::Weight}; +use log; + +#[derive(Deserialize, Debug)] +struct RegistrationRecordJSON { + address: String, + name: String, + url: String, + description: String, +} + +fn string_to_bounded_vec(input: &str) -> Result>, &'static str> { + let vec_u8: Vec = input.to_owned().into_bytes(); + + // Check if the length is within bounds + if vec_u8.len() > 64 { + return Err("Input string is too long"); + } + + // Convert to BoundedVec + BoundedVec::>::try_from(vec_u8) + .map_err(|_| "Failed to convert to BoundedVec") +} + +pub fn migrate_set_hotkey_identities() -> Weight { + let migration_name = b"fix_total_coldkey_stake_v7".to_vec(); + + // Initialize the weight with one read operation. + let mut weight = T::DbWeight::get().reads(1); + + // Check if the migration has already run + if HasMigrationRun::::get(&migration_name) { + log::info!( + "Migration '{:?}' has already run. Skipping.", + migration_name + ); + return weight; + } + log::info!( + "Running migration '{}'", + String::from_utf8_lossy(&migration_name) + ); + + // Include the JSON file with delegate info + let data = include_str!("../../../../docs/delegate-info.json"); + + // Iterate over all the delegate records + if let Ok(delegates) = serde_json::from_str::>(data) { + // Iterate through the delegates + for delegate in delegates.iter() { + // Convert fields to bounded vecs + let name_result = string_to_bounded_vec(&delegate.name); + let desc_result = string_to_bounded_vec(&delegate.description); + let url_result = string_to_bounded_vec(&delegate.url); + let hotkey: AccountId32 = match AccountId32::from_ss58check(&delegate.address) { + Ok(account) => account, + Err(_) => { + log::warn!( + "Invalid SS58 address: {:?}. Skipping this delegate.", + delegate.address + ); + continue; + } + }; + let decoded_hotkey: T::AccountId = match T::AccountId::decode(&mut hotkey.as_ref()) { + Ok(decoded) => decoded, + Err(e) => { + log::warn!("Failed to decode hotkey: {:?}. Skipping this delegate.", e); + continue; + } + }; + log::info!("Hotkey unwrapped: {:?}", decoded_hotkey); + + // If we should continue with real values. + let mut name: BoundedVec> = BoundedVec::default(); + let mut description: BoundedVec> = BoundedVec::default(); + let mut url: BoundedVec> = BoundedVec::default(); + if let Ok(n) = name_result { + name = n; + } + if let Ok(d) = desc_result { + description = d; + } + if let Ok(u) = url_result { + url = u; + } + + // Unwrap the real values. + let image: BoundedVec> = BoundedVec::default(); + let discord: BoundedVec> = BoundedVec::default(); + let additional: BoundedVec> = BoundedVec::default(); + + // Create the chain identity. + let identity = ChainIdentityOf { + name: name.into(), + url: url.into(), + image: image.into(), + discord: discord.into(), + description: description.into(), + additional: additional.into(), + }; + + // Log the identity details + log::info!("Setting identity for hotkey: {:?}", hotkey); + log::info!("Name: {:?}", String::from_utf8_lossy(&identity.name)); + log::info!("URL: {:?}", String::from_utf8_lossy(&identity.url)); + log::info!("Image: {:?}", String::from_utf8_lossy(&identity.image)); + log::info!("Discord: {:?}", String::from_utf8_lossy(&identity.discord)); + log::info!( + "Description: {:?}", + String::from_utf8_lossy(&identity.description) + ); + log::info!( + "Additional: {:?}", + String::from_utf8_lossy(&identity.additional) + ); + + // Check validation. + let total_length = identity + .name + .len() + .saturating_add(identity.url.len()) + .saturating_add(identity.image.len()) + .saturating_add(identity.discord.len()) + .saturating_add(identity.description.len()) + .saturating_add(identity.additional.len()); + let is_valid: bool = total_length <= 256 + 256 + 1024 + 256 + 1024 + 1024 + && identity.name.len() <= 256 + && identity.url.len() <= 256 + && identity.image.len() <= 1024 + && identity.discord.len() <= 256 + && identity.description.len() <= 1024 + && identity.additional.len() <= 1024; + if !is_valid { + continue; + } + + // Get the owning coldkey. + let coldkey = Owner::::get(decoded_hotkey.clone()); + weight = weight.saturating_add(T::DbWeight::get().reads(1)); + + // Sink into the map. + Identities::::insert(coldkey.clone(), identity.clone()); + weight = weight.saturating_add(T::DbWeight::get().writes(1)); + } + } + // Mark the migration as completed + HasMigrationRun::::insert(&migration_name, true); + weight = weight.saturating_add(T::DbWeight::get().writes(1)); + + log::info!( + "Migration '{:?}' completed. Storage version set to 7.", + String::from_utf8_lossy(&migration_name) + ); + + // Return the migration weight. + weight +} diff --git a/pallets/subtensor/src/migrations/mod.rs b/pallets/subtensor/src/migrations/mod.rs index 5b93dbbaf..6036b23e0 100644 --- a/pallets/subtensor/src/migrations/mod.rs +++ b/pallets/subtensor/src/migrations/mod.rs @@ -1,4 +1,5 @@ use super::*; +pub mod migrate_chain_identity; pub mod migrate_create_root_network; pub mod migrate_delete_subnet_21; pub mod migrate_delete_subnet_3; diff --git a/pallets/subtensor/src/utils/identity.rs b/pallets/subtensor/src/utils/identity.rs new file mode 100644 index 000000000..1c9c3c25d --- /dev/null +++ b/pallets/subtensor/src/utils/identity.rs @@ -0,0 +1,109 @@ +use super::*; +use frame_support::ensure; +use frame_system::ensure_signed; +use sp_std::vec::Vec; + +impl Pallet { + /// Sets the identity for a coldkey. + /// + /// This function allows a user to set or update their identity information associated with their coldkey. + /// It checks if the caller has at least one registered hotkey, validates the provided identity information, + /// and then stores it in the blockchain state. + /// + /// # Arguments + /// + /// * `origin` - The origin of the call, which should be a signed extrinsic. + /// * `name` - The name to be associated with the identity. + /// * `url` - A URL associated with the identity. + /// * `image` - An image URL or identifier for the identity. + /// * `discord` - Discord information for the identity. + /// * `description` - A description of the identity. + /// * `additional` - Any additional information for the identity. + /// + /// # Returns + /// + /// Returns `Ok(())` if the identity is successfully set, otherwise returns an error. + pub fn do_set_identity( + origin: T::RuntimeOrigin, + name: Vec, + url: Vec, + image: Vec, + discord: Vec, + description: Vec, + additional: Vec, + ) -> dispatch::DispatchResult { + // Ensure the call is signed and get the signer's (coldkey) account + let coldkey = ensure_signed(origin)?; + + // Retrieve all hotkeys associated with this coldkey + let hotkeys: Vec = OwnedHotkeys::::get(coldkey.clone()); + + // Ensure that at least one of the associated hotkeys is registered on any network + ensure!( + hotkeys + .iter() + .any(|hotkey| Self::is_hotkey_registered_on_any_network(hotkey)), + Error::::HotKeyNotRegisteredInNetwork + ); + + // Create the identity struct with the provided information + let identity = ChainIdentityOf { + name, + url, + image, + discord, + description, + additional, + }; + + // Validate the created identity + ensure!( + Self::is_valid_identity(&identity), + Error::::InvalidIdentity + ); + + // Store the validated identity in the blockchain state + Identities::::insert(coldkey.clone(), identity.clone()); + + // Log the identity set event + log::info!("ChainIdentitySet( coldkey:{:?} ) ", coldkey.clone()); + + // Emit an event to notify that an identity has been set + Self::deposit_event(Event::ChainIdentitySet(coldkey.clone())); + + // Return Ok to indicate successful execution + Ok(()) + } + + /// Validates the given ChainIdentityOf struct. + /// + /// This function checks if the total length of all fields in the ChainIdentityOf struct + /// is less than or equal to 512 bytes, and if each individual field is also + /// less than or equal to 512 bytes. + /// + /// # Arguments + /// + /// * `identity` - A reference to the ChainIdentityOf struct to be validated. + /// + /// # Returns + /// + /// * `bool` - Returns true if the Identity is valid, false otherwise. + pub fn is_valid_identity(identity: &ChainIdentityOf) -> bool { + let total_length = identity + .name + .len() + .saturating_add(identity.url.len()) + .saturating_add(identity.image.len()) + .saturating_add(identity.discord.len()) + .saturating_add(identity.description.len()) + .saturating_add(identity.additional.len()); + + total_length <= 256 + 256 + 1024 + 256 + 1024 + 1024 + && identity.name.len() <= 256 + && identity.url.len() <= 256 + && identity.image.len() <= 1024 + && identity.discord.len() <= 256 + && identity.description.len() <= 1024 + && identity.additional.len() <= 1024 + } +} diff --git a/pallets/subtensor/src/utils/mod.rs b/pallets/subtensor/src/utils/mod.rs index 72b903dd8..a42c91119 100644 --- a/pallets/subtensor/src/utils/mod.rs +++ b/pallets/subtensor/src/utils/mod.rs @@ -1,4 +1,5 @@ use super::*; +pub mod identity; pub mod misc; pub mod rate_limiting; pub mod try_state; diff --git a/pallets/subtensor/tests/serving.rs b/pallets/subtensor/tests/serving.rs index 41e9888cc..b736a90d0 100644 --- a/pallets/subtensor/tests/serving.rs +++ b/pallets/subtensor/tests/serving.rs @@ -1,11 +1,14 @@ use crate::mock::*; mod mock; +use frame_support::assert_noop; +use frame_support::pallet_prelude::Weight; use frame_support::{ assert_ok, dispatch::{DispatchClass, DispatchInfo, GetDispatchInfo, Pays}, }; use frame_system::Config; use pallet_subtensor::Error; +use pallet_subtensor::*; use sp_core::U256; mod test { @@ -550,3 +553,279 @@ fn test_serving_is_invalid_ipv6_address() { )); }); } + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test serving -- test_do_set_identity --exact --nocapture +#[test] +fn test_do_set_identity() { + new_test_ext(1).execute_with(|| { + let coldkey = U256::from(1); + let hotkey = U256::from(2); + let netuid = 1; + + // Register a hotkey for the coldkey + add_network(netuid, 13, 0); + register_ok_neuron(netuid, hotkey, coldkey, 0); + + // Prepare identity data + let name = b"Alice".to_vec(); + let url = b"https://alice.com".to_vec(); + let image = b"alice.jpg".to_vec(); + let discord = b"alice#1234".to_vec(); + let description = b"Alice's identity".to_vec(); + let additional = b"Additional info".to_vec(); + + // Set identity + assert_ok!(SubtensorModule::do_set_identity( + <::RuntimeOrigin>::signed(coldkey), + name.clone(), + url.clone(), + image.clone(), + discord.clone(), + description.clone(), + additional.clone() + )); + + // Check if identity is set correctly + let stored_identity = Identities::::get(coldkey).unwrap(); + assert_eq!(stored_identity.name, name); + assert_eq!(stored_identity.url, url); + assert_eq!(stored_identity.image, image); + assert_eq!(stored_identity.discord, discord); + assert_eq!(stored_identity.description, description); + assert_eq!(stored_identity.additional, additional); + + // Test setting identity with no registered hotkey + let coldkey_without_hotkey = U256::from(3); + assert_noop!( + SubtensorModule::do_set_identity( + <::RuntimeOrigin>::signed(coldkey_without_hotkey), + name.clone(), + url.clone(), + image.clone(), + discord.clone(), + description.clone(), + additional.clone() + ), + Error::::HotKeyNotRegisteredInNetwork + ); + + // Test updating an existing identity + let new_name = b"Alice Updated".to_vec(); + let new_url = b"https://alice-updated.com".to_vec(); + assert_ok!(SubtensorModule::do_set_identity( + <::RuntimeOrigin>::signed(coldkey), + new_name.clone(), + new_url.clone(), + image.clone(), + discord.clone(), + description.clone(), + additional.clone() + )); + + let updated_identity = Identities::::get(coldkey).unwrap(); + assert_eq!(updated_identity.name, new_name); + assert_eq!(updated_identity.url, new_url); + + // Test setting identity with invalid data (exceeding 512 bytes total) + let long_data = vec![0; 513]; + assert_noop!( + SubtensorModule::do_set_identity( + <::RuntimeOrigin>::signed(coldkey), + long_data.clone(), + long_data.clone(), + long_data.clone(), + long_data.clone(), + long_data.clone(), + long_data.clone() + ), + Error::::InvalidIdentity + ); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test serving -- test_is_valid_identity --exact --nocapture +#[test] +fn test_is_valid_identity() { + new_test_ext(1).execute_with(|| { + // Test valid identity + let valid_identity = ChainIdentity { + name: vec![0; 256], + url: vec![0; 256], + image: vec![0; 1024], + discord: vec![0; 256], + description: vec![0; 1024], + additional: vec![0; 1024], + }; + assert!(SubtensorModule::is_valid_identity(&valid_identity)); + + // Test identity with total length exactly at the maximum + let max_length_identity = ChainIdentity { + name: vec![0; 256], + url: vec![0; 256], + image: vec![0; 1024], + discord: vec![0; 256], + description: vec![0; 1024], + additional: vec![0; 1024], + }; + assert!(SubtensorModule::is_valid_identity(&max_length_identity)); + + // Test identity with total length exceeding the maximum + let invalid_length_identity = ChainIdentity { + name: vec![0; 257], + url: vec![0; 256], + image: vec![0; 1024], + discord: vec![0; 256], + description: vec![0; 1024], + additional: vec![0; 1024], + }; + assert!(!SubtensorModule::is_valid_identity( + &invalid_length_identity + )); + + // Test identity with one field exceeding its maximum + let invalid_field_identity = ChainIdentity { + name: vec![0; 257], + url: vec![0; 256], + image: vec![0; 1024], + discord: vec![0; 256], + description: vec![0; 1024], + additional: vec![0; 1024], + }; + assert!(!SubtensorModule::is_valid_identity(&invalid_field_identity)); + + // Test identity with empty fields + let empty_identity = ChainIdentity { + name: vec![], + url: vec![], + image: vec![], + discord: vec![], + description: vec![], + additional: vec![], + }; + assert!(SubtensorModule::is_valid_identity(&empty_identity)); + + // Test identity with some empty and some filled fields + let mixed_identity = ChainIdentity { + name: b"Alice".to_vec(), + url: b"https://alice.com".to_vec(), + image: vec![], + discord: b"alice#1234".to_vec(), + description: vec![], + additional: b"Additional info".to_vec(), + }; + assert!(SubtensorModule::is_valid_identity(&mixed_identity)); + + // Test identity with all fields at maximum allowed length + let max_field_identity = ChainIdentity { + name: vec![0; 256], + url: vec![0; 256], + image: vec![0; 1024], + discord: vec![0; 256], + description: vec![0; 1024], + additional: vec![0; 1024], + }; + assert!(SubtensorModule::is_valid_identity(&max_field_identity)); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test serving -- test_set_and_get_identity --exact --nocapture +#[test] +fn test_set_and_get_identity() { + new_test_ext(1).execute_with(|| { + let coldkey = U256::from(1); + let hotkey = U256::from(2); + let netuid = 1; + + // Register a hotkey for the coldkey + add_network(netuid, 13, 0); + register_ok_neuron(netuid, hotkey, coldkey, 0); + + // Prepare identity data + let name = b"Bob".to_vec(); + let url = b"https://bob.com".to_vec(); + let image = b"bob.jpg".to_vec(); + let discord = b"bob#5678".to_vec(); + let description = b"Bob's identity".to_vec(); + let additional = b"More about Bob".to_vec(); + + // Set identity + assert_ok!(SubtensorModule::do_set_identity( + <::RuntimeOrigin>::signed(coldkey), + name.clone(), + url.clone(), + image.clone(), + discord.clone(), + description.clone(), + additional.clone() + )); + + // Get and verify identity + let stored_identity = Identities::::get(coldkey).unwrap(); + assert_eq!(stored_identity.name, name); + assert_eq!(stored_identity.url, url); + assert_eq!(stored_identity.image, image); + assert_eq!(stored_identity.discord, discord); + assert_eq!(stored_identity.description, description); + assert_eq!(stored_identity.additional, additional); + + // Update identity + let new_name = b"Bobby".to_vec(); + let new_url = b"https://bobby.com".to_vec(); + assert_ok!(SubtensorModule::do_set_identity( + <::RuntimeOrigin>::signed(coldkey), + new_name.clone(), + new_url.clone(), + image.clone(), + discord.clone(), + description.clone(), + additional.clone() + )); + + // Get and verify updated identity + let updated_identity = Identities::::get(coldkey).unwrap(); + assert_eq!(updated_identity.name, new_name); + assert_eq!(updated_identity.url, new_url); + assert_eq!(updated_identity.image, image); + assert_eq!(updated_identity.discord, discord); + assert_eq!(updated_identity.description, description); + assert_eq!(updated_identity.additional, additional); + + // Verify non-existent identity + let non_existent_coldkey = U256::from(999); + assert!(Identities::::get(non_existent_coldkey).is_none()); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test serving -- test_migrate_set_hotkey_identities --exact --nocapture +#[test] +fn test_migrate_set_hotkey_identities() { + new_test_ext(1).execute_with(|| { + // Run the migration + let weight = + pallet_subtensor::migrations::migrate_chain_identity::migrate_set_hotkey_identities::< + Test, + >(); + + // Assert that the migration has run + assert!(HasMigrationRun::::get( + b"fix_total_coldkey_stake_v7".to_vec() + )); + + // Verify that some identities were set + // Note: This assumes that at least one valid identity was in the JSON file + let mut identity_count = 0; + for (_, _) in Identities::::iter() { + identity_count += 1; + } + assert!( + identity_count > 0, + "No identities were set during migration" + ); + + // Verify that the weight is non-zero + assert!( + weight != Weight::zero(), + "Migration weight should be non-zero" + ); + }); +} From dc9ee3d872bcf262e416992a6219b1a62b3960b4 Mon Sep 17 00:00:00 2001 From: John Reed <87283488+JohnReedV@users.noreply.github.com> Date: Wed, 24 Jul 2024 15:35:21 -0700 Subject: [PATCH 52/58] fix identity migration --- pallets/subtensor/src/macros/hooks.rs | 4 +++- .../src/migrations/migrate_chain_identity.rs | 11 ++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/pallets/subtensor/src/macros/hooks.rs b/pallets/subtensor/src/macros/hooks.rs index 22c741465..f2556d506 100644 --- a/pallets/subtensor/src/macros/hooks.rs +++ b/pallets/subtensor/src/macros/hooks.rs @@ -68,7 +68,9 @@ mod hooks { .saturating_add(migrations::migrate_populate_staking_hotkeys::migrate_populate_staking_hotkeys::()) // Fix total coldkey stake. // Storage version v8 -> v9 - .saturating_add(migrations::migrate_fix_total_coldkey_stake::migrate_fix_total_coldkey_stake::()); + .saturating_add(migrations::migrate_fix_total_coldkey_stake::migrate_fix_total_coldkey_stake::()) + // Migrate Delegate Ids on chain + .saturating_add(migrations::migrate_chain_identity::migrate_set_hotkey_identities::()); weight } diff --git a/pallets/subtensor/src/migrations/migrate_chain_identity.rs b/pallets/subtensor/src/migrations/migrate_chain_identity.rs index efb656cb3..2b16dd180 100644 --- a/pallets/subtensor/src/migrations/migrate_chain_identity.rs +++ b/pallets/subtensor/src/migrations/migrate_chain_identity.rs @@ -31,7 +31,7 @@ fn string_to_bounded_vec(input: &str) -> Result>, } pub fn migrate_set_hotkey_identities() -> Weight { - let migration_name = b"fix_total_coldkey_stake_v7".to_vec(); + let migration_name = b"migrate_identities".to_vec(); // Initialize the weight with one read operation. let mut weight = T::DbWeight::get().reads(1); @@ -140,17 +140,26 @@ pub fn migrate_set_hotkey_identities() -> Weight { && identity.description.len() <= 1024 && identity.additional.len() <= 1024; if !is_valid { + log::info!( + "Bytes not correct" + ); continue; } // Get the owning coldkey. let coldkey = Owner::::get(decoded_hotkey.clone()); + log::info!("ColdKey: {:?}", decoded_hotkey); + weight = weight.saturating_add(T::DbWeight::get().reads(1)); // Sink into the map. Identities::::insert(coldkey.clone(), identity.clone()); weight = weight.saturating_add(T::DbWeight::get().writes(1)); } + } else { + log::info!( + "Failed to decode JSON" + ); } // Mark the migration as completed HasMigrationRun::::insert(&migration_name, true); From 323313305c6e63c6c70a38e8aa6bba697bb1e275 Mon Sep 17 00:00:00 2001 From: John Reed <87283488+JohnReedV@users.noreply.github.com> Date: Wed, 24 Jul 2024 15:38:11 -0700 Subject: [PATCH 53/58] fmt --- .../subtensor/src/migrations/migrate_chain_identity.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/pallets/subtensor/src/migrations/migrate_chain_identity.rs b/pallets/subtensor/src/migrations/migrate_chain_identity.rs index 2b16dd180..06ee5dd3f 100644 --- a/pallets/subtensor/src/migrations/migrate_chain_identity.rs +++ b/pallets/subtensor/src/migrations/migrate_chain_identity.rs @@ -140,9 +140,7 @@ pub fn migrate_set_hotkey_identities() -> Weight { && identity.description.len() <= 1024 && identity.additional.len() <= 1024; if !is_valid { - log::info!( - "Bytes not correct" - ); + log::info!("Bytes not correct"); continue; } @@ -157,9 +155,7 @@ pub fn migrate_set_hotkey_identities() -> Weight { weight = weight.saturating_add(T::DbWeight::get().writes(1)); } } else { - log::info!( - "Failed to decode JSON" - ); + log::info!("Failed to decode JSON"); } // Mark the migration as completed HasMigrationRun::::insert(&migration_name, true); From 771ce01eba20d4bd4f683535fa5e9341014ce8dd Mon Sep 17 00:00:00 2001 From: John Reed <87283488+JohnReedV@users.noreply.github.com> Date: Thu, 25 Jul 2024 09:30:00 -0700 Subject: [PATCH 54/58] fix test --- pallets/subtensor/tests/serving.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/subtensor/tests/serving.rs b/pallets/subtensor/tests/serving.rs index b736a90d0..56f788e0f 100644 --- a/pallets/subtensor/tests/serving.rs +++ b/pallets/subtensor/tests/serving.rs @@ -808,7 +808,7 @@ fn test_migrate_set_hotkey_identities() { // Assert that the migration has run assert!(HasMigrationRun::::get( - b"fix_total_coldkey_stake_v7".to_vec() + b"migrate_identities".to_vec() )); // Verify that some identities were set From dccfd98fe195c15b1dc92ad1713146a99389a835 Mon Sep 17 00:00:00 2001 From: John Reed <87283488+JohnReedV@users.noreply.github.com> Date: Fri, 26 Jul 2024 09:32:02 -0700 Subject: [PATCH 55/58] fmt & clippy --- pallets/collective/src/lib.rs | 6 +++--- pallets/subtensor/tests/serving.rs | 4 +--- runtime/src/lib.rs | 2 ++ 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pallets/collective/src/lib.rs b/pallets/collective/src/lib.rs index 96040f99c..6aae3c85e 100644 --- a/pallets/collective/src/lib.rs +++ b/pallets/collective/src/lib.rs @@ -951,9 +951,9 @@ impl, I: 'static> Pallet { /// /// If not `approved`: /// - one event deposited. - /// Two removals, one mutation. - /// Computation and i/o `O(P)` where: - /// - `P` is number of active proposals + /// - two removals, one mutation. + /// - computation and i/o `O(P)` where: + /// - `P` is number of active proposals fn do_approve_proposal( seats: MemberCount, yes_votes: MemberCount, diff --git a/pallets/subtensor/tests/serving.rs b/pallets/subtensor/tests/serving.rs index 56f788e0f..4fb6c589a 100644 --- a/pallets/subtensor/tests/serving.rs +++ b/pallets/subtensor/tests/serving.rs @@ -807,9 +807,7 @@ fn test_migrate_set_hotkey_identities() { >(); // Assert that the migration has run - assert!(HasMigrationRun::::get( - b"migrate_identities".to_vec() - )); + assert!(HasMigrationRun::::get(b"migrate_identities".to_vec())); // Verify that some identities were set // Note: This assumes that at least one valid identity was in the JSON file diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 3bd71977e..534395f22 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -529,6 +529,7 @@ impl pallet_collective::Config for Runtime { } // We call council members Triumvirate +#[allow(dead_code)] type TriumvirateMembership = pallet_membership::Instance1; impl pallet_membership::Config for Runtime { type RuntimeEvent = RuntimeEvent; @@ -544,6 +545,7 @@ impl pallet_membership::Config for Runtime { } // We call our top K delegates membership Senate +#[allow(dead_code)] type SenateMembership = pallet_membership::Instance2; impl pallet_membership::Config for Runtime { type RuntimeEvent = RuntimeEvent; From 4dbdd77b2e478cd822b34f513062550c383faec7 Mon Sep 17 00:00:00 2001 From: John Reed <87283488+JohnReedV@users.noreply.github.com> Date: Fri, 26 Jul 2024 10:03:40 -0700 Subject: [PATCH 56/58] fmt & clippy --- pallets/subtensor/tests/mock.rs | 4 ++++ pallets/subtensor/tests/serving.rs | 10 ++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/pallets/subtensor/tests/mock.rs b/pallets/subtensor/tests/mock.rs index 27d11eb13..d8d677006 100644 --- a/pallets/subtensor/tests/mock.rs +++ b/pallets/subtensor/tests/mock.rs @@ -264,6 +264,7 @@ impl CollectiveInterface for TriumvirateVotes { } // We call pallet_collective TriumvirateCollective +#[allow(dead_code)] type TriumvirateCollective = pallet_collective::Instance1; impl pallet_collective::Config for Test { type RuntimeOrigin = RuntimeOrigin; @@ -281,6 +282,7 @@ impl pallet_collective::Config for Test { } // We call council members Triumvirate +#[allow(dead_code)] type TriumvirateMembership = pallet_membership::Instance1; impl pallet_membership::Config for Test { type RuntimeEvent = RuntimeEvent; @@ -297,6 +299,7 @@ impl pallet_membership::Config for Test { // This is a dummy collective instance for managing senate members // Probably not the best solution, but fastest implementation +#[allow(dead_code)] type SenateCollective = pallet_collective::Instance2; impl pallet_collective::Config for Test { type RuntimeOrigin = RuntimeOrigin; @@ -314,6 +317,7 @@ impl pallet_collective::Config for Test { } // We call our top K delegates membership Senate +#[allow(dead_code)] type SenateMembership = pallet_membership::Instance2; impl pallet_membership::Config for Test { type RuntimeEvent = RuntimeEvent; diff --git a/pallets/subtensor/tests/serving.rs b/pallets/subtensor/tests/serving.rs index 4fb6c589a..18b207609 100644 --- a/pallets/subtensor/tests/serving.rs +++ b/pallets/subtensor/tests/serving.rs @@ -586,7 +586,7 @@ fn test_do_set_identity() { )); // Check if identity is set correctly - let stored_identity = Identities::::get(coldkey).unwrap(); + let stored_identity = Identities::::get(coldkey).expect("Identity should be set"); assert_eq!(stored_identity.name, name); assert_eq!(stored_identity.url, url); assert_eq!(stored_identity.image, image); @@ -622,7 +622,8 @@ fn test_do_set_identity() { additional.clone() )); - let updated_identity = Identities::::get(coldkey).unwrap(); + let updated_identity = + Identities::::get(coldkey).expect("Updated identity should be set"); assert_eq!(updated_identity.name, new_name); assert_eq!(updated_identity.url, new_url); @@ -760,7 +761,7 @@ fn test_set_and_get_identity() { )); // Get and verify identity - let stored_identity = Identities::::get(coldkey).unwrap(); + let stored_identity = Identities::::get(coldkey).expect("Identity should be set"); assert_eq!(stored_identity.name, name); assert_eq!(stored_identity.url, url); assert_eq!(stored_identity.image, image); @@ -782,7 +783,8 @@ fn test_set_and_get_identity() { )); // Get and verify updated identity - let updated_identity = Identities::::get(coldkey).unwrap(); + let updated_identity = + Identities::::get(coldkey).expect("Updated identity should be set"); assert_eq!(updated_identity.name, new_name); assert_eq!(updated_identity.url, new_url); assert_eq!(updated_identity.image, image); From 646f19d58c3f47b821b331aed7548195c98d52ba Mon Sep 17 00:00:00 2001 From: John Reed <87283488+JohnReedV@users.noreply.github.com> Date: Fri, 26 Jul 2024 11:40:38 -0700 Subject: [PATCH 57/58] remove tarpaulin references --- pallets/subtensor/tests/children.rs | 1 - pallets/subtensor/tests/coinbase.rs | 4 ---- pallets/subtensor/tests/difficulty.rs | 1 - pallets/subtensor/tests/epoch.rs | 1 - pallets/subtensor/tests/neuron_info.rs | 1 - pallets/subtensor/tests/registration.rs | 1 - pallets/subtensor/tests/serving.rs | 2 -- pallets/subtensor/tests/staking.rs | 2 -- pallets/subtensor/tests/weights.rs | 3 --- 9 files changed, 16 deletions(-) diff --git a/pallets/subtensor/tests/children.rs b/pallets/subtensor/tests/children.rs index 9ad07e1e7..e834baa85 100644 --- a/pallets/subtensor/tests/children.rs +++ b/pallets/subtensor/tests/children.rs @@ -297,7 +297,6 @@ fn test_do_set_child_singular_multiple_children() { // SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_add_singular_child --exact --nocapture #[test] -#[cfg(not(tarpaulin))] fn test_add_singular_child() { new_test_ext(1).execute_with(|| { let netuid: u16 = 1; diff --git a/pallets/subtensor/tests/coinbase.rs b/pallets/subtensor/tests/coinbase.rs index 8fd963dff..d6e48bbcc 100644 --- a/pallets/subtensor/tests/coinbase.rs +++ b/pallets/subtensor/tests/coinbase.rs @@ -6,7 +6,6 @@ use sp_core::U256; // Test the ability to hash all sorts of hotkeys. #[test] -#[cfg(not(tarpaulin))] fn test_hotkey_hashing() { new_test_ext(1).execute_with(|| { for i in 0..10000 { @@ -18,7 +17,6 @@ fn test_hotkey_hashing() { // Test drain tempo on hotkeys. // SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test coinbase test_hotkey_drain_time -- --nocapture #[test] -#[cfg(not(tarpaulin))] fn test_hotkey_drain_time() { new_test_ext(1).execute_with(|| { // Block 0 @@ -46,7 +44,6 @@ fn test_hotkey_drain_time() { // To run this test specifically, use the following command: // SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test coinbase test_coinbase_basic -- --nocapture #[test] -#[cfg(not(tarpaulin))] fn test_coinbase_basic() { new_test_ext(1).execute_with(|| { // Define network ID @@ -138,7 +135,6 @@ fn test_coinbase_basic() { // Test getting and setting hotkey emission tempo // SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test coinbase test_set_and_get_hotkey_emission_tempo -- --nocapture #[test] -#[cfg(not(tarpaulin))] fn test_set_and_get_hotkey_emission_tempo() { new_test_ext(1).execute_with(|| { // Get the default hotkey emission tempo diff --git a/pallets/subtensor/tests/difficulty.rs b/pallets/subtensor/tests/difficulty.rs index 05238bc43..c3023b829 100644 --- a/pallets/subtensor/tests/difficulty.rs +++ b/pallets/subtensor/tests/difficulty.rs @@ -5,7 +5,6 @@ mod mock; use sp_core::U256; #[test] -#[cfg(not(tarpaulin))] fn test_registration_difficulty_adjustment() { new_test_ext(1).execute_with(|| { // Create Net 1 diff --git a/pallets/subtensor/tests/epoch.rs b/pallets/subtensor/tests/epoch.rs index 526a58b4e..b639a4ac4 100644 --- a/pallets/subtensor/tests/epoch.rs +++ b/pallets/subtensor/tests/epoch.rs @@ -2107,7 +2107,6 @@ fn test_zero_weights() { // Test that epoch assigns validator permits to highest stake uids, varies uid interleaving and stake values. #[test] -#[cfg(not(tarpaulin))] fn test_validator_permits() { let netuid: u16 = 1; let tempo: u16 = u16::MAX - 1; // high tempo to skip automatic epochs in on_initialize, use manual epochs instead diff --git a/pallets/subtensor/tests/neuron_info.rs b/pallets/subtensor/tests/neuron_info.rs index 10df1c07d..3494fdc5f 100644 --- a/pallets/subtensor/tests/neuron_info.rs +++ b/pallets/subtensor/tests/neuron_info.rs @@ -15,7 +15,6 @@ fn test_get_neuron_none() { } #[test] -#[cfg(not(tarpaulin))] fn test_get_neuron_some() { new_test_ext(1).execute_with(|| { let netuid: u16 = 1; diff --git a/pallets/subtensor/tests/registration.rs b/pallets/subtensor/tests/registration.rs index bd95ae3b1..7d6e8ea65 100644 --- a/pallets/subtensor/tests/registration.rs +++ b/pallets/subtensor/tests/registration.rs @@ -539,7 +539,6 @@ fn test_burn_adjustment() { } #[test] -#[cfg(not(tarpaulin))] fn test_registration_too_many_registrations_per_block() { new_test_ext(1).execute_with(|| { let netuid: u16 = 1; diff --git a/pallets/subtensor/tests/serving.rs b/pallets/subtensor/tests/serving.rs index 18b207609..b0eada8e6 100644 --- a/pallets/subtensor/tests/serving.rs +++ b/pallets/subtensor/tests/serving.rs @@ -164,7 +164,6 @@ fn test_serving_set_metadata_update() { } #[test] -#[cfg(not(tarpaulin))] fn test_axon_serving_rate_limit_exceeded() { new_test_ext(1).execute_with(|| { let hotkey_account_id = U256::from(1); @@ -382,7 +381,6 @@ fn test_prometheus_serving_set_metadata_update() { } #[test] -#[cfg(not(tarpaulin))] fn test_prometheus_serving_rate_limit_exceeded() { new_test_ext(1).execute_with(|| { let hotkey_account_id = U256::from(1); diff --git a/pallets/subtensor/tests/staking.rs b/pallets/subtensor/tests/staking.rs index 2952426a9..5bf95841a 100644 --- a/pallets/subtensor/tests/staking.rs +++ b/pallets/subtensor/tests/staking.rs @@ -15,7 +15,6 @@ use sp_core::{H256, U256}; ************************************************************/ #[test] -#[cfg(not(tarpaulin))] fn test_add_stake_dispatch_info_ok() { new_test_ext(1).execute_with(|| { let hotkey = U256::from(0); @@ -521,7 +520,6 @@ fn test_remove_stake_rate_limit_exceeded() { } #[test] -#[cfg(not(tarpaulin))] fn test_remove_stake_dispatch_info_ok() { new_test_ext(1).execute_with(|| { let hotkey = U256::from(0); diff --git a/pallets/subtensor/tests/weights.rs b/pallets/subtensor/tests/weights.rs index 2344bd425..020eb1f6b 100644 --- a/pallets/subtensor/tests/weights.rs +++ b/pallets/subtensor/tests/weights.rs @@ -21,7 +21,6 @@ use substrate_fixed::types::I32F32; // Test the call passes through the subtensor module. #[test] -#[cfg(not(tarpaulin))] fn test_set_weights_dispatch_info_ok() { new_test_ext(0).execute_with(|| { let dests = vec![1, 1]; @@ -41,7 +40,6 @@ fn test_set_weights_dispatch_info_ok() { }); } #[test] -#[cfg(not(tarpaulin))] fn test_set_rootweights_dispatch_info_ok() { new_test_ext(0).execute_with(|| { let dests = vec![1, 1]; @@ -404,7 +402,6 @@ fn test_weights_err_no_validator_permit() { // To execute this test: cargo test --package pallet-subtensor --test weights test_set_weights_min_stake_failed -- --nocapture` #[test] -#[cfg(not(tarpaulin))] fn test_set_weights_min_stake_failed() { new_test_ext(0).execute_with(|| { let dests = vec![0]; From 2ab7d27b73ccdf19e4819abf504b8dafd476c430 Mon Sep 17 00:00:00 2001 From: John Reed <87283488+JohnReedV@users.noreply.github.com> Date: Fri, 26 Jul 2024 12:09:45 -0700 Subject: [PATCH 58/58] Update Cargo.toml --- pallets/subtensor/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pallets/subtensor/Cargo.toml b/pallets/subtensor/Cargo.toml index 82ed28646..9f022b5b7 100644 --- a/pallets/subtensor/Cargo.toml +++ b/pallets/subtensor/Cargo.toml @@ -84,6 +84,7 @@ std = [ "serde_with/std", "substrate-fixed/std", "num-traits/std", + "serde_json/std" ] runtime-benchmarks = [ "frame-benchmarking/runtime-benchmarks",