From f241f6683b0345a88b9c3658b90dd0a9d5b884ff Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Wed, 17 Jul 2024 10:33:25 -0400 Subject: [PATCH 001/177] add root crate --- Cargo.lock | 11 +++++++++++ Cargo.toml | 18 ++++++++++++++++++ src/lib.rs | 0 3 files changed, 29 insertions(+) create mode 100644 src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 868e85b89..cc30d5335 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9112,6 +9112,17 @@ dependencies = [ "wasm-opt", ] +[[package]] +name = "subtensor" +version = "0.1.0" +dependencies = [ + "node-subtensor", + "node-subtensor-runtime", + "pallet-commitments", + "pallet-subtensor", + "subtensor-macros", +] + [[package]] name = "subtensor-custom-rpc" version = "0.0.2" diff --git a/Cargo.toml b/Cargo.toml index 8d9eff122..cd5208864 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,3 +1,21 @@ +[package] +name = "subtensor" +version = "0.1.0" +description = "Implementation of the bittensor blockchain" +authors = ["Substrate DevHub "] +homepage = "https://substrate.io/" +edition = "2021" +license = "Unlicense" +publish = false +repository = "https://github.com/opentensor/subtensor" + +[dependencies] +node-subtensor = { path = "node", version = "4.0.0-dev" } +pallet-commitments = { path = "pallets/commitments", version = "4.0.0-dev" } +pallet-subtensor = { path = "pallets/subtensor", version = "4.0.0-dev" } +node-subtensor-runtime = { path = "runtime", version = "4.0.0-dev" } +subtensor-macros = { path = "support/macros", version = "0.1.0" } + [workspace] members = [ "node", diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 000000000..e69de29bb From 770b21afb8b5cd78420b30edf3b04db39dde5101 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Wed, 17 Jul 2024 11:13:24 -0400 Subject: [PATCH 002/177] linting scaffold --- Cargo.lock | 113 +++++++++++++++++++------------------- Cargo.toml | 9 +++ build.rs | 40 ++++++++++++++ support/macros/Cargo.toml | 6 +- 4 files changed, 110 insertions(+), 58 deletions(-) create mode 100644 build.rs diff --git a/Cargo.lock b/Cargo.lock index cc30d5335..7d98e1d14 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -223,7 +223,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -625,7 +625,7 @@ checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -751,7 +751,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -1159,7 +1159,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -1553,7 +1553,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -1580,7 +1580,7 @@ dependencies = [ "proc-macro2", "quote", "scratch", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -1597,7 +1597,7 @@ checksum = "4b2c1c1776b986979be68bb2285da855f8d8a35851a769fca8740df7c3d07877" dependencies = [ "proc-macro2", "quote", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -1621,7 +1621,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -1632,7 +1632,7 @@ checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" dependencies = [ "darling_core", "quote", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -1738,7 +1738,7 @@ checksum = "d65d7ce8132b7c0e54497a4d9a55a1c2a0912a0d786cf894472ba818fba45762" dependencies = [ "proc-macro2", "quote", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -1751,7 +1751,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version 0.4.0", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -1840,7 +1840,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -1880,7 +1880,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.67", + "syn 2.0.71", "termcolor", "toml 0.8.14", "walkdir", @@ -2040,7 +2040,7 @@ checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -2153,7 +2153,7 @@ dependencies = [ "prettyplease 0.2.20", "proc-macro2", "quote", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -2489,7 +2489,7 @@ dependencies = [ "proc-macro2", "quote", "sp-crypto-hashing", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -2501,7 +2501,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -2511,7 +2511,7 @@ source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10. dependencies = [ "proc-macro2", "quote", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -2662,7 +2662,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -3453,7 +3453,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -4204,7 +4204,7 @@ dependencies = [ "macro_magic_core", "macro_magic_macros", "quote", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -4218,7 +4218,7 @@ dependencies = [ "macro_magic_core_macros", "proc-macro2", "quote", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -4229,7 +4229,7 @@ checksum = "9ea73aa640dc01d62a590d48c0c3521ed739d53b27f919b25c3551e233481654" dependencies = [ "proc-macro2", "quote", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -4240,7 +4240,7 @@ checksum = "ef9d79ae96aaba821963320eb2b6e34d17df1e5a83d8a1985c29cc5be59577b3" dependencies = [ "macro_magic_core", "quote", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -5590,7 +5590,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -5631,7 +5631,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -5717,7 +5717,7 @@ dependencies = [ "polkavm-common", "proc-macro2", "quote", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -5727,7 +5727,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ba81f7b5faac81e528eb6158a6f3c9e0bb1008e0ffa19653bc8dea925ecb429" dependencies = [ "polkavm-derive-impl", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -5854,7 +5854,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" dependencies = [ "proc-macro2", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -5922,7 +5922,7 @@ checksum = "834da187cfe638ae8abb0203f0b33e5ccdb02a28e7199f2f47b3e2754f50edca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -5968,7 +5968,7 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -6036,7 +6036,7 @@ dependencies = [ "itertools 0.12.1", "proc-macro2", "quote", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -6304,7 +6304,7 @@ checksum = "bcc303e793d3734489387d205e9b186fac9c6cfacedd98cbb2e8a5943595f3e6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -6763,7 +6763,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -7597,7 +7597,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -7878,7 +7878,7 @@ checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -7926,7 +7926,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -8159,7 +8159,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -8382,7 +8382,7 @@ source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10. dependencies = [ "quote", "sp-crypto-hashing", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -8401,7 +8401,7 @@ source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.10. dependencies = [ "proc-macro2", "quote", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -8411,7 +8411,7 @@ source = "git+https://github.com/paritytech/polkadot-sdk#c4b3c1c6c6e492c4196e06f dependencies = [ "proc-macro2", "quote", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -8636,7 +8636,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -8649,7 +8649,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -8862,7 +8862,7 @@ dependencies = [ "parity-scale-codec", "proc-macro2", "quote", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -9031,7 +9031,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -9120,7 +9120,10 @@ dependencies = [ "node-subtensor-runtime", "pallet-commitments", "pallet-subtensor", + "proc-macro2", "subtensor-macros", + "syn 2.0.71", + "walkdir", ] [[package]] @@ -9155,7 +9158,7 @@ dependencies = [ "ahash 0.8.11", "proc-macro2", "quote", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -9183,9 +9186,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.67" +version = "2.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff8655ed1d86f3af4ee3fd3263786bc14245ad17c4c7e85ba7187fb3ae028c90" +checksum = "b146dcf730474b4bcd16c311627b31ede9ab149045db4d6088b3becaea046462" dependencies = [ "proc-macro2", "quote", @@ -9291,7 +9294,7 @@ checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -9411,7 +9414,7 @@ checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -9569,7 +9572,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -9974,7 +9977,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.67", + "syn 2.0.71", "wasm-bindgen-shared", ] @@ -10008,7 +10011,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.67", + "syn 2.0.71", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -10727,7 +10730,7 @@ checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] @@ -10747,7 +10750,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.67", + "syn 2.0.71", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index cd5208864..0ae193639 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,11 @@ pallet-subtensor = { path = "pallets/subtensor", version = "4.0.0-dev" } node-subtensor-runtime = { path = "runtime", version = "4.0.0-dev" } subtensor-macros = { path = "support/macros", version = "0.1.0" } +[build-dependencies] +syn.workspace = true +proc-macro2.workspace = true +walkdir.workspace = true + [workspace] members = [ "node", @@ -54,6 +59,10 @@ serde_json = { version = "1.0.116", default-features = false } serde_with = { version = "=2.0.0", default-features = false } smallvec = "1.13.2" litep2p = { git = "https://github.com/paritytech/litep2p", branch = "master" } +syn = { version = "2", features = ["full", "visit-mut", "extra-traits"] } +quote = "1" +proc-macro2 = "1" +walkdir = "2" subtensor-macros = { path = "support/macros" } diff --git a/build.rs b/build.rs new file mode 100644 index 000000000..82843fefa --- /dev/null +++ b/build.rs @@ -0,0 +1,40 @@ +use std::env; +use std::fs; +use std::path::{Path, PathBuf}; +use walkdir::WalkDir; + +fn main() { + // Get the root directory of the workspace + let workspace_root = env::var("CARGO_MANIFEST_DIR").unwrap(); + let workspace_root = Path::new(&workspace_root); + + // Collect all Rust source files in the workspace + let rust_files = collect_rust_files(workspace_root); + + // Parse each Rust file with syn + for file in rust_files { + let Ok(content) = fs::read_to_string(&file) else { + continue; + }; + let Ok(parsed_file) = syn::parse_file(&content) else { + continue; + }; + //println!("{}", parsed_file.items.len()) + } +} + +// Recursively collects all Rust files in the given directory +fn collect_rust_files(dir: &Path) -> Vec { + let mut rust_files = Vec::new(); + + for entry in WalkDir::new(dir) { + let entry = entry.unwrap(); + let path = entry.path(); + + if path.is_file() && path.extension().and_then(|ext| ext.to_str()) == Some("rs") { + rust_files.push(path.to_path_buf()); + } + } + + rust_files +} diff --git a/support/macros/Cargo.toml b/support/macros/Cargo.toml index 10a15ba0d..b5a5febad 100644 --- a/support/macros/Cargo.toml +++ b/support/macros/Cargo.toml @@ -12,9 +12,9 @@ homepage = "https://bittensor.com/" proc-macro = true [dependencies] -syn = { version = "2", features = ["full", "visit-mut", "extra-traits"] } -proc-macro2 = "1" -quote = "1" +syn.workspace = true +proc-macro2.workspace = true +quote.workspace = true ahash = "0.8" [lints] From aebe7418ee8c1b359ba3a06ee29d4ce8c7e38b68 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Wed, 17 Jul 2024 11:33:07 -0400 Subject: [PATCH 003/177] lints trait --- build.rs | 2 ++ lints/mod.rs | 10 ++++++++++ 2 files changed, 12 insertions(+) create mode 100644 lints/mod.rs diff --git a/build.rs b/build.rs index 82843fefa..b5dd45950 100644 --- a/build.rs +++ b/build.rs @@ -3,6 +3,8 @@ use std::fs; use std::path::{Path, PathBuf}; use walkdir::WalkDir; +mod lints; + fn main() { // Get the root directory of the workspace let workspace_root = env::var("CARGO_MANIFEST_DIR").unwrap(); diff --git a/lints/mod.rs b/lints/mod.rs new file mode 100644 index 000000000..4338ee07c --- /dev/null +++ b/lints/mod.rs @@ -0,0 +1,10 @@ +use syn::{File, Result}; + +/// A trait that defines custom lints that can be run within our workspace. +/// +/// Each lint is run in parallel on all Rust source files in the workspace. Within a lint you +/// can issue an error the same way you would in a proc macro, and otherwise return `Ok(())` if +/// there are no errors. +pub trait Lint { + fn lint(source: &File) -> Result<()>; +} From 33d11d7986ef32d71d5a4e2d0c065b40a7924df1 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Wed, 17 Jul 2024 12:10:43 -0400 Subject: [PATCH 004/177] more --- build.rs | 1 + lints/dummy_lint.rs | 10 ++++++++++ lints/lint.rs | 11 +++++++++++ lints/mod.rs | 13 +++++-------- 4 files changed, 27 insertions(+), 8 deletions(-) create mode 100644 lints/dummy_lint.rs create mode 100644 lints/lint.rs diff --git a/build.rs b/build.rs index b5dd45950..155cbd226 100644 --- a/build.rs +++ b/build.rs @@ -4,6 +4,7 @@ use std::path::{Path, PathBuf}; use walkdir::WalkDir; mod lints; +use lints::*; fn main() { // Get the root directory of the workspace diff --git a/lints/dummy_lint.rs b/lints/dummy_lint.rs new file mode 100644 index 000000000..889d43be0 --- /dev/null +++ b/lints/dummy_lint.rs @@ -0,0 +1,10 @@ +use super::*; + +pub struct DummyLint; + +impl Lint for DummyLint { + fn lint(_source: &File) -> Result<()> { + // This is a dummy lint that does nothing + Ok(()) + } +} diff --git a/lints/lint.rs b/lints/lint.rs new file mode 100644 index 000000000..400af5401 --- /dev/null +++ b/lints/lint.rs @@ -0,0 +1,11 @@ +use super::*; + +/// A trait that defines custom lints that can be run within our workspace. +/// +/// Each lint is run in parallel on all Rust source files in the workspace. Within a lint you +/// can issue an error the same way you would in a proc macro, and otherwise return `Ok(())` if +/// there are no errors. +pub trait Lint { + /// Lints the given Rust source file, returning a compile error if any issues are found. + fn lint(source: &File) -> Result<()>; +} diff --git a/lints/mod.rs b/lints/mod.rs index 4338ee07c..3db2d6bd3 100644 --- a/lints/mod.rs +++ b/lints/mod.rs @@ -1,10 +1,7 @@ use syn::{File, Result}; -/// A trait that defines custom lints that can be run within our workspace. -/// -/// Each lint is run in parallel on all Rust source files in the workspace. Within a lint you -/// can issue an error the same way you would in a proc macro, and otherwise return `Ok(())` if -/// there are no errors. -pub trait Lint { - fn lint(source: &File) -> Result<()>; -} +pub mod lint; +pub use lint::*; + +mod dummy_lint; +use dummy_lint::DummyLint; From 44e1d4d88f5e6f9f974dc65d8fca17c3230f8e77 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Wed, 17 Jul 2024 14:57:04 -0400 Subject: [PATCH 005/177] working but not parallel --- Cargo.lock | 1 + Cargo.toml | 1 + build.rs | 37 ++++++++++++++++++++++++++++++++++++- lints/dummy_lint.rs | 5 +++-- lints/lint.rs | 6 ++++-- lints/mod.rs | 2 +- 6 files changed, 46 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7d98e1d14..41d243a01 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9121,6 +9121,7 @@ dependencies = [ "pallet-commitments", "pallet-subtensor", "proc-macro2", + "rayon", "subtensor-macros", "syn 2.0.71", "walkdir", diff --git a/Cargo.toml b/Cargo.toml index 0ae193639..8a34008d1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,7 @@ subtensor-macros = { path = "support/macros", version = "0.1.0" } syn.workspace = true proc-macro2.workspace = true walkdir.workspace = true +rayon = "1.10" [workspace] members = [ diff --git a/build.rs b/build.rs index 155cbd226..96bc52b67 100644 --- a/build.rs +++ b/build.rs @@ -1,6 +1,13 @@ +use rayon::prelude::*; use std::env; use std::fs; use std::path::{Path, PathBuf}; +use std::process::exit; +use std::sync::mpsc::channel; +use syn::spanned::Spanned; +use syn::Error; +use syn::File; +use syn::Result; use walkdir::WalkDir; mod lints; @@ -14,15 +21,39 @@ fn main() { // Collect all Rust source files in the workspace let rust_files = collect_rust_files(workspace_root); + let mut found_error = None; + // Parse each Rust file with syn for file in rust_files { + if found_error.is_some() { + break; + } let Ok(content) = fs::read_to_string(&file) else { continue; }; let Ok(parsed_file) = syn::parse_file(&content) else { continue; }; - //println!("{}", parsed_file.items.len()) + + let track_lint = |result: Result<()>| { + let Err(error) = result else { + return; + }; + found_error = Some((error, file)); + }; + + track_lint(DummyLint::lint(parsed_file)); + } + + if let Some((error, file)) = found_error { + let start = error.span().start(); + let end = error.span().end(); + let start_line = start.line; + let start_col = start.column; + let end_line = end.line; + let end_col = end.column; + let file_path = file.display(); + panic!("{}:{}:{}: {}", file_path, start_line, start_col, error); } } @@ -34,6 +65,10 @@ fn collect_rust_files(dir: &Path) -> Vec { let entry = entry.unwrap(); let path = entry.path(); + if path.ends_with("target") || path.ends_with("build.rs") { + continue; + } + if path.is_file() && path.extension().and_then(|ext| ext.to_str()) == Some("rs") { rust_files.push(path.to_path_buf()); } diff --git a/lints/dummy_lint.rs b/lints/dummy_lint.rs index 889d43be0..4447b66b5 100644 --- a/lints/dummy_lint.rs +++ b/lints/dummy_lint.rs @@ -1,10 +1,11 @@ +use syn::{spanned::Spanned, Error}; + use super::*; pub struct DummyLint; impl Lint for DummyLint { - fn lint(_source: &File) -> Result<()> { - // This is a dummy lint that does nothing + fn lint(_source: File) -> Result<()> { Ok(()) } } diff --git a/lints/lint.rs b/lints/lint.rs index 400af5401..69047c34c 100644 --- a/lints/lint.rs +++ b/lints/lint.rs @@ -1,3 +1,5 @@ +use rayon::iter::IntoParallelIterator; + use super::*; /// A trait that defines custom lints that can be run within our workspace. @@ -5,7 +7,7 @@ use super::*; /// Each lint is run in parallel on all Rust source files in the workspace. Within a lint you /// can issue an error the same way you would in a proc macro, and otherwise return `Ok(())` if /// there are no errors. -pub trait Lint { +pub trait Lint: Send + Sync { /// Lints the given Rust source file, returning a compile error if any issues are found. - fn lint(source: &File) -> Result<()>; + fn lint(source: File) -> Result<()>; } diff --git a/lints/mod.rs b/lints/mod.rs index 3db2d6bd3..d2f9bb1e7 100644 --- a/lints/mod.rs +++ b/lints/mod.rs @@ -4,4 +4,4 @@ pub mod lint; pub use lint::*; mod dummy_lint; -use dummy_lint::DummyLint; +pub use dummy_lint::DummyLint; From e900f03eb3460c11bc5de4f6ebf1813ccd4bc089 Mon Sep 17 00:00:00 2001 From: Watchmaker Date: Mon, 22 Jul 2024 12:56:17 -0700 Subject: [PATCH 006/177] Removing from the "main" branch the doc to run subtensor locally As per this Discord thread: https://discord.com/channels/799672011265015819/1260678915186495509 Docs issue: https://github.com/opentensor/developer-docs/issues/221 --- docs/running-subtensor-locally.md | 205 +----------------------------- 1 file changed, 1 insertion(+), 204 deletions(-) diff --git a/docs/running-subtensor-locally.md b/docs/running-subtensor-locally.md index 505fe2fb5..82bb87356 100644 --- a/docs/running-subtensor-locally.md +++ b/docs/running-subtensor-locally.md @@ -1,206 +1,3 @@ # Running subtensor node locally -- [Method 1: Using Docker](#method-1-using-docker) -- [Method 2: Using Source Code](#method-2-using-source-code) -- [Running on Cloud](#running-on-cloud) - -## Method 1: Using Docker - -To run a subtensor node with Docker, follow the below steps. - -If you are already running a subtensor node using Docker, then go directly to [Step 5 Prepare to Run](#step-5-prepare-to-run) to restart the Docker container. The below steps 1 through 4 are for first time users only. - -### Step 1: Install git - -Make sure you installed `git` on your machine. See [GitHub docs](https://docs.github.com/en/get-started). - -### Step 2: Install Docker - -Follow Docker's [official installation guides](https://docs.docker.com/engine/install/) and install Docker. - -**Run Docker first** -Before you proceed, make sure that Docker is running. - -### Step 3: Clone the subtensor repo - -Clone the subtensor repo: - -```bash -git clone https://github.com/opentensor/subtensor.git -``` - -### Step 4: Go into subtensor directory - -Then `cd` into the subtensor directory: - -```bash -cd subtensor -``` - -### Step 5: Prepare to run - -Execute the below three commands in this order: - -Make sure you are on the `main` branch. If not, switch to it: - -```bash -git checkout main -``` - -Pull the latest `main` branch contents: - -```bash -git pull -``` - -Stop the currently running Docker containers: - -```bash -docker compose down --volumes -``` - -### Run a lite node on mainchain - -To run a lite node connected to the Bittensor mainchain, run the below command. - -```bash -sudo ./scripts/run/subtensor.sh -e docker --network mainnet --node-type lite -``` - -### Run an archive node on mainchain - -To run an archive node connected to the Bittensor mainchain, run the below command. - -```bash -sudo ./scripts/run/subtensor.sh -e docker --network mainnet --node-type archive -``` - -### Run a lite node on testchain - -To run a lite node connected to the Bittensor testchain, run the below command. - -```bash -sudo ./scripts/run/subtensor.sh -e docker --network testnet --node-type lite -``` - -### Run an archive node on testchain - -To run an archive node connected to the Bittensor testchain, run the below command. - -```bash -sudo ./scripts/run/subtensor.sh -e docker --network testnet --node-type archive -``` - ---- - -## Method 2: Using Source Code - -To install and run a subtensor node by compiling the source code, follow the below steps. - -## Install basic packages - -Install the basic requirements by running the below commands on a Linux terminal. - -```bash title="On Linux" -sudo apt-get update -sudo apt install build-essential -sudo apt-get install clang -sudo apt-get install curl -sudo apt-get install git -sudo apt-get install make -sudo apt install --assume-yes git clang curl libssl-dev protobuf-compiler -sudo apt install --assume-yes git clang curl libssl-dev llvm libudev-dev make protobuf-compiler -``` - -## Install Rust - -Next, install Rust and update the environment by running the following commands: - -```bash -curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -source ~/.cargo/env -``` - -Next, install Rust toolchain: - -```bash -rustup default stable -rustup update -rustup target add wasm32-unknown-unknown -rustup toolchain install nightly -rustup target add --toolchain nightly wasm32-unknown-unknown -``` - -## Compile subtensor code - -Next, to compile the subtensor source code, follow the below steps: - -Clone the subtensor repo: - -```bash -git clone https://github.com/opentensor/subtensor.git -``` - -`cd` into the subtensor directory: - -```bash -cd subtensor -``` - -Make sure you are on the `main` branch. If not, switch to it: - -```bash -git checkout main -``` - -Remove previous chain state: - -```bash -rm -rf /tmp/blockchain -``` - -Install subtensor by compiling with `cargo`: - -```bash -cargo build --profile production --features=runtime-benchmarks -``` - -## Run the subtensor node - -You can now run the public subtensor node either as a lite node or as an archive node. See below: - -### Lite node on mainchain - -To run a lite node connected to the mainchain, execute the below command (note the `--sync=warp` flag which runs the subtensor node in lite mode): - -```bash title="With --sync=warp setting, for lite node" -./target/production/node-subtensor --chain raw_spec.json --base-path /tmp/blockchain --sync=warp --port 30333 --max-runtime-instances 32 --rpc-max-response-size 2048 --rpc-cors all --rpc-port 9944 --bootnodes /ip4/13.58.175.193/tcp/30333/p2p/12D3KooWDe7g2JbNETiKypcKT1KsCEZJbTzEHCn8hpd4PHZ6pdz5 --no-mdns --in-peers 8000 --out-peers 8000 --prometheus-external --rpc-external -``` - -### Archive node on mainchain - -To run an archive node connected to the mainchain, execute the below command (note the `--sync=full` which syncs the node to the full chain and `--pruning archive` flags, which disables the node's automatic pruning of older historical data): - -```bash title="With --sync=full and --pruning archive setting, for archive node" -./target/production/node-subtensor --chain raw_spec.json --base-path /tmp/blockchain --sync=full --pruning archive --port 30333 --max-runtime-instances 32 --rpc-max-response-size 2048 --rpc-cors all --rpc-port 9944 --bootnodes /ip4/13.58.175.193/tcp/30333/p2p/12D3KooWDe7g2JbNETiKypcKT1KsCEZJbTzEHCn8hpd4PHZ6pdz5 --no-mdns --in-peers 8000 --out-peers 8000 --prometheus-external --rpc-external -``` - -### Lite node on testchain - -To run a lite node connected to the testchain, execute the below command: - -```bash title="With bootnodes set to testnet and --sync=warp setting, for lite node." -./target/production/node-subtensor --chain raw_testspec.json --base-path /tmp/blockchain --sync=warp --port 30333 --max-runtime-instances 32 --rpc-max-response-size 2048 --rpc-cors all --rpc-port 9944 --bootnodes /dns/bootnode.test.finney.opentensor.ai/tcp/30333/p2p/12D3KooWPM4mLcKJGtyVtkggqdG84zWrd7Rij6PGQDoijh1X86Vr --no-mdns --in-peers 8000 --out-peers 8000 --prometheus-external --rpc-external -``` - -### Archive node on testchain - -To run an archive node connected to the testchain, execute the below command: - -```bash title="With bootnodes set to testnet and --sync=full and --pruning archive setting, for archive node" -./target/production/node-subtensor --chain raw_testspec.json --base-path /tmp/blockchain --sync=full --pruning archive --port 30333 --max-runtime-instances 32 --rpc-max-response-size 2048 --rpc-cors all --rpc-port 9944 --bootnodes /dns/bootnode.test.finney.opentensor.ai/tcp/30333/p2p/12D3KooWPM4mLcKJGtyVtkggqdG84zWrd7Rij6PGQDoijh1X86Vr --no-mdns --in-peers 8000 --out-peers 8000 --prometheus-external --rpc-external -``` - -## Running on cloud - -We have not tested these installation scripts on any cloud service. In addition, if you are using Runpod cloud service, then note that this service is already [containerized](https://docs.runpod.io/pods/overview). Hence, the only option available to you is to compile from the source, as described in the above [Method 2: Using Source Code](#method-2-using-source-code) section. Note that these scripts have not been tested on Runpod. +See the [**Subtensor Nodes** section in Bittensor Developer Documentation](https://docs.bittensor.com/subtensor-nodes). From 55e6d0681d7521eaf314d6b6c6643fd0f54a4ae8 Mon Sep 17 00:00:00 2001 From: Watchmaker Date: Mon, 22 Jul 2024 13:11:09 -0700 Subject: [PATCH 007/177] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 47639b640..30f36ffab 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ Requirements: ## For Subnet Development -If you are developing and testing subnet incentive mechanism, you will need to run a local subtensor node. Follow the detailed step-by-step instructions provided in the document [Running subtensor locally](./docs/running-subtensor-locally.md) to run either a lite node or an archive node. Also see the [**Subtensor Nodes** section in Bittensor Developer Documentation](https://docs.bittensor.com/subtensor-nodes). +If you are developing and testing subnet incentive mechanism, you will need to run a local subtensor node. Follow the detailed step-by-step instructions provided in the [**Subtensor Nodes** section in Bittensor Developer Documentation](https://docs.bittensor.com/subtensor-nodes). ### Lite node vs Archive node From ed729b644d229d3d9fe574997532db37d6e4d945 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 23 Jul 2024 09:03:50 -0700 Subject: [PATCH 008/177] 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 aec052a099de7f3977964a3d6117b8222cc351a2 Mon Sep 17 00:00:00 2001 From: Unconst <32490803+unconst@users.noreply.github.com> Date: Tue, 23 Jul 2024 12:38:54 -0500 Subject: [PATCH 009/177] Update CODEOWNERS --- CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODEOWNERS b/CODEOWNERS index 5fefbd608..ffc01511b 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1 +1 @@ -* @sacha-l @lisa-parity +* @unconst From b003138ed292c13dc98d74b35de248a28c77241e Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 23 Jul 2024 12:05:33 -0700 Subject: [PATCH 010/177] 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 f9b6828806dd252de9255226c9822a6647c54c7a Mon Sep 17 00:00:00 2001 From: unconst Date: Wed, 24 Jul 2024 13:42:18 -0500 Subject: [PATCH 011/177] 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 012/177] 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 013/177] 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 014/177] 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 015/177] 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 016/177] 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 017/177] 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 3b1352dafddff722709524166223484f5ad5f6bf Mon Sep 17 00:00:00 2001 From: Keith Date: Thu, 25 Jul 2024 16:55:52 +0200 Subject: [PATCH 018/177] Only run spec version check when the skip label doesn't exist --- .github/workflows/check-finney.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/check-finney.yml b/.github/workflows/check-finney.yml index 4bb12caf2..2428487b7 100644 --- a/.github/workflows/check-finney.yml +++ b/.github/workflows/check-finney.yml @@ -11,6 +11,7 @@ jobs: check-spec-version: name: Check spec_version bump runs-on: SubtensorCI + if: !contains(github.event.issue.labels.*.name, 'no-spec-version-bump') steps: - name: Dependencies run: | From 58cc59b8f2f482243305f233677949510e11fef0 Mon Sep 17 00:00:00 2001 From: Keith Date: Thu, 25 Jul 2024 17:01:01 +0200 Subject: [PATCH 019/177] Fix syntax error --- .github/workflows/check-finney.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/check-finney.yml b/.github/workflows/check-finney.yml index 2428487b7..ac14dd601 100644 --- a/.github/workflows/check-finney.yml +++ b/.github/workflows/check-finney.yml @@ -11,7 +11,7 @@ jobs: check-spec-version: name: Check spec_version bump runs-on: SubtensorCI - if: !contains(github.event.issue.labels.*.name, 'no-spec-version-bump') + if: ${{ !contains(github.event.issue.labels.*.name, 'no-spec-version-bump') }} steps: - name: Dependencies run: | 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 020/177] 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 021/177] 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 cb78f39dea933e7510bc34701044b5691b046240 Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Fri, 26 Jul 2024 20:59:56 +0400 Subject: [PATCH 022/177] clippy --- pallets/collective/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pallets/collective/src/lib.rs b/pallets/collective/src/lib.rs index 96040f99c..c6552b036 100644 --- a/pallets/collective/src/lib.rs +++ b/pallets/collective/src/lib.rs @@ -951,8 +951,8 @@ impl, I: 'static> Pallet { /// /// If not `approved`: /// - one event deposited. - /// Two removals, one mutation. - /// Computation and i/o `O(P)` where: + /// Two removals, one mutation. + /// Computation and i/o `O(P)` where: /// - `P` is number of active proposals fn do_approve_proposal( seats: MemberCount, 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 023/177] 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 024/177] 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 025/177] 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", From d9b8eb9570641c65118b974520fb59e79ea5f79f Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Mon, 29 Jul 2024 20:06:11 +0400 Subject: [PATCH 026/177] stash --- Cargo.toml | 2 +- pallets/subtensor/src/lib.rs | 1 + pallets/subtensor/src/macros/config.rs | 13 +++- pallets/subtensor/src/macros/dispatches.rs | 87 +++++++++++++++++++++- runtime/Cargo.toml | 6 +- runtime/src/lib.rs | 24 +++++- runtime/tests/pallet_proxy.rs | 2 +- 7 files changed, 127 insertions(+), 8 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4a7565a01..2db7ce1d2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,7 +42,7 @@ subtensor-macros = { path = "support/macros" } 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-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 } diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index abf6a8613..3f9004167 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -19,6 +19,7 @@ use codec::{Decode, Encode}; use frame_support::sp_runtime::transaction_validity::InvalidTransaction; use frame_support::sp_runtime::transaction_validity::ValidTransaction; use pallet_balances::Call as BalancesCall; +// use pallet_scheduler as Scheduler; use scale_info::TypeInfo; use sp_runtime::{ traits::{DispatchInfoOf, Dispatchable, PostDispatchInfoOf, SignedExtension}, diff --git a/pallets/subtensor/src/macros/config.rs b/pallets/subtensor/src/macros/config.rs index e59eac5ca..fb1ad5415 100644 --- a/pallets/subtensor/src/macros/config.rs +++ b/pallets/subtensor/src/macros/config.rs @@ -1,7 +1,6 @@ #![allow(clippy::crate_in_macro_def)] 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] @@ -31,6 +30,18 @@ mod config { /// Interface to allow other pallets to control who can register identities type TriumvirateInterface: crate::CollectiveInterface; + /// The scheduler type used for scheduling delayed calls. + type Scheduler: ScheduleNamed, Call, Self::RuntimeOrigin>; + + /// The hashing system (algorithm) being used in the runtime, matching the Scheduler's Hasher. + type Hasher: Hash< + Output = <, + Call, + Self::RuntimeOrigin, + >>::Hasher as Hash>::Output, + >; + /// ================================= /// ==== Initial Value Constants ==== /// ================================= diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 293dc0238..a84c5964d 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -4,6 +4,12 @@ use frame_support::pallet_macros::pallet_section; /// This can later be imported into the pallet using [`import_section`]. #[pallet_section] mod dispatches { + use frame_support::traits::schedule::v3::Named as ScheduleNamed; + use frame_support::traits::schedule::DispatchTime; + use frame_support::traits::Bounded; + use frame_system::pallet_prelude::BlockNumberFor; + use sp_runtime::traits::Hash; + use sp_runtime::traits::Saturating; /// 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. @@ -675,7 +681,11 @@ mod dispatches { origin: OriginFor, new_coldkey: T::AccountId, ) -> DispatchResultWithPostInfo { - Self::do_swap_coldkey(origin, &new_coldkey) + // Ensure it's called with root privileges (scheduler has root privileges) + ensure_root(origin.clone())?; + + let who = ensure_signed(origin)?; + Self::do_swap_coldkey(frame_system::RawOrigin::Signed(who).into(), &new_coldkey) } /// Unstakes all tokens associated with a hotkey and transfers them to a new coldkey. @@ -901,5 +911,80 @@ mod dispatches { Self::do_set_children(origin, hotkey, netuid, children)?; Ok(().into()) } + + /// Schedules a coldkey swap operation to be executed at a future block. + /// + /// This function allows a user to schedule the swapping of their coldkey to a new one + /// at a specified future block. The swap is not executed immediately but is scheduled + /// to occur at the specified block number. + /// + /// # Arguments + /// + /// * `origin` - The origin of the call, which should be signed by the current coldkey owner. + /// * `new_coldkey` - The account ID of the new coldkey that will replace the current one. + /// * `when` - The block number at which the coldkey swap should be executed. + /// + /// # Returns + /// + /// Returns a `DispatchResultWithPostInfo` indicating whether the scheduling was successful. + /// + /// # Errors + /// + /// This function may return an error if: + /// * The origin is not signed. + /// * The scheduling fails due to conflicts or system constraints. + /// + /// # Notes + /// + /// - The actual swap is not performed by this function. It merely schedules the swap operation. + /// - The weight of this call is set to a fixed value and may need adjustment based on benchmarking. + /// + /// # TODO + /// + /// - Implement proper weight calculation based on the complexity of the operation. + /// - Consider adding checks to prevent scheduling too far into the future. + /// TODO: Benchmark this call + #[pallet::call_index(73)] + #[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 schedule_swap_coldkey( + origin: OriginFor, + new_coldkey: T::AccountId, + ) -> DispatchResultWithPostInfo { + let who = ensure_signed(origin)?; + + // Calculate the number of blocks in 5 days + let blocks_in_5_days: u32 = 5 * 24 * 60 * 60 / 12; + + let current_block = >::block_number(); + let when = current_block.saturating_add(BlockNumberFor::::from(blocks_in_5_days)); + + let call = Call::::swap_coldkey { + new_coldkey: new_coldkey.clone(), + }; + + let unique_id = ( + b"schedule_swap_coldkey", + who.clone(), + new_coldkey.clone(), + when, + ) + .using_encoded(sp_io::hashing::blake2_256); + + let hash = T::Hasher::hash(&call.encode()); + let len = call.using_encoded(|e| e.len() as u32); + + T::Scheduler::schedule_named( + unique_id, + DispatchTime::At(when), + None, + 63, + frame_system::RawOrigin::Root.into(), + Bounded::Lookup { hash, len }, + )?; + + Ok(().into()) + } } } diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index 042d0337c..c8fac478b 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -155,7 +155,7 @@ std = [ "sp-tracing/std", "log/std", "sp-storage/std", - "sp-genesis-builder/std" + "sp-genesis-builder/std", ] runtime-benchmarks = [ "frame-benchmarking/runtime-benchmarks", @@ -178,7 +178,7 @@ runtime-benchmarks = [ "pallet-multisig/runtime-benchmarks", "pallet-preimage/runtime-benchmarks", "pallet-scheduler/runtime-benchmarks", - "pallet-sudo/runtime-benchmarks" + "pallet-sudo/runtime-benchmarks", ] try-runtime = [ "frame-try-runtime/try-runtime", @@ -204,6 +204,6 @@ try-runtime = [ "sp-runtime/try-runtime", "pallet-admin-utils/try-runtime", "pallet-commitments/try-runtime", - "pallet-registry/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 61f3a3c85..1d2236dc3 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_support::traits::schedule::v3::Named as ScheduleNamed; use frame_support::{ dispatch::DispatchResultWithPostInfo, genesis_builder_helper::{build_config, create_default_config}, @@ -68,6 +69,7 @@ pub use sp_runtime::BuildStorage; pub use sp_runtime::{Perbill, Permill}; // Subtensor module +pub use pallet_scheduler; pub use pallet_subtensor; // An index to a block. @@ -94,6 +96,10 @@ type MemberCount = u32; pub type Nonce = u32; +/// The scheduler type used for scheduling delayed calls. +// With something like this: +// type Scheduler = pallet_subtensor::Scheduler; + // Method used to calculate the fee of an extrinsic pub const fn deposit(items: u32, bytes: u32) -> Balance { pub const ITEMS_FEE: Balance = 2_000 * 10_000; @@ -834,6 +840,19 @@ impl pallet_commitments::Config for Runtime { type RateLimit = CommitmentRateLimit; } +impl pallet_scheduler::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type RuntimeOrigin = RuntimeOrigin; + type PalletsOrigin = OriginCaller; + type RuntimeCall = RuntimeCall; + type MaximumWeight = MaximumSchedulerWeight; + type ScheduleOrigin = EnsureRoot; + type MaxScheduledPerBlock = ConstU32<50>; + type WeightInfo = pallet_scheduler::weights::SubstrateWeight; + type OriginPrivilegeCmp = EqualPrivilegeOnly; + type Preimages = Preimage; +} + // Configure the pallet subtensor. parameter_types! { pub const SubtensorInitialRho: u16 = 10; @@ -883,6 +902,7 @@ parameter_types! { 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 { @@ -892,6 +912,8 @@ impl pallet_subtensor::Config for Runtime { type CouncilOrigin = EnsureMajoritySenate; type SenateMembers = ManageSenateMembers; type TriumvirateInterface = TriumvirateVotes; + type Scheduler = pallet_scheduler::Pallet; + type Hasher = BlakeTwo256; type InitialRho = SubtensorInitialRho; type InitialKappa = SubtensorInitialKappa; @@ -1266,12 +1288,12 @@ construct_runtime!( Sudo: pallet_sudo, Multisig: pallet_multisig, Preimage: pallet_preimage, - Scheduler: pallet_scheduler, Proxy: pallet_proxy, Registry: pallet_registry, Commitments: pallet_commitments, AdminUtils: pallet_admin_utils, SafeMode: pallet_safe_mode, + Scheduler: pallet_scheduler, } ); diff --git a/runtime/tests/pallet_proxy.rs b/runtime/tests/pallet_proxy.rs index 796dfc471..192893c1e 100644 --- a/runtime/tests/pallet_proxy.rs +++ b/runtime/tests/pallet_proxy.rs @@ -4,7 +4,7 @@ use codec::Encode; use frame_support::{assert_ok, traits::InstanceFilter, BoundedVec}; use node_subtensor_runtime::{ AccountId, BalancesCall, BuildStorage, Proxy, ProxyType, Runtime, RuntimeCall, RuntimeEvent, - RuntimeGenesisConfig, RuntimeOrigin, SubtensorModule, System, SystemCall, + RuntimeGenesisConfig, RuntimeOrigin, SchedulerCall, SubtensorModule, System, SystemCall, }; const ACCOUNT: [u8; 32] = [1_u8; 32]; From d7ef0586047420de51651782678150a20bf5168a Mon Sep 17 00:00:00 2001 From: open-junius Date: Tue, 30 Jul 2024 18:57:04 +0800 Subject: [PATCH 027/177] fix compile error --- pallets/subtensor/src/lib.rs | 9 ++++++++- pallets/subtensor/src/macros/config.rs | 11 +---------- pallets/subtensor/src/macros/dispatches.rs | 19 ++++++++++--------- runtime/src/lib.rs | 18 +----------------- 4 files changed, 20 insertions(+), 37 deletions(-) diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index 3f9004167..f5febb0aa 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -65,7 +65,7 @@ pub mod pallet { use frame_support::{ dispatch::GetDispatchInfo, pallet_prelude::{DispatchResult, StorageMap, ValueQuery, *}, - traits::{tokens::fungible, UnfilteredDispatchable}, + traits::{tokens::fungible, OriginTrait, UnfilteredDispatchable}, }; use frame_system::pallet_prelude::*; use sp_core::H256; @@ -78,6 +78,13 @@ pub mod pallet { #[cfg(feature = "std")] use sp_std::prelude::Box; + /// Origin for the pallet + pub type PalletsOriginOf = + <::RuntimeOrigin as OriginTrait>::PalletsOrigin; + + /// Call type for the pallet + pub type CallOf = ::RuntimeCall; + /// Tracks version for migrations. Should be monotonic with respect to the /// order of migrations. (i.e. always increasing) const STORAGE_VERSION: StorageVersion = StorageVersion::new(7); diff --git a/pallets/subtensor/src/macros/config.rs b/pallets/subtensor/src/macros/config.rs index fb1ad5415..d2504eb4e 100644 --- a/pallets/subtensor/src/macros/config.rs +++ b/pallets/subtensor/src/macros/config.rs @@ -31,16 +31,7 @@ mod config { type TriumvirateInterface: crate::CollectiveInterface; /// The scheduler type used for scheduling delayed calls. - type Scheduler: ScheduleNamed, Call, Self::RuntimeOrigin>; - - /// The hashing system (algorithm) being used in the runtime, matching the Scheduler's Hasher. - type Hasher: Hash< - Output = <, - Call, - Self::RuntimeOrigin, - >>::Hasher as Hash>::Output, - >; + type Scheduler: ScheduleNamed, CallOf, PalletsOriginOf>; /// ================================= /// ==== Initial Value Constants ==== diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index a84c5964d..43eeb4105 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -972,17 +972,18 @@ mod dispatches { ) .using_encoded(sp_io::hashing::blake2_256); - let hash = T::Hasher::hash(&call.encode()); + let hash = sp_runtime::traits::BlakeTwo256::hash_of(&call); + let len = call.using_encoded(|e| e.len() as u32); - T::Scheduler::schedule_named( - unique_id, - DispatchTime::At(when), - None, - 63, - frame_system::RawOrigin::Root.into(), - Bounded::Lookup { hash, len }, - )?; + // T::Scheduler::schedule_named( + // unique_id, + // DispatchTime::At(when), + // None, + // 63, + // frame_system::RawOrigin::Root.into(), + // Bounded::Lookup { hash, len }, + // )?; Ok(().into()) } diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 1d2236dc3..289e9effe 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_support::traits::schedule::v3::Named as ScheduleNamed; use frame_support::{ dispatch::DispatchResultWithPostInfo, genesis_builder_helper::{build_config, create_default_config}, @@ -840,19 +839,6 @@ impl pallet_commitments::Config for Runtime { type RateLimit = CommitmentRateLimit; } -impl pallet_scheduler::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type RuntimeOrigin = RuntimeOrigin; - type PalletsOrigin = OriginCaller; - type RuntimeCall = RuntimeCall; - type MaximumWeight = MaximumSchedulerWeight; - type ScheduleOrigin = EnsureRoot; - type MaxScheduledPerBlock = ConstU32<50>; - type WeightInfo = pallet_scheduler::weights::SubstrateWeight; - type OriginPrivilegeCmp = EqualPrivilegeOnly; - type Preimages = Preimage; -} - // Configure the pallet subtensor. parameter_types! { pub const SubtensorInitialRho: u16 = 10; @@ -912,9 +898,7 @@ impl pallet_subtensor::Config for Runtime { type CouncilOrigin = EnsureMajoritySenate; type SenateMembers = ManageSenateMembers; type TriumvirateInterface = TriumvirateVotes; - type Scheduler = pallet_scheduler::Pallet; - type Hasher = BlakeTwo256; - + type Scheduler = Scheduler; type InitialRho = SubtensorInitialRho; type InitialKappa = SubtensorInitialKappa; type InitialMaxAllowedUids = SubtensorInitialMaxAllowedUids; From 2260fa0340dbb6f15991068314f79503e6db6446 Mon Sep 17 00:00:00 2001 From: open-junius Date: Tue, 30 Jul 2024 20:15:19 +0800 Subject: [PATCH 028/177] fix error --- pallets/subtensor/src/macros/dispatches.rs | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 43eeb4105..f5599adae 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -972,18 +972,22 @@ mod dispatches { ) .using_encoded(sp_io::hashing::blake2_256); - let hash = sp_runtime::traits::BlakeTwo256::hash_of(&call); + let hash = , + CallOf, + PalletsOriginOf, + >>::Hasher::hash_of(&call); let len = call.using_encoded(|e| e.len() as u32); - // T::Scheduler::schedule_named( - // unique_id, - // DispatchTime::At(when), - // None, - // 63, - // frame_system::RawOrigin::Root.into(), - // Bounded::Lookup { hash, len }, - // )?; + T::Scheduler::schedule_named( + unique_id, + DispatchTime::At(when), + None, + 63, + frame_system::RawOrigin::Root.into(), + Bounded::Lookup { hash, len }, + )?; Ok(().into()) } From ed345c5428ce858b18211179592079cf410538a9 Mon Sep 17 00:00:00 2001 From: open-junius Date: Tue, 30 Jul 2024 22:10:34 +0800 Subject: [PATCH 029/177] fix clippy --- pallets/collective/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pallets/collective/src/lib.rs b/pallets/collective/src/lib.rs index c6552b036..e3c64f1a7 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, From 3e6d1af7375cca6adc82241f5d838c398cd694b6 Mon Sep 17 00:00:00 2001 From: open-junius Date: Tue, 30 Jul 2024 22:19:07 +0800 Subject: [PATCH 030/177] fix clippy --- pallets/collective/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pallets/collective/src/lib.rs b/pallets/collective/src/lib.rs index e3c64f1a7..0ce5e3e08 100644 --- a/pallets/collective/src/lib.rs +++ b/pallets/collective/src/lib.rs @@ -951,8 +951,8 @@ impl, I: 'static> Pallet { /// /// If not `approved`: /// - one event deposited. - /// - Two removals, one mutation. - /// - Computation and i/o `O(P)` where: + /// - Two removals, one mutation. + /// - Computation and i/o `O(P)` where: /// - `P` is number of active proposals fn do_approve_proposal( seats: MemberCount, From 31d6fe3512048deb81edd8ac79a9f49f2653dee6 Mon Sep 17 00:00:00 2001 From: Keith Date: Tue, 30 Jul 2024 23:22:45 +0900 Subject: [PATCH 031/177] Fix syntax --- .github/workflows/check-finney.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/check-finney.yml b/.github/workflows/check-finney.yml index ac14dd601..3e9fb5994 100644 --- a/.github/workflows/check-finney.yml +++ b/.github/workflows/check-finney.yml @@ -11,7 +11,7 @@ jobs: check-spec-version: name: Check spec_version bump runs-on: SubtensorCI - if: ${{ !contains(github.event.issue.labels.*.name, 'no-spec-version-bump') }} + if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-spec-version-bump') }} steps: - name: Dependencies run: | From 8dda65de145547fd050b34a99fd58d3177cded80 Mon Sep 17 00:00:00 2001 From: open-junius Date: Tue, 30 Jul 2024 22:51:56 +0800 Subject: [PATCH 032/177] fix unit test --- pallets/admin-utils/Cargo.toml | 3 ++- pallets/admin-utils/tests/mock.rs | 40 +++++++++++++++++++++++++++---- pallets/subtensor/Cargo.toml | 2 ++ pallets/subtensor/tests/mock.rs | 34 ++++++++++++++++++++++++-- 4 files changed, 71 insertions(+), 8 deletions(-) diff --git a/pallets/admin-utils/Cargo.toml b/pallets/admin-utils/Cargo.toml index 859972fce..97371a79f 100644 --- a/pallets/admin-utils/Cargo.toml +++ b/pallets/admin-utils/Cargo.toml @@ -37,7 +37,8 @@ sp-io = { workspace = true } sp-tracing = { workspace = true } sp-consensus-aura = { workspace = true } pallet-balances = { workspace = true, features = ["std"] } - +pallet-scheduler = { workspace = true } +sp-std = { workspace = true } [features] default = ["std"] diff --git a/pallets/admin-utils/tests/mock.rs b/pallets/admin-utils/tests/mock.rs index 7ae11b6fb..4b08c578b 100644 --- a/pallets/admin-utils/tests/mock.rs +++ b/pallets/admin-utils/tests/mock.rs @@ -2,19 +2,20 @@ use frame_support::{ assert_ok, derive_impl, parameter_types, - traits::{Everything, Hooks}, + traits::{Everything, Hooks, PrivilegeCmp}, weights, }; use frame_system as system; -use frame_system::{limits, EnsureNever}; +use frame_system::{limits, EnsureNever, EnsureRoot}; use sp_consensus_aura::sr25519::AuthorityId as AuraId; use sp_core::U256; use sp_core::{ConstU64, H256}; use sp_runtime::{ traits::{BlakeTwo256, ConstU32, IdentityLookup}, - BuildStorage, DispatchError, + BuildStorage, DispatchError, Perbill, }; - +use sp_std::cmp::Ordering; +use sp_weights::Weight; type Block = frame_system::mocking::MockBlock; // Configure a mock runtime to test the pallet. @@ -25,6 +26,7 @@ frame_support::construct_runtime!( Balances: pallet_balances, AdminUtils: pallet_admin_utils, SubtensorModule: pallet_subtensor::{Pallet, Call, Storage, Event, Error}, + Scheduler: pallet_scheduler, } ); @@ -126,7 +128,7 @@ impl pallet_subtensor::Config for Test { type CouncilOrigin = EnsureNever; type SenateMembers = (); type TriumvirateInterface = (); - + type Scheduler = Scheduler; type InitialMinAllowedWeights = InitialMinAllowedWeights; type InitialEmissionValue = InitialEmissionValue; type InitialMaxWeightsLimit = InitialMaxWeightsLimit; @@ -218,6 +220,34 @@ impl pallet_balances::Config for Test { type RuntimeHoldReason = (); } +pub struct OriginPrivilegeCmp; + +impl PrivilegeCmp for OriginPrivilegeCmp { + fn cmp_privilege(_left: &OriginCaller, _right: &OriginCaller) -> Option { + None + } +} + +parameter_types! { + pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) * + BlockWeights::get().max_block; + pub const MaxScheduledPerBlock: u32 = 50; + pub const NoPreimagePostponement: Option = Some(10); +} + +impl pallet_scheduler::Config for Test { + type RuntimeOrigin = RuntimeOrigin; + type RuntimeEvent = RuntimeEvent; + type PalletsOrigin = OriginCaller; + type RuntimeCall = RuntimeCall; + type MaximumWeight = MaximumSchedulerWeight; + type ScheduleOrigin = EnsureRoot; + type MaxScheduledPerBlock = MaxScheduledPerBlock; + type WeightInfo = pallet_scheduler::weights::SubstrateWeight; + type OriginPrivilegeCmp = OriginPrivilegeCmp; + type Preimages = (); +} + pub struct SubtensorIntrf; impl pallet_admin_utils::SubtensorInterface for SubtensorIntrf { diff --git a/pallets/subtensor/Cargo.toml b/pallets/subtensor/Cargo.toml index a0835008f..b002c2371 100644 --- a/pallets/subtensor/Cargo.toml +++ b/pallets/subtensor/Cargo.toml @@ -48,12 +48,14 @@ num-traits = { version = "0.2.19", default-features = false, features = ["libm"] [dev-dependencies] pallet-balances = { workspace = true, features = ["std"] } +pallet-scheduler = { workspace = true } sp-version = { workspace = true } # Substrate sp-tracing = { workspace = true } parity-util-mem = { workspace = true, features = ["primitive-types"] } rand = { workspace = true } sp-core = { workspace = true } +sp-std = { workspace = true } [features] default = ["std"] diff --git a/pallets/subtensor/tests/mock.rs b/pallets/subtensor/tests/mock.rs index 27d11eb13..6f75fcb1a 100644 --- a/pallets/subtensor/tests/mock.rs +++ b/pallets/subtensor/tests/mock.rs @@ -6,7 +6,7 @@ use frame_support::weights::constants::RocksDbWeight; use frame_support::weights::Weight; use frame_support::{ assert_ok, parameter_types, - traits::{Everything, Hooks}, + traits::{Everything, Hooks, PrivilegeCmp}, }; use frame_system as system; use frame_system::{limits, EnsureNever, EnsureRoot, RawOrigin}; @@ -17,6 +17,7 @@ use sp_runtime::{ traits::{BlakeTwo256, IdentityLookup}, BuildStorage, }; +use sp_std::cmp::Ordering; type Block = frame_system::mocking::MockBlock; @@ -32,6 +33,7 @@ frame_support::construct_runtime!( SenateMembers: pallet_membership::::{Pallet, Call, Storage, Event, Config}, SubtensorModule: pallet_subtensor::{Pallet, Call, Storage, Event}, Utility: pallet_utility::{Pallet, Call, Storage, Event}, + Scheduler: pallet_scheduler::{Pallet, Call, Storage, Event}, } ); @@ -336,7 +338,7 @@ impl pallet_subtensor::Config for Test { type CouncilOrigin = frame_system::EnsureSigned; type SenateMembers = ManageSenateMembers; type TriumvirateInterface = TriumvirateVotes; - + type Scheduler = Scheduler; type InitialMinAllowedWeights = InitialMinAllowedWeights; type InitialEmissionValue = InitialEmissionValue; type InitialMaxWeightsLimit = InitialMaxWeightsLimit; @@ -385,6 +387,34 @@ impl pallet_subtensor::Config for Test { type InitialNetworkMaxStake = InitialNetworkMaxStake; } +pub struct OriginPrivilegeCmp; + +impl PrivilegeCmp for OriginPrivilegeCmp { + fn cmp_privilege(_left: &OriginCaller, _right: &OriginCaller) -> Option { + None + } +} + +parameter_types! { + pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) * + BlockWeights::get().max_block; + pub const MaxScheduledPerBlock: u32 = 50; + pub const NoPreimagePostponement: Option = Some(10); +} + +impl pallet_scheduler::Config for Test { + type RuntimeOrigin = RuntimeOrigin; + type RuntimeEvent = RuntimeEvent; + type PalletsOrigin = OriginCaller; + type RuntimeCall = RuntimeCall; + type MaximumWeight = MaximumSchedulerWeight; + type ScheduleOrigin = EnsureRoot; + type MaxScheduledPerBlock = MaxScheduledPerBlock; + type WeightInfo = pallet_scheduler::weights::SubstrateWeight; + type OriginPrivilegeCmp = OriginPrivilegeCmp; + type Preimages = (); +} + impl pallet_utility::Config for Test { type RuntimeEvent = RuntimeEvent; type RuntimeCall = RuntimeCall; From 8ce0d690b37fdd0635267fe1f6f78fe5d3e1078f Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Tue, 30 Jul 2024 19:20:21 +0400 Subject: [PATCH 033/177] feat: child key takes --- pallets/admin-utils/tests/mock.rs | 13 +- pallets/admin-utils/tests/tests.rs | 6 +- .../subtensor/src/coinbase/run_coinbase.rs | 2 +- pallets/subtensor/src/lib.rs | 55 ++++-- pallets/subtensor/src/macros/config.rs | 13 +- pallets/subtensor/src/macros/dispatches.rs | 80 +++++++- pallets/subtensor/src/macros/errors.rs | 4 + pallets/subtensor/src/macros/events.rs | 8 + .../subtensor/src/staking/become_delegate.rs | 6 +- .../subtensor/src/staking/decrease_take.rs | 4 +- pallets/subtensor/src/staking/helpers.rs | 7 + .../subtensor/src/staking/increase_take.rs | 4 +- pallets/subtensor/src/staking/set_children.rs | 98 ++++++++++ pallets/subtensor/src/utils.rs | 70 +++++-- pallets/subtensor/tests/children.rs | 183 +++++++++++++++++- pallets/subtensor/tests/mock.rs | 13 +- pallets/subtensor/tests/staking.rs | 70 +++---- runtime/src/lib.rs | 12 +- scripts/test_specific.sh | 2 +- 19 files changed, 558 insertions(+), 92 deletions(-) diff --git a/pallets/admin-utils/tests/mock.rs b/pallets/admin-utils/tests/mock.rs index 7ae11b6fb..0142a435a 100644 --- a/pallets/admin-utils/tests/mock.rs +++ b/pallets/admin-utils/tests/mock.rs @@ -77,12 +77,16 @@ parameter_types! { pub const InitialBondsMovingAverage: u64 = 900_000; pub const InitialStakePruningMin: u16 = 0; pub const InitialFoundationDistribution: u64 = 0; - pub const InitialDefaultTake: u16 = 11_796; // 18% honest number. + pub const InitialDefaultDelegateTake: u16 = 11_796; // 18% honest number. + pub const InitialMinDelegateTake: u16 = 5_898; // 9%; + pub const InitialDefaultChildKeyTake: u16 = 11_796; // 18% honest number. + pub const InitialMinChildKeyTake: u16 = 5_898; // 9%; pub const InitialMinTake: u16 = 5_898; // 9%; pub const InitialWeightsVersionKey: u16 = 0; pub const InitialServingRateLimit: u64 = 0; // No limit. pub const InitialTxRateLimit: u64 = 0; // Disable rate limit for testing pub const InitialTxDelegateTakeRateLimit: u64 = 0; // Disable rate limit for testing + pub const InitialTxChildKeyTakeRateLimit: u64 = 0; // Disable rate limit for testing pub const InitialBurn: u64 = 0; pub const InitialMinBurn: u64 = 0; pub const InitialMaxBurn: u64 = 1_000_000_000; @@ -146,14 +150,17 @@ impl pallet_subtensor::Config for Test { type InitialPruningScore = InitialPruningScore; type InitialBondsMovingAverage = InitialBondsMovingAverage; type InitialMaxAllowedValidators = InitialMaxAllowedValidators; - type InitialDefaultTake = InitialDefaultTake; - type InitialMinTake = InitialMinTake; + type InitialDefaultDelegateTake = InitialDefaultDelegateTake; + type InitialMinDelegateTake = InitialMinDelegateTake; + type InitialDefaultChildKeyTake = InitialDefaultChildKeyTake; + type InitialMinChildKeyTake = InitialMinChildKeyTake; type InitialWeightsVersionKey = InitialWeightsVersionKey; type InitialMaxDifficulty = InitialMaxDifficulty; type InitialMinDifficulty = InitialMinDifficulty; type InitialServingRateLimit = InitialServingRateLimit; type InitialTxRateLimit = InitialTxRateLimit; type InitialTxDelegateTakeRateLimit = InitialTxDelegateTakeRateLimit; + type InitialTxChildKeyTakeRateLimit = InitialTxChildKeyTakeRateLimit; type InitialBurn = InitialBurn; type InitialMaxBurn = InitialMaxBurn; type InitialMinBurn = InitialMinBurn; diff --git a/pallets/admin-utils/tests/tests.rs b/pallets/admin-utils/tests/tests.rs index 6e78a1ed6..af3bf66d7 100644 --- a/pallets/admin-utils/tests/tests.rs +++ b/pallets/admin-utils/tests/tests.rs @@ -16,7 +16,7 @@ use mock::*; fn test_sudo_set_default_take() { new_test_ext().execute_with(|| { let to_be_set: u16 = 10; - let init_value: u16 = SubtensorModule::get_default_take(); + let init_value: u16 = SubtensorModule::get_default_delegate_take(); assert_eq!( AdminUtils::sudo_set_default_take( <::RuntimeOrigin>::signed(U256::from(0)), @@ -24,12 +24,12 @@ fn test_sudo_set_default_take() { ), Err(DispatchError::BadOrigin) ); - assert_eq!(SubtensorModule::get_default_take(), init_value); + assert_eq!(SubtensorModule::get_default_delegate_take(), init_value); assert_ok!(AdminUtils::sudo_set_default_take( <::RuntimeOrigin>::root(), to_be_set )); - assert_eq!(SubtensorModule::get_default_take(), to_be_set); + assert_eq!(SubtensorModule::get_default_delegate_take(), to_be_set); }); } diff --git a/pallets/subtensor/src/coinbase/run_coinbase.rs b/pallets/subtensor/src/coinbase/run_coinbase.rs index fcf76728f..442a9f085 100644 --- a/pallets/subtensor/src/coinbase/run_coinbase.rs +++ b/pallets/subtensor/src/coinbase/run_coinbase.rs @@ -186,7 +186,7 @@ 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)) + let take_proportion: I64F64 = I64F64::from_num(Self::get_childkey_take(hotkey, netuid)) .saturating_div(I64F64::from_num(u16::MAX)); let hotkey_take: u64 = take_proportion .saturating_mul(I64F64::from_num(validating_emission)) diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index abf6a8613..c58c6a0c6 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -143,15 +143,27 @@ pub mod pallet { 21_000_000_000_000_000 } #[pallet::type_value] - /// Default total stake. - pub fn DefaultDefaultTake() -> u16 { - T::InitialDefaultTake::get() + /// Default Delegate Take. + pub fn DefaultDelegateTake() -> u16 { + T::InitialDefaultDelegateTake::get() + } + + #[pallet::type_value] + /// Default childkey take. + pub fn DefaultChildKeyTake() -> u16 { + T::InitialDefaultChildKeyTake::get() } #[pallet::type_value] - /// Default minimum take. - pub fn DefaultMinTake() -> u16 { - T::InitialMinTake::get() + /// Default minimum delegate take. + pub fn DefaultMinDelegateTake() -> u16 { + T::InitialMinDelegateTake::get() } + #[pallet::type_value] + /// Default minimum childkey take. + pub fn DefaultMinChildKeyTake() -> u16 { + T::InitialMinChildKeyTake::get() + } + #[pallet::type_value] /// Default account take. pub fn DefaultAccountTake() -> u64 { @@ -516,6 +528,11 @@ pub mod pallet { T::InitialTxDelegateTakeRateLimit::get() } #[pallet::type_value] + /// Default value for chidlkey take rate limiting + pub fn DefaultTxChildKeyTakeRateLimit() -> u64 { + T::InitialTxChildKeyTakeRateLimit::get() + } + #[pallet::type_value] /// Default value for last extrinsic block. pub fn DefaultLastTxBlock() -> u64 { 0 @@ -567,10 +584,15 @@ pub mod pallet { 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 ( default_delegate_take ) + pub type MaxDelegateTake = StorageValue<_, u16, ValueQuery, DefaultDelegateTake>; + #[pallet::storage] // --- ITEM ( min_delegate_take ) + pub type MinDelegateTake = StorageValue<_, u16, ValueQuery, DefaultMinDelegateTake>; + #[pallet::storage] // --- ITEM ( default_childkey_take ) + pub type MaxChildkeyTake = StorageValue<_, u16, ValueQuery, DefaultChildKeyTake>; + #[pallet::storage] // --- ITEM ( min_childkey_take ) + pub type MinChildkeyTake = StorageValue<_, u16, ValueQuery, DefaultMinChildKeyTake>; + #[pallet::storage] // --- ITEM ( global_block_emission ) pub type BlockEmission = StorageValue<_, u64, ValueQuery, DefaultBlockEmission>; #[pallet::storage] // --- ITEM (target_stakes_per_interval) @@ -603,7 +625,12 @@ pub mod pallet { #[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>; + StorageMap<_, Blake2_128Concat, T::AccountId, u16, ValueQuery, DefaultDelegateTake>; + #[pallet::storage] + /// DMAP ( hot, netuid ) --> take | Returns the hotkey childkey take for a specific subnet + pub type ChildkeyTake = + StorageMap<_, Blake2_128Concat, (T::AccountId, u16), u16, ValueQuery>; + #[pallet::storage] /// DMAP ( hot, cold ) --> stake | Returns the stake under a coldkey prefixed by hotkey. pub type Stake = StorageDoubleMap< @@ -921,10 +948,14 @@ pub mod pallet { /// --- ITEM ( tx_rate_limit ) pub type TxRateLimit = StorageValue<_, u64, ValueQuery, DefaultTxRateLimit>; #[pallet::storage] - /// --- ITEM ( tx_rate_limit ) + /// --- ITEM ( tx_delegate_take_rate_limit ) pub type TxDelegateTakeRateLimit = StorageValue<_, u64, ValueQuery, DefaultTxDelegateTakeRateLimit>; #[pallet::storage] + /// --- ITEM ( tx_childkey_take_rate_limit ) + pub type TxChildkeyTakeRateLimit = + StorageValue<_, u64, ValueQuery, DefaultTxChildKeyTakeRateLimit>; + #[pallet::storage] /// --- MAP ( netuid ) --> Whether or not Liquid Alpha is enabled pub type LiquidAlphaOn = StorageMap<_, Blake2_128Concat, u16, bool, ValueQuery, DefaultLiquidAlpha>; diff --git a/pallets/subtensor/src/macros/config.rs b/pallets/subtensor/src/macros/config.rs index e59eac5ca..2a6d8db00 100644 --- a/pallets/subtensor/src/macros/config.rs +++ b/pallets/subtensor/src/macros/config.rs @@ -112,10 +112,16 @@ mod config { type InitialMaxAllowedValidators: Get; /// Initial default delegation take. #[pallet::constant] - type InitialDefaultTake: Get; + type InitialDefaultDelegateTake: Get; /// Initial minimum delegation take. #[pallet::constant] - type InitialMinTake: Get; + type InitialMinDelegateTake: Get; + /// Initial default childkey take. + #[pallet::constant] + type InitialDefaultChildKeyTake: Get; + /// Initial minimum childkey take. + #[pallet::constant] + type InitialMinChildKeyTake: Get; /// Initial weights version key. #[pallet::constant] type InitialWeightsVersionKey: Get; @@ -128,6 +134,9 @@ mod config { /// Initial delegate take transaction rate limit. #[pallet::constant] type InitialTxDelegateTakeRateLimit: Get; + /// Initial childkey take transaction rate limit. + #[pallet::constant] + type InitialTxChildKeyTakeRateLimit: Get; /// Initial percentage of total stake required to join senate. #[pallet::constant] type InitialSenateRequiredStakePercentage: Get; diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 293dc0238..7954e77c1 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -262,7 +262,7 @@ mod dispatches { .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()) + Self::do_become_delegate(origin, hotkey, Self::get_default_delegate_take()) } /// --- Allows delegates to decrease its take value. @@ -708,6 +708,84 @@ mod dispatches { Ok(()) } + /// Sets the childkey take for a given hotkey. + /// + /// This function allows a coldkey to set the childkey take for a given hotkey. + /// The childkey take determines the proportion of stake that the hotkey keeps for itself + /// when distributing stake to its children. + /// + /// # Arguments: + /// * `origin` (::RuntimeOrigin): + /// - The signature of the calling coldkey. Setting childkey take can only be done by the coldkey. + /// + /// * `hotkey` (T::AccountId): + /// - The hotkey for which the childkey take will be set. + /// + /// * `take` (u16): + /// - The new childkey take value. This is a percentage represented as a value between 0 and 10000, + /// where 10000 represents 100%. + /// + /// # Events: + /// * `ChildkeyTakeSet`: + /// - On successfully setting the childkey take for a hotkey. + /// + /// # Errors: + /// * `NonAssociatedColdKey`: + /// - The coldkey does not own the hotkey. + /// * `InvalidChildkeyTake`: + /// - The provided take value is invalid (greater than the maximum allowed take). + /// * `TxChildkeyTakeRateLimitExceeded`: + /// - The rate limit for changing childkey take has been exceeded. + /// + #[pallet::call_index(68)] + #[pallet::weight(( + Weight::from_parts(10_000_000, 0) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)), + DispatchClass::Normal, + Pays::Yes +))] + pub fn set_childkey_take( + origin: OriginFor, + hotkey: T::AccountId, + netuid: u16, + take: u16, + ) -> DispatchResult { + let coldkey = ensure_signed(origin)?; + + // Call the utility function to set the childkey take + Self::do_set_childkey_take(coldkey, hotkey, netuid, take) + } + + /// Sets the transaction rate limit for changing childkey take. + /// + /// This function can only be called by the root origin. + /// + /// # Arguments: + /// * `origin` - The origin of the call, must be root. + /// * `tx_rate_limit` - The new rate limit in blocks. + /// + /// # Errors: + /// * `BadOrigin` - If the origin is not root. + /// + // TODO: Benchmark this call + #[pallet::call_index(69)] + #[pallet::weight(( + Weight::from_parts(10_000_000, 0) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)), + DispatchClass::Operational, + Pays::No +))] + pub fn sudo_set_tx_childkey_take_rate_limit( + origin: OriginFor, + tx_rate_limit: u64, + ) -> DispatchResult { + ensure_root(origin)?; + Self::set_tx_childkey_take_rate_limit(tx_rate_limit); + Ok(()) + } + // ---- SUDO ONLY FUNCTIONS ------------------------------------------------------------ // ================================== diff --git a/pallets/subtensor/src/macros/errors.rs b/pallets/subtensor/src/macros/errors.rs index 156cbea56..4c5103fa2 100644 --- a/pallets/subtensor/src/macros/errors.rs +++ b/pallets/subtensor/src/macros/errors.rs @@ -168,5 +168,9 @@ mod errors { TooManyChildren, /// Default transaction rate limit exceeded. TxRateLimitExceeded, + /// Childkey take is invalid. + InvalidChildkeyTake, + /// Childkey take rate limit exceeded. + TxChildkeyTakeRateLimitExceeded, } } diff --git a/pallets/subtensor/src/macros/events.rs b/pallets/subtensor/src/macros/events.rs index b93b8296b..c9fbb0b44 100644 --- a/pallets/subtensor/src/macros/events.rs +++ b/pallets/subtensor/src/macros/events.rs @@ -83,6 +83,14 @@ mod events { TxRateLimitSet(u64), /// setting the delegate take transaction rate limit. TxDelegateTakeRateLimitSet(u64), + /// setting the childkey take transaction rate limit. + TxChildKeyTakeRateLimitSet(u64), + /// minimum childkey take set + MinChildKeyTakeSet(u16), + /// maximum childkey take set + MaxChildKeyTakeSet(u16), + /// childkey take set + ChildKeyTakeSet(T::AccountId, u16), /// a sudo call is done. Sudid(DispatchResult), /// registration is allowed/disallowed for a subnet. diff --git a/pallets/subtensor/src/staking/become_delegate.rs b/pallets/subtensor/src/staking/become_delegate.rs index 064f47c12..ccbdc44a2 100644 --- a/pallets/subtensor/src/staking/become_delegate.rs +++ b/pallets/subtensor/src/staking/become_delegate.rs @@ -58,9 +58,9 @@ impl Pallet { Error::::DelegateTxRateLimitExceeded ); - // --- 5.1 Ensure take is within the min ..= InitialDefaultTake (18%) range - let min_take = MinTake::::get(); - let max_take = MaxTake::::get(); + // --- 5.1 Ensure take is within the min ..= InitialDefaultDelegateTake (18%) range + let min_take = MinDelegateTake::::get(); + let max_take = MaxDelegateTake::::get(); ensure!(take >= min_take, Error::::DelegateTakeTooLow); ensure!(take <= max_take, Error::::DelegateTakeTooHigh); diff --git a/pallets/subtensor/src/staking/decrease_take.rs b/pallets/subtensor/src/staking/decrease_take.rs index 9e48bac91..6da669ca2 100644 --- a/pallets/subtensor/src/staking/decrease_take.rs +++ b/pallets/subtensor/src/staking/decrease_take.rs @@ -50,8 +50,8 @@ impl Pallet { ensure!(take < current_take, Error::::DelegateTakeTooLow); } - // --- 3.1 Ensure take is within the min ..= InitialDefaultTake (18%) range - let min_take = MinTake::::get(); + // --- 3.1 Ensure take is within the min ..= InitialDefaultDelegateTake (18%) range + let min_take = MinDelegateTake::::get(); ensure!(take >= min_take, Error::::DelegateTakeTooLow); // --- 4. Set the new take value. diff --git a/pallets/subtensor/src/staking/helpers.rs b/pallets/subtensor/src/staking/helpers.rs index 486577712..7445bd154 100644 --- a/pallets/subtensor/src/staking/helpers.rs +++ b/pallets/subtensor/src/staking/helpers.rs @@ -218,6 +218,13 @@ impl Pallet { hotkey: &T::AccountId, increment: u64, ) { + log::debug!( + "Increasing stake: coldkey: {:?}, hotkey: {:?}, amount: {}", + coldkey, + hotkey, + increment + ); + TotalColdkeyStake::::insert( coldkey, TotalColdkeyStake::::get(coldkey).saturating_add(increment), diff --git a/pallets/subtensor/src/staking/increase_take.rs b/pallets/subtensor/src/staking/increase_take.rs index aa6dd443c..bc72bda4e 100644 --- a/pallets/subtensor/src/staking/increase_take.rs +++ b/pallets/subtensor/src/staking/increase_take.rs @@ -53,8 +53,8 @@ impl Pallet { ensure!(take > current_take, Error::::DelegateTakeTooLow); } - // --- 4. Ensure take is within the min ..= InitialDefaultTake (18%) range - let max_take = MaxTake::::get(); + // --- 4. Ensure take is within the min ..= InitialDefaultDelegateTake (18%) range + let max_take = MaxDelegateTake::::get(); ensure!(take <= max_take, Error::::DelegateTakeTooHigh); // --- 5. Enforce the rate limit (independently on do_add_stake rate limits) diff --git a/pallets/subtensor/src/staking/set_children.rs b/pallets/subtensor/src/staking/set_children.rs index f413db23f..bfe5d1c1e 100644 --- a/pallets/subtensor/src/staking/set_children.rs +++ b/pallets/subtensor/src/staking/set_children.rs @@ -190,4 +190,102 @@ impl Pallet { pub fn get_parents(child: &T::AccountId, netuid: u16) -> Vec<(u64, T::AccountId)> { ParentKeys::::get(child, netuid) } + + /// Sets the childkey take for a given hotkey. + /// + /// This function allows a coldkey to set the childkey take for a given hotkey. + /// The childkey take determines the proportion of stake that the hotkey keeps for itself + /// when distributing stake to its children. + /// + /// # Arguments: + /// * `coldkey` (T::AccountId): + /// - The coldkey that owns the hotkey. + /// + /// * `hotkey` (T::AccountId): + /// - The hotkey for which the childkey take will be set. + /// + /// * `take` (u16): + /// - The new childkey take value. This is a percentage represented as a value between 0 and 10000, + /// where 10000 represents 100%. + /// + /// # Returns: + /// * `DispatchResult` - The result of the operation. + /// + /// # Errors: + /// * `NonAssociatedColdKey`: + /// - The coldkey does not own the hotkey. + /// * `InvalidChildkeyTake`: + /// - The provided take value is invalid (greater than the maximum allowed take). + /// * `TxChildkeyTakeRateLimitExceeded`: + /// - The rate limit for changing childkey take has been exceeded. + pub fn do_set_childkey_take( + coldkey: T::AccountId, + hotkey: T::AccountId, + netuid: u16, + take: u16, + ) -> DispatchResult { + // Ensure the coldkey owns the hotkey + ensure!( + Self::coldkey_owns_hotkey(&coldkey, &hotkey), + Error::::NonAssociatedColdKey + ); + + // Ensure the take value is valid + ensure!( + take <= Self::get_max_childkey_take(), + Error::::InvalidChildkeyTake + ); + + // Ensure the hotkey passes the rate limit + ensure!( + Self::passes_rate_limit_on_subnet(&TransactionType::SetChildkeyTake, &hotkey, netuid), + Error::::TxChildkeyTakeRateLimitExceeded + ); + + // Set the new childkey take value for the given hotkey and network + ChildkeyTake::::insert((hotkey.clone(), netuid), take); + + // TODO: Consider adding a check to ensure the hotkey is registered on the specified network (netuid) + // before setting the childkey take. This could prevent setting takes for non-existent or + // unregistered hotkeys. + + // NOTE: The childkey take is now associated with both the hotkey and the network ID. + // This allows for different take values across different networks for the same hotkey. + + // Update the last transaction block + let current_block: u64 = >::block_number() + .try_into() + .unwrap_or_else(|_| 0); + Self::set_last_transaction_block( + &hotkey, + netuid, + &TransactionType::SetChildkeyTake, + current_block, + ); + + // Emit the event + Self::deposit_event(Event::ChildKeyTakeSet(hotkey.clone(), take)); + log::debug!( + "Childkey take set for hotkey: {:?} and take: {:?}", + hotkey, + take + ); + Ok(()) + } + + /// Gets the childkey take for a given hotkey. + /// + /// This function retrieves the current childkey take value for a specified hotkey. + /// If no specific take value has been set, it returns the default childkey take. + /// + /// # Arguments: + /// * `hotkey` (&T::AccountId): + /// - The hotkey for which to retrieve the childkey take. + /// + /// # Returns: + /// * `u16` - The childkey take value. This is a percentage represented as a value between 0 and 10000, + /// where 10000 represents 100%. + pub fn get_childkey_take(hotkey: &T::AccountId, netuid: u16) -> u16 { + ChildkeyTake::::get((hotkey, netuid)) + } } diff --git a/pallets/subtensor/src/utils.rs b/pallets/subtensor/src/utils.rs index 2cd49e198..edbe02a36 100644 --- a/pallets/subtensor/src/utils.rs +++ b/pallets/subtensor/src/utils.rs @@ -11,6 +11,7 @@ use substrate_fixed::types::I32F32; #[derive(Copy, Clone)] pub enum TransactionType { SetChildren, + SetChildkeyTake, Unknown, } @@ -19,7 +20,8 @@ impl From for u16 { fn from(tx_type: TransactionType) -> Self { match tx_type { TransactionType::SetChildren => 0, - TransactionType::Unknown => 1, + TransactionType::SetChildkeyTake => 1, + TransactionType::Unknown => 2, } } } @@ -29,6 +31,7 @@ impl From for TransactionType { fn from(value: u16) -> Self { match value { 0 => TransactionType::SetChildren, + 1 => TransactionType::SetChildkeyTake, _ => TransactionType::Unknown, } } @@ -309,6 +312,7 @@ impl Pallet { 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::SetChildkeyTake => (TxChildkeyTakeRateLimit::::get()).into(), TransactionType::Unknown => 0, // Default to no limit for unknown types (no limit) } } @@ -319,10 +323,22 @@ impl Pallet { hotkey: &T::AccountId, netuid: u16, ) -> bool { - let block: u64 = Self::get_current_block_as_u64(); + let current_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 + + log::info!( + "Rate limit check: current_block: {}, last_block: {}, limit: {}", + current_block, + last_block, + limit + ); + + if last_block == 0 { + true + } else { + current_block.saturating_sub(last_block) > limit + } } /// Check if a transaction should be rate limited globally @@ -393,17 +409,6 @@ impl Pallet { pub fn coinbase(amount: u64) { TotalIssuance::::put(TotalIssuance::::get().saturating_add(amount)); } - pub fn get_default_take() -> u16 { - // Default to maximum - MaxTake::::get() - } - pub fn set_max_take(default_take: u16) { - MaxTake::::put(default_take); - Self::deposit_event(Event::DefaultTakeSet(default_take)); - } - pub fn get_min_take() -> u16 { - MinTake::::get() - } pub fn set_subnet_locked_balance(netuid: u16, amount: u64) { SubnetLocked::::insert(netuid, amount); @@ -425,6 +430,11 @@ impl Pallet { TxRateLimit::::put(tx_rate_limit); Self::deposit_event(Event::TxRateLimitSet(tx_rate_limit)); } + + pub fn get_default_delegate_take() -> u16 { + // Default to maximum + MaxDelegateTake::::get() + } pub fn get_tx_delegate_take_rate_limit() -> u64 { TxDelegateTakeRateLimit::::get() } @@ -433,18 +443,42 @@ impl Pallet { Self::deposit_event(Event::TxDelegateTakeRateLimitSet(tx_rate_limit)); } pub fn set_min_delegate_take(take: u16) { - MinTake::::put(take); + MinDelegateTake::::put(take); Self::deposit_event(Event::MinDelegateTakeSet(take)); } pub fn set_max_delegate_take(take: u16) { - MaxTake::::put(take); + MaxDelegateTake::::put(take); Self::deposit_event(Event::MaxDelegateTakeSet(take)); } pub fn get_min_delegate_take() -> u16 { - MinTake::::get() + MinDelegateTake::::get() } pub fn get_max_delegate_take() -> u16 { - MaxTake::::get() + MaxDelegateTake::::get() + } + pub fn set_tx_childkey_take_rate_limit(tx_rate_limit: u64) { + TxChildkeyTakeRateLimit::::put(tx_rate_limit); + Self::deposit_event(Event::TxChildKeyTakeRateLimitSet(tx_rate_limit)); + } + + pub fn set_min_childkey_take(take: u16) { + MinChildkeyTake::::put(take); + Self::deposit_event(Event::MinChildKeyTakeSet(take)); + } + pub fn set_max_childkey_take(take: u16) { + MaxChildkeyTake::::put(take); + Self::deposit_event(Event::MaxChildKeyTakeSet(take)); + } + pub fn get_min_childkey_take() -> u16 { + MinChildkeyTake::::get() + } + pub fn get_max_childkey_take() -> u16 { + MaxChildkeyTake::::get() + } + + pub fn get_default_childkey_take() -> u16 { + // Default to maximum + MaxChildkeyTake::::get() } pub fn get_serving_rate_limit(netuid: u16) -> u64 { diff --git a/pallets/subtensor/tests/children.rs b/pallets/subtensor/tests/children.rs index e834baa85..c38005a53 100644 --- a/pallets/subtensor/tests/children.rs +++ b/pallets/subtensor/tests/children.rs @@ -1,7 +1,7 @@ use crate::mock::*; -use frame_support::{assert_err, assert_ok}; +use frame_support::{assert_err, assert_noop, assert_ok}; mod mock; -use pallet_subtensor::*; +use pallet_subtensor::{utils::TransactionType, *}; use sp_core::U256; // SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_set_child_singular_success --exact --nocapture @@ -791,7 +791,184 @@ fn test_do_set_children_multiple_overwrite_existing() { }); } -// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_set_children_multiple_empty_list --exact --nocapture +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_childkey_take_functionality --exact --nocapture +#[test] +fn test_childkey_take_functionality() { + 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); + + // Test default and max childkey take + let default_take = SubtensorModule::get_default_childkey_take(); + let max_take = SubtensorModule::get_max_childkey_take(); + log::info!("Default take: {}, Max take: {}", default_take, max_take); + + // Check if default take and max take are the same + assert_eq!( + default_take, max_take, + "Default take should be equal to max take" + ); + + // Log the actual value of MaxChildkeyTake + log::info!( + "MaxChildkeyTake value: {:?}", + MaxChildkeyTake::::get() + ); + + // Test setting childkey take + let new_take: u16 = max_take / 2; // 50% of max_take + assert_ok!(SubtensorModule::set_childkey_take( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + new_take + )); + + // Verify childkey take was set correctly + let stored_take = SubtensorModule::get_childkey_take(&hotkey, netuid); + log::info!("Stored take: {}", stored_take); + assert_eq!(stored_take, new_take); + + // Test setting childkey take outside of allowed range + let invalid_take: u16 = max_take + 1; + assert_noop!( + SubtensorModule::set_childkey_take( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + invalid_take + ), + Error::::InvalidChildkeyTake + ); + + // Test setting childkey take with non-associated coldkey + let non_associated_coldkey = U256::from(999); + assert_noop!( + SubtensorModule::set_childkey_take( + RuntimeOrigin::signed(non_associated_coldkey), + hotkey, + netuid, + new_take + ), + Error::::NonAssociatedColdKey + ); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_childkey_take_rate_limiting --exact --nocapture +#[test] +fn test_childkey_take_rate_limiting() { + 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 a rate limit for childkey take changes + let rate_limit: u64 = 100; + SubtensorModule::set_tx_childkey_take_rate_limit(rate_limit.into()); + + log::info!( + "TxChildkeyTakeRateLimit: {:?}", + TxChildkeyTakeRateLimit::::get() + ); + + // First transaction (should succeed) + assert_ok!(SubtensorModule::set_childkey_take( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + 500 + )); + + let current_block = SubtensorModule::get_current_block_as_u64(); + let last_block = SubtensorModule::get_last_transaction_block( + &hotkey, + netuid, + &TransactionType::SetChildkeyTake, + ); + log::info!( + "After first transaction: current_block: {}, last_block: {}", + current_block, + last_block + ); + + // Second transaction (should fail due to rate limit) + let result = + SubtensorModule::set_childkey_take(RuntimeOrigin::signed(coldkey), hotkey, netuid, 600); + log::info!("Second transaction result: {:?}", result); + let current_block = SubtensorModule::get_current_block_as_u64(); + let last_block = SubtensorModule::get_last_transaction_block( + &hotkey, + netuid, + &TransactionType::SetChildkeyTake, + ); + log::info!( + "After second transaction attempt: current_block: {}, last_block: {}", + current_block, + last_block + ); + + assert_noop!(result, Error::::TxChildkeyTakeRateLimitExceeded); + + // Advance the block number to just before the rate limit + run_to_block(rate_limit); + + // Third transaction (should still fail) + let result = + SubtensorModule::set_childkey_take(RuntimeOrigin::signed(coldkey), hotkey, netuid, 650); + log::info!("Third transaction result: {:?}", result); + let current_block = SubtensorModule::get_current_block_as_u64(); + let last_block = SubtensorModule::get_last_transaction_block( + &hotkey, + netuid, + &TransactionType::SetChildkeyTake, + ); + log::info!( + "After third transaction attempt: current_block: {}, last_block: {}", + current_block, + last_block + ); + + assert_noop!(result, Error::::TxChildkeyTakeRateLimitExceeded); + + // Advance the block number to just after the rate limit + run_to_block(rate_limit * 2); + + // Fourth transaction (should succeed) + assert_ok!(SubtensorModule::set_childkey_take( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + 700 + )); + + let current_block = SubtensorModule::get_current_block_as_u64(); + let last_block = SubtensorModule::get_last_transaction_block( + &hotkey, + netuid, + &TransactionType::SetChildkeyTake, + ); + log::info!( + "After fourth transaction: current_block: {}, last_block: {}", + current_block, + last_block + ); + + // Verify the final take was set + let stored_take = SubtensorModule::get_childkey_take(&hotkey, netuid); + assert_eq!(stored_take, 700); + }); +} + #[test] fn test_do_set_children_multiple_empty_list() { new_test_ext(1).execute_with(|| { diff --git a/pallets/subtensor/tests/mock.rs b/pallets/subtensor/tests/mock.rs index d8d677006..4de74f4ab 100644 --- a/pallets/subtensor/tests/mock.rs +++ b/pallets/subtensor/tests/mock.rs @@ -131,12 +131,16 @@ parameter_types! { pub const InitialBondsMovingAverage: u64 = 900_000; pub const InitialStakePruningMin: u16 = 0; pub const InitialFoundationDistribution: u64 = 0; - pub const InitialDefaultTake: u16 = 11_796; // 18%, same as in production + pub const InitialDefaultDelegateTake: u16 = 11_796; // 18%, same as in production + pub const InitialMinDelegateTake: u16 = 5_898; // 9%; + pub const InitialDefaultChildKeyTake: u16 = 11_796; // 18%, same as in production + pub const InitialMinChildKeyTake: u16 = 5_898; // 9%; pub const InitialMinTake: u16 =5_898; // 9%; pub const InitialWeightsVersionKey: u16 = 0; pub const InitialServingRateLimit: u64 = 0; // No limit. pub const InitialTxRateLimit: u64 = 0; // Disable rate limit for testing pub const InitialTxDelegateTakeRateLimit: u64 = 1; // 1 block take rate limit for testing + pub const InitialTxChildKeyTakeRateLimit: u64 = 1; // 1 block take rate limit for testing pub const InitialBurn: u64 = 0; pub const InitialMinBurn: u64 = 0; pub const InitialMaxBurn: u64 = 1_000_000_000; @@ -360,8 +364,11 @@ impl pallet_subtensor::Config for Test { type InitialPruningScore = InitialPruningScore; type InitialBondsMovingAverage = InitialBondsMovingAverage; type InitialMaxAllowedValidators = InitialMaxAllowedValidators; - type InitialDefaultTake = InitialDefaultTake; - type InitialMinTake = InitialMinTake; + type InitialDefaultDelegateTake = InitialDefaultDelegateTake; + type InitialMinDelegateTake = InitialMinDelegateTake; + type InitialDefaultChildKeyTake = InitialDefaultChildKeyTake; + type InitialMinChildKeyTake = InitialMinChildKeyTake; + type InitialTxChildKeyTakeRateLimit = InitialTxChildKeyTakeRateLimit; type InitialWeightsVersionKey = InitialWeightsVersionKey; type InitialMaxDifficulty = InitialMaxDifficulty; type InitialMinDifficulty = InitialMinDifficulty; diff --git a/pallets/subtensor/tests/staking.rs b/pallets/subtensor/tests/staking.rs index 5bf95841a..f053c7ca6 100644 --- a/pallets/subtensor/tests/staking.rs +++ b/pallets/subtensor/tests/staking.rs @@ -1395,7 +1395,7 @@ fn test_clear_small_nominations() { assert_ok!(SubtensorModule::do_become_delegate( <::RuntimeOrigin>::signed(cold1), hot1, - SubtensorModule::get_min_take() + SubtensorModule::get_min_delegate_take() )); assert_eq!(SubtensorModule::get_owning_coldkey_for_hotkey(&hot1), cold1); @@ -1404,7 +1404,7 @@ fn test_clear_small_nominations() { assert_ok!(SubtensorModule::do_become_delegate( <::RuntimeOrigin>::signed(cold2), hot2, - SubtensorModule::get_min_take() + SubtensorModule::get_min_delegate_take() )); assert_eq!(SubtensorModule::get_owning_coldkey_for_hotkey(&hot2), cold2); @@ -1697,11 +1697,11 @@ fn test_delegate_take_can_be_decreased() { assert_ok!(SubtensorModule::do_become_delegate( <::RuntimeOrigin>::signed(coldkey0), hotkey0, - SubtensorModule::get_min_take() + SubtensorModule::get_min_delegate_take() )); assert_eq!( SubtensorModule::get_hotkey_take(&hotkey0), - SubtensorModule::get_min_take() + SubtensorModule::get_min_delegate_take() ); // Coldkey / hotkey 0 decreases take to 5%. This should fail as the minimum take is 9% @@ -1743,11 +1743,11 @@ fn test_can_set_min_take_ok() { assert_ok!(SubtensorModule::do_decrease_take( <::RuntimeOrigin>::signed(coldkey0), hotkey0, - SubtensorModule::get_min_take() + SubtensorModule::get_min_delegate_take() )); assert_eq!( SubtensorModule::get_hotkey_take(&hotkey0), - SubtensorModule::get_min_take() + SubtensorModule::get_min_delegate_take() ); }); } @@ -1772,11 +1772,11 @@ fn test_delegate_take_can_not_be_increased_with_decrease_take() { assert_ok!(SubtensorModule::do_become_delegate( <::RuntimeOrigin>::signed(coldkey0), hotkey0, - SubtensorModule::get_min_take() + SubtensorModule::get_min_delegate_take() )); assert_eq!( SubtensorModule::get_hotkey_take(&hotkey0), - SubtensorModule::get_min_take() + SubtensorModule::get_min_delegate_take() ); // Coldkey / hotkey 0 tries to increase take to 12.5% @@ -1790,7 +1790,7 @@ fn test_delegate_take_can_not_be_increased_with_decrease_take() { ); assert_eq!( SubtensorModule::get_hotkey_take(&hotkey0), - SubtensorModule::get_min_take() + SubtensorModule::get_min_delegate_take() ); }); } @@ -1815,11 +1815,11 @@ fn test_delegate_take_can_be_increased() { assert_ok!(SubtensorModule::do_become_delegate( <::RuntimeOrigin>::signed(coldkey0), hotkey0, - SubtensorModule::get_min_take() + SubtensorModule::get_min_delegate_take() )); assert_eq!( SubtensorModule::get_hotkey_take(&hotkey0), - SubtensorModule::get_min_take() + SubtensorModule::get_min_delegate_take() ); step_block(1 + InitialTxDelegateTakeRateLimit::get() as u16); @@ -1854,11 +1854,11 @@ fn test_delegate_take_can_not_be_decreased_with_increase_take() { assert_ok!(SubtensorModule::do_become_delegate( <::RuntimeOrigin>::signed(coldkey0), hotkey0, - SubtensorModule::get_min_take() + SubtensorModule::get_min_delegate_take() )); assert_eq!( SubtensorModule::get_hotkey_take(&hotkey0), - SubtensorModule::get_min_take() + SubtensorModule::get_min_delegate_take() ); // Coldkey / hotkey 0 tries to decrease take to 5% @@ -1872,12 +1872,12 @@ fn test_delegate_take_can_not_be_decreased_with_increase_take() { ); assert_eq!( SubtensorModule::get_hotkey_take(&hotkey0), - SubtensorModule::get_min_take() + SubtensorModule::get_min_delegate_take() ); }); } -// Verify delegate take can be increased up to InitialDefaultTake (18%) +// Verify delegate take can be increased up to InitialDefaultDelegateTake (18%) #[test] fn test_delegate_take_can_be_increased_to_limit() { new_test_ext(1).execute_with(|| { @@ -1897,29 +1897,29 @@ fn test_delegate_take_can_be_increased_to_limit() { assert_ok!(SubtensorModule::do_become_delegate( <::RuntimeOrigin>::signed(coldkey0), hotkey0, - SubtensorModule::get_min_take() + SubtensorModule::get_min_delegate_take() )); assert_eq!( SubtensorModule::get_hotkey_take(&hotkey0), - SubtensorModule::get_min_take() + SubtensorModule::get_min_delegate_take() ); step_block(1 + InitialTxDelegateTakeRateLimit::get() as u16); - // Coldkey / hotkey 0 tries to increase take to InitialDefaultTake+1 + // Coldkey / hotkey 0 tries to increase take to InitialDefaultDelegateTake+1 assert_ok!(SubtensorModule::do_increase_take( <::RuntimeOrigin>::signed(coldkey0), hotkey0, - InitialDefaultTake::get() + InitialDefaultDelegateTake::get() )); assert_eq!( SubtensorModule::get_hotkey_take(&hotkey0), - InitialDefaultTake::get() + InitialDefaultDelegateTake::get() ); }); } -// Verify delegate take can not be set above InitialDefaultTake +// Verify delegate take can not be set above InitialDefaultDelegateTake #[test] fn test_delegate_take_can_not_be_set_beyond_limit() { new_test_ext(1).execute_with(|| { @@ -1937,13 +1937,13 @@ fn test_delegate_take_can_not_be_set_beyond_limit() { let before = SubtensorModule::get_hotkey_take(&hotkey0); // Coldkey / hotkey 0 attempt to become delegates with take above maximum - // (Disable this check if InitialDefaultTake is u16::MAX) - if InitialDefaultTake::get() != u16::MAX { + // (Disable this check if InitialDefaultDelegateTake is u16::MAX) + if InitialDefaultDelegateTake::get() != u16::MAX { assert_eq!( SubtensorModule::do_become_delegate( <::RuntimeOrigin>::signed(coldkey0), hotkey0, - InitialDefaultTake::get() + 1 + InitialDefaultDelegateTake::get() + 1 ), Err(Error::::DelegateTakeTooHigh.into()) ); @@ -1952,7 +1952,7 @@ fn test_delegate_take_can_not_be_set_beyond_limit() { }); } -// Verify delegate take can not be increased above InitialDefaultTake (18%) +// Verify delegate take can not be increased above InitialDefaultDelegateTake (18%) #[test] fn test_delegate_take_can_not_be_increased_beyond_limit() { new_test_ext(1).execute_with(|| { @@ -1972,28 +1972,28 @@ fn test_delegate_take_can_not_be_increased_beyond_limit() { assert_ok!(SubtensorModule::do_become_delegate( <::RuntimeOrigin>::signed(coldkey0), hotkey0, - SubtensorModule::get_min_take() + SubtensorModule::get_min_delegate_take() )); assert_eq!( SubtensorModule::get_hotkey_take(&hotkey0), - SubtensorModule::get_min_take() + SubtensorModule::get_min_delegate_take() ); - // Coldkey / hotkey 0 tries to increase take to InitialDefaultTake+1 - // (Disable this check if InitialDefaultTake is u16::MAX) - if InitialDefaultTake::get() != u16::MAX { + // Coldkey / hotkey 0 tries to increase take to InitialDefaultDelegateTake+1 + // (Disable this check if InitialDefaultDelegateTake is u16::MAX) + if InitialDefaultDelegateTake::get() != u16::MAX { assert_eq!( SubtensorModule::do_increase_take( <::RuntimeOrigin>::signed(coldkey0), hotkey0, - InitialDefaultTake::get() + 1 + InitialDefaultDelegateTake::get() + 1 ), Err(Error::::DelegateTakeTooHigh.into()) ); } assert_eq!( SubtensorModule::get_hotkey_take(&hotkey0), - SubtensorModule::get_min_take() + SubtensorModule::get_min_delegate_take() ); }); } @@ -2018,11 +2018,11 @@ fn test_rate_limits_enforced_on_increase_take() { assert_ok!(SubtensorModule::do_become_delegate( <::RuntimeOrigin>::signed(coldkey0), hotkey0, - SubtensorModule::get_min_take() + SubtensorModule::get_min_delegate_take() )); assert_eq!( SubtensorModule::get_hotkey_take(&hotkey0), - SubtensorModule::get_min_take() + SubtensorModule::get_min_delegate_take() ); // Coldkey / hotkey 0 increases take to 12.5% @@ -2036,7 +2036,7 @@ fn test_rate_limits_enforced_on_increase_take() { ); assert_eq!( SubtensorModule::get_hotkey_take(&hotkey0), - SubtensorModule::get_min_take() + SubtensorModule::get_min_delegate_take() ); step_block(1 + InitialTxDelegateTakeRateLimit::get() as u16); diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 66951b7fc..1fecf7dbc 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -858,7 +858,9 @@ parameter_types! { pub const SubtensorInitialPruningScore : u16 = u16::MAX; pub const SubtensorInitialBondsMovingAverage: u64 = 900_000; pub const SubtensorInitialDefaultTake: u16 = 11_796; // 18% honest number. - pub const SubtensorInitialMinTake: u16 = 5_898; // 9% + pub const SubtensorInitialMinDelegateTake: u16 = 5_898; // 9% + pub const SubtensorInitialDefaultChildKeyTake: u16 = 11_796; // 18% honest number. + pub const SubtensorInitialMinChildKeyTake: u16 = 5_898; // 9% pub const SubtensorInitialWeightsVersionKey: u64 = 0; pub const SubtensorInitialMinDifficulty: u64 = 10_000_000; pub const SubtensorInitialMaxDifficulty: u64 = u64::MAX / 4; @@ -868,6 +870,7 @@ parameter_types! { pub const SubtensorInitialMaxBurn: u64 = 100_000_000_000; // 100 tao pub const SubtensorInitialTxRateLimit: u64 = 1000; pub const SubtensorInitialTxDelegateTakeRateLimit: u64 = 216000; // 30 days at 12 seconds per block + pub const SubtensorInitialTxChildKeyTakeRateLimit: u64 = 216000; // 30 days at 12 seconds per block pub const SubtensorInitialRAORecycledForRegistration: u64 = 0; // 0 rao pub const SubtensorInitialSenateRequiredStakePercentage: u64 = 1; // 1 percent of total stake pub const SubtensorInitialNetworkImmunity: u64 = 7 * 7200; @@ -914,8 +917,10 @@ impl pallet_subtensor::Config for Runtime { type InitialMaxRegistrationsPerBlock = SubtensorInitialMaxRegistrationsPerBlock; type InitialPruningScore = SubtensorInitialPruningScore; type InitialMaxAllowedValidators = SubtensorInitialMaxAllowedValidators; - type InitialDefaultTake = SubtensorInitialDefaultTake; - type InitialMinTake = SubtensorInitialMinTake; + type InitialDefaultDelegateTake = SubtensorInitialDefaultTake; + type InitialDefaultChildKeyTake = SubtensorInitialDefaultChildKeyTake; + type InitialMinDelegateTake = SubtensorInitialMinDelegateTake; + type InitialMinChildKeyTake = SubtensorInitialMinChildKeyTake; type InitialWeightsVersionKey = SubtensorInitialWeightsVersionKey; type InitialMaxDifficulty = SubtensorInitialMaxDifficulty; type InitialMinDifficulty = SubtensorInitialMinDifficulty; @@ -925,6 +930,7 @@ impl pallet_subtensor::Config for Runtime { type InitialMinBurn = SubtensorInitialMinBurn; type InitialTxRateLimit = SubtensorInitialTxRateLimit; type InitialTxDelegateTakeRateLimit = SubtensorInitialTxDelegateTakeRateLimit; + type InitialTxChildKeyTakeRateLimit = SubtensorInitialTxChildKeyTakeRateLimit; type InitialRAORecycledForRegistration = SubtensorInitialRAORecycledForRegistration; type InitialSenateRequiredStakePercentage = SubtensorInitialSenateRequiredStakePercentage; type InitialNetworkImmunityPeriod = SubtensorInitialNetworkImmunity; diff --git a/scripts/test_specific.sh b/scripts/test_specific.sh index 018872d33..c5b940f0f 100755 --- a/scripts/test_specific.sh +++ b/scripts/test_specific.sh @@ -3,4 +3,4 @@ features="${4:-pow-faucet}" # RUST_LOG="pallet_subtensor=info" cargo test --release --features=$features -p $pallet --test $1 -- $2 --nocapture --exact -RUST_LOG=INFO cargo test --release --features=$features -p $pallet --test $1 -- $2 --nocapture --exact \ No newline at end of file +RUST_LOG=DEBUG cargo test --release --features=$features -p $pallet --test $1 -- $2 --nocapture --exact \ No newline at end of file From 9917c03357f5632ca1e9ff9510a6ccdcf28772cb Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Tue, 30 Jul 2024 19:22:23 +0400 Subject: [PATCH 034/177] chore: lints --- pallets/subtensor/src/staking/set_children.rs | 2 +- pallets/subtensor/src/utils.rs | 2 +- pallets/subtensor/tests/children.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pallets/subtensor/src/staking/set_children.rs b/pallets/subtensor/src/staking/set_children.rs index bfe5d1c1e..c62d8f130 100644 --- a/pallets/subtensor/src/staking/set_children.rs +++ b/pallets/subtensor/src/staking/set_children.rs @@ -255,7 +255,7 @@ impl Pallet { // Update the last transaction block let current_block: u64 = >::block_number() .try_into() - .unwrap_or_else(|_| 0); + .unwrap_or(0); Self::set_last_transaction_block( &hotkey, netuid, diff --git a/pallets/subtensor/src/utils.rs b/pallets/subtensor/src/utils.rs index edbe02a36..7f70de0fe 100644 --- a/pallets/subtensor/src/utils.rs +++ b/pallets/subtensor/src/utils.rs @@ -312,7 +312,7 @@ impl Pallet { 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::SetChildkeyTake => (TxChildkeyTakeRateLimit::::get()).into(), + TransactionType::SetChildkeyTake => TxChildkeyTakeRateLimit::::get(), TransactionType::Unknown => 0, // Default to no limit for unknown types (no limit) } } diff --git a/pallets/subtensor/tests/children.rs b/pallets/subtensor/tests/children.rs index c38005a53..8dfeedc29 100644 --- a/pallets/subtensor/tests/children.rs +++ b/pallets/subtensor/tests/children.rs @@ -874,7 +874,7 @@ fn test_childkey_take_rate_limiting() { // Set a rate limit for childkey take changes let rate_limit: u64 = 100; - SubtensorModule::set_tx_childkey_take_rate_limit(rate_limit.into()); + SubtensorModule::set_tx_childkey_take_rate_limit(rate_limit); log::info!( "TxChildkeyTakeRateLimit: {:?}", From f212a59371ade5bdbd18d6870e98cdc1a063ca7a Mon Sep 17 00:00:00 2001 From: Keith Date: Wed, 31 Jul 2024 00:41:09 +0900 Subject: [PATCH 035/177] Fix clippy --- pallets/collective/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/pallets/collective/src/lib.rs b/pallets/collective/src/lib.rs index 96040f99c..66c55036d 100644 --- a/pallets/collective/src/lib.rs +++ b/pallets/collective/src/lib.rs @@ -951,6 +951,7 @@ 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 From b656a583b563bb55f24d6536f4377f27669c0159 Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Tue, 30 Jul 2024 20:16:02 +0400 Subject: [PATCH 036/177] feat: benchmarks --- pallets/subtensor/src/benchmarks.rs | 30 +++++++++++++++++++++- pallets/subtensor/src/macros/dispatches.rs | 13 +++++----- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/pallets/subtensor/src/benchmarks.rs b/pallets/subtensor/src/benchmarks.rs index 03e087a92..25176dab7 100644 --- a/pallets/subtensor/src/benchmarks.rs +++ b/pallets/subtensor/src/benchmarks.rs @@ -159,7 +159,7 @@ benchmarks! { Subtensor::::add_balance_to_coldkey_account(&coldkey.clone(), wallet_bal); assert_ok!(Subtensor::::do_burned_registration(RawOrigin::Signed(coldkey.clone()).into(), netuid, hotkey.clone())); - assert_ok!(Subtensor::::do_become_delegate(RawOrigin::Signed(coldkey.clone()).into(), hotkey.clone(), Subtensor::::get_default_take())); + assert_ok!(Subtensor::::do_become_delegate(RawOrigin::Signed(coldkey.clone()).into(), hotkey.clone(), Subtensor::::get_default_delegate_take())); // Stake 10% of our current total staked TAO let u64_staked_amt = 100_000_000_000; @@ -429,4 +429,32 @@ reveal_weights { }: reveal_weights(RawOrigin::Signed(hotkey.clone()), netuid, uids, weight_values, salt, version_key) + benchmark_sudo_set_tx_childkey_take_rate_limit { + // We don't need to set up any initial state for this benchmark + // as it's a simple setter function that only requires root origin + let new_rate_limit: u64 = 100; +}: sudo_set_tx_childkey_take_rate_limit(RawOrigin::Root, new_rate_limit) + +benchmark_set_childkey_take { + // Setup + let netuid: u16 = 1; + let tempo: u16 = 1; + let seed: u32 = 1; + let coldkey: T::AccountId = account("Cold", 0, seed); + let hotkey: T::AccountId = account("Hot", 0, seed); + let take: u16 = 1000; // 10% in basis points + + // Initialize the network + Subtensor::::init_new_network(netuid, tempo); + + // Register the hotkey + Subtensor::::set_burn(netuid, 1); + let amount_to_be_staked = 1_000_000u32.into(); + Subtensor::::add_balance_to_coldkey_account(&coldkey, amount_to_be_staked); + assert_ok!(Subtensor::::do_burned_registration(RawOrigin::Signed(coldkey.clone()).into(), netuid, hotkey.clone())); + + // Ensure the coldkey owns the hotkey + // Subtensor::::set_coldkey_ownership(coldkey.clone(), hotkey.clone(), true); + +}: set_childkey_take(RawOrigin::Signed(coldkey), hotkey, netuid, take) } diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 7954e77c1..26cba6abd 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -739,9 +739,9 @@ mod dispatches { /// #[pallet::call_index(68)] #[pallet::weight(( - Weight::from_parts(10_000_000, 0) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(1)), + Weight::from_parts(34_000, 0) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(2)), DispatchClass::Normal, Pays::Yes ))] @@ -757,6 +757,8 @@ mod dispatches { Self::do_set_childkey_take(coldkey, hotkey, netuid, take) } + // ---- SUDO ONLY FUNCTIONS ------------------------------------------------------------ + /// Sets the transaction rate limit for changing childkey take. /// /// This function can only be called by the root origin. @@ -771,8 +773,7 @@ mod dispatches { // TODO: Benchmark this call #[pallet::call_index(69)] #[pallet::weight(( - Weight::from_parts(10_000_000, 0) - .saturating_add(T::DbWeight::get().reads(1)) + Weight::from_parts(6_000, 0) .saturating_add(T::DbWeight::get().writes(1)), DispatchClass::Operational, Pays::No @@ -786,8 +787,6 @@ mod dispatches { Ok(()) } - // ---- SUDO ONLY FUNCTIONS ------------------------------------------------------------ - // ================================== // ==== Parameter Sudo calls ======== // ================================== From ee8aa6b52cafb3b0d51899e767f9612a37767029 Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Tue, 30 Jul 2024 20:16:19 +0400 Subject: [PATCH 037/177] chore: remove todos --- pallets/subtensor/src/macros/dispatches.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 26cba6abd..95dec13d3 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -770,7 +770,6 @@ mod dispatches { /// # Errors: /// * `BadOrigin` - If the origin is not root. /// - // TODO: Benchmark this call #[pallet::call_index(69)] #[pallet::weight(( Weight::from_parts(6_000, 0) From c1dbc59c3f0e6d8fea4555a4fc5590edc091a821 Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Tue, 30 Jul 2024 20:17:13 +0400 Subject: [PATCH 038/177] chore: remove more comments --- pallets/subtensor/src/benchmarks.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pallets/subtensor/src/benchmarks.rs b/pallets/subtensor/src/benchmarks.rs index 25176dab7..0a251894e 100644 --- a/pallets/subtensor/src/benchmarks.rs +++ b/pallets/subtensor/src/benchmarks.rs @@ -452,9 +452,5 @@ benchmark_set_childkey_take { let amount_to_be_staked = 1_000_000u32.into(); Subtensor::::add_balance_to_coldkey_account(&coldkey, amount_to_be_staked); assert_ok!(Subtensor::::do_burned_registration(RawOrigin::Signed(coldkey.clone()).into(), netuid, hotkey.clone())); - - // Ensure the coldkey owns the hotkey - // Subtensor::::set_coldkey_ownership(coldkey.clone(), hotkey.clone(), true); - }: set_childkey_take(RawOrigin::Signed(coldkey), hotkey, netuid, take) } From 01cabbdc033f9455aa30ae14ccba2fa507327cd7 Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Tue, 30 Jul 2024 20:25:27 +0400 Subject: [PATCH 039/177] chore: multiple network child key takes --- pallets/subtensor/tests/children.rs | 52 +++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/pallets/subtensor/tests/children.rs b/pallets/subtensor/tests/children.rs index 8dfeedc29..68e13e56e 100644 --- a/pallets/subtensor/tests/children.rs +++ b/pallets/subtensor/tests/children.rs @@ -969,6 +969,58 @@ fn test_childkey_take_rate_limiting() { }); } +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_multiple_networks_childkey_take --exact --nocapture +#[test] +fn test_multiple_networks_childkey_take() { + new_test_ext(1).execute_with(|| { + const NUM_NETWORKS: u16 = 10; + let coldkey = U256::from(1); + let hotkey = U256::from(2); + + // Create 10 networks and set up neurons (skip network 0) + for netuid in 1..NUM_NETWORKS { + // Add network + add_network(netuid, 13, 0); + + // Register neuron + register_ok_neuron(netuid, hotkey, coldkey, 0); + + // Set a unique childkey take value for each network + let take_value = (netuid as u16 + 1) * 1000; // Values will be 1000, 2000, ..., 10000 + assert_ok!(SubtensorModule::set_childkey_take( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + take_value + )); + + // Verify the childkey take was set correctly + let stored_take = SubtensorModule::get_childkey_take(&hotkey, netuid); + assert_eq!( + stored_take, take_value, + "Childkey take not set correctly for network {}", + netuid + ); + + // Log the set value + log::info!("Network {}: Childkey take set to {}", netuid, take_value); + } + + // Verify all networks have different childkey take values + for i in 1..NUM_NETWORKS { + for j in (i + 1)..NUM_NETWORKS { + let take_i = SubtensorModule::get_childkey_take(&hotkey, i); + let take_j = SubtensorModule::get_childkey_take(&hotkey, j); + assert_ne!( + take_i, take_j, + "Childkey take values should be different for networks {} and {}", + i, j + ); + } + } + }); +} + #[test] fn test_do_set_children_multiple_empty_list() { new_test_ext(1).execute_with(|| { From f7f243cef46dc6245eaa6d60e99a8a59ccedeee1 Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Tue, 30 Jul 2024 20:30:26 +0400 Subject: [PATCH 040/177] chore: clippy --- pallets/subtensor/tests/children.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/subtensor/tests/children.rs b/pallets/subtensor/tests/children.rs index 68e13e56e..147a8edae 100644 --- a/pallets/subtensor/tests/children.rs +++ b/pallets/subtensor/tests/children.rs @@ -986,7 +986,7 @@ fn test_multiple_networks_childkey_take() { register_ok_neuron(netuid, hotkey, coldkey, 0); // Set a unique childkey take value for each network - let take_value = (netuid as u16 + 1) * 1000; // Values will be 1000, 2000, ..., 10000 + let take_value = (netuid + 1) * 1000; // Values will be 1000, 2000, ..., 10000 assert_ok!(SubtensorModule::set_childkey_take( RuntimeOrigin::signed(coldkey), hotkey, From e0ff0739f374f1bc35f8d4b27f12efc04e74f4f3 Mon Sep 17 00:00:00 2001 From: John Reed <87283488+JohnReedV@users.noreply.github.com> Date: Tue, 30 Jul 2024 09:31:47 -0700 Subject: [PATCH 041/177] custom errors signed extension --- pallets/subtensor/src/lib.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index f7824e2a3..ff4297ae2 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -2425,7 +2425,7 @@ where ..Default::default() }) } else { - Err(InvalidTransaction::Call.into()) + Err(InvalidTransaction::Custom(1).into()) } } Some(Call::reveal_weights { netuid, .. }) => { @@ -2437,7 +2437,7 @@ where ..Default::default() }) } else { - Err(InvalidTransaction::Call.into()) + Err(InvalidTransaction::Custom(2).into()) } } Some(Call::set_weights { netuid, .. }) => { @@ -2449,7 +2449,7 @@ where ..Default::default() }) } else { - Err(InvalidTransaction::Call.into()) + Err(InvalidTransaction::Custom(3).into()) } } Some(Call::set_root_weights { netuid, hotkey, .. }) => { @@ -2461,7 +2461,7 @@ where ..Default::default() }) } else { - Err(InvalidTransaction::Call.into()) + Err(InvalidTransaction::Custom(4).into()) } } Some(Call::add_stake { .. }) => Ok(ValidTransaction { @@ -2480,7 +2480,7 @@ where if registrations_this_interval >= (max_registrations_per_interval.saturating_mul(3)) { // If the registration limit for the interval is exceeded, reject the transaction - return InvalidTransaction::ExhaustsResources.into(); + return Err(InvalidTransaction::Custom(5).into()); } Ok(ValidTransaction { priority: Self::get_priority_vanilla(), @@ -2493,7 +2493,7 @@ where }), Some(Call::dissolve_network { .. }) => { if Pallet::::coldkey_in_arbitration(who) { - Err(TransactionValidityError::Invalid(InvalidTransaction::Call)) + Err(InvalidTransaction::Custom(6).into()) } else { Ok(ValidTransaction { priority: Self::get_priority_vanilla(), From 18879258d792d3b8597f4fef3d5b9701386c69c3 Mon Sep 17 00:00:00 2001 From: John Reed <87283488+JohnReedV@users.noreply.github.com> Date: Tue, 30 Jul 2024 11:47:46 -0700 Subject: [PATCH 042/177] update tests --- pallets/subtensor/tests/registration.rs | 4 ++-- pallets/subtensor/tests/weights.rs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pallets/subtensor/tests/registration.rs b/pallets/subtensor/tests/registration.rs index bd95ae3b1..74a493e04 100644 --- a/pallets/subtensor/tests/registration.rs +++ b/pallets/subtensor/tests/registration.rs @@ -276,7 +276,7 @@ fn test_registration_rate_limit_exceeded() { let result = extension.validate(&who, &call.into(), &info, 10); // Expectation: The transaction should be rejected - assert_err!(result, InvalidTransaction::ExhaustsResources); + assert_err!(result, InvalidTransaction::Custom(5)); let current_registrants = SubtensorModule::get_registrations_this_interval(netuid); assert!(current_registrants <= max_registrants); @@ -362,7 +362,7 @@ fn test_burned_registration_rate_limit_exceeded() { // Expectation: The transaction should be rejected assert_err!( burned_register_result, - InvalidTransaction::ExhaustsResources + InvalidTransaction::Custom(5) ); let current_registrants = SubtensorModule::get_registrations_this_interval(netuid); diff --git a/pallets/subtensor/tests/weights.rs b/pallets/subtensor/tests/weights.rs index 2344bd425..88b8aaf25 100644 --- a/pallets/subtensor/tests/weights.rs +++ b/pallets/subtensor/tests/weights.rs @@ -109,7 +109,7 @@ fn test_set_rootweights_validate() { assert_err!( // Should get an invalid transaction error result_no_stake, - TransactionValidityError::Invalid(InvalidTransaction::Call,) + TransactionValidityError::Invalid(InvalidTransaction::Custom(4)) ); // Increase the stake to be equal to the minimum @@ -209,7 +209,7 @@ fn test_commit_weights_validate() { assert_err!( // Should get an invalid transaction error result_no_stake, - TransactionValidityError::Invalid(InvalidTransaction::Call,) + TransactionValidityError::Invalid(InvalidTransaction::Custom(1)) ); // Increase the stake to be equal to the minimum @@ -308,7 +308,7 @@ fn test_reveal_weights_validate() { assert_err!( // Should get an invalid transaction error result_no_stake, - TransactionValidityError::Invalid(InvalidTransaction::Call,) + TransactionValidityError::Invalid(InvalidTransaction::Custom(2)) ); // Increase the stake to be equal to the minimum From 75e7299f96907f51a04a4e27dae6d717df19361e Mon Sep 17 00:00:00 2001 From: John Reed <87283488+JohnReedV@users.noreply.github.com> Date: Tue, 30 Jul 2024 11:58:24 -0700 Subject: [PATCH 043/177] clippy --- pallets/collective/src/lib.rs | 6 +++--- pallets/subtensor/tests/difficulty.rs | 1 - pallets/subtensor/tests/epoch.rs | 1 - pallets/subtensor/tests/mock.rs | 4 ++++ pallets/subtensor/tests/neuron_info.rs | 1 - pallets/subtensor/tests/registration.rs | 1 - pallets/subtensor/tests/serving.rs | 2 -- pallets/subtensor/tests/staking.rs | 3 --- pallets/subtensor/tests/weights.rs | 3 --- 9 files changed, 7 insertions(+), 15 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/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 676b3cd35..e2b911525 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/mock.rs b/pallets/subtensor/tests/mock.rs index fc784f46f..3b4ee8de8 100644 --- a/pallets/subtensor/tests/mock.rs +++ b/pallets/subtensor/tests/mock.rs @@ -262,6 +262,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; @@ -279,6 +280,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; @@ -295,6 +297,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; @@ -312,6 +315,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/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 74a493e04..8c1c6e6bd 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 41e9888cc..b87b7fd10 100644 --- a/pallets/subtensor/tests/serving.rs +++ b/pallets/subtensor/tests/serving.rs @@ -161,7 +161,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); @@ -379,7 +378,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 cb2cac4ef..12d299d8f 100644 --- a/pallets/subtensor/tests/staking.rs +++ b/pallets/subtensor/tests/staking.rs @@ -22,7 +22,6 @@ use sp_runtime::traits::SignedExtension; ************************************************************/ #[test] -#[cfg(not(tarpaulin))] fn test_add_stake_dispatch_info_ok() { new_test_ext(1).execute_with(|| { let hotkey = U256::from(0); @@ -528,7 +527,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); @@ -1201,7 +1199,6 @@ fn test_delegate_stake_division_by_zero_check() { } #[test] -#[cfg(not(tarpaulin))] fn test_full_with_delegating() { new_test_ext(1).execute_with(|| { let netuid = 1; diff --git a/pallets/subtensor/tests/weights.rs b/pallets/subtensor/tests/weights.rs index 88b8aaf25..c87f818b2 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 38ad5169256aafe913b2389bb8ce5e925362edc6 Mon Sep 17 00:00:00 2001 From: John Reed <87283488+JohnReedV@users.noreply.github.com> Date: Tue, 30 Jul 2024 12:01:30 -0700 Subject: [PATCH 044/177] fmt --- pallets/subtensor/tests/registration.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/pallets/subtensor/tests/registration.rs b/pallets/subtensor/tests/registration.rs index 8c1c6e6bd..4d235cb7e 100644 --- a/pallets/subtensor/tests/registration.rs +++ b/pallets/subtensor/tests/registration.rs @@ -360,10 +360,7 @@ fn test_burned_registration_rate_limit_exceeded() { extension.validate(&who, &call_burned_register.into(), &info, 10); // Expectation: The transaction should be rejected - assert_err!( - burned_register_result, - InvalidTransaction::Custom(5) - ); + assert_err!(burned_register_result, InvalidTransaction::Custom(5)); let current_registrants = SubtensorModule::get_registrations_this_interval(netuid); assert!(current_registrants <= max_registrants); From 826e55c1f26322adc3f84dd3b74207de5795f84b Mon Sep 17 00:00:00 2001 From: John Reed <87283488+JohnReedV@users.noreply.github.com> Date: Tue, 30 Jul 2024 12:35:52 -0700 Subject: [PATCH 045/177] add custom error 7 & fix clippy --- pallets/subtensor/src/lib.rs | 18 ++++++++---------- pallets/subtensor/tests/staking.rs | 6 ++---- runtime/src/lib.rs | 2 ++ 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index ff4297ae2..f5d70362f 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -2403,16 +2403,14 @@ where _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 + if let Some( + BalancesCall::transfer_allow_death { .. } + | BalancesCall::transfer_keep_alive { .. } + | BalancesCall::transfer_all { .. }, + ) = call.is_sub_type() + { + if Pallet::::coldkey_in_arbitration(who) { + return Err(InvalidTransaction::Custom(7).into()); } } match call.is_sub_type() { diff --git a/pallets/subtensor/tests/staking.rs b/pallets/subtensor/tests/staking.rs index 12d299d8f..fff6749fc 100644 --- a/pallets/subtensor/tests/staking.rs +++ b/pallets/subtensor/tests/staking.rs @@ -1,9 +1,7 @@ #![allow(clippy::unwrap_used)] #![allow(clippy::arithmetic_side_effects)] -use frame_support::pallet_prelude::{ - InvalidTransaction, TransactionValidity, TransactionValidityError, -}; +use frame_support::pallet_prelude::{InvalidTransaction, TransactionValidity}; use frame_support::traits::{OnFinalize, OnIdle, OnInitialize}; use frame_support::weights::Weight; use frame_support::{assert_err, assert_noop, assert_ok, traits::Currency}; @@ -3876,7 +3874,7 @@ fn test_transfer_coldkey_in_arbitration() { assert_eq!( validate_transaction(&coldkey_account_id, &call), - Err(TransactionValidityError::Invalid(InvalidTransaction::Call)) + Err(InvalidTransaction::Custom(7).into()) ); }); } diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index a4abd124f..303e7040f 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -516,6 +516,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; @@ -531,6 +532,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 0b5e24d0687d7a1aaef277208cae81b77a18b883 Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Wed, 31 Jul 2024 00:16:42 +0400 Subject: [PATCH 046/177] chore: scheduler tests --- Cargo.lock | 3 + pallets/subtensor/src/macros/dispatches.rs | 9 +- pallets/subtensor/src/macros/errors.rs | 6 + pallets/subtensor/src/macros/events.rs | 2 +- pallets/subtensor/tests/swap_coldkey.rs | 194 +++++++++++++++++++++ runtime/src/lib.rs | 2 +- runtime/tests/pallet_proxy.rs | 2 +- 7 files changed, 214 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4a50f8a12..ea30f4e25 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4976,6 +4976,7 @@ dependencies = [ "frame-system", "log", "pallet-balances", + "pallet-scheduler", "pallet-subtensor", "parity-scale-codec", "scale-info", @@ -4983,6 +4984,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-rc3)", "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3)", "sp-weights", "substrate-fixed", @@ -5264,6 +5266,7 @@ dependencies = [ "pallet-balances", "pallet-collective", "pallet-membership", + "pallet-scheduler", "pallet-transaction-payment", "pallet-utility", "parity-scale-codec", diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index f5599adae..6a88d44ca 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -987,7 +987,14 @@ mod dispatches { 63, frame_system::RawOrigin::Root.into(), Bounded::Lookup { hash, len }, - )?; + ) + .map_err(|_| Error::::FailedToSchedule)?; + // Emit the SwapScheduled event + Self::deposit_event(Event::ColdkeySwapScheduled { + old_coldkey: who.clone(), + new_coldkey: new_coldkey.clone(), + execution_block: when, + }); Ok(().into()) } diff --git a/pallets/subtensor/src/macros/errors.rs b/pallets/subtensor/src/macros/errors.rs index 156cbea56..d51469482 100644 --- a/pallets/subtensor/src/macros/errors.rs +++ b/pallets/subtensor/src/macros/errors.rs @@ -168,5 +168,11 @@ mod errors { TooManyChildren, /// Default transaction rate limit exceeded. TxRateLimitExceeded, + /// Swap coldkey only callable by root. + SwapColdkeyOnlyCallableByRoot, + /// Swap already scheduled. + SwapAlreadyScheduled, + /// failed to swap coldkey + FailedToSchedule, } } diff --git a/pallets/subtensor/src/macros/events.rs b/pallets/subtensor/src/macros/events.rs index b93b8296b..b2c14ae76 100644 --- a/pallets/subtensor/src/macros/events.rs +++ b/pallets/subtensor/src/macros/events.rs @@ -164,7 +164,7 @@ mod events { /// The account ID of the new coldkey new_coldkey: T::AccountId, /// The arbitration block for the coldkey swap - arbitration_block: u64, + execution_block: BlockNumberFor, }, /// The arbitration period has been extended ArbitrationPeriodExtended { diff --git a/pallets/subtensor/tests/swap_coldkey.rs b/pallets/subtensor/tests/swap_coldkey.rs index 9203e2b3f..6ea0bb542 100644 --- a/pallets/subtensor/tests/swap_coldkey.rs +++ b/pallets/subtensor/tests/swap_coldkey.rs @@ -4,10 +4,16 @@ use frame_support::weights::Weight; use frame_support::{assert_err, assert_noop, assert_ok}; use frame_system::{Config, RawOrigin}; mod mock; +use frame_support::error::BadOrigin; +use frame_support::traits::schedule::v3::Named as ScheduleNamed; +use frame_support::traits::schedule::DispatchTime; +use frame_support::traits::OnInitialize; use mock::*; use pallet_subtensor::*; +use pallet_subtensor::{Call, Error}; use sp_core::H256; use sp_core::U256; +use sp_runtime::DispatchError; // SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_coldkey -- test_swap_total_hotkey_coldkey_stakes_this_interval --exact --nocapture #[test] @@ -1286,3 +1292,191 @@ fn test_coldkey_delegations() { assert_eq!(Stake::::get(delegate, coldkey), 0); }); } + +#[test] +fn test_schedule_swap_coldkey_success() { + new_test_ext(1).execute_with(|| { + // Initialize test accounts + let old_coldkey: U256 = U256::from(1); + let new_coldkey: U256 = U256::from(2); + + // Add balance to the old coldkey account + SubtensorModule::add_balance_to_coldkey_account(&old_coldkey, 1000); + + // Schedule the coldkey swap + assert_ok!(SubtensorModule::schedule_swap_coldkey( + <::RuntimeOrigin>::signed(old_coldkey), + new_coldkey + )); + + // Get the current block number + let current_block: u64 = System::block_number(); + + // Calculate the expected execution block (5 days from now) + let expected_execution_block: u64 = current_block + 5 * 24 * 60 * 60 / 12; + + // Check for the SwapScheduled event + System::assert_last_event( + Event::ColdkeySwapScheduled { + old_coldkey, + new_coldkey, + execution_block: expected_execution_block, + } + .into(), + ); + + // TODO: Add additional checks to ensure the swap is correctly scheduled in the system + // For example, verify that the swap is present in the appropriate storage or scheduler + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test swap_coldkey -- test_schedule_swap_coldkey_duplicate --exact --nocapture +#[test] +fn test_schedule_swap_coldkey_duplicate() { + new_test_ext(1).execute_with(|| { + let old_coldkey = U256::from(1); + let new_coldkey = U256::from(2); + + SubtensorModule::add_balance_to_coldkey_account(&old_coldkey, 2000); + + assert_ok!(SubtensorModule::schedule_swap_coldkey( + <::RuntimeOrigin>::signed(old_coldkey), + new_coldkey + )); + + // Attempt to schedule again + assert_noop!( + SubtensorModule::schedule_swap_coldkey( + <::RuntimeOrigin>::signed(old_coldkey), + new_coldkey + ), + Error::::FailedToSchedule + ); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test swap_coldkey -- test_schedule_swap_coldkey_execution --exact --nocapture +#[test] +fn test_schedule_swap_coldkey_execution() { + new_test_ext(1).execute_with(|| { + let old_coldkey = U256::from(1); + let new_coldkey = U256::from(2); + let hotkey = U256::from(3); + let netuid = 1u16; + let stake_amount = 100; + + add_network(netuid, 13, 0); + register_ok_neuron(netuid, hotkey, old_coldkey, 0); + SubtensorModule::add_balance_to_coldkey_account(&old_coldkey, 1000); + assert_ok!(SubtensorModule::add_stake( + <::RuntimeOrigin>::signed(old_coldkey), + hotkey, + stake_amount + )); + + // Check initial ownership + assert_eq!( + Owner::::get(hotkey), + old_coldkey, + "Initial ownership check failed" + ); + + // Schedule the swap + assert_ok!(SubtensorModule::schedule_swap_coldkey( + <::RuntimeOrigin>::signed(old_coldkey), + new_coldkey + )); + + // Get the scheduled execution block + let current_block = System::block_number(); + let blocks_in_5_days = 5 * 24 * 60 * 60 / 12; + let execution_block = current_block + blocks_in_5_days; + + println!("Current block: {}", current_block); + println!("Execution block: {}", execution_block); + + // Fast forward to the execution block + // System::set_block_number(execution_block); + run_to_block(execution_block); + + // Run on_initialize for the execution block + SubtensorModule::on_initialize(execution_block); + + // // Also run Scheduler's on_initialize + // as OnInitialize>::on_initialize( + // execution_block, + // ); + + // // Check if the swap has occurred + // let new_owner = Owner::::get(hotkey); + // println!("New owner after swap: {:?}", new_owner); + // assert_eq!( + // new_owner, new_coldkey, + // "Ownership was not updated as expected" + // ); + + // assert_eq!( + // Stake::::get(hotkey, new_coldkey), + // stake_amount, + // "Stake was not transferred to new coldkey" + // ); + // assert_eq!( + // Stake::::get(hotkey, old_coldkey), + // 0, + // "Old coldkey still has stake" + // ); + + // Check for the SwapExecuted event + System::assert_last_event( + Event::ColdkeySwapScheduled { + old_coldkey, + new_coldkey, + execution_block, + } + .into(), + ); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test swap_coldkey -- test_direct_swap_coldkey_call_fails --exact --nocapture +#[test] +fn test_direct_swap_coldkey_call_fails() { + new_test_ext(1).execute_with(|| { + let old_coldkey = U256::from(1); + let new_coldkey = U256::from(2); + + assert_noop!( + SubtensorModule::swap_coldkey( + <::RuntimeOrigin>::signed(old_coldkey), + new_coldkey + ), + BadOrigin + ); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test swap_coldkey -- test_schedule_swap_coldkey_with_pending_swap --exact --nocapture +#[test] +fn test_schedule_swap_coldkey_with_pending_swap() { + new_test_ext(1).execute_with(|| { + let old_coldkey = U256::from(1); + let new_coldkey1 = U256::from(2); + let new_coldkey2 = U256::from(3); + + SubtensorModule::add_balance_to_coldkey_account(&old_coldkey, 2000); + + assert_ok!(SubtensorModule::schedule_swap_coldkey( + <::RuntimeOrigin>::signed(old_coldkey), + new_coldkey1 + )); + + // Attempt to schedule another swap before the first one executes + assert_noop!( + SubtensorModule::schedule_swap_coldkey( + <::RuntimeOrigin>::signed(old_coldkey), + new_coldkey2 + ), + Error::::SwapAlreadyScheduled + ); + }); +} diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 289e9effe..d6699e759 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -144,7 +144,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: 191, + spec_version: 192, impl_version: 1, apis: RUNTIME_API_VERSIONS, diff --git a/runtime/tests/pallet_proxy.rs b/runtime/tests/pallet_proxy.rs index 192893c1e..796dfc471 100644 --- a/runtime/tests/pallet_proxy.rs +++ b/runtime/tests/pallet_proxy.rs @@ -4,7 +4,7 @@ use codec::Encode; use frame_support::{assert_ok, traits::InstanceFilter, BoundedVec}; use node_subtensor_runtime::{ AccountId, BalancesCall, BuildStorage, Proxy, ProxyType, Runtime, RuntimeCall, RuntimeEvent, - RuntimeGenesisConfig, RuntimeOrigin, SchedulerCall, SubtensorModule, System, SystemCall, + RuntimeGenesisConfig, RuntimeOrigin, SubtensorModule, System, SystemCall, }; const ACCOUNT: [u8; 32] = [1_u8; 32]; From 06f1b9d44504a501492f6a4c30d8d148ab4edf94 Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Wed, 31 Jul 2024 00:17:30 +0400 Subject: [PATCH 047/177] 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 1fecf7dbc..4f10474c8 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: 191, + spec_version: 192, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1, From 850caf681d85e3bb4f7b32eee0c496392dcf160f Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Wed, 31 Jul 2024 01:29:29 +0400 Subject: [PATCH 048/177] chore: lints --- pallets/subtensor/tests/children.rs | 1 - pallets/subtensor/tests/coinbase.rs | 8 ++++---- pallets/subtensor/tests/difficulty.rs | 2 +- pallets/subtensor/tests/epoch.rs | 2 +- pallets/subtensor/tests/mock.rs | 4 ++++ pallets/subtensor/tests/neuron_info.rs | 2 +- pallets/subtensor/tests/registration.rs | 2 +- pallets/subtensor/tests/serving.rs | 4 ++-- pallets/subtensor/tests/staking.rs | 4 ++-- pallets/subtensor/tests/weights.rs | 6 +++--- runtime/src/lib.rs | 1 + 11 files changed, 20 insertions(+), 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..a6c1acde1 100644 --- a/pallets/subtensor/tests/coinbase.rs +++ b/pallets/subtensor/tests/coinbase.rs @@ -6,7 +6,7 @@ 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 +18,7 @@ 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 +46,7 @@ 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 +138,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() { 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..b9524de57 100644 --- a/pallets/subtensor/tests/difficulty.rs +++ b/pallets/subtensor/tests/difficulty.rs @@ -5,7 +5,7 @@ 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..53a825fee 100644 --- a/pallets/subtensor/tests/epoch.rs +++ b/pallets/subtensor/tests/epoch.rs @@ -2107,7 +2107,7 @@ 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/mock.rs b/pallets/subtensor/tests/mock.rs index 6f75fcb1a..5503b8190 100644 --- a/pallets/subtensor/tests/mock.rs +++ b/pallets/subtensor/tests/mock.rs @@ -266,6 +266,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; @@ -283,6 +284,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; @@ -299,6 +301,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; @@ -316,6 +319,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/neuron_info.rs b/pallets/subtensor/tests/neuron_info.rs index 10df1c07d..4375979bd 100644 --- a/pallets/subtensor/tests/neuron_info.rs +++ b/pallets/subtensor/tests/neuron_info.rs @@ -15,7 +15,7 @@ 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..f951971f5 100644 --- a/pallets/subtensor/tests/registration.rs +++ b/pallets/subtensor/tests/registration.rs @@ -539,7 +539,7 @@ 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 41e9888cc..8232a936d 100644 --- a/pallets/subtensor/tests/serving.rs +++ b/pallets/subtensor/tests/serving.rs @@ -161,7 +161,7 @@ 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); @@ -379,7 +379,7 @@ 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..409348180 100644 --- a/pallets/subtensor/tests/staking.rs +++ b/pallets/subtensor/tests/staking.rs @@ -15,7 +15,7 @@ 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 +521,7 @@ 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..f56b5e038 100644 --- a/pallets/subtensor/tests/weights.rs +++ b/pallets/subtensor/tests/weights.rs @@ -21,7 +21,7 @@ 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 +41,7 @@ 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 +404,7 @@ 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]; diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index d6699e759..000e3d7a1 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -522,6 +522,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; From d8acb8bc10fa6148f188c15d76a88fdf7a7f32f2 Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Wed, 31 Jul 2024 01:40:10 +0400 Subject: [PATCH 049/177] feat: isabella question --- pallets/subtensor/tests/children.rs | 96 +++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/pallets/subtensor/tests/children.rs b/pallets/subtensor/tests/children.rs index 147a8edae..9db206c06 100644 --- a/pallets/subtensor/tests/children.rs +++ b/pallets/subtensor/tests/children.rs @@ -1487,3 +1487,99 @@ fn test_children_stake_values() { ); }); } + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_get_parents_chain --exact --nocapture +#[test] +fn test_get_parents_chain() { + new_test_ext(1).execute_with(|| { + let netuid: u16 = 1; + let coldkey = U256::from(1); + let num_keys: usize = 5; + let proportion = u64::MAX / 2; // 50% stake allocation + + log::info!("Test setup: netuid={}, coldkey={}, num_keys={}, proportion={}", netuid, coldkey, num_keys, proportion); + + // Create a vector of hotkeys + let hotkeys: Vec = (0..num_keys).map(|i| U256::from(i as u64 + 2)).collect(); + log::info!("Created hotkeys: {:?}", hotkeys); + + // Add network + add_network(netuid, 13, 0); + SubtensorModule::set_max_registrations_per_block(netuid, 1000); + SubtensorModule::set_target_registrations_per_interval(netuid, 1000); + log::info!("Network added and parameters set: netuid={}", netuid); + + // Register all neurons + for hotkey in &hotkeys { + register_ok_neuron(netuid, *hotkey, coldkey, 0); + log::info!("Registered neuron: hotkey={}, coldkey={}, netuid={}", hotkey, coldkey, netuid); + } + + // Set up parent-child relationships + for i in 0..num_keys - 1 { + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkeys[i], + netuid, + vec![(proportion, hotkeys[i + 1])] + )); + log::info!("Set parent-child relationship: parent={}, child={}, proportion={}", hotkeys[i], hotkeys[i + 1], proportion); + } + + // Test get_parents for each hotkey + for i in 1..num_keys { + let parents = SubtensorModule::get_parents(&hotkeys[i], netuid); + log::info!("Testing get_parents for hotkey {}: {:?}", hotkeys[i], parents); + assert_eq!( + parents.len(), + 1, + "Hotkey {} should have exactly one parent", + i + ); + assert_eq!( + parents[0], + (proportion, hotkeys[i - 1]), + "Incorrect parent for hotkey {}", + i + ); + } + + // Test get_parents for the root (should be empty) + let root_parents = SubtensorModule::get_parents(&hotkeys[0], netuid); + log::info!("Testing get_parents for root hotkey {}: {:?}", hotkeys[0], root_parents); + assert!( + root_parents.is_empty(), + "Root hotkey should have no parents" + ); + + // Test multiple parents + let last_hotkey = hotkeys[num_keys - 1]; + let new_parent = U256::from(num_keys as u64 + 2); + register_ok_neuron(netuid, new_parent, coldkey, 0); + log::info!("Registered new parent neuron: new_parent={}, coldkey={}, netuid={}", new_parent, coldkey, netuid); + + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + new_parent, + netuid, + vec![(proportion / 2, last_hotkey)] + )); + log::info!("Set additional parent-child relationship: parent={}, child={}, proportion={}", new_parent, last_hotkey, proportion / 2); + + let last_hotkey_parents = SubtensorModule::get_parents(&last_hotkey, netuid); + log::info!("Testing get_parents for last hotkey {} with multiple parents: {:?}", last_hotkey, last_hotkey_parents); + assert_eq!( + last_hotkey_parents.len(), + 2, + "Last hotkey should have two parents" + ); + assert!( + last_hotkey_parents.contains(&(proportion, hotkeys[num_keys - 2])), + "Last hotkey should still have its original parent" + ); + assert!( + last_hotkey_parents.contains(&(proportion / 2, new_parent)), + "Last hotkey should have the new parent" + ); + }); +} From 3d4d57155c7a0a996cc32912b72a40b375ea5947 Mon Sep 17 00:00:00 2001 From: open-junius Date: Wed, 31 Jul 2024 15:18:19 +0800 Subject: [PATCH 050/177] start the unit test fix --- pallets/subtensor/src/lib.rs | 4 ++++ pallets/subtensor/src/macros/dispatches.rs | 6 ++++++ pallets/subtensor/src/swap/swap_coldkey.rs | 5 ++++- pallets/subtensor/tests/swap_coldkey.rs | 17 +++++++++-------- 4 files changed, 23 insertions(+), 9 deletions(-) diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index f5febb0aa..321e58b4a 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -691,6 +691,10 @@ pub mod pallet { pub type OwnedHotkeys = StorageMap<_, Blake2_128Concat, T::AccountId, Vec, ValueQuery>; + #[pallet::storage] // --- DMAP ( cold ) --> () | Maps coldkey to if a coldkey swap is scheduled. + pub type ColdkeySwapScheduled = + StorageMap<_, Blake2_128Concat, T::AccountId, (), ValueQuery>; + /// ============================ /// ==== Global Parameters ===== /// ============================ diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 6a88d44ca..348f57f73 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -953,6 +953,10 @@ mod dispatches { new_coldkey: T::AccountId, ) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; + ensure!( + !ColdkeySwapScheduled::::contains_key(&who), + Error::::SwapAlreadyScheduled + ); // Calculate the number of blocks in 5 days let blocks_in_5_days: u32 = 5 * 24 * 60 * 60 / 12; @@ -989,6 +993,8 @@ mod dispatches { Bounded::Lookup { hash, len }, ) .map_err(|_| Error::::FailedToSchedule)?; + + ColdkeySwapScheduled::::insert(&who, ()); // Emit the SwapScheduled event Self::deposit_event(Event::ColdkeySwapScheduled { old_coldkey: who.clone(), diff --git a/pallets/subtensor/src/swap/swap_coldkey.rs b/pallets/subtensor/src/swap/swap_coldkey.rs index bd8a11fa1..b47b0ac95 100644 --- a/pallets/subtensor/src/swap/swap_coldkey.rs +++ b/pallets/subtensor/src/swap/swap_coldkey.rs @@ -74,7 +74,10 @@ impl Pallet { Self::set_last_tx_block(new_coldkey, Self::get_current_block_as_u64()); weight.saturating_accrue(T::DbWeight::get().writes(1)); - // 10. Emit the ColdkeySwapped event + // 10. Remove the coldkey swap scheduled record + ColdkeySwapScheduled::::remove(&old_coldkey); + + // 11. Emit the ColdkeySwapped event Self::deposit_event(Event::ColdkeySwapped { old_coldkey: old_coldkey.clone(), new_coldkey: new_coldkey.clone(), diff --git a/pallets/subtensor/tests/swap_coldkey.rs b/pallets/subtensor/tests/swap_coldkey.rs index 6ea0bb542..8c2bb2330 100644 --- a/pallets/subtensor/tests/swap_coldkey.rs +++ b/pallets/subtensor/tests/swap_coldkey.rs @@ -1395,6 +1395,15 @@ fn test_schedule_swap_coldkey_execution() { println!("Current block: {}", current_block); println!("Execution block: {}", execution_block); + System::assert_last_event( + Event::ColdkeySwapScheduled { + old_coldkey, + new_coldkey, + execution_block, + } + .into(), + ); + // Fast forward to the execution block // System::set_block_number(execution_block); run_to_block(execution_block); @@ -1427,14 +1436,6 @@ fn test_schedule_swap_coldkey_execution() { // ); // Check for the SwapExecuted event - System::assert_last_event( - Event::ColdkeySwapScheduled { - old_coldkey, - new_coldkey, - execution_block, - } - .into(), - ); }); } From 5d48fae1b40c919db94ee7e5ce38080c300cf959 Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Wed, 31 Jul 2024 12:03:16 +0400 Subject: [PATCH 051/177] chore: PR review comments --- pallets/subtensor/src/lib.rs | 11 +- pallets/subtensor/src/staking/set_children.rs | 9 +- pallets/subtensor/tests/children.rs | 106 ++++++++++++++++-- runtime/src/lib.rs | 4 +- scripts/test_specific.sh | 4 +- 5 files changed, 117 insertions(+), 17 deletions(-) diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index c58c6a0c6..89aa76bb7 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -628,8 +628,15 @@ pub mod pallet { StorageMap<_, Blake2_128Concat, T::AccountId, u16, ValueQuery, DefaultDelegateTake>; #[pallet::storage] /// DMAP ( hot, netuid ) --> take | Returns the hotkey childkey take for a specific subnet - pub type ChildkeyTake = - StorageMap<_, Blake2_128Concat, (T::AccountId, u16), u16, ValueQuery>; + pub type ChildkeyTake = StorageDoubleMap< + _, + Blake2_128Concat, + T::AccountId, // First key: hotkey + Identity, + u16, // Second key: netuid + u16, // Value: take + ValueQuery, + >; #[pallet::storage] /// DMAP ( hot, cold ) --> stake | Returns the stake under a coldkey prefixed by hotkey. diff --git a/pallets/subtensor/src/staking/set_children.rs b/pallets/subtensor/src/staking/set_children.rs index c62d8f130..f60298d57 100644 --- a/pallets/subtensor/src/staking/set_children.rs +++ b/pallets/subtensor/src/staking/set_children.rs @@ -130,6 +130,11 @@ impl Pallet { // --- 7.1. Insert my new children + proportion list into the map. ChildKeys::::insert(hotkey.clone(), netuid, children.clone()); + if children.is_empty() { + // If there are no children, remove the ChildkeyTake value + ChildkeyTake::::remove(hotkey.clone(), netuid); + } + // --- 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. @@ -243,7 +248,7 @@ impl Pallet { ); // Set the new childkey take value for the given hotkey and network - ChildkeyTake::::insert((hotkey.clone(), netuid), take); + ChildkeyTake::::insert(hotkey.clone(), netuid, take); // TODO: Consider adding a check to ensure the hotkey is registered on the specified network (netuid) // before setting the childkey take. This could prevent setting takes for non-existent or @@ -286,6 +291,6 @@ impl Pallet { /// * `u16` - The childkey take value. This is a percentage represented as a value between 0 and 10000, /// where 10000 represents 100%. pub fn get_childkey_take(hotkey: &T::AccountId, netuid: u16) -> u16 { - ChildkeyTake::::get((hotkey, netuid)) + ChildkeyTake::::get(hotkey, netuid) } } diff --git a/pallets/subtensor/tests/children.rs b/pallets/subtensor/tests/children.rs index 9db206c06..0025dd24a 100644 --- a/pallets/subtensor/tests/children.rs +++ b/pallets/subtensor/tests/children.rs @@ -1497,7 +1497,13 @@ fn test_get_parents_chain() { let num_keys: usize = 5; let proportion = u64::MAX / 2; // 50% stake allocation - log::info!("Test setup: netuid={}, coldkey={}, num_keys={}, proportion={}", netuid, coldkey, num_keys, proportion); + log::info!( + "Test setup: netuid={}, coldkey={}, num_keys={}, proportion={}", + netuid, + coldkey, + num_keys, + proportion + ); // Create a vector of hotkeys let hotkeys: Vec = (0..num_keys).map(|i| U256::from(i as u64 + 2)).collect(); @@ -1512,7 +1518,12 @@ fn test_get_parents_chain() { // Register all neurons for hotkey in &hotkeys { register_ok_neuron(netuid, *hotkey, coldkey, 0); - log::info!("Registered neuron: hotkey={}, coldkey={}, netuid={}", hotkey, coldkey, netuid); + log::info!( + "Registered neuron: hotkey={}, coldkey={}, netuid={}", + hotkey, + coldkey, + netuid + ); } // Set up parent-child relationships @@ -1523,13 +1534,22 @@ fn test_get_parents_chain() { netuid, vec![(proportion, hotkeys[i + 1])] )); - log::info!("Set parent-child relationship: parent={}, child={}, proportion={}", hotkeys[i], hotkeys[i + 1], proportion); + log::info!( + "Set parent-child relationship: parent={}, child={}, proportion={}", + hotkeys[i], + hotkeys[i + 1], + proportion + ); } // Test get_parents for each hotkey for i in 1..num_keys { let parents = SubtensorModule::get_parents(&hotkeys[i], netuid); - log::info!("Testing get_parents for hotkey {}: {:?}", hotkeys[i], parents); + log::info!( + "Testing get_parents for hotkey {}: {:?}", + hotkeys[i], + parents + ); assert_eq!( parents.len(), 1, @@ -1546,7 +1566,11 @@ fn test_get_parents_chain() { // Test get_parents for the root (should be empty) let root_parents = SubtensorModule::get_parents(&hotkeys[0], netuid); - log::info!("Testing get_parents for root hotkey {}: {:?}", hotkeys[0], root_parents); + log::info!( + "Testing get_parents for root hotkey {}: {:?}", + hotkeys[0], + root_parents + ); assert!( root_parents.is_empty(), "Root hotkey should have no parents" @@ -1556,7 +1580,12 @@ fn test_get_parents_chain() { let last_hotkey = hotkeys[num_keys - 1]; let new_parent = U256::from(num_keys as u64 + 2); register_ok_neuron(netuid, new_parent, coldkey, 0); - log::info!("Registered new parent neuron: new_parent={}, coldkey={}, netuid={}", new_parent, coldkey, netuid); + log::info!( + "Registered new parent neuron: new_parent={}, coldkey={}, netuid={}", + new_parent, + coldkey, + netuid + ); assert_ok!(SubtensorModule::do_set_children( RuntimeOrigin::signed(coldkey), @@ -1564,10 +1593,19 @@ fn test_get_parents_chain() { netuid, vec![(proportion / 2, last_hotkey)] )); - log::info!("Set additional parent-child relationship: parent={}, child={}, proportion={}", new_parent, last_hotkey, proportion / 2); + log::info!( + "Set additional parent-child relationship: parent={}, child={}, proportion={}", + new_parent, + last_hotkey, + proportion / 2 + ); let last_hotkey_parents = SubtensorModule::get_parents(&last_hotkey, netuid); - log::info!("Testing get_parents for last hotkey {} with multiple parents: {:?}", last_hotkey, last_hotkey_parents); + log::info!( + "Testing get_parents for last hotkey {} with multiple parents: {:?}", + last_hotkey, + last_hotkey_parents + ); assert_eq!( last_hotkey_parents.len(), 2, @@ -1583,3 +1621,55 @@ fn test_get_parents_chain() { ); }); } + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_childkey_take_removal_on_empty_children --exact --nocapture +#[test] +fn test_childkey_take_removal_on_empty_children() { + 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 a child and childkey take + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![(proportion, child)] + )); + + let take: u16 = u16::MAX / 10; // 10% take + assert_ok!(SubtensorModule::set_childkey_take( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + take + )); + + // Verify childkey take is set + assert_eq!(SubtensorModule::get_childkey_take(&hotkey, netuid), take); + + // Remove all children + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + vec![] + )); + + // Verify children are removed + let children = SubtensorModule::get_children(&hotkey, netuid); + assert!(children.is_empty()); + + // Verify childkey take is removed + assert_eq!(SubtensorModule::get_childkey_take(&hotkey, netuid), 0); + // Verify childkey take storage is empty + assert_eq!(ChildkeyTake::::get(hotkey, netuid), 0); + }); +} diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 4f10474c8..20d337d64 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -858,8 +858,8 @@ parameter_types! { pub const SubtensorInitialPruningScore : u16 = u16::MAX; pub const SubtensorInitialBondsMovingAverage: u64 = 900_000; pub const SubtensorInitialDefaultTake: u16 = 11_796; // 18% honest number. - pub const SubtensorInitialMinDelegateTake: u16 = 5_898; // 9% - pub const SubtensorInitialDefaultChildKeyTake: u16 = 11_796; // 18% honest number. + pub const SubtensorInitialMinDelegateTake: u16 = 0; // Allow 0% delegate take + pub const SubtensorInitialDefaultChildKeyTake: u16 = 0; // Allow 0% childkey take pub const SubtensorInitialMinChildKeyTake: u16 = 5_898; // 9% pub const SubtensorInitialWeightsVersionKey: u64 = 0; pub const SubtensorInitialMinDifficulty: u64 = 10_000_000; diff --git a/scripts/test_specific.sh b/scripts/test_specific.sh index c5b940f0f..85f3ebe30 100755 --- a/scripts/test_specific.sh +++ b/scripts/test_specific.sh @@ -1,6 +1,4 @@ pallet="${3:-pallet-subtensor}" features="${4:-pow-faucet}" -# RUST_LOG="pallet_subtensor=info" cargo test --release --features=$features -p $pallet --test $1 -- $2 --nocapture --exact - -RUST_LOG=DEBUG cargo test --release --features=$features -p $pallet --test $1 -- $2 --nocapture --exact \ No newline at end of file +SKIP_WASM_BUILD=1 RUST_LOG=DEBUG cargo test --release --features=$features -p $pallet --test $1 -- $2 --nocapture --exact \ No newline at end of file From b1037ab0ff7566ccaea79679d482b19a1def8a18 Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Wed, 31 Jul 2024 12:09:40 +0400 Subject: [PATCH 052/177] chore: clippy --- pallets/subtensor/tests/children.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/pallets/subtensor/tests/children.rs b/pallets/subtensor/tests/children.rs index 0025dd24a..2a15d05d6 100644 --- a/pallets/subtensor/tests/children.rs +++ b/pallets/subtensor/tests/children.rs @@ -1,3 +1,4 @@ +#![allow(clippy::indexing_slicing)] use crate::mock::*; use frame_support::{assert_err, assert_noop, assert_ok}; mod mock; From 531417a2788947fbdfc7773e7ae92fda8d211362 Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Wed, 31 Jul 2024 12:11:44 +0400 Subject: [PATCH 053/177] chore: bump spec --- 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 20d337d64..c7187e0f4 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: 192, + spec_version: 193, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1, From beadf9f51b1a54c472c3afa6a29a51145878c4bd Mon Sep 17 00:00:00 2001 From: John Reed <87283488+JohnReedV@users.noreply.github.com> Date: Wed, 31 Jul 2024 08:49:30 -0700 Subject: [PATCH 054/177] add missing validate tests --- pallets/subtensor/tests/root.rs | 114 +++++++++++++++++++++++++++-- pallets/subtensor/tests/weights.rs | 60 +++++++++++++++ 2 files changed, 169 insertions(+), 5 deletions(-) diff --git a/pallets/subtensor/tests/root.rs b/pallets/subtensor/tests/root.rs index 7c6622670..9e5cdbb3b 100644 --- a/pallets/subtensor/tests/root.rs +++ b/pallets/subtensor/tests/root.rs @@ -1,12 +1,16 @@ #![allow(clippy::indexing_slicing, clippy::unwrap_used)] 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::Error; +use frame_support::{assert_err, assert_ok, dispatch::DispatchInfo}; +use frame_system::{Config, EventRecord, Phase}; +use pallet_subtensor::{ + migration, BaseDifficulty, ColdkeySwapDestinations, Error, MIN_BALANCE_TO_PERFORM_COLDKEY_SWAP, +}; use sp_core::{Get, H256, U256}; +use sp_runtime::{ + traits::{DispatchInfoOf, SignedExtension}, + transaction_validity::{InvalidTransaction, TransactionValidityError}, +}; mod mock; @@ -974,3 +978,103 @@ fn test_dissolve_network_does_not_exist_err() { ); }); } + +#[test] +fn test_dissolve_network_validate() { + 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; + } + } + // Testing the signed extension validate function + // correctly filters the `dissolve_network` transaction. + + new_test_ext(0).execute_with(|| { + let netuid: u16 = 1; + let delegate_coldkey = U256::from(1); + let delegate_hotkey = U256::from(2); + let new_coldkey = U256::from(3); + 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 + let delegator = U256::from(4); + SubtensorModule::add_balance_to_coldkey_account(&delegator, stake_amount); + assert_ok!(SubtensorModule::add_stake( + RuntimeOrigin::signed(delegator), + delegate_hotkey, + stake_amount + )); + + // Ensure the 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()), + ); + + // Schedule coldkey swap + assert_ok!(SubtensorModule::do_schedule_coldkey_swap( + &delegate_coldkey, + &new_coldkey, + work.to_fixed_bytes().to_vec(), + current_block, + nonce, + )); + + // Verify that the swap was scheduled + assert_eq!( + ColdkeySwapDestinations::::get(delegate_coldkey), + vec![new_coldkey] + ); + + // Check if the coldkey is in arbitration + assert!( + SubtensorModule::coldkey_in_arbitration(&delegate_coldkey), + "Delegate coldkey should be in arbitration after swap" + ); + + let who = delegate_coldkey; // The coldkey signs this transaction + let call = RuntimeCall::SubtensorModule(SubtensorCall::dissolve_network { netuid }); + + let info: DispatchInfo = + DispatchInfoOf::<::RuntimeCall>::default(); + + let extension = pallet_subtensor::SubtensorSignedExtension::::new(); + + // Submit to the signed extension validate function + let result_in_arbitration = extension.validate(&who, &call.clone(), &info, 10); + // Should fail with InvalidTransaction::Custom(6) because coldkey is in arbitration + assert_err!( + result_in_arbitration, + TransactionValidityError::Invalid(InvalidTransaction::Custom(6)) + ); + }); +} diff --git a/pallets/subtensor/tests/weights.rs b/pallets/subtensor/tests/weights.rs index c87f818b2..214e3add0 100644 --- a/pallets/subtensor/tests/weights.rs +++ b/pallets/subtensor/tests/weights.rs @@ -259,6 +259,66 @@ fn test_reveal_weights_dispatch_info_ok() { }); } +#[test] +fn test_set_weights_validate() { + // Testing the signed extension validate function + // correctly filters the `set_weights` transaction. + + new_test_ext(0).execute_with(|| { + let netuid: u16 = 1; + let coldkey = U256::from(0); + let hotkey: U256 = U256::from(1); + assert_ne!(hotkey, coldkey); + + let who = hotkey; // The hotkey signs this transaction + + let call = RuntimeCall::SubtensorModule(SubtensorCall::set_weights { + netuid, + dests: vec![1, 1], + weights: vec![1, 1], + version_key: 0, + }); + + // Create netuid + add_network(netuid, 0, 0); + // Register the hotkey + SubtensorModule::append_neuron(netuid, &hotkey, 0); + Owner::::insert(hotkey, coldkey); + + let min_stake = 500_000_000_000; + // Set the minimum stake + SubtensorModule::set_weights_min_stake(min_stake); + + // Verify stake is less than minimum + assert!(SubtensorModule::get_total_stake_for_hotkey(&hotkey) < min_stake); + let info: DispatchInfo = + DispatchInfoOf::<::RuntimeCall>::default(); + + let extension = pallet_subtensor::SubtensorSignedExtension::::new(); + // Submit to the signed extension validate function + let result_no_stake = extension.validate(&who, &call.clone(), &info, 10); + // Should fail due to insufficient stake + assert_err!( + result_no_stake, + TransactionValidityError::Invalid(InvalidTransaction::Custom(3)) + ); + + // Increase the stake to be equal to the minimum + SubtensorModule::increase_stake_on_hotkey_account(&hotkey, min_stake); + + // Verify stake is equal to minimum + assert_eq!( + SubtensorModule::get_total_stake_for_hotkey(&hotkey), + min_stake + ); + + // Submit to the signed extension validate function + let result_min_stake = extension.validate(&who, &call.clone(), &info, 10); + // Now the call should pass + assert_ok!(result_min_stake); + }); +} + #[test] fn test_reveal_weights_validate() { // Testing the signed extension validate function From a125856bb4aec20ab968c8dd3b6460a8c589ff50 Mon Sep 17 00:00:00 2001 From: open-junius Date: Thu, 1 Aug 2024 11:19:24 +0800 Subject: [PATCH 055/177] fix unit test --- pallets/subtensor/Cargo.toml | 4 +- pallets/subtensor/src/macros/config.rs | 2 +- pallets/subtensor/src/macros/dispatches.rs | 29 ++++++-- pallets/subtensor/src/swap/swap_coldkey.rs | 1 + pallets/subtensor/tests/mock.rs | 81 ++++++++++++++++++++-- pallets/subtensor/tests/swap_coldkey.rs | 57 ++++++++------- 6 files changed, 138 insertions(+), 36 deletions(-) diff --git a/pallets/subtensor/Cargo.toml b/pallets/subtensor/Cargo.toml index b002c2371..37c579db0 100644 --- a/pallets/subtensor/Cargo.toml +++ b/pallets/subtensor/Cargo.toml @@ -24,7 +24,7 @@ sp-core = { workspace = true } pallet-balances = { workspace = true } scale-info = { workspace = true, features = ["derive"] } frame-benchmarking = { workspace = true, optional = true } -frame-support = { workspace = true } +frame-support = { workspace = true , features = ["experimental", "tuples-96"]} frame-system = { workspace = true } sp-io = { workspace = true } serde = { workspace = true, features = ["derive"] } @@ -56,6 +56,8 @@ parity-util-mem = { workspace = true, features = ["primitive-types"] } rand = { workspace = true } sp-core = { workspace = true } sp-std = { workspace = true } +pallet-preimage = { workspace = true } +pallet-parameters = { workspace = true } [features] default = ["std"] diff --git a/pallets/subtensor/src/macros/config.rs b/pallets/subtensor/src/macros/config.rs index d2504eb4e..82e3f5afc 100644 --- a/pallets/subtensor/src/macros/config.rs +++ b/pallets/subtensor/src/macros/config.rs @@ -31,7 +31,7 @@ mod config { type TriumvirateInterface: crate::CollectiveInterface; /// The scheduler type used for scheduling delayed calls. - type Scheduler: ScheduleNamed, CallOf, PalletsOriginOf>; + type Scheduler: ScheduleAnon, CallOf, PalletsOriginOf>; /// ================================= /// ==== Initial Value Constants ==== diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 348f57f73..3b1aa4418 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -4,6 +4,7 @@ use frame_support::pallet_macros::pallet_section; /// This can later be imported into the pallet using [`import_section`]. #[pallet_section] mod dispatches { + use frame_support::traits::schedule::v3::Anon as ScheduleAnon; use frame_support::traits::schedule::v3::Named as ScheduleNamed; use frame_support::traits::schedule::DispatchTime; use frame_support::traits::Bounded; @@ -959,7 +960,7 @@ mod dispatches { ); // Calculate the number of blocks in 5 days - let blocks_in_5_days: u32 = 5 * 24 * 60 * 60 / 12; + let blocks_in_5_days: u32 = 2; let current_block = >::block_number(); let when = current_block.saturating_add(BlockNumberFor::::from(blocks_in_5_days)); @@ -976,7 +977,7 @@ mod dispatches { ) .using_encoded(sp_io::hashing::blake2_256); - let hash = , CallOf, PalletsOriginOf, @@ -984,16 +985,34 @@ mod dispatches { let len = call.using_encoded(|e| e.len() as u32); - T::Scheduler::schedule_named( - unique_id, + // fn schedule( + // when: DispatchTime, + // maybe_periodic: Option>, + // priority: Priority, + // origin: Origin, + // call: Bounded, + // ) -> Result; + + T::Scheduler::schedule( DispatchTime::At(when), None, - 63, + 0, + // T::RuntimeOrigin::root(), frame_system::RawOrigin::Root.into(), Bounded::Lookup { hash, len }, ) .map_err(|_| Error::::FailedToSchedule)?; + // T::Scheduler::schedule_named( + // unique_id, + // DispatchTime::At(when), + // None, + // 63, + // frame_system::RawOrigin::Root.into(), + // Bounded::Lookup { hash, len }, + // ) + // .map_err(|_| Error::::FailedToSchedule)?; + ColdkeySwapScheduled::::insert(&who, ()); // Emit the SwapScheduled event Self::deposit_event(Event::ColdkeySwapScheduled { diff --git a/pallets/subtensor/src/swap/swap_coldkey.rs b/pallets/subtensor/src/swap/swap_coldkey.rs index b47b0ac95..5c866e663 100644 --- a/pallets/subtensor/src/swap/swap_coldkey.rs +++ b/pallets/subtensor/src/swap/swap_coldkey.rs @@ -33,6 +33,7 @@ impl Pallet { origin: T::RuntimeOrigin, new_coldkey: &T::AccountId, ) -> DispatchResultWithPostInfo { + log::info!("+++ do_swap_coldkey +++"); // 1. Ensure the origin is signed and get the old coldkey let old_coldkey = ensure_signed(origin)?; diff --git a/pallets/subtensor/tests/mock.rs b/pallets/subtensor/tests/mock.rs index 5503b8190..62deba782 100644 --- a/pallets/subtensor/tests/mock.rs +++ b/pallets/subtensor/tests/mock.rs @@ -5,12 +5,17 @@ use frame_support::weights::constants::RocksDbWeight; // use frame_support::weights::constants::WEIGHT_PER_SECOND; use frame_support::weights::Weight; use frame_support::{ - assert_ok, parameter_types, - traits::{Everything, Hooks, PrivilegeCmp}, + assert_ok, + dynamic_params::{dynamic_pallet_params, dynamic_params}, + parameter_types, + traits::fungible::HoldConsideration, + traits::{Everything, Hooks, LinearStoragePrice, PrivilegeCmp}, }; use frame_system as system; use frame_system::{limits, EnsureNever, EnsureRoot, RawOrigin}; use pallet_collective::MemberCount; +use pallet_parameters; +use pallet_preimage; use sp_core::{Get, H256, U256}; use sp_runtime::Perbill; use sp_runtime::{ @@ -34,6 +39,8 @@ frame_support::construct_runtime!( SubtensorModule: pallet_subtensor::{Pallet, Call, Storage, Event}, Utility: pallet_utility::{Pallet, Call, Storage, Event}, Scheduler: pallet_scheduler::{Pallet, Call, Storage, Event}, + Preimage: pallet_preimage::{Pallet, Call, Storage, Event}, + Parameters: pallet_parameters::{Pallet, Call, Storage, Event}, } ); @@ -69,6 +76,36 @@ pub type Balance = u64; #[allow(dead_code)] pub type BlockNumber = u64; +#[dynamic_params(RuntimeParameters, pallet_parameters::Parameters::)] +pub mod dynamic_params { + use super::*; + + #[dynamic_pallet_params] + #[codec(index = 0)] + pub mod storage { + /// Configures the base deposit of storing some data. + #[codec(index = 0)] + pub static BaseDeposit: Balance = 1; + + /// Configures the per-byte deposit of storing some data. + #[codec(index = 1)] + pub static ByteDeposit: Balance = 1; + } + + #[dynamic_pallet_params] + #[codec(index = 1)] + pub mod contracts { + #[codec(index = 0)] + pub static DepositPerItem: Balance = 1; + + #[codec(index = 1)] + pub static DepositPerByte: Balance = 1; + + #[codec(index = 2)] + pub static DefaultDepositLimit: Balance = 1; + } +} + #[derive_impl(pallet_balances::config_preludes::TestDefaultConfig)] impl pallet_balances::Config for Test { type Balance = Balance; @@ -395,7 +432,7 @@ pub struct OriginPrivilegeCmp; impl PrivilegeCmp for OriginPrivilegeCmp { fn cmp_privilege(_left: &OriginCaller, _right: &OriginCaller) -> Option { - None + Some(Ordering::Less) } } @@ -416,7 +453,7 @@ impl pallet_scheduler::Config for Test { type MaxScheduledPerBlock = MaxScheduledPerBlock; type WeightInfo = pallet_scheduler::weights::SubstrateWeight; type OriginPrivilegeCmp = OriginPrivilegeCmp; - type Preimages = (); + type Preimages = Preimage; } impl pallet_utility::Config for Test { @@ -426,6 +463,34 @@ impl pallet_utility::Config for Test { type WeightInfo = pallet_utility::weights::SubstrateWeight; } +parameter_types! { + pub const PreimageMaxSize: u32 = 4096 * 1024; + pub const PreimageBaseDeposit: Balance = 1; + pub const PreimageByteDeposit: Balance = 1; + // pub const PreimageHoldReason: RuntimeHoldReason = RuntimeHoldReason::Preimage(pallet_preimage::HoldReason::Preimage); +} + +impl pallet_preimage::Config for Test { + type WeightInfo = pallet_preimage::weights::SubstrateWeight; + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type ManagerOrigin = EnsureRoot; + type Consideration = (); + // HoldConsideration< + // AccountId, + // Balances, + // PreimageHoldReason, + // LinearStoragePrice, + // >; +} + +impl pallet_parameters::Config for Test { + type RuntimeParameters = RuntimeParameters; + type RuntimeEvent = RuntimeEvent; + type AdminOrigin = EnsureRoot; + type WeightInfo = (); +} + #[allow(dead_code)] // Build genesis storage according to the mock runtime. pub fn new_test_ext(block_number: BlockNumber) -> sp_io::TestExternalities { @@ -460,22 +525,30 @@ pub fn test_ext_with_balances(balances: Vec<(U256, u128)>) -> sp_io::TestExterna #[allow(dead_code)] pub(crate) fn step_block(n: u16) { for _ in 0..n { + Scheduler::on_finalize(System::block_number()); SubtensorModule::on_finalize(System::block_number()); System::on_finalize(System::block_number()); System::set_block_number(System::block_number() + 1); System::on_initialize(System::block_number()); SubtensorModule::on_initialize(System::block_number()); + Scheduler::on_initialize(System::block_number()); } } #[allow(dead_code)] pub(crate) fn run_to_block(n: u64) { while System::block_number() < n { + Scheduler::on_finalize(System::block_number()); SubtensorModule::on_finalize(System::block_number()); System::on_finalize(System::block_number()); System::set_block_number(System::block_number() + 1); System::on_initialize(System::block_number()); + System::events().iter().for_each(|event| { + log::info!("Event: {:?}", event.event); + }); + System::reset_events(); SubtensorModule::on_initialize(System::block_number()); + Scheduler::on_initialize(System::block_number()); } } diff --git a/pallets/subtensor/tests/swap_coldkey.rs b/pallets/subtensor/tests/swap_coldkey.rs index 8c2bb2330..3ba9a0468 100644 --- a/pallets/subtensor/tests/swap_coldkey.rs +++ b/pallets/subtensor/tests/swap_coldkey.rs @@ -1389,7 +1389,7 @@ fn test_schedule_swap_coldkey_execution() { // Get the scheduled execution block let current_block = System::block_number(); - let blocks_in_5_days = 5 * 24 * 60 * 60 / 12; + let blocks_in_5_days = 2; let execution_block = current_block + blocks_in_5_days; println!("Current block: {}", current_block); @@ -1406,34 +1406,41 @@ fn test_schedule_swap_coldkey_execution() { // Fast forward to the execution block // System::set_block_number(execution_block); - run_to_block(execution_block); + for block_number in current_block..(execution_block + 3) { + log::info!("+++++ Block number: {}", block_number); + // System::events().iter().for_each(|event| { + // log::info!("Event: {:?}", event.event); + // }); + // Preimage::len(); + run_to_block(block_number + 1); + } // Run on_initialize for the execution block SubtensorModule::on_initialize(execution_block); - // // Also run Scheduler's on_initialize - // as OnInitialize>::on_initialize( - // execution_block, - // ); - - // // Check if the swap has occurred - // let new_owner = Owner::::get(hotkey); - // println!("New owner after swap: {:?}", new_owner); - // assert_eq!( - // new_owner, new_coldkey, - // "Ownership was not updated as expected" - // ); - - // assert_eq!( - // Stake::::get(hotkey, new_coldkey), - // stake_amount, - // "Stake was not transferred to new coldkey" - // ); - // assert_eq!( - // Stake::::get(hotkey, old_coldkey), - // 0, - // "Old coldkey still has stake" - // ); + // Also run Scheduler's on_initialize + as OnInitialize>::on_initialize( + execution_block, + ); + + // Check if the swap has occurred + let new_owner = Owner::::get(hotkey); + println!("New owner after swap: {:?}", new_owner); + assert_eq!( + new_owner, new_coldkey, + "Ownership was not updated as expected" + ); + + assert_eq!( + Stake::::get(hotkey, new_coldkey), + stake_amount, + "Stake was not transferred to new coldkey" + ); + assert_eq!( + Stake::::get(hotkey, old_coldkey), + 0, + "Old coldkey still has stake" + ); // Check for the SwapExecuted event }); From 0c1816cfd7b705dd17ffe0902d48b79384f4a361 Mon Sep 17 00:00:00 2001 From: open-junius Date: Thu, 1 Aug 2024 15:41:50 +0800 Subject: [PATCH 056/177] fixed the config level issue --- pallets/subtensor/src/lib.rs | 20 ++++--- pallets/subtensor/src/macros/config.rs | 18 ++++++- pallets/subtensor/src/macros/dispatches.rs | 61 +++++++++++++++------- pallets/subtensor/src/swap/swap_coldkey.rs | 5 +- pallets/subtensor/tests/mock.rs | 2 + pallets/subtensor/tests/swap_coldkey.rs | 6 ++- runtime/src/lib.rs | 2 + 7 files changed, 83 insertions(+), 31 deletions(-) diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index 321e58b4a..34b4ab5b2 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -65,11 +65,13 @@ pub mod pallet { use frame_support::{ dispatch::GetDispatchInfo, pallet_prelude::{DispatchResult, StorageMap, ValueQuery, *}, - traits::{tokens::fungible, OriginTrait, UnfilteredDispatchable}, + traits::{ + tokens::fungible, OriginTrait, QueryPreimage, StorePreimage, UnfilteredDispatchable, + }, }; use frame_system::pallet_prelude::*; use sp_core::H256; - use sp_runtime::traits::TrailingZeroInput; + use sp_runtime::traits::{Dispatchable, TrailingZeroInput}; use sp_std::vec; use sp_std::vec::Vec; @@ -103,6 +105,9 @@ pub mod pallet { /// Struct for Axon. pub type AxonInfoOf = AxonInfo; + /// local one + pub type LocalCallOf = ::RuntimeCall; + /// Data structure for Axon information. #[derive(Encode, Decode, Default, TypeInfo, Clone, PartialEq, Eq, Debug)] pub struct AxonInfo { @@ -1189,7 +1194,8 @@ pub struct SubtensorSignedExtension(pub Phan impl Default for SubtensorSignedExtension where - T::RuntimeCall: Dispatchable, + ::RuntimeCall: + Dispatchable, ::RuntimeCall: IsSubType>, { fn default() -> Self { @@ -1199,7 +1205,8 @@ where impl SubtensorSignedExtension where - T::RuntimeCall: Dispatchable, + ::RuntimeCall: + Dispatchable, ::RuntimeCall: IsSubType>, { pub fn new() -> Self { @@ -1230,14 +1237,15 @@ impl sp_std::fmt::Debug for SubtensorSignedE impl SignedExtension for SubtensorSignedExtension where - T::RuntimeCall: Dispatchable, + ::RuntimeCall: + Dispatchable, ::RuntimeCall: IsSubType>, ::RuntimeCall: IsSubType>, { const IDENTIFIER: &'static str = "SubtensorSignedExtension"; type AccountId = T::AccountId; - type Call = T::RuntimeCall; + type Call = ::RuntimeCall; type AdditionalSigned = (); type Pre = (CallType, u64, Self::AccountId); diff --git a/pallets/subtensor/src/macros/config.rs b/pallets/subtensor/src/macros/config.rs index 82e3f5afc..c333dfed6 100644 --- a/pallets/subtensor/src/macros/config.rs +++ b/pallets/subtensor/src/macros/config.rs @@ -9,6 +9,13 @@ mod config { /// Configure the pallet by specifying the parameters and types on which it depends. #[pallet::config] pub trait Config: frame_system::Config { + /// call type + type RuntimeCall: Parameter + + Dispatchable + + From> + + IsType<::RuntimeCall> + + From>; + /// Because this pallet emits events, it depends on the runtime's definition of an event. type RuntimeEvent: From> + IsType<::RuntimeEvent>; @@ -31,7 +38,16 @@ mod config { type TriumvirateInterface: crate::CollectiveInterface; /// The scheduler type used for scheduling delayed calls. - type Scheduler: ScheduleAnon, CallOf, PalletsOriginOf>; + type Scheduler: ScheduleNamed, LocalCallOf, PalletsOriginOf> + + ScheduleAnon< + BlockNumberFor, + LocalCallOf, + PalletsOriginOf, + Hasher = Self::Hashing, + >; + + /// the preimage to store the call data. + type Preimages: QueryPreimage + StorePreimage; /// ================================= /// ==== Initial Value Constants ==== diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 3b1aa4418..3e3590bf9 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -683,10 +683,10 @@ mod dispatches { new_coldkey: T::AccountId, ) -> DispatchResultWithPostInfo { // Ensure it's called with root privileges (scheduler has root privileges) - ensure_root(origin.clone())?; + // ensure_root(origin.clone())?; let who = ensure_signed(origin)?; - Self::do_swap_coldkey(frame_system::RawOrigin::Signed(who).into(), &new_coldkey) + Self::do_swap_coldkey(&who, &new_coldkey) } /// Unstakes all tokens associated with a hotkey and transfers them to a new coldkey. @@ -969,21 +969,24 @@ mod dispatches { new_coldkey: new_coldkey.clone(), }; - let unique_id = ( - b"schedule_swap_coldkey", - who.clone(), - new_coldkey.clone(), - when, - ) - .using_encoded(sp_io::hashing::blake2_256); + let bound_call = T::Preimages::bound(LocalCallOf::::from(call.clone())) + .map_err(|_| Error::::FailedToSchedule)?; + + // let unique_id = ( + // b"schedule_swap_coldkey", + // who.clone(), + // new_coldkey.clone(), + // when, + // ) + // .using_encoded(sp_io::hashing::blake2_256); - let hash = , - CallOf, - PalletsOriginOf, - >>::Hasher::hash_of(&call); + // let hash = , + // CallOf, + // PalletsOriginOf, + // >>::Hasher::hash_of(&call); - let len = call.using_encoded(|e| e.len() as u32); + // let len = call.using_encoded(|e| e.len() as u32); // fn schedule( // when: DispatchTime, @@ -993,13 +996,33 @@ mod dispatches { // call: Bounded, // ) -> Result; + // T::Scheduler::schedule_named( + // unique_id, + // DispatchTime::At(when), + // None, + // 63, + // frame_system::RawOrigin::Root.into(), + // // bound_call, + // Bounded::Lookup { hash, len }, + // ) + // .map_err(|_| Error::::FailedToSchedule)?; + + // let result = T::Scheduler::schedule( + // DispatchTime::At(when), + // None, + // 128u8, + // frame_system::RawOrigin::Root.into(), + // call, + // ); + T::Scheduler::schedule( DispatchTime::At(when), None, - 0, - // T::RuntimeOrigin::root(), - frame_system::RawOrigin::Root.into(), - Bounded::Lookup { hash, len }, + 63, + // frame_system::RawOrigin::Root.into(), + frame_system::RawOrigin::Signed(who.clone()).into(), + // frame_system::RawOrigin::Signed(&who).into(), + bound_call, ) .map_err(|_| Error::::FailedToSchedule)?; diff --git a/pallets/subtensor/src/swap/swap_coldkey.rs b/pallets/subtensor/src/swap/swap_coldkey.rs index 5c866e663..1b87b386b 100644 --- a/pallets/subtensor/src/swap/swap_coldkey.rs +++ b/pallets/subtensor/src/swap/swap_coldkey.rs @@ -30,12 +30,11 @@ impl Pallet { /// /// Weight is tracked and updated throughout the function execution. pub fn do_swap_coldkey( - origin: T::RuntimeOrigin, + old_coldkey: &T::AccountId, new_coldkey: &T::AccountId, ) -> DispatchResultWithPostInfo { - log::info!("+++ do_swap_coldkey +++"); // 1. Ensure the origin is signed and get the old coldkey - let old_coldkey = ensure_signed(origin)?; + // let old_coldkey = ensure_signed(origin)?; // 2. Initialize the weight for this operation let mut weight: Weight = T::DbWeight::get().reads(2); diff --git a/pallets/subtensor/tests/mock.rs b/pallets/subtensor/tests/mock.rs index 62deba782..c357e0948 100644 --- a/pallets/subtensor/tests/mock.rs +++ b/pallets/subtensor/tests/mock.rs @@ -373,6 +373,7 @@ impl pallet_membership::Config for Test { impl pallet_subtensor::Config for Test { type RuntimeEvent = RuntimeEvent; + type RuntimeCall = RuntimeCall; type Currency = Balances; type InitialIssuance = InitialIssuance; type SudoRuntimeCall = TestRuntimeCall; @@ -426,6 +427,7 @@ impl pallet_subtensor::Config for Test { type LiquidAlphaOn = InitialLiquidAlphaOn; type InitialHotkeyEmissionTempo = InitialHotkeyEmissionTempo; type InitialNetworkMaxStake = InitialNetworkMaxStake; + type Preimages = Preimage; } pub struct OriginPrivilegeCmp; diff --git a/pallets/subtensor/tests/swap_coldkey.rs b/pallets/subtensor/tests/swap_coldkey.rs index 3ba9a0468..b27549a8f 100644 --- a/pallets/subtensor/tests/swap_coldkey.rs +++ b/pallets/subtensor/tests/swap_coldkey.rs @@ -548,7 +548,8 @@ fn test_do_swap_coldkey_success() { // Perform the swap assert_ok!(SubtensorModule::do_swap_coldkey( - <::RuntimeOrigin>::signed(old_coldkey), + // <::RuntimeOrigin>::signed(old_coldkey), + &old_coldkey, &new_coldkey )); @@ -889,7 +890,8 @@ fn test_do_swap_coldkey_with_subnet_ownership() { // Perform the swap assert_ok!(SubtensorModule::do_swap_coldkey( - <::RuntimeOrigin>::signed(old_coldkey), + // <::RuntimeOrigin>::signed(old_coldkey), + &old_coldkey, &new_coldkey )); diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 000e3d7a1..12fb55586 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -894,6 +894,7 @@ parameter_types! { impl pallet_subtensor::Config for Runtime { type RuntimeEvent = RuntimeEvent; + type RuntimeCall = RuntimeCall; type SudoRuntimeCall = RuntimeCall; type Currency = Balances; type CouncilOrigin = EnsureMajoritySenate; @@ -947,6 +948,7 @@ impl pallet_subtensor::Config for Runtime { type LiquidAlphaOn = InitialLiquidAlphaOn; type InitialHotkeyEmissionTempo = SubtensorInitialHotkeyEmissionTempo; type InitialNetworkMaxStake = SubtensorInitialNetworkMaxStake; + type Preimages = Preimage; } use sp_runtime::BoundedVec; From aad89d88aeb8c701f609562ba03b7b22c225cdc0 Mon Sep 17 00:00:00 2001 From: open-junius Date: Thu, 1 Aug 2024 18:35:26 +0800 Subject: [PATCH 057/177] fix compilation --- pallets/subtensor/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/pallets/subtensor/Cargo.toml b/pallets/subtensor/Cargo.toml index 37c579db0..c05b12b2e 100644 --- a/pallets/subtensor/Cargo.toml +++ b/pallets/subtensor/Cargo.toml @@ -57,7 +57,6 @@ rand = { workspace = true } sp-core = { workspace = true } sp-std = { workspace = true } pallet-preimage = { workspace = true } -pallet-parameters = { workspace = true } [features] default = ["std"] From 53ccd943faa6038dfab66dc0bd6cb81370dfa65c Mon Sep 17 00:00:00 2001 From: open-junius Date: Thu, 1 Aug 2024 19:15:53 +0800 Subject: [PATCH 058/177] all unit test passed --- pallets/subtensor/src/macros/dispatches.rs | 69 +++------------------- pallets/subtensor/src/swap/swap_coldkey.rs | 7 +++ pallets/subtensor/tests/mock.rs | 64 ++++++++++---------- pallets/subtensor/tests/swap_coldkey.rs | 29 ++++----- 4 files changed, 58 insertions(+), 111 deletions(-) diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 3e3590bf9..9105dc0ea 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -7,9 +7,7 @@ mod dispatches { use frame_support::traits::schedule::v3::Anon as ScheduleAnon; use frame_support::traits::schedule::v3::Named as ScheduleNamed; use frame_support::traits::schedule::DispatchTime; - use frame_support::traits::Bounded; use frame_system::pallet_prelude::BlockNumberFor; - use sp_runtime::traits::Hash; use sp_runtime::traits::Saturating; /// Dispatchable functions allow users to interact with the pallet and invoke state changes. /// These functions materialize as "extrinsics", which are often compared to transactions. @@ -680,13 +678,14 @@ mod dispatches { .saturating_add(T::DbWeight::get().writes(527)), DispatchClass::Operational, Pays::No))] pub fn swap_coldkey( origin: OriginFor, + old_coldkey: T::AccountId, new_coldkey: T::AccountId, ) -> DispatchResultWithPostInfo { // Ensure it's called with root privileges (scheduler has root privileges) - // ensure_root(origin.clone())?; + ensure_root(origin.clone())?; + log::info!("swap_coldkey: {:?} -> {:?}", old_coldkey, new_coldkey); - let who = ensure_signed(origin)?; - Self::do_swap_coldkey(&who, &new_coldkey) + Self::do_swap_coldkey(&old_coldkey, &new_coldkey) } /// Unstakes all tokens associated with a hotkey and transfers them to a new coldkey. @@ -960,82 +959,28 @@ mod dispatches { ); // Calculate the number of blocks in 5 days - let blocks_in_5_days: u32 = 2; + let blocks_in_5_days: u32 = 5 * 24 * 60 * 60 / 12; let current_block = >::block_number(); let when = current_block.saturating_add(BlockNumberFor::::from(blocks_in_5_days)); let call = Call::::swap_coldkey { + old_coldkey: who.clone(), new_coldkey: new_coldkey.clone(), }; let bound_call = T::Preimages::bound(LocalCallOf::::from(call.clone())) .map_err(|_| Error::::FailedToSchedule)?; - // let unique_id = ( - // b"schedule_swap_coldkey", - // who.clone(), - // new_coldkey.clone(), - // when, - // ) - // .using_encoded(sp_io::hashing::blake2_256); - - // let hash = , - // CallOf, - // PalletsOriginOf, - // >>::Hasher::hash_of(&call); - - // let len = call.using_encoded(|e| e.len() as u32); - - // fn schedule( - // when: DispatchTime, - // maybe_periodic: Option>, - // priority: Priority, - // origin: Origin, - // call: Bounded, - // ) -> Result; - - // T::Scheduler::schedule_named( - // unique_id, - // DispatchTime::At(when), - // None, - // 63, - // frame_system::RawOrigin::Root.into(), - // // bound_call, - // Bounded::Lookup { hash, len }, - // ) - // .map_err(|_| Error::::FailedToSchedule)?; - - // let result = T::Scheduler::schedule( - // DispatchTime::At(when), - // None, - // 128u8, - // frame_system::RawOrigin::Root.into(), - // call, - // ); - T::Scheduler::schedule( DispatchTime::At(when), None, 63, - // frame_system::RawOrigin::Root.into(), - frame_system::RawOrigin::Signed(who.clone()).into(), - // frame_system::RawOrigin::Signed(&who).into(), + frame_system::RawOrigin::Root.into(), bound_call, ) .map_err(|_| Error::::FailedToSchedule)?; - // T::Scheduler::schedule_named( - // unique_id, - // DispatchTime::At(when), - // None, - // 63, - // frame_system::RawOrigin::Root.into(), - // Bounded::Lookup { hash, len }, - // ) - // .map_err(|_| Error::::FailedToSchedule)?; - ColdkeySwapScheduled::::insert(&who, ()); // Emit the SwapScheduled event Self::deposit_event(Event::ColdkeySwapScheduled { diff --git a/pallets/subtensor/src/swap/swap_coldkey.rs b/pallets/subtensor/src/swap/swap_coldkey.rs index 1b87b386b..c76da4ef2 100644 --- a/pallets/subtensor/src/swap/swap_coldkey.rs +++ b/pallets/subtensor/src/swap/swap_coldkey.rs @@ -39,17 +39,22 @@ impl Pallet { // 2. Initialize the weight for this operation let mut weight: Weight = T::DbWeight::get().reads(2); + log::info!("do_swap_coldkey old_coldkey: {:?}", old_coldkey); + // 3. Ensure the new coldkey is not associated with any hotkeys ensure!( StakingHotkeys::::get(new_coldkey).is_empty(), Error::::ColdKeyAlreadyAssociated ); + log::info!("do_swap_coldkey ColdKeyAlreadyAssociated"); + // 4. Ensure the new coldkey is not a hotkey ensure!( !Self::hotkey_account_exists(new_coldkey), Error::::ColdKeyAlreadyAssociated ); + log::info!("do_swap_coldkey ColdKeyAlreadyAssociated 2"); // 5. Calculate the swap cost and ensure sufficient balance let swap_cost = Self::get_key_swap_cost(); @@ -58,6 +63,7 @@ impl Pallet { Self::can_remove_balance_from_coldkey_account(&old_coldkey, swap_cost), Error::::NotEnoughBalanceToPaySwapColdKey ); + log::info!("do_swap_coldkey NotEnoughBalanceToPaySwapColdKey"); // 6. Remove and burn the swap cost from the old coldkey's account let actual_burn_amount = @@ -69,6 +75,7 @@ impl Pallet { // 8. Perform the actual coldkey swap let _ = Self::perform_swap_coldkey(&old_coldkey, new_coldkey, &mut weight); + log::info!("do_swap_coldkey perform_swap_coldkey"); // 9. Update the last transaction block for the new coldkey Self::set_last_tx_block(new_coldkey, Self::get_current_block_as_u64()); diff --git a/pallets/subtensor/tests/mock.rs b/pallets/subtensor/tests/mock.rs index c357e0948..e1c5f07d7 100644 --- a/pallets/subtensor/tests/mock.rs +++ b/pallets/subtensor/tests/mock.rs @@ -14,7 +14,7 @@ use frame_support::{ use frame_system as system; use frame_system::{limits, EnsureNever, EnsureRoot, RawOrigin}; use pallet_collective::MemberCount; -use pallet_parameters; +// use pallet_parameters; use pallet_preimage; use sp_core::{Get, H256, U256}; use sp_runtime::Perbill; @@ -40,7 +40,7 @@ frame_support::construct_runtime!( Utility: pallet_utility::{Pallet, Call, Storage, Event}, Scheduler: pallet_scheduler::{Pallet, Call, Storage, Event}, Preimage: pallet_preimage::{Pallet, Call, Storage, Event}, - Parameters: pallet_parameters::{Pallet, Call, Storage, Event}, + // Parameters: pallet_parameters::{Pallet, Call, Storage, Event}, } ); @@ -76,35 +76,35 @@ pub type Balance = u64; #[allow(dead_code)] pub type BlockNumber = u64; -#[dynamic_params(RuntimeParameters, pallet_parameters::Parameters::)] -pub mod dynamic_params { - use super::*; +// #[dynamic_params(RuntimeParameters, pallet_parameters::Parameters::)] +// pub mod dynamic_params { +// use super::*; - #[dynamic_pallet_params] - #[codec(index = 0)] - pub mod storage { - /// Configures the base deposit of storing some data. - #[codec(index = 0)] - pub static BaseDeposit: Balance = 1; +// #[dynamic_pallet_params] +// #[codec(index = 0)] +// pub mod storage { +// /// Configures the base deposit of storing some data. +// #[codec(index = 0)] +// pub static BaseDeposit: Balance = 1; - /// Configures the per-byte deposit of storing some data. - #[codec(index = 1)] - pub static ByteDeposit: Balance = 1; - } +// /// Configures the per-byte deposit of storing some data. +// #[codec(index = 1)] +// pub static ByteDeposit: Balance = 1; +// } - #[dynamic_pallet_params] - #[codec(index = 1)] - pub mod contracts { - #[codec(index = 0)] - pub static DepositPerItem: Balance = 1; +// #[dynamic_pallet_params] +// #[codec(index = 1)] +// pub mod contracts { +// #[codec(index = 0)] +// pub static DepositPerItem: Balance = 1; - #[codec(index = 1)] - pub static DepositPerByte: Balance = 1; +// #[codec(index = 1)] +// pub static DepositPerByte: Balance = 1; - #[codec(index = 2)] - pub static DefaultDepositLimit: Balance = 1; - } -} +// #[codec(index = 2)] +// pub static DefaultDepositLimit: Balance = 1; +// } +// } #[derive_impl(pallet_balances::config_preludes::TestDefaultConfig)] impl pallet_balances::Config for Test { @@ -486,12 +486,12 @@ impl pallet_preimage::Config for Test { // >; } -impl pallet_parameters::Config for Test { - type RuntimeParameters = RuntimeParameters; - type RuntimeEvent = RuntimeEvent; - type AdminOrigin = EnsureRoot; - type WeightInfo = (); -} +// impl pallet_parameters::Config for Test { +// type RuntimeParameters = RuntimeParameters; +// type RuntimeEvent = RuntimeEvent; +// type AdminOrigin = EnsureRoot; +// type WeightInfo = (); +// } #[allow(dead_code)] // Build genesis storage according to the mock runtime. diff --git a/pallets/subtensor/tests/swap_coldkey.rs b/pallets/subtensor/tests/swap_coldkey.rs index b27549a8f..cfc2d0098 100644 --- a/pallets/subtensor/tests/swap_coldkey.rs +++ b/pallets/subtensor/tests/swap_coldkey.rs @@ -1352,7 +1352,7 @@ fn test_schedule_swap_coldkey_duplicate() { <::RuntimeOrigin>::signed(old_coldkey), new_coldkey ), - Error::::FailedToSchedule + Error::::SwapAlreadyScheduled ); }); } @@ -1369,7 +1369,7 @@ fn test_schedule_swap_coldkey_execution() { add_network(netuid, 13, 0); register_ok_neuron(netuid, hotkey, old_coldkey, 0); - SubtensorModule::add_balance_to_coldkey_account(&old_coldkey, 1000); + SubtensorModule::add_balance_to_coldkey_account(&old_coldkey, 1000000000000000); assert_ok!(SubtensorModule::add_stake( <::RuntimeOrigin>::signed(old_coldkey), hotkey, @@ -1391,12 +1391,9 @@ fn test_schedule_swap_coldkey_execution() { // Get the scheduled execution block let current_block = System::block_number(); - let blocks_in_5_days = 2; + let blocks_in_5_days = 5 * 24 * 60 * 60 / 12; let execution_block = current_block + blocks_in_5_days; - println!("Current block: {}", current_block); - println!("Execution block: {}", execution_block); - System::assert_last_event( Event::ColdkeySwapScheduled { old_coldkey, @@ -1406,16 +1403,7 @@ fn test_schedule_swap_coldkey_execution() { .into(), ); - // Fast forward to the execution block - // System::set_block_number(execution_block); - for block_number in current_block..(execution_block + 3) { - log::info!("+++++ Block number: {}", block_number); - // System::events().iter().for_each(|event| { - // log::info!("Event: {:?}", event.event); - // }); - // Preimage::len(); - run_to_block(block_number + 1); - } + run_to_block(execution_block); // Run on_initialize for the execution block SubtensorModule::on_initialize(execution_block); @@ -1427,7 +1415,6 @@ fn test_schedule_swap_coldkey_execution() { // Check if the swap has occurred let new_owner = Owner::::get(hotkey); - println!("New owner after swap: {:?}", new_owner); assert_eq!( new_owner, new_coldkey, "Ownership was not updated as expected" @@ -1445,6 +1432,13 @@ fn test_schedule_swap_coldkey_execution() { ); // Check for the SwapExecuted event + System::assert_last_event( + Event::ColdkeySwapped { + old_coldkey, + new_coldkey, + } + .into(), + ); }); } @@ -1458,6 +1452,7 @@ fn test_direct_swap_coldkey_call_fails() { assert_noop!( SubtensorModule::swap_coldkey( <::RuntimeOrigin>::signed(old_coldkey), + old_coldkey, new_coldkey ), BadOrigin From 2f83b84e726b22e5171d6bfcacc211db4bcf2dbf Mon Sep 17 00:00:00 2001 From: open-junius Date: Thu, 1 Aug 2024 19:19:19 +0800 Subject: [PATCH 059/177] clean up code --- pallets/subtensor/src/swap/swap_coldkey.rs | 20 ++-------- pallets/subtensor/tests/mock.rs | 45 ---------------------- 2 files changed, 4 insertions(+), 61 deletions(-) diff --git a/pallets/subtensor/src/swap/swap_coldkey.rs b/pallets/subtensor/src/swap/swap_coldkey.rs index c76da4ef2..2b54d4313 100644 --- a/pallets/subtensor/src/swap/swap_coldkey.rs +++ b/pallets/subtensor/src/swap/swap_coldkey.rs @@ -33,56 +33,44 @@ impl Pallet { old_coldkey: &T::AccountId, new_coldkey: &T::AccountId, ) -> DispatchResultWithPostInfo { - // 1. Ensure the origin is signed and get the old coldkey - // let old_coldkey = ensure_signed(origin)?; - // 2. Initialize the weight for this operation let mut weight: Weight = T::DbWeight::get().reads(2); - log::info!("do_swap_coldkey old_coldkey: {:?}", old_coldkey); - // 3. Ensure the new coldkey is not associated with any hotkeys ensure!( StakingHotkeys::::get(new_coldkey).is_empty(), Error::::ColdKeyAlreadyAssociated ); - log::info!("do_swap_coldkey ColdKeyAlreadyAssociated"); - // 4. Ensure the new coldkey is not a hotkey ensure!( !Self::hotkey_account_exists(new_coldkey), Error::::ColdKeyAlreadyAssociated ); - log::info!("do_swap_coldkey ColdKeyAlreadyAssociated 2"); // 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!( - Self::can_remove_balance_from_coldkey_account(&old_coldkey, swap_cost), + Self::can_remove_balance_from_coldkey_account(old_coldkey, swap_cost), Error::::NotEnoughBalanceToPaySwapColdKey ); - log::info!("do_swap_coldkey NotEnoughBalanceToPaySwapColdKey"); // 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)?; + let actual_burn_amount = Self::remove_balance_from_coldkey_account(old_coldkey, swap_cost)?; Self::burn_tokens(actual_burn_amount); // 7. Update the weight for the balance operations weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); // 8. Perform the actual coldkey swap - let _ = Self::perform_swap_coldkey(&old_coldkey, new_coldkey, &mut weight); - log::info!("do_swap_coldkey perform_swap_coldkey"); + let _ = Self::perform_swap_coldkey(old_coldkey, new_coldkey, &mut weight); // 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)); // 10. Remove the coldkey swap scheduled record - ColdkeySwapScheduled::::remove(&old_coldkey); + ColdkeySwapScheduled::::remove(old_coldkey); // 11. Emit the ColdkeySwapped event Self::deposit_event(Event::ColdkeySwapped { diff --git a/pallets/subtensor/tests/mock.rs b/pallets/subtensor/tests/mock.rs index e1c5f07d7..d6b45c63f 100644 --- a/pallets/subtensor/tests/mock.rs +++ b/pallets/subtensor/tests/mock.rs @@ -40,7 +40,6 @@ frame_support::construct_runtime!( Utility: pallet_utility::{Pallet, Call, Storage, Event}, Scheduler: pallet_scheduler::{Pallet, Call, Storage, Event}, Preimage: pallet_preimage::{Pallet, Call, Storage, Event}, - // Parameters: pallet_parameters::{Pallet, Call, Storage, Event}, } ); @@ -76,36 +75,6 @@ pub type Balance = u64; #[allow(dead_code)] pub type BlockNumber = u64; -// #[dynamic_params(RuntimeParameters, pallet_parameters::Parameters::)] -// pub mod dynamic_params { -// use super::*; - -// #[dynamic_pallet_params] -// #[codec(index = 0)] -// pub mod storage { -// /// Configures the base deposit of storing some data. -// #[codec(index = 0)] -// pub static BaseDeposit: Balance = 1; - -// /// Configures the per-byte deposit of storing some data. -// #[codec(index = 1)] -// pub static ByteDeposit: Balance = 1; -// } - -// #[dynamic_pallet_params] -// #[codec(index = 1)] -// pub mod contracts { -// #[codec(index = 0)] -// pub static DepositPerItem: Balance = 1; - -// #[codec(index = 1)] -// pub static DepositPerByte: Balance = 1; - -// #[codec(index = 2)] -// pub static DefaultDepositLimit: Balance = 1; -// } -// } - #[derive_impl(pallet_balances::config_preludes::TestDefaultConfig)] impl pallet_balances::Config for Test { type Balance = Balance; @@ -117,7 +86,6 @@ impl pallet_balances::Config for Test { type WeightInfo = (); type MaxReserves = (); type ReserveIdentifier = (); - type RuntimeHoldReason = (); type FreezeIdentifier = (); type MaxFreezes = (); @@ -478,21 +446,8 @@ impl pallet_preimage::Config for Test { type Currency = Balances; type ManagerOrigin = EnsureRoot; type Consideration = (); - // HoldConsideration< - // AccountId, - // Balances, - // PreimageHoldReason, - // LinearStoragePrice, - // >; } -// impl pallet_parameters::Config for Test { -// type RuntimeParameters = RuntimeParameters; -// type RuntimeEvent = RuntimeEvent; -// type AdminOrigin = EnsureRoot; -// type WeightInfo = (); -// } - #[allow(dead_code)] // Build genesis storage according to the mock runtime. pub fn new_test_ext(block_number: BlockNumber) -> sp_io::TestExternalities { From d80a92889adc893716440250c7ee48e3197b7c96 Mon Sep 17 00:00:00 2001 From: open-junius Date: Thu, 1 Aug 2024 19:31:18 +0800 Subject: [PATCH 060/177] fix clippy --- pallets/subtensor/tests/mock.rs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/pallets/subtensor/tests/mock.rs b/pallets/subtensor/tests/mock.rs index d6b45c63f..328b6e5c7 100644 --- a/pallets/subtensor/tests/mock.rs +++ b/pallets/subtensor/tests/mock.rs @@ -2,20 +2,14 @@ use frame_support::derive_impl; use frame_support::dispatch::DispatchResultWithPostInfo; use frame_support::weights::constants::RocksDbWeight; -// use frame_support::weights::constants::WEIGHT_PER_SECOND; use frame_support::weights::Weight; use frame_support::{ - assert_ok, - dynamic_params::{dynamic_pallet_params, dynamic_params}, - parameter_types, - traits::fungible::HoldConsideration, - traits::{Everything, Hooks, LinearStoragePrice, PrivilegeCmp}, + assert_ok, parameter_types, + traits::{Everything, Hooks, PrivilegeCmp}, }; use frame_system as system; use frame_system::{limits, EnsureNever, EnsureRoot, RawOrigin}; use pallet_collective::MemberCount; -// use pallet_parameters; -use pallet_preimage; use sp_core::{Get, H256, U256}; use sp_runtime::Perbill; use sp_runtime::{ From 1633b6c98b7d037c1ead9cff69ad90a041a6cd54 Mon Sep 17 00:00:00 2001 From: open-junius Date: Thu, 1 Aug 2024 19:40:17 +0800 Subject: [PATCH 061/177] fix admin test --- pallets/admin-utils/tests/mock.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pallets/admin-utils/tests/mock.rs b/pallets/admin-utils/tests/mock.rs index 4b08c578b..3f3ef843d 100644 --- a/pallets/admin-utils/tests/mock.rs +++ b/pallets/admin-utils/tests/mock.rs @@ -122,6 +122,7 @@ parameter_types! { impl pallet_subtensor::Config for Test { type RuntimeEvent = RuntimeEvent; + type RuntimeCall = RuntimeCall; type Currency = Balances; type InitialIssuance = InitialIssuance; type SudoRuntimeCall = TestRuntimeCall; @@ -175,6 +176,7 @@ impl pallet_subtensor::Config for Test { type LiquidAlphaOn = InitialLiquidAlphaOn; type InitialHotkeyEmissionTempo = InitialHotkeyEmissionTempo; type InitialNetworkMaxStake = InitialNetworkMaxStake; + type Preimages = (); } #[derive_impl(frame_system::config_preludes::TestDefaultConfig)] From 49bd0c553702f6b3e7e9b9654bd5103806c78efd Mon Sep 17 00:00:00 2001 From: open-junius Date: Thu, 1 Aug 2024 20:08:33 +0800 Subject: [PATCH 062/177] fix test --- pallets/subtensor/tests/swap_coldkey.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/subtensor/tests/swap_coldkey.rs b/pallets/subtensor/tests/swap_coldkey.rs index cfc2d0098..5a576fd2d 100644 --- a/pallets/subtensor/tests/swap_coldkey.rs +++ b/pallets/subtensor/tests/swap_coldkey.rs @@ -1432,7 +1432,7 @@ fn test_schedule_swap_coldkey_execution() { ); // Check for the SwapExecuted event - System::assert_last_event( + System::assert_has_event( Event::ColdkeySwapped { old_coldkey, new_coldkey, From 0f2fa057419a7a726df656b0da29699010034f52 Mon Sep 17 00:00:00 2001 From: open-junius Date: Thu, 1 Aug 2024 20:46:29 +0800 Subject: [PATCH 063/177] remove unneeded feature --- pallets/subtensor/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/subtensor/Cargo.toml b/pallets/subtensor/Cargo.toml index c05b12b2e..d7a9bc06c 100644 --- a/pallets/subtensor/Cargo.toml +++ b/pallets/subtensor/Cargo.toml @@ -24,7 +24,7 @@ sp-core = { workspace = true } pallet-balances = { workspace = true } scale-info = { workspace = true, features = ["derive"] } frame-benchmarking = { workspace = true, optional = true } -frame-support = { workspace = true , features = ["experimental", "tuples-96"]} +frame-support = { workspace = true } frame-system = { workspace = true } sp-io = { workspace = true } serde = { workspace = true, features = ["derive"] } From 59dc95cf5a189dc7dafef622ce4986dc7656ffe9 Mon Sep 17 00:00:00 2001 From: open-junius Date: Thu, 1 Aug 2024 20:52:46 +0800 Subject: [PATCH 064/177] clean up code --- pallets/subtensor/src/macros/config.rs | 13 ++++++------- pallets/subtensor/src/macros/dispatches.rs | 1 - pallets/subtensor/tests/mock.rs | 1 - pallets/subtensor/tests/swap_coldkey.rs | 6 +----- 4 files changed, 7 insertions(+), 14 deletions(-) diff --git a/pallets/subtensor/src/macros/config.rs b/pallets/subtensor/src/macros/config.rs index c333dfed6..2f924905d 100644 --- a/pallets/subtensor/src/macros/config.rs +++ b/pallets/subtensor/src/macros/config.rs @@ -38,13 +38,12 @@ mod config { type TriumvirateInterface: crate::CollectiveInterface; /// The scheduler type used for scheduling delayed calls. - type Scheduler: ScheduleNamed, LocalCallOf, PalletsOriginOf> - + ScheduleAnon< - BlockNumberFor, - LocalCallOf, - PalletsOriginOf, - Hasher = Self::Hashing, - >; + type Scheduler: ScheduleAnon< + BlockNumberFor, + LocalCallOf, + PalletsOriginOf, + Hasher = Self::Hashing, + >; /// the preimage to store the call data. type Preimages: QueryPreimage + StorePreimage; diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 9105dc0ea..011fdfe83 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -5,7 +5,6 @@ use frame_support::pallet_macros::pallet_section; #[pallet_section] mod dispatches { use frame_support::traits::schedule::v3::Anon as ScheduleAnon; - use frame_support::traits::schedule::v3::Named as ScheduleNamed; use frame_support::traits::schedule::DispatchTime; use frame_system::pallet_prelude::BlockNumberFor; use sp_runtime::traits::Saturating; diff --git a/pallets/subtensor/tests/mock.rs b/pallets/subtensor/tests/mock.rs index 328b6e5c7..3497b6d67 100644 --- a/pallets/subtensor/tests/mock.rs +++ b/pallets/subtensor/tests/mock.rs @@ -431,7 +431,6 @@ parameter_types! { pub const PreimageMaxSize: u32 = 4096 * 1024; pub const PreimageBaseDeposit: Balance = 1; pub const PreimageByteDeposit: Balance = 1; - // pub const PreimageHoldReason: RuntimeHoldReason = RuntimeHoldReason::Preimage(pallet_preimage::HoldReason::Preimage); } impl pallet_preimage::Config for Test { diff --git a/pallets/subtensor/tests/swap_coldkey.rs b/pallets/subtensor/tests/swap_coldkey.rs index 5a576fd2d..48168addc 100644 --- a/pallets/subtensor/tests/swap_coldkey.rs +++ b/pallets/subtensor/tests/swap_coldkey.rs @@ -889,11 +889,7 @@ fn test_do_swap_coldkey_with_subnet_ownership() { OwnedHotkeys::::insert(old_coldkey, vec![hotkey]); // Perform the swap - assert_ok!(SubtensorModule::do_swap_coldkey( - // <::RuntimeOrigin>::signed(old_coldkey), - &old_coldkey, - &new_coldkey - )); + assert_ok!(SubtensorModule::do_swap_coldkey(&old_coldkey, &new_coldkey)); // Verify subnet ownership transfer assert_eq!(SubnetOwner::::get(netuid), new_coldkey); From 9250464572a049778042d391b9c695f8766414f7 Mon Sep 17 00:00:00 2001 From: open-junius Date: Fri, 2 Aug 2024 13:44:36 +0800 Subject: [PATCH 065/177] update feature dependency --- Cargo.lock | 36 ++++++++++++++++++---------------- pallets/admin-utils/Cargo.toml | 4 +++- pallets/subtensor/Cargo.toml | 6 +++++- 3 files changed, 27 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ea30f4e25..d8959b99b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1198,7 +1198,7 @@ dependencies = [ [[package]] name = "common" version = "0.1.0" -source = "git+https://github.com/w3f/ring-proof#b273d33f9981e2bb3375ab45faeb537f7ee35224" +source = "git+https://github.com/w3f/ring-proof#665f5f51af5734c7b6d90b985dd6861d4c5b4752" dependencies = [ "ark-ec", "ark-ff", @@ -4150,9 +4150,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.21" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "lru" @@ -5266,6 +5266,7 @@ dependencies = [ "pallet-balances", "pallet-collective", "pallet-membership", + "pallet-preimage", "pallet-scheduler", "pallet-transaction-payment", "pallet-utility", @@ -6433,13 +6434,14 @@ dependencies = [ [[package]] name = "ring" version = "0.1.0" -source = "git+https://github.com/w3f/ring-proof#b273d33f9981e2bb3375ab45faeb537f7ee35224" +source = "git+https://github.com/w3f/ring-proof#665f5f51af5734c7b6d90b985dd6861d4c5b4752" dependencies = [ "ark-ec", "ark-ff", "ark-poly", "ark-serialize", "ark-std", + "arrayvec", "blake2 0.10.6", "common", "fflonk", @@ -7908,9 +7910,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.203" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" dependencies = [ "serde_derive", ] @@ -7935,9 +7937,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.203" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", @@ -8408,7 +8410,7 @@ dependencies = [ [[package]] name = "sp-crypto-ec-utils" version = "0.10.0" -source = "git+https://github.com/paritytech/polkadot-sdk#c4b3c1c6c6e492c4196e06fbba824a58e8119a3b" +source = "git+https://github.com/paritytech/polkadot-sdk#6a5b6e03bfc8d0c6f5f05f3180313902c15aee84" dependencies = [ "ark-bls12-377", "ark-bls12-377-ext", @@ -8470,7 +8472,7 @@ dependencies = [ [[package]] name = "sp-debug-derive" version = "14.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#c4b3c1c6c6e492c4196e06fbba824a58e8119a3b" +source = "git+https://github.com/paritytech/polkadot-sdk#6a5b6e03bfc8d0c6f5f05f3180313902c15aee84" dependencies = [ "proc-macro2", "quote", @@ -8490,7 +8492,7 @@ dependencies = [ [[package]] name = "sp-externalities" version = "0.25.0" -source = "git+https://github.com/paritytech/polkadot-sdk#c4b3c1c6c6e492c4196e06fbba824a58e8119a3b" +source = "git+https://github.com/paritytech/polkadot-sdk#6a5b6e03bfc8d0c6f5f05f3180313902c15aee84" dependencies = [ "environmental", "parity-scale-codec", @@ -8673,7 +8675,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface" version = "24.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#c4b3c1c6c6e492c4196e06fbba824a58e8119a3b" +source = "git+https://github.com/paritytech/polkadot-sdk#6a5b6e03bfc8d0c6f5f05f3180313902c15aee84" dependencies = [ "bytes", "impl-trait-for-tuples", @@ -8705,7 +8707,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" version = "17.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#c4b3c1c6c6e492c4196e06fbba824a58e8119a3b" +source = "git+https://github.com/paritytech/polkadot-sdk#6a5b6e03bfc8d0c6f5f05f3180313902c15aee84" dependencies = [ "Inflector", "expander", @@ -8794,7 +8796,7 @@ source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2 [[package]] name = "sp-std" version = "14.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#c4b3c1c6c6e492c4196e06fbba824a58e8119a3b" +source = "git+https://github.com/paritytech/polkadot-sdk#6a5b6e03bfc8d0c6f5f05f3180313902c15aee84" [[package]] name = "sp-storage" @@ -8811,7 +8813,7 @@ dependencies = [ [[package]] name = "sp-storage" version = "19.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#c4b3c1c6c6e492c4196e06fbba824a58e8119a3b" +source = "git+https://github.com/paritytech/polkadot-sdk#6a5b6e03bfc8d0c6f5f05f3180313902c15aee84" dependencies = [ "impl-serde", "parity-scale-codec", @@ -8846,7 +8848,7 @@ dependencies = [ [[package]] name = "sp-tracing" version = "16.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#c4b3c1c6c6e492c4196e06fbba824a58e8119a3b" +source = "git+https://github.com/paritytech/polkadot-sdk#6a5b6e03bfc8d0c6f5f05f3180313902c15aee84" dependencies = [ "parity-scale-codec", "tracing", @@ -8943,7 +8945,7 @@ dependencies = [ [[package]] name = "sp-wasm-interface" version = "20.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#c4b3c1c6c6e492c4196e06fbba824a58e8119a3b" +source = "git+https://github.com/paritytech/polkadot-sdk#6a5b6e03bfc8d0c6f5f05f3180313902c15aee84" dependencies = [ "impl-trait-for-tuples", "log", diff --git a/pallets/admin-utils/Cargo.toml b/pallets/admin-utils/Cargo.toml index 97371a79f..ff54989cd 100644 --- a/pallets/admin-utils/Cargo.toml +++ b/pallets/admin-utils/Cargo.toml @@ -65,12 +65,14 @@ runtime-benchmarks = [ "frame-system/runtime-benchmarks", "pallet-balances/runtime-benchmarks", "sp-runtime/runtime-benchmarks", - "pallet-subtensor/runtime-benchmarks" + "pallet-subtensor/runtime-benchmarks", + "pallet-scheduler/runtime-benchmarks", ] try-runtime = [ "frame-support/try-runtime", "frame-system/try-runtime", "pallet-balances/try-runtime", + "pallet-scheduler/try-runtime", "sp-runtime/try-runtime", "pallet-subtensor/try-runtime" ] diff --git a/pallets/subtensor/Cargo.toml b/pallets/subtensor/Cargo.toml index d7a9bc06c..2baee6127 100644 --- a/pallets/subtensor/Cargo.toml +++ b/pallets/subtensor/Cargo.toml @@ -95,13 +95,17 @@ runtime-benchmarks = [ "pallet-membership/runtime-benchmarks", "pallet-utility/runtime-benchmarks", "sp-runtime/runtime-benchmarks", - "pallet-collective/runtime-benchmarks" + "pallet-collective/runtime-benchmarks", + "pallet-preimage/runtime-benchmarks", + "pallet-scheduler/runtime-benchmarks", ] try-runtime = [ "frame-support/try-runtime", "frame-system/try-runtime", "pallet-balances/try-runtime", "pallet-membership/try-runtime", + "pallet-preimage/try-runtime", + "pallet-scheduler/try-runtime", "pallet-transaction-payment/try-runtime", "pallet-utility/try-runtime", "sp-runtime/try-runtime", From 93644925bebcf5091704cf23f1bd0008bb1b37a7 Mon Sep 17 00:00:00 2001 From: Keith Date: Fri, 2 Aug 2024 15:43:45 +0900 Subject: [PATCH 066/177] Replace SubtensorInterface with tight pallet coupling --- pallets/admin-utils/src/lib.rs | 302 +++++++++++++-------------------- runtime/src/lib.rs | 279 ------------------------------ 2 files changed, 114 insertions(+), 467 deletions(-) diff --git a/pallets/admin-utils/src/lib.rs b/pallets/admin-utils/src/lib.rs index 9a8744dc6..60209de7d 100644 --- a/pallets/admin-utils/src/lib.rs +++ b/pallets/admin-utils/src/lib.rs @@ -4,7 +4,6 @@ pub use pallet::*; pub mod weights; pub use weights::WeightInfo; -use sp_runtime::DispatchError; use sp_runtime::{traits::Member, RuntimeAppPublic}; mod benchmarking; @@ -26,7 +25,7 @@ pub mod pallet { /// Configure the pallet by specifying the parameters and types on which it depends. #[pallet::config] - pub trait Config: frame_system::Config { + pub trait Config: frame_system::Config + pallet_subtensor::pallet::Config { /// Because this pallet emits events, it depends on the runtime's definition of an event. type RuntimeEvent: From> + IsType<::RuntimeEvent>; @@ -48,13 +47,6 @@ pub mod pallet { /// Unit of assets type Balance: Balance; - - /// Implementation of the subtensor interface - type Subtensor: crate::SubtensorInterface< - Self::AccountId, - Self::Balance, - Self::RuntimeOrigin, - >; } #[pallet::event] @@ -100,7 +92,7 @@ pub mod pallet { #[pallet::weight(T::WeightInfo::sudo_set_default_take())] pub fn sudo_set_default_take(origin: OriginFor, default_take: u16) -> DispatchResult { ensure_root(origin)?; - T::Subtensor::set_max_delegate_take(default_take); + pallet_subtensor::Pallet::::set_max_delegate_take(default_take); log::info!("DefaultTakeSet( default_take: {:?} ) ", default_take); Ok(()) } @@ -112,7 +104,7 @@ pub mod pallet { #[pallet::weight((0, DispatchClass::Operational, Pays::No))] pub fn sudo_set_tx_rate_limit(origin: OriginFor, tx_rate_limit: u64) -> DispatchResult { ensure_root(origin)?; - T::Subtensor::set_tx_rate_limit(tx_rate_limit); + pallet_subtensor::Pallet::::set_tx_rate_limit(tx_rate_limit); log::info!("TxRateLimitSet( tx_rate_limit: {:?} ) ", tx_rate_limit); Ok(()) } @@ -127,9 +119,9 @@ pub mod pallet { netuid: u16, serving_rate_limit: u64, ) -> DispatchResult { - T::Subtensor::ensure_subnet_owner_or_root(origin, netuid)?; + pallet_subtensor::Pallet::::ensure_subnet_owner_or_root(origin, netuid)?; - T::Subtensor::set_serving_rate_limit(netuid, serving_rate_limit); + pallet_subtensor::Pallet::::set_serving_rate_limit(netuid, serving_rate_limit); log::info!( "ServingRateLimitSet( serving_rate_limit: {:?} ) ", serving_rate_limit @@ -147,13 +139,13 @@ pub mod pallet { netuid: u16, min_difficulty: u64, ) -> DispatchResult { - T::Subtensor::ensure_subnet_owner_or_root(origin, netuid)?; + pallet_subtensor::Pallet::::ensure_subnet_owner_or_root(origin, netuid)?; ensure!( - T::Subtensor::if_subnet_exist(netuid), + pallet_subtensor::Pallet::::if_subnet_exist(netuid), Error::::SubnetDoesNotExist ); - T::Subtensor::set_min_difficulty(netuid, min_difficulty); + pallet_subtensor::Pallet::::set_min_difficulty(netuid, min_difficulty); log::info!( "MinDifficultySet( netuid: {:?} min_difficulty: {:?} ) ", netuid, @@ -172,13 +164,13 @@ pub mod pallet { netuid: u16, max_difficulty: u64, ) -> DispatchResult { - T::Subtensor::ensure_subnet_owner_or_root(origin, netuid)?; + pallet_subtensor::Pallet::::ensure_subnet_owner_or_root(origin, netuid)?; ensure!( - T::Subtensor::if_subnet_exist(netuid), + pallet_subtensor::Pallet::::if_subnet_exist(netuid), Error::::SubnetDoesNotExist ); - T::Subtensor::set_max_difficulty(netuid, max_difficulty); + pallet_subtensor::Pallet::::set_max_difficulty(netuid, max_difficulty); log::info!( "MaxDifficultySet( netuid: {:?} max_difficulty: {:?} ) ", netuid, @@ -197,13 +189,13 @@ pub mod pallet { netuid: u16, weights_version_key: u64, ) -> DispatchResult { - T::Subtensor::ensure_subnet_owner_or_root(origin, netuid)?; + pallet_subtensor::Pallet::::ensure_subnet_owner_or_root(origin, netuid)?; ensure!( - T::Subtensor::if_subnet_exist(netuid), + pallet_subtensor::Pallet::::if_subnet_exist(netuid), Error::::SubnetDoesNotExist ); - T::Subtensor::set_weights_version_key(netuid, weights_version_key); + pallet_subtensor::Pallet::::set_weights_version_key(netuid, weights_version_key); log::info!( "WeightsVersionKeySet( netuid: {:?} weights_version_key: {:?} ) ", netuid, @@ -222,13 +214,16 @@ pub mod pallet { netuid: u16, weights_set_rate_limit: u64, ) -> DispatchResult { - T::Subtensor::ensure_subnet_owner_or_root(origin, netuid)?; + pallet_subtensor::Pallet::::ensure_subnet_owner_or_root(origin, netuid)?; ensure!( - T::Subtensor::if_subnet_exist(netuid), + pallet_subtensor::Pallet::::if_subnet_exist(netuid), Error::::SubnetDoesNotExist ); - T::Subtensor::set_weights_set_rate_limit(netuid, weights_set_rate_limit); + pallet_subtensor::Pallet::::set_weights_set_rate_limit( + netuid, + weights_set_rate_limit, + ); log::info!( "WeightsSetRateLimitSet( netuid: {:?} weights_set_rate_limit: {:?} ) ", netuid, @@ -250,10 +245,10 @@ pub mod pallet { ensure_root(origin)?; ensure!( - T::Subtensor::if_subnet_exist(netuid), + pallet_subtensor::Pallet::::if_subnet_exist(netuid), Error::::SubnetDoesNotExist ); - T::Subtensor::set_adjustment_interval(netuid, adjustment_interval); + pallet_subtensor::Pallet::::set_adjustment_interval(netuid, adjustment_interval); log::info!( "AdjustmentIntervalSet( netuid: {:?} adjustment_interval: {:?} ) ", netuid, @@ -278,13 +273,13 @@ pub mod pallet { netuid: u16, adjustment_alpha: u64, ) -> DispatchResult { - T::Subtensor::ensure_subnet_owner_or_root(origin, netuid)?; + pallet_subtensor::Pallet::::ensure_subnet_owner_or_root(origin, netuid)?; ensure!( - T::Subtensor::if_subnet_exist(netuid), + pallet_subtensor::Pallet::::if_subnet_exist(netuid), Error::::SubnetDoesNotExist ); - T::Subtensor::set_adjustment_alpha(netuid, adjustment_alpha); + pallet_subtensor::Pallet::::set_adjustment_alpha(netuid, adjustment_alpha); log::info!( "AdjustmentAlphaSet( adjustment_alpha: {:?} ) ", adjustment_alpha @@ -302,13 +297,13 @@ pub mod pallet { netuid: u16, max_weight_limit: u16, ) -> DispatchResult { - T::Subtensor::ensure_subnet_owner_or_root(origin, netuid)?; + pallet_subtensor::Pallet::::ensure_subnet_owner_or_root(origin, netuid)?; ensure!( - T::Subtensor::if_subnet_exist(netuid), + pallet_subtensor::Pallet::::if_subnet_exist(netuid), Error::::SubnetDoesNotExist ); - T::Subtensor::set_max_weight_limit(netuid, max_weight_limit); + pallet_subtensor::Pallet::::set_max_weight_limit(netuid, max_weight_limit); log::info!( "MaxWeightLimitSet( netuid: {:?} max_weight_limit: {:?} ) ", netuid, @@ -327,13 +322,13 @@ pub mod pallet { netuid: u16, immunity_period: u16, ) -> DispatchResult { - T::Subtensor::ensure_subnet_owner_or_root(origin, netuid)?; + pallet_subtensor::Pallet::::ensure_subnet_owner_or_root(origin, netuid)?; ensure!( - T::Subtensor::if_subnet_exist(netuid), + pallet_subtensor::Pallet::::if_subnet_exist(netuid), Error::::SubnetDoesNotExist ); - T::Subtensor::set_immunity_period(netuid, immunity_period); + pallet_subtensor::Pallet::::set_immunity_period(netuid, immunity_period); log::info!( "ImmunityPeriodSet( netuid: {:?} immunity_period: {:?} ) ", netuid, @@ -352,13 +347,13 @@ pub mod pallet { netuid: u16, min_allowed_weights: u16, ) -> DispatchResult { - T::Subtensor::ensure_subnet_owner_or_root(origin, netuid)?; + pallet_subtensor::Pallet::::ensure_subnet_owner_or_root(origin, netuid)?; ensure!( - T::Subtensor::if_subnet_exist(netuid), + pallet_subtensor::Pallet::::if_subnet_exist(netuid), Error::::SubnetDoesNotExist ); - T::Subtensor::set_min_allowed_weights(netuid, min_allowed_weights); + pallet_subtensor::Pallet::::set_min_allowed_weights(netuid, min_allowed_weights); log::info!( "MinAllowedWeightSet( netuid: {:?} min_allowed_weights: {:?} ) ", netuid, @@ -379,14 +374,14 @@ pub mod pallet { ) -> DispatchResult { ensure_root(origin)?; ensure!( - T::Subtensor::if_subnet_exist(netuid), + pallet_subtensor::Pallet::::if_subnet_exist(netuid), Error::::SubnetDoesNotExist ); ensure!( - T::Subtensor::get_subnetwork_n(netuid) < max_allowed_uids, + pallet_subtensor::Pallet::::get_subnetwork_n(netuid) < max_allowed_uids, Error::::MaxAllowedUIdsLessThanCurrentUIds ); - T::Subtensor::set_max_allowed_uids(netuid, max_allowed_uids); + pallet_subtensor::Pallet::::set_max_allowed_uids(netuid, max_allowed_uids); log::info!( "MaxAllowedUidsSet( netuid: {:?} max_allowed_uids: {:?} ) ", netuid, @@ -401,13 +396,13 @@ pub mod pallet { #[pallet::call_index(16)] #[pallet::weight(T::WeightInfo::sudo_set_kappa())] pub fn sudo_set_kappa(origin: OriginFor, netuid: u16, kappa: u16) -> DispatchResult { - T::Subtensor::ensure_subnet_owner_or_root(origin, netuid)?; + pallet_subtensor::Pallet::::ensure_subnet_owner_or_root(origin, netuid)?; ensure!( - T::Subtensor::if_subnet_exist(netuid), + pallet_subtensor::Pallet::::if_subnet_exist(netuid), Error::::SubnetDoesNotExist ); - T::Subtensor::set_kappa(netuid, kappa); + pallet_subtensor::Pallet::::set_kappa(netuid, kappa); log::info!("KappaSet( netuid: {:?} kappa: {:?} ) ", netuid, kappa); Ok(()) } @@ -418,13 +413,13 @@ pub mod pallet { #[pallet::call_index(17)] #[pallet::weight(T::WeightInfo::sudo_set_rho())] pub fn sudo_set_rho(origin: OriginFor, netuid: u16, rho: u16) -> DispatchResult { - T::Subtensor::ensure_subnet_owner_or_root(origin, netuid)?; + pallet_subtensor::Pallet::::ensure_subnet_owner_or_root(origin, netuid)?; ensure!( - T::Subtensor::if_subnet_exist(netuid), + pallet_subtensor::Pallet::::if_subnet_exist(netuid), Error::::SubnetDoesNotExist ); - T::Subtensor::set_rho(netuid, rho); + pallet_subtensor::Pallet::::set_rho(netuid, rho); log::info!("RhoSet( netuid: {:?} rho: {:?} ) ", netuid, rho); Ok(()) } @@ -439,13 +434,13 @@ pub mod pallet { netuid: u16, activity_cutoff: u16, ) -> DispatchResult { - T::Subtensor::ensure_subnet_owner_or_root(origin, netuid)?; + pallet_subtensor::Pallet::::ensure_subnet_owner_or_root(origin, netuid)?; ensure!( - T::Subtensor::if_subnet_exist(netuid), + pallet_subtensor::Pallet::::if_subnet_exist(netuid), Error::::SubnetDoesNotExist ); - T::Subtensor::set_activity_cutoff(netuid, activity_cutoff); + pallet_subtensor::Pallet::::set_activity_cutoff(netuid, activity_cutoff); log::info!( "ActivityCutoffSet( netuid: {:?} activity_cutoff: {:?} ) ", netuid, @@ -470,9 +465,12 @@ pub mod pallet { netuid: u16, registration_allowed: bool, ) -> DispatchResult { - T::Subtensor::ensure_subnet_owner_or_root(origin, netuid)?; + pallet_subtensor::Pallet::::ensure_subnet_owner_or_root(origin, netuid)?; - T::Subtensor::set_network_registration_allowed(netuid, registration_allowed); + pallet_subtensor::Pallet::::set_network_registration_allowed( + netuid, + registration_allowed, + ); log::info!( "NetworkRegistrationAllowed( registration_allowed: {:?} ) ", registration_allowed @@ -495,9 +493,12 @@ pub mod pallet { netuid: u16, registration_allowed: bool, ) -> DispatchResult { - T::Subtensor::ensure_subnet_owner_or_root(origin, netuid)?; + pallet_subtensor::Pallet::::ensure_subnet_owner_or_root(origin, netuid)?; - T::Subtensor::set_network_pow_registration_allowed(netuid, registration_allowed); + pallet_subtensor::Pallet::::set_network_pow_registration_allowed( + netuid, + registration_allowed, + ); log::info!( "NetworkPowRegistrationAllowed( registration_allowed: {:?} ) ", registration_allowed @@ -518,10 +519,10 @@ pub mod pallet { ensure_root(origin)?; ensure!( - T::Subtensor::if_subnet_exist(netuid), + pallet_subtensor::Pallet::::if_subnet_exist(netuid), Error::::SubnetDoesNotExist ); - T::Subtensor::set_target_registrations_per_interval( + pallet_subtensor::Pallet::::set_target_registrations_per_interval( netuid, target_registrations_per_interval, ); @@ -543,13 +544,13 @@ pub mod pallet { netuid: u16, min_burn: u64, ) -> DispatchResult { - T::Subtensor::ensure_subnet_owner_or_root(origin, netuid)?; + pallet_subtensor::Pallet::::ensure_subnet_owner_or_root(origin, netuid)?; ensure!( - T::Subtensor::if_subnet_exist(netuid), + pallet_subtensor::Pallet::::if_subnet_exist(netuid), Error::::SubnetDoesNotExist ); - T::Subtensor::set_min_burn(netuid, min_burn); + pallet_subtensor::Pallet::::set_min_burn(netuid, min_burn); log::info!( "MinBurnSet( netuid: {:?} min_burn: {:?} ) ", netuid, @@ -568,13 +569,13 @@ pub mod pallet { netuid: u16, max_burn: u64, ) -> DispatchResult { - T::Subtensor::ensure_subnet_owner_or_root(origin, netuid)?; + pallet_subtensor::Pallet::::ensure_subnet_owner_or_root(origin, netuid)?; ensure!( - T::Subtensor::if_subnet_exist(netuid), + pallet_subtensor::Pallet::::if_subnet_exist(netuid), Error::::SubnetDoesNotExist ); - T::Subtensor::set_max_burn(netuid, max_burn); + pallet_subtensor::Pallet::::set_max_burn(netuid, max_burn); log::info!( "MaxBurnSet( netuid: {:?} max_burn: {:?} ) ", netuid, @@ -593,12 +594,12 @@ pub mod pallet { netuid: u16, difficulty: u64, ) -> DispatchResult { - T::Subtensor::ensure_subnet_owner_or_root(origin, netuid)?; + pallet_subtensor::Pallet::::ensure_subnet_owner_or_root(origin, netuid)?; ensure!( - T::Subtensor::if_subnet_exist(netuid), + pallet_subtensor::Pallet::::if_subnet_exist(netuid), Error::::SubnetDoesNotExist ); - T::Subtensor::set_difficulty(netuid, difficulty); + pallet_subtensor::Pallet::::set_difficulty(netuid, difficulty); log::info!( "DifficultySet( netuid: {:?} difficulty: {:?} ) ", netuid, @@ -619,15 +620,19 @@ pub mod pallet { ) -> DispatchResult { ensure_root(origin)?; ensure!( - T::Subtensor::if_subnet_exist(netuid), + pallet_subtensor::Pallet::::if_subnet_exist(netuid), Error::::SubnetDoesNotExist ); ensure!( - max_allowed_validators <= T::Subtensor::get_max_allowed_uids(netuid), + max_allowed_validators + <= pallet_subtensor::Pallet::::get_max_allowed_uids(netuid), Error::::MaxValidatorsLargerThanMaxUIds ); - T::Subtensor::set_max_allowed_validators(netuid, max_allowed_validators); + pallet_subtensor::Pallet::::set_max_allowed_validators( + netuid, + max_allowed_validators, + ); log::info!( "MaxAllowedValidatorsSet( netuid: {:?} max_allowed_validators: {:?} ) ", netuid, @@ -646,13 +651,13 @@ pub mod pallet { netuid: u16, bonds_moving_average: u64, ) -> DispatchResult { - T::Subtensor::ensure_subnet_owner_or_root(origin, netuid)?; + pallet_subtensor::Pallet::::ensure_subnet_owner_or_root(origin, netuid)?; ensure!( - T::Subtensor::if_subnet_exist(netuid), + pallet_subtensor::Pallet::::if_subnet_exist(netuid), Error::::SubnetDoesNotExist ); - T::Subtensor::set_bonds_moving_average(netuid, bonds_moving_average); + pallet_subtensor::Pallet::::set_bonds_moving_average(netuid, bonds_moving_average); log::info!( "BondsMovingAverageSet( netuid: {:?} bonds_moving_average: {:?} ) ", netuid, @@ -674,10 +679,13 @@ pub mod pallet { ensure_root(origin)?; ensure!( - T::Subtensor::if_subnet_exist(netuid), + pallet_subtensor::Pallet::::if_subnet_exist(netuid), Error::::SubnetDoesNotExist ); - T::Subtensor::set_max_registrations_per_block(netuid, max_registrations_per_block); + pallet_subtensor::Pallet::::set_max_registrations_per_block( + netuid, + max_registrations_per_block, + ); log::info!( "MaxRegistrationsPerBlock( netuid: {:?} max_registrations_per_block: {:?} ) ", netuid, @@ -701,7 +709,7 @@ pub mod pallet { subnet_owner_cut: u16, ) -> DispatchResult { ensure_root(origin)?; - T::Subtensor::set_subnet_owner_cut(subnet_owner_cut); + pallet_subtensor::Pallet::::set_subnet_owner_cut(subnet_owner_cut); log::info!( "SubnetOwnerCut( subnet_owner_cut: {:?} ) ", subnet_owner_cut @@ -724,7 +732,7 @@ pub mod pallet { rate_limit: u64, ) -> DispatchResult { ensure_root(origin)?; - T::Subtensor::set_network_rate_limit(rate_limit); + pallet_subtensor::Pallet::::set_network_rate_limit(rate_limit); log::info!("NetworkRateLimit( rate_limit: {:?} ) ", rate_limit); Ok(()) } @@ -737,10 +745,10 @@ pub mod pallet { pub fn sudo_set_tempo(origin: OriginFor, netuid: u16, tempo: u16) -> DispatchResult { ensure_root(origin)?; ensure!( - T::Subtensor::if_subnet_exist(netuid), + pallet_subtensor::Pallet::::if_subnet_exist(netuid), Error::::SubnetDoesNotExist ); - T::Subtensor::set_tempo(netuid, tempo); + pallet_subtensor::Pallet::::set_tempo(netuid, tempo); log::info!("TempoSet( netuid: {:?} tempo: {:?} ) ", netuid, tempo); Ok(()) } @@ -756,7 +764,7 @@ pub mod pallet { ) -> DispatchResult { ensure_root(origin)?; - T::Subtensor::set_total_issuance(total_issuance); + pallet_subtensor::Pallet::::set_total_issuance(total_issuance); Ok(()) } @@ -777,7 +785,7 @@ pub mod pallet { ) -> DispatchResult { ensure_root(origin)?; - T::Subtensor::set_network_immunity_period(immunity_period); + pallet_subtensor::Pallet::::set_network_immunity_period(immunity_period); log::info!("NetworkImmunityPeriod( period: {:?} ) ", immunity_period); @@ -800,7 +808,7 @@ pub mod pallet { ) -> DispatchResult { ensure_root(origin)?; - T::Subtensor::set_network_min_lock(lock_cost); + pallet_subtensor::Pallet::::set_network_min_lock(lock_cost); log::info!("NetworkMinLockCost( lock_cost: {:?} ) ", lock_cost); @@ -819,7 +827,7 @@ pub mod pallet { ))] pub fn sudo_set_subnet_limit(origin: OriginFor, max_subnets: u16) -> DispatchResult { ensure_root(origin)?; - T::Subtensor::set_subnet_limit(max_subnets); + pallet_subtensor::Pallet::::set_max_subnets(max_subnets); log::info!("SubnetLimit( max_subnets: {:?} ) ", max_subnets); @@ -842,7 +850,7 @@ pub mod pallet { ) -> DispatchResult { ensure_root(origin)?; - T::Subtensor::set_lock_reduction_interval(interval); + pallet_subtensor::Pallet::::set_lock_reduction_interval(interval); log::info!("NetworkLockReductionInterval( interval: {:?} ) ", interval); @@ -861,10 +869,10 @@ pub mod pallet { ) -> DispatchResult { ensure_root(origin)?; ensure!( - T::Subtensor::if_subnet_exist(netuid), + pallet_subtensor::Pallet::::if_subnet_exist(netuid), Error::::SubnetDoesNotExist ); - T::Subtensor::set_rao_recycled(netuid, rao_recycled); + pallet_subtensor::Pallet::::set_rao_recycled(netuid, rao_recycled); Ok(()) } @@ -875,7 +883,7 @@ pub mod pallet { #[pallet::weight((0, DispatchClass::Operational, Pays::No))] pub fn sudo_set_weights_min_stake(origin: OriginFor, min_stake: u64) -> DispatchResult { ensure_root(origin)?; - T::Subtensor::set_weights_min_stake(min_stake); + pallet_subtensor::Pallet::::set_weights_min_stake(min_stake); Ok(()) } @@ -890,12 +898,12 @@ pub mod pallet { min_stake: u64, ) -> DispatchResult { ensure_root(origin)?; - let prev_min_stake = T::Subtensor::get_nominator_min_required_stake(); + let prev_min_stake = pallet_subtensor::Pallet::::get_nominator_min_required_stake(); log::trace!("Setting minimum stake to: {}", min_stake); - T::Subtensor::set_nominator_min_required_stake(min_stake); + pallet_subtensor::Pallet::::set_nominator_min_required_stake(min_stake); if min_stake > prev_min_stake { log::trace!("Clearing small nominations"); - T::Subtensor::clear_small_nominations(); + pallet_subtensor::Pallet::::clear_small_nominations(); log::trace!("Small nominations cleared"); } Ok(()) @@ -911,7 +919,7 @@ pub mod pallet { tx_rate_limit: u64, ) -> DispatchResult { ensure_root(origin)?; - T::Subtensor::set_tx_delegate_take_rate_limit(tx_rate_limit); + pallet_subtensor::Pallet::::set_tx_delegate_take_rate_limit(tx_rate_limit); log::info!( "TxRateLimitDelegateTakeSet( tx_delegate_take_rate_limit: {:?} ) ", tx_rate_limit @@ -926,7 +934,7 @@ pub mod pallet { #[pallet::weight((0, DispatchClass::Operational, Pays::No))] pub fn sudo_set_min_delegate_take(origin: OriginFor, take: u16) -> DispatchResult { ensure_root(origin)?; - T::Subtensor::set_min_delegate_take(take); + pallet_subtensor::Pallet::::set_min_delegate_take(take); log::info!("TxMinDelegateTakeSet( tx_min_delegate_take: {:?} ) ", take); Ok(()) } @@ -941,7 +949,9 @@ pub mod pallet { target_stakes_per_interval: u64, ) -> DispatchResult { ensure_root(origin)?; - T::Subtensor::set_target_stakes_per_interval(target_stakes_per_interval); + pallet_subtensor::Pallet::::set_target_stakes_per_interval( + target_stakes_per_interval, + ); log::info!( "TxTargetStakesPerIntervalSet( set_target_stakes_per_interval: {:?} ) ", target_stakes_per_interval @@ -959,14 +969,14 @@ pub mod pallet { netuid: u16, interval: u64, ) -> DispatchResult { - T::Subtensor::ensure_subnet_owner_or_root(origin, netuid)?; + pallet_subtensor::Pallet::::ensure_subnet_owner_or_root(origin, netuid)?; ensure!( - T::Subtensor::if_subnet_exist(netuid), + pallet_subtensor::Pallet::::if_subnet_exist(netuid), Error::::SubnetDoesNotExist ); - T::Subtensor::set_commit_reveal_weights_interval(netuid, interval); + pallet_subtensor::Pallet::::set_commit_reveal_weights_interval(netuid, interval); log::info!( "SetWeightCommitInterval( netuid: {:?}, interval: {:?} ) ", netuid, @@ -985,14 +995,14 @@ pub mod pallet { netuid: u16, enabled: bool, ) -> DispatchResult { - T::Subtensor::ensure_subnet_owner_or_root(origin, netuid)?; + pallet_subtensor::Pallet::::ensure_subnet_owner_or_root(origin, netuid)?; ensure!( - T::Subtensor::if_subnet_exist(netuid), + pallet_subtensor::Pallet::::if_subnet_exist(netuid), Error::::SubnetDoesNotExist ); - T::Subtensor::set_commit_reveal_weights_enabled(netuid, enabled); + pallet_subtensor::Pallet::::set_commit_reveal_weights_enabled(netuid, enabled); log::info!("ToggleSetWeightsCommitReveal( netuid: {:?} ) ", netuid); Ok(()) } @@ -1013,8 +1023,8 @@ pub mod pallet { netuid: u16, enabled: bool, ) -> DispatchResult { - T::Subtensor::ensure_subnet_owner_or_root(origin, netuid)?; - T::Subtensor::set_liquid_alpha_enabled(netuid, enabled); + pallet_subtensor::Pallet::::ensure_subnet_owner_or_root(origin, netuid)?; + pallet_subtensor::Pallet::::set_liquid_alpha_enabled(netuid, enabled); log::info!( "LiquidAlphaEnableToggled( netuid: {:?}, Enabled: {:?} ) ", netuid, @@ -1032,8 +1042,10 @@ pub mod pallet { alpha_low: u16, alpha_high: u16, ) -> DispatchResult { - T::Subtensor::ensure_subnet_owner_or_root(origin.clone(), netuid)?; - T::Subtensor::do_set_alpha_values(origin, netuid, alpha_low, alpha_high) + pallet_subtensor::Pallet::::ensure_subnet_owner_or_root(origin.clone(), netuid)?; + pallet_subtensor::Pallet::::do_set_alpha_values( + origin, netuid, alpha_low, alpha_high, + ) } } } @@ -1052,89 +1064,3 @@ pub trait AuraInterface { impl AuraInterface for () { fn change_authorities(_: BoundedVec) {} } - -/////////////////////////////////////////// - -pub trait SubtensorInterface { - fn set_min_delegate_take(take: u16); - fn set_max_delegate_take(take: u16); - fn set_tx_rate_limit(rate_limit: u64); - fn set_tx_delegate_take_rate_limit(rate_limit: u64); - - fn set_serving_rate_limit(netuid: u16, rate_limit: u64); - - fn set_max_burn(netuid: u16, max_burn: u64); - fn set_min_burn(netuid: u16, min_burn: u64); - fn set_burn(netuid: u16, burn: u64); - - fn set_max_difficulty(netuid: u16, max_diff: u64); - fn set_min_difficulty(netuid: u16, min_diff: u64); - fn set_difficulty(netuid: u16, diff: u64); - - fn set_weights_rate_limit(netuid: u16, rate_limit: u64); - - fn set_weights_version_key(netuid: u16, version: u64); - - fn set_bonds_moving_average(netuid: u16, moving_average: u64); - - fn set_max_allowed_validators(netuid: u16, max_validators: u16); - - fn get_root_netuid() -> u16; - fn if_subnet_exist(netuid: u16) -> bool; - fn create_account_if_non_existent(coldkey: &AccountId, hotkey: &AccountId); - fn coldkey_owns_hotkey(coldkey: &AccountId, hotkey: &AccountId) -> bool; - fn increase_stake_on_coldkey_hotkey_account( - coldkey: &AccountId, - hotkey: &AccountId, - increment: u64, - ); - fn add_balance_to_coldkey_account(coldkey: &AccountId, amount: Balance); - fn get_current_block_as_u64() -> u64; - fn get_subnetwork_n(netuid: u16) -> u16; - fn get_max_allowed_uids(netuid: u16) -> u16; - fn append_neuron(netuid: u16, new_hotkey: &AccountId, block_number: u64); - fn get_neuron_to_prune(netuid: u16) -> u16; - fn replace_neuron(netuid: u16, uid_to_replace: u16, new_hotkey: &AccountId, block_number: u64); - fn set_total_issuance(total_issuance: u64); - fn set_network_immunity_period(net_immunity_period: u64); - fn set_network_min_lock(net_min_lock: u64); - fn set_rao_recycled(netuid: u16, rao_recycled: u64); - fn set_subnet_limit(limit: u16); - fn is_hotkey_registered_on_network(netuid: u16, hotkey: &AccountId) -> bool; - fn set_lock_reduction_interval(interval: u64); - fn set_tempo(netuid: u16, tempo: u16); - fn set_subnet_owner_cut(subnet_owner_cut: u16); - fn set_network_rate_limit(limit: u64); - fn set_max_registrations_per_block(netuid: u16, max_registrations_per_block: u16); - fn set_adjustment_alpha(netuid: u16, adjustment_alpha: u64); - fn set_target_registrations_per_interval(netuid: u16, target_registrations_per_interval: u16); - fn set_network_pow_registration_allowed(netuid: u16, registration_allowed: bool); - fn set_network_registration_allowed(netuid: u16, registration_allowed: bool); - fn set_activity_cutoff(netuid: u16, activity_cutoff: u16); - fn ensure_subnet_owner_or_root(o: RuntimeOrigin, netuid: u16) -> Result<(), DispatchError>; - fn set_rho(netuid: u16, rho: u16); - fn set_kappa(netuid: u16, kappa: u16); - fn set_max_allowed_uids(netuid: u16, max_allowed: u16); - fn set_min_allowed_weights(netuid: u16, min_allowed_weights: u16); - fn set_immunity_period(netuid: u16, immunity_period: u16); - fn set_max_weight_limit(netuid: u16, max_weight_limit: u16); - fn set_scaling_law_power(netuid: u16, scaling_law_power: u16); - fn set_validator_prune_len(netuid: u16, validator_prune_len: u64); - fn set_adjustment_interval(netuid: u16, adjustment_interval: u16); - fn set_weights_set_rate_limit(netuid: u16, weights_set_rate_limit: u64); - fn init_new_network(netuid: u16, tempo: u16); - fn set_weights_min_stake(min_stake: u64); - fn get_nominator_min_required_stake() -> u64; - fn set_nominator_min_required_stake(min_stake: u64); - fn clear_small_nominations(); - fn set_target_stakes_per_interval(target_stakes_per_interval: u64); - fn set_commit_reveal_weights_interval(netuid: u16, interval: u64); - fn set_commit_reveal_weights_enabled(netuid: u16, enabled: bool); - fn set_liquid_alpha_enabled(netuid: u16, enabled: bool); - fn do_set_alpha_values( - origin: RuntimeOrigin, - netuid: u16, - alpha_low: u16, - alpha_high: u16, - ) -> Result<(), DispatchError>; -} diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index a4abd124f..d302652d4 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -948,291 +948,12 @@ impl pallet_admin_utils::AuraInterface> for AuraPalletIntrf } } -pub struct SubtensorInterface; - -impl - pallet_admin_utils::SubtensorInterface< - AccountId, - as frame_support::traits::Currency>::Balance, - RuntimeOrigin, - > for SubtensorInterface -{ - fn set_max_delegate_take(max_take: u16) { - SubtensorModule::set_max_delegate_take(max_take); - } - - fn set_min_delegate_take(max_take: u16) { - SubtensorModule::set_min_delegate_take(max_take); - } - - fn set_tx_rate_limit(rate_limit: u64) { - SubtensorModule::set_tx_rate_limit(rate_limit); - } - - fn set_tx_delegate_take_rate_limit(rate_limit: u64) { - SubtensorModule::set_tx_delegate_take_rate_limit(rate_limit); - } - - fn set_serving_rate_limit(netuid: u16, rate_limit: u64) { - SubtensorModule::set_serving_rate_limit(netuid, rate_limit); - } - - fn set_max_burn(netuid: u16, max_burn: u64) { - SubtensorModule::set_max_burn(netuid, max_burn); - } - - fn set_min_burn(netuid: u16, min_burn: u64) { - SubtensorModule::set_min_burn(netuid, min_burn); - } - - fn set_burn(netuid: u16, burn: u64) { - SubtensorModule::set_burn(netuid, burn); - } - - fn set_max_difficulty(netuid: u16, max_diff: u64) { - SubtensorModule::set_max_difficulty(netuid, max_diff); - } - - fn set_min_difficulty(netuid: u16, min_diff: u64) { - SubtensorModule::set_min_difficulty(netuid, min_diff); - } - - fn set_difficulty(netuid: u16, diff: u64) { - SubtensorModule::set_difficulty(netuid, diff); - } - - fn set_weights_rate_limit(netuid: u16, rate_limit: u64) { - SubtensorModule::set_weights_set_rate_limit(netuid, rate_limit); - } - - fn set_weights_version_key(netuid: u16, version: u64) { - SubtensorModule::set_weights_version_key(netuid, version); - } - - fn set_bonds_moving_average(netuid: u16, moving_average: u64) { - SubtensorModule::set_bonds_moving_average(netuid, moving_average); - } - - fn set_max_allowed_validators(netuid: u16, max_validators: u16) { - SubtensorModule::set_max_allowed_validators(netuid, max_validators); - } - - fn get_root_netuid() -> u16 { - SubtensorModule::get_root_netuid() - } - - fn if_subnet_exist(netuid: u16) -> bool { - SubtensorModule::if_subnet_exist(netuid) - } - - fn create_account_if_non_existent(coldkey: &AccountId, hotkey: &AccountId) { - SubtensorModule::create_account_if_non_existent(coldkey, hotkey) - } - - fn coldkey_owns_hotkey(coldkey: &AccountId, hotkey: &AccountId) -> bool { - SubtensorModule::coldkey_owns_hotkey(coldkey, hotkey) - } - - fn increase_stake_on_coldkey_hotkey_account( - coldkey: &AccountId, - hotkey: &AccountId, - increment: u64, - ) { - SubtensorModule::increase_stake_on_coldkey_hotkey_account(coldkey, hotkey, increment); - } - - fn add_balance_to_coldkey_account(coldkey: &AccountId, amount: Balance) { - SubtensorModule::add_balance_to_coldkey_account(coldkey, amount); - } - - fn get_current_block_as_u64() -> u64 { - SubtensorModule::get_current_block_as_u64() - } - - fn get_subnetwork_n(netuid: u16) -> u16 { - SubtensorModule::get_subnetwork_n(netuid) - } - - fn get_max_allowed_uids(netuid: u16) -> u16 { - SubtensorModule::get_max_allowed_uids(netuid) - } - - fn append_neuron(netuid: u16, new_hotkey: &AccountId, block_number: u64) { - SubtensorModule::append_neuron(netuid, new_hotkey, block_number) - } - - fn get_neuron_to_prune(netuid: u16) -> u16 { - SubtensorModule::get_neuron_to_prune(netuid) - } - - fn replace_neuron(netuid: u16, uid_to_replace: u16, new_hotkey: &AccountId, block_number: u64) { - SubtensorModule::replace_neuron(netuid, uid_to_replace, new_hotkey, block_number); - } - - fn set_total_issuance(total_issuance: u64) { - SubtensorModule::set_total_issuance(total_issuance); - } - - fn set_network_immunity_period(net_immunity_period: u64) { - SubtensorModule::set_network_immunity_period(net_immunity_period); - } - - fn set_network_min_lock(net_min_lock: u64) { - SubtensorModule::set_network_min_lock(net_min_lock); - } - - fn set_subnet_limit(limit: u16) { - SubtensorModule::set_max_subnets(limit); - } - - fn set_lock_reduction_interval(interval: u64) { - SubtensorModule::set_lock_reduction_interval(interval); - } - - fn set_tempo(netuid: u16, tempo: u16) { - SubtensorModule::set_tempo(netuid, tempo); - } - - fn set_subnet_owner_cut(subnet_owner_cut: u16) { - SubtensorModule::set_subnet_owner_cut(subnet_owner_cut); - } - - fn set_network_rate_limit(limit: u64) { - SubtensorModule::set_network_rate_limit(limit); - } - - fn set_max_registrations_per_block(netuid: u16, max_registrations_per_block: u16) { - SubtensorModule::set_max_registrations_per_block(netuid, max_registrations_per_block); - } - - fn set_adjustment_alpha(netuid: u16, adjustment_alpha: u64) { - SubtensorModule::set_adjustment_alpha(netuid, adjustment_alpha); - } - - fn set_target_registrations_per_interval(netuid: u16, target_registrations_per_interval: u16) { - SubtensorModule::set_target_registrations_per_interval( - netuid, - target_registrations_per_interval, - ); - } - - fn set_network_pow_registration_allowed(netuid: u16, registration_allowed: bool) { - SubtensorModule::set_network_pow_registration_allowed(netuid, registration_allowed); - } - - fn set_network_registration_allowed(netuid: u16, registration_allowed: bool) { - SubtensorModule::set_network_registration_allowed(netuid, registration_allowed); - } - - fn set_activity_cutoff(netuid: u16, activity_cutoff: u16) { - SubtensorModule::set_activity_cutoff(netuid, activity_cutoff); - } - - fn ensure_subnet_owner_or_root(o: RuntimeOrigin, netuid: u16) -> Result<(), DispatchError> { - SubtensorModule::ensure_subnet_owner_or_root(o, netuid) - } - - fn set_rho(netuid: u16, rho: u16) { - SubtensorModule::set_rho(netuid, rho); - } - - fn set_kappa(netuid: u16, kappa: u16) { - SubtensorModule::set_kappa(netuid, kappa); - } - - fn set_max_allowed_uids(netuid: u16, max_allowed: u16) { - SubtensorModule::set_max_allowed_uids(netuid, max_allowed); - } - - fn set_min_allowed_weights(netuid: u16, min_allowed_weights: u16) { - SubtensorModule::set_min_allowed_weights(netuid, min_allowed_weights); - } - - fn set_immunity_period(netuid: u16, immunity_period: u16) { - SubtensorModule::set_immunity_period(netuid, immunity_period); - } - - fn set_max_weight_limit(netuid: u16, max_weight_limit: u16) { - SubtensorModule::set_max_weight_limit(netuid, max_weight_limit); - } - - fn set_scaling_law_power(netuid: u16, scaling_law_power: u16) { - SubtensorModule::set_scaling_law_power(netuid, scaling_law_power); - } - - fn set_validator_prune_len(netuid: u16, validator_prune_len: u64) { - SubtensorModule::set_validator_prune_len(netuid, validator_prune_len); - } - - fn set_adjustment_interval(netuid: u16, adjustment_interval: u16) { - SubtensorModule::set_adjustment_interval(netuid, adjustment_interval); - } - - fn set_weights_set_rate_limit(netuid: u16, weights_set_rate_limit: u64) { - SubtensorModule::set_weights_set_rate_limit(netuid, weights_set_rate_limit); - } - - fn set_rao_recycled(netuid: u16, rao_recycled: u64) { - SubtensorModule::set_rao_recycled(netuid, rao_recycled); - } - - fn is_hotkey_registered_on_network(netuid: u16, hotkey: &AccountId) -> bool { - SubtensorModule::is_hotkey_registered_on_network(netuid, hotkey) - } - - fn init_new_network(netuid: u16, tempo: u16) { - SubtensorModule::init_new_network(netuid, tempo); - } - - fn set_weights_min_stake(min_stake: u64) { - SubtensorModule::set_weights_min_stake(min_stake); - } - - fn clear_small_nominations() { - SubtensorModule::clear_small_nominations(); - } - - fn set_nominator_min_required_stake(min_stake: u64) { - SubtensorModule::set_nominator_min_required_stake(min_stake); - } - - fn get_nominator_min_required_stake() -> u64 { - SubtensorModule::get_nominator_min_required_stake() - } - - fn set_target_stakes_per_interval(target_stakes_per_interval: u64) { - SubtensorModule::set_target_stakes_per_interval(target_stakes_per_interval) - } - - fn set_commit_reveal_weights_interval(netuid: u16, interval: u64) { - SubtensorModule::set_commit_reveal_weights_interval(netuid, interval); - } - - fn set_commit_reveal_weights_enabled(netuid: u16, enabled: bool) { - SubtensorModule::set_commit_reveal_weights_enabled(netuid, enabled); - } - - fn set_liquid_alpha_enabled(netuid: u16, enabled: bool) { - SubtensorModule::set_liquid_alpha_enabled(netuid, enabled); - } - - fn do_set_alpha_values( - origin: RuntimeOrigin, - netuid: u16, - alpha_low: u16, - alpha_high: u16, - ) -> Result<(), DispatchError> { - SubtensorModule::do_set_alpha_values(origin, netuid, alpha_low, alpha_high) - } -} - impl pallet_admin_utils::Config for Runtime { type RuntimeEvent = RuntimeEvent; type AuthorityId = AuraId; type MaxAuthorities = ConstU32<32>; type Aura = AuraPalletIntrf; type Balance = Balance; - type Subtensor = SubtensorInterface; type WeightInfo = pallet_admin_utils::weights::SubstrateWeight; } From b0202f4a2fd1ae8bac71214a374eff9f5adc0bb2 Mon Sep 17 00:00:00 2001 From: Keith Date: Fri, 2 Aug 2024 15:53:58 +0900 Subject: [PATCH 067/177] Remove SubtensorInterface in tests --- pallets/admin-utils/tests/mock.rs | 274 +----------------------------- 1 file changed, 1 insertion(+), 273 deletions(-) diff --git a/pallets/admin-utils/tests/mock.rs b/pallets/admin-utils/tests/mock.rs index dbf88bdfa..3b6ec0ccd 100644 --- a/pallets/admin-utils/tests/mock.rs +++ b/pallets/admin-utils/tests/mock.rs @@ -12,7 +12,7 @@ use sp_core::U256; use sp_core::{ConstU64, H256}; use sp_runtime::{ traits::{BlakeTwo256, ConstU32, IdentityLookup}, - BuildStorage, DispatchError, + BuildStorage, }; type Block = frame_system::mocking::MockBlock; @@ -216,284 +216,12 @@ impl pallet_balances::Config for Test { type RuntimeHoldReason = (); } -pub struct SubtensorIntrf; - -impl pallet_admin_utils::SubtensorInterface for SubtensorIntrf { - fn set_max_delegate_take(default_take: u16) { - SubtensorModule::set_max_delegate_take(default_take); - } - - fn set_min_delegate_take(default_take: u16) { - SubtensorModule::set_min_delegate_take(default_take); - } - - fn set_tx_rate_limit(rate_limit: u64) { - SubtensorModule::set_tx_rate_limit(rate_limit); - } - - fn set_tx_delegate_take_rate_limit(rate_limit: u64) { - SubtensorModule::set_tx_delegate_take_rate_limit(rate_limit); - } - - fn set_serving_rate_limit(netuid: u16, rate_limit: u64) { - SubtensorModule::set_serving_rate_limit(netuid, rate_limit); - } - - fn set_max_burn(netuid: u16, max_burn: u64) { - SubtensorModule::set_max_burn(netuid, max_burn); - } - - fn set_min_burn(netuid: u16, min_burn: u64) { - SubtensorModule::set_min_burn(netuid, min_burn); - } - - fn set_burn(netuid: u16, burn: u64) { - SubtensorModule::set_burn(netuid, burn); - } - - fn set_max_difficulty(netuid: u16, max_diff: u64) { - SubtensorModule::set_max_difficulty(netuid, max_diff); - } - - fn set_min_difficulty(netuid: u16, min_diff: u64) { - SubtensorModule::set_min_difficulty(netuid, min_diff); - } - - fn set_difficulty(netuid: u16, diff: u64) { - SubtensorModule::set_difficulty(netuid, diff); - } - - fn set_weights_rate_limit(netuid: u16, rate_limit: u64) { - SubtensorModule::set_weights_set_rate_limit(netuid, rate_limit); - } - - fn set_weights_version_key(netuid: u16, version: u64) { - SubtensorModule::set_weights_version_key(netuid, version); - } - - fn set_bonds_moving_average(netuid: u16, moving_average: u64) { - SubtensorModule::set_bonds_moving_average(netuid, moving_average); - } - - fn set_max_allowed_validators(netuid: u16, max_validators: u16) { - SubtensorModule::set_max_allowed_validators(netuid, max_validators); - } - - fn get_root_netuid() -> u16 { - SubtensorModule::get_root_netuid() - } - - fn if_subnet_exist(netuid: u16) -> bool { - SubtensorModule::if_subnet_exist(netuid) - } - - fn create_account_if_non_existent(coldkey: &AccountId, hotkey: &AccountId) { - SubtensorModule::create_account_if_non_existent(coldkey, hotkey) - } - - fn coldkey_owns_hotkey(coldkey: &AccountId, hotkey: &AccountId) -> bool { - SubtensorModule::coldkey_owns_hotkey(coldkey, hotkey) - } - - fn increase_stake_on_coldkey_hotkey_account( - coldkey: &AccountId, - hotkey: &AccountId, - increment: u64, - ) { - SubtensorModule::increase_stake_on_coldkey_hotkey_account(coldkey, hotkey, increment); - } - - fn add_balance_to_coldkey_account(coldkey: &AccountId, amount: Balance) { - SubtensorModule::add_balance_to_coldkey_account(coldkey, amount); - } - - fn get_current_block_as_u64() -> u64 { - SubtensorModule::get_current_block_as_u64() - } - - fn get_subnetwork_n(netuid: u16) -> u16 { - SubtensorModule::get_subnetwork_n(netuid) - } - - fn get_max_allowed_uids(netuid: u16) -> u16 { - SubtensorModule::get_max_allowed_uids(netuid) - } - - fn append_neuron(netuid: u16, new_hotkey: &AccountId, block_number: u64) { - SubtensorModule::append_neuron(netuid, new_hotkey, block_number) - } - - fn get_neuron_to_prune(netuid: u16) -> u16 { - SubtensorModule::get_neuron_to_prune(netuid) - } - - fn replace_neuron(netuid: u16, uid_to_replace: u16, new_hotkey: &AccountId, block_number: u64) { - SubtensorModule::replace_neuron(netuid, uid_to_replace, new_hotkey, block_number); - } - - fn set_total_issuance(total_issuance: u64) { - SubtensorModule::set_total_issuance(total_issuance); - } - - fn set_network_immunity_period(net_immunity_period: u64) { - SubtensorModule::set_network_immunity_period(net_immunity_period); - } - - fn set_network_min_lock(net_min_lock: u64) { - SubtensorModule::set_network_min_lock(net_min_lock); - } - - fn set_subnet_limit(limit: u16) { - SubtensorModule::set_max_subnets(limit); - } - - fn set_lock_reduction_interval(interval: u64) { - SubtensorModule::set_lock_reduction_interval(interval); - } - - fn set_tempo(netuid: u16, tempo: u16) { - SubtensorModule::set_tempo(netuid, tempo); - } - - fn set_subnet_owner_cut(subnet_owner_cut: u16) { - SubtensorModule::set_subnet_owner_cut(subnet_owner_cut); - } - - fn set_network_rate_limit(limit: u64) { - SubtensorModule::set_network_rate_limit(limit); - } - - fn set_max_registrations_per_block(netuid: u16, max_registrations_per_block: u16) { - SubtensorModule::set_max_registrations_per_block(netuid, max_registrations_per_block); - } - - fn set_adjustment_alpha(netuid: u16, adjustment_alpha: u64) { - SubtensorModule::set_adjustment_alpha(netuid, adjustment_alpha); - } - - fn set_target_registrations_per_interval(netuid: u16, target_registrations_per_interval: u16) { - SubtensorModule::set_target_registrations_per_interval( - netuid, - target_registrations_per_interval, - ); - } - - fn set_network_pow_registration_allowed(netuid: u16, registration_allowed: bool) { - SubtensorModule::set_network_pow_registration_allowed(netuid, registration_allowed); - } - - fn set_network_registration_allowed(netuid: u16, registration_allowed: bool) { - SubtensorModule::set_network_pow_registration_allowed(netuid, registration_allowed); - } - - fn set_activity_cutoff(netuid: u16, activity_cutoff: u16) { - SubtensorModule::set_activity_cutoff(netuid, activity_cutoff); - } - - fn ensure_subnet_owner_or_root(o: RuntimeOrigin, netuid: u16) -> Result<(), DispatchError> { - SubtensorModule::ensure_subnet_owner_or_root(o, netuid) - } - - fn set_rho(netuid: u16, rho: u16) { - SubtensorModule::set_rho(netuid, rho); - } - - fn set_kappa(netuid: u16, kappa: u16) { - SubtensorModule::set_kappa(netuid, kappa); - } - - fn set_max_allowed_uids(netuid: u16, max_allowed: u16) { - SubtensorModule::set_max_allowed_uids(netuid, max_allowed); - } - - fn set_min_allowed_weights(netuid: u16, min_allowed_weights: u16) { - SubtensorModule::set_min_allowed_weights(netuid, min_allowed_weights); - } - - fn set_immunity_period(netuid: u16, immunity_period: u16) { - SubtensorModule::set_immunity_period(netuid, immunity_period); - } - - fn set_max_weight_limit(netuid: u16, max_weight_limit: u16) { - SubtensorModule::set_max_weight_limit(netuid, max_weight_limit); - } - - fn set_scaling_law_power(netuid: u16, scaling_law_power: u16) { - SubtensorModule::set_scaling_law_power(netuid, scaling_law_power); - } - - fn set_validator_prune_len(netuid: u16, validator_prune_len: u64) { - SubtensorModule::set_validator_prune_len(netuid, validator_prune_len); - } - - fn set_adjustment_interval(netuid: u16, adjustment_interval: u16) { - SubtensorModule::set_adjustment_interval(netuid, adjustment_interval); - } - - fn set_weights_set_rate_limit(netuid: u16, weights_set_rate_limit: u64) { - SubtensorModule::set_weights_set_rate_limit(netuid, weights_set_rate_limit); - } - - fn set_rao_recycled(netuid: u16, rao_recycled: u64) { - SubtensorModule::set_rao_recycled(netuid, rao_recycled); - } - - fn is_hotkey_registered_on_network(netuid: u16, hotkey: &AccountId) -> bool { - SubtensorModule::is_hotkey_registered_on_network(netuid, hotkey) - } - - fn init_new_network(netuid: u16, tempo: u16) { - SubtensorModule::init_new_network(netuid, tempo); - } - - fn set_weights_min_stake(min_stake: u64) { - SubtensorModule::set_weights_min_stake(min_stake); - } - - fn set_nominator_min_required_stake(min_stake: u64) { - SubtensorModule::set_nominator_min_required_stake(min_stake); - } - - fn get_nominator_min_required_stake() -> u64 { - SubtensorModule::get_nominator_min_required_stake() - } - - fn clear_small_nominations() { - SubtensorModule::clear_small_nominations(); - } - - fn set_target_stakes_per_interval(target_stakes_per_interval: u64) { - SubtensorModule::set_target_stakes_per_interval(target_stakes_per_interval); - } - - fn set_commit_reveal_weights_interval(netuid: u16, interval: u64) { - SubtensorModule::set_commit_reveal_weights_interval(netuid, interval); - } - - fn set_commit_reveal_weights_enabled(netuid: u16, enabled: bool) { - SubtensorModule::set_commit_reveal_weights_enabled(netuid, enabled); - } - - fn set_liquid_alpha_enabled(netuid: u16, enabled: bool) { - SubtensorModule::set_liquid_alpha_enabled(netuid, enabled); - } - fn do_set_alpha_values( - origin: RuntimeOrigin, - netuid: u16, - alpha_low: u16, - alpha_high: u16, - ) -> Result<(), DispatchError> { - SubtensorModule::do_set_alpha_values(origin, netuid, alpha_low, alpha_high) - } -} - impl pallet_admin_utils::Config for Test { type RuntimeEvent = RuntimeEvent; type AuthorityId = AuraId; type MaxAuthorities = ConstU32<32>; type Aura = (); type Balance = Balance; - type Subtensor = SubtensorIntrf; type WeightInfo = (); } From 83d680d1e3785c8e9a2f3ad34e46950ea46cffb7 Mon Sep 17 00:00:00 2001 From: Keith Date: Fri, 2 Aug 2024 15:55:22 +0900 Subject: [PATCH 068/177] Remove unused import --- 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 d302652d4..66cea80d4 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -15,7 +15,7 @@ use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::{ dispatch::DispatchResultWithPostInfo, genesis_builder_helper::{build_config, create_default_config}, - pallet_prelude::{DispatchError, Get}, + pallet_prelude::Get, traits::{fungible::HoldConsideration, Contains, LinearStoragePrice}, }; use frame_system::{EnsureNever, EnsureRoot, EnsureRootWithSuccess, RawOrigin}; From 063cf574cca294b8f67c7c9ee84b915879d20599 Mon Sep 17 00:00:00 2001 From: Keith Date: Fri, 2 Aug 2024 16:05:00 +0900 Subject: [PATCH 069/177] Fix clippy --- pallets/collective/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/pallets/collective/src/lib.rs b/pallets/collective/src/lib.rs index 96040f99c..66c55036d 100644 --- a/pallets/collective/src/lib.rs +++ b/pallets/collective/src/lib.rs @@ -951,6 +951,7 @@ 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 From af4bf3527fcea4fd8586f0c37039d12e8758d614 Mon Sep 17 00:00:00 2001 From: open-junius Date: Fri, 2 Aug 2024 15:20:51 +0800 Subject: [PATCH 070/177] fix zepter --- pallets/admin-utils/Cargo.toml | 2 ++ pallets/subtensor/Cargo.toml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/pallets/admin-utils/Cargo.toml b/pallets/admin-utils/Cargo.toml index ff54989cd..c67c00914 100644 --- a/pallets/admin-utils/Cargo.toml +++ b/pallets/admin-utils/Cargo.toml @@ -51,12 +51,14 @@ std = [ "pallet-subtensor/std", "sp-consensus-aura/std", "pallet-balances/std", + "pallet-scheduler/std", "sp-runtime/std", "sp-tracing/std", "sp-weights/std", "log/std", "sp-core/std", "sp-io/std", + "sp-std/std", "substrate-fixed/std", ] runtime-benchmarks = [ diff --git a/pallets/subtensor/Cargo.toml b/pallets/subtensor/Cargo.toml index 2baee6127..3c0bd71c1 100644 --- a/pallets/subtensor/Cargo.toml +++ b/pallets/subtensor/Cargo.toml @@ -70,6 +70,8 @@ std = [ "pallet-membership/std", "substrate-fixed/std", "pallet-balances/std", + "pallet-preimage/std", + "pallet-scheduler/std", "pallet-transaction-payment/std", "pallet-utility/std", "sp-core/std", From 0bce83eaeb2a0d4de86dfab4cf68bf431c7625c1 Mon Sep 17 00:00:00 2001 From: open-junius Date: Fri, 2 Aug 2024 15:25:41 +0800 Subject: [PATCH 071/177] fix clippy --- runtime/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 12fb55586..b606d2eb1 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -538,6 +538,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 5181bef8424c1ce31a2c0a30f0e14b64a4c69eec Mon Sep 17 00:00:00 2001 From: Keith Date: Fri, 2 Aug 2024 17:41:27 +0900 Subject: [PATCH 072/177] Remove references to T::Subtensor in benchmarks --- pallets/admin-utils/src/benchmarking.rs | 48 ++++++++++++------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/pallets/admin-utils/src/benchmarking.rs b/pallets/admin-utils/src/benchmarking.rs index 0158311f7..59f16f6c4 100644 --- a/pallets/admin-utils/src/benchmarking.rs +++ b/pallets/admin-utils/src/benchmarking.rs @@ -47,7 +47,7 @@ mod benchmarks { #[benchmark] fn sudo_set_max_difficulty() { - T::Subtensor::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/); + pallet_subtensor::Pallet::::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/); #[extrinsic_call] _(RawOrigin::Root, 1u16/*netuid*/, 10000u64/*max_difficulty*/)/*sudo_set_max_difficulty*/; @@ -55,7 +55,7 @@ mod benchmarks { #[benchmark] fn sudo_set_min_difficulty() { - T::Subtensor::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/); + pallet_subtensor::Pallet::::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/); #[extrinsic_call] _(RawOrigin::Root, 1u16/*netuid*/, 1000u64/*min_difficulty*/)/*sudo_set_min_difficulty*/; @@ -63,7 +63,7 @@ mod benchmarks { #[benchmark] fn sudo_set_weights_set_rate_limit() { - T::Subtensor::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/); + pallet_subtensor::Pallet::::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/); #[extrinsic_call] _(RawOrigin::Root, 1u16/*netuid*/, 3u64/*rate_limit*/)/*sudo_set_weights_set_rate_limit*/; @@ -71,7 +71,7 @@ mod benchmarks { #[benchmark] fn sudo_set_weights_version_key() { - T::Subtensor::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/); + pallet_subtensor::Pallet::::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/); #[extrinsic_call] _(RawOrigin::Root, 1u16/*netuid*/, 1u64/*version_key*/)/*sudo_set_weights_version_key*/; @@ -79,7 +79,7 @@ mod benchmarks { #[benchmark] fn sudo_set_bonds_moving_average() { - T::Subtensor::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/); + pallet_subtensor::Pallet::::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/); #[extrinsic_call] _(RawOrigin::Root, 1u16/*netuid*/, 100u64/*bonds_moving_average*/)/*sudo_set_bonds_moving_average*/; @@ -87,7 +87,7 @@ mod benchmarks { #[benchmark] fn sudo_set_max_allowed_validators() { - T::Subtensor::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/); + pallet_subtensor::Pallet::::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/); #[extrinsic_call] _(RawOrigin::Root, 1u16/*netuid*/, 10u16/*max_allowed_validators*/)/*sudo_set_max_allowed_validators*/; @@ -95,7 +95,7 @@ mod benchmarks { #[benchmark] fn sudo_set_difficulty() { - T::Subtensor::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/); + pallet_subtensor::Pallet::::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/); #[extrinsic_call] _(RawOrigin::Root, 1u16/*netuid*/, 1200000u64/*difficulty*/)/*sudo_set_difficulty*/; @@ -103,7 +103,7 @@ mod benchmarks { #[benchmark] fn sudo_set_adjustment_interval() { - T::Subtensor::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/); + pallet_subtensor::Pallet::::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/); #[extrinsic_call] _(RawOrigin::Root, 1u16/*netuid*/, 12u16/*adjustment_interval*/)/*sudo_set_adjustment_interval*/; @@ -111,7 +111,7 @@ mod benchmarks { #[benchmark] fn sudo_set_target_registrations_per_interval() { - T::Subtensor::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/); + pallet_subtensor::Pallet::::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/); #[extrinsic_call] _(RawOrigin::Root, 1u16/*netuid*/, 300u16/*target_registrations*/)/*sudo_set_target_registrations_per_interval*/; @@ -119,7 +119,7 @@ mod benchmarks { #[benchmark] fn sudo_set_activity_cutoff() { - T::Subtensor::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/); + pallet_subtensor::Pallet::::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/); #[extrinsic_call] _(RawOrigin::Root, 1u16/*netuid*/, 300u16/*activity_cutoff*/)/*sudo_set_activity_cutoff*/; @@ -127,7 +127,7 @@ mod benchmarks { #[benchmark] fn sudo_set_rho() { - T::Subtensor::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/); + pallet_subtensor::Pallet::::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/); #[extrinsic_call] _(RawOrigin::Root, 1u16/*netuid*/, 300u16/*rho*/)/*sudo_set_rho*/; @@ -135,7 +135,7 @@ mod benchmarks { #[benchmark] fn sudo_set_kappa() { - T::Subtensor::init_new_network(1u16 /*netuid*/, 1u16 /*sudo_tempo*/); + pallet_subtensor::Pallet::::init_new_network(1u16 /*netuid*/, 1u16 /*sudo_tempo*/); #[extrinsic_call] _(RawOrigin::Root, 1u16/*netuid*/, 3u16/*kappa*/)/*set_kappa*/; @@ -143,7 +143,7 @@ mod benchmarks { #[benchmark] fn sudo_set_max_allowed_uids() { - T::Subtensor::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/); + pallet_subtensor::Pallet::::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/); #[extrinsic_call] _(RawOrigin::Root, 1u16/*netuid*/, 4097u16/*max_allowed_uids*/)/*sudo_set_max_allowed_uids*/; @@ -151,7 +151,7 @@ mod benchmarks { #[benchmark] fn sudo_set_min_allowed_weights() { - T::Subtensor::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/); + pallet_subtensor::Pallet::::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/); #[extrinsic_call] _(RawOrigin::Root, 1u16/*netuid*/, 10u16/*max_allowed_uids*/)/*sudo_set_min_allowed_weights*/; @@ -159,7 +159,7 @@ mod benchmarks { #[benchmark] fn sudo_set_immunity_period() { - T::Subtensor::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/); + pallet_subtensor::Pallet::::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/); #[extrinsic_call] _(RawOrigin::Root, 1u16/*netuid*/, 100u16/*immunity_period*/)/*sudo_set_immunity_period*/; @@ -167,7 +167,7 @@ mod benchmarks { #[benchmark] fn sudo_set_max_weight_limit() { - T::Subtensor::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/); + pallet_subtensor::Pallet::::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/); #[extrinsic_call] _(RawOrigin::Root, 1u16/*netuid*/, 100u16/*max_weight_limit*/)/*sudo_set_max_weight_limit*/; @@ -175,7 +175,7 @@ mod benchmarks { #[benchmark] fn sudo_set_max_registrations_per_block() { - T::Subtensor::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/); + pallet_subtensor::Pallet::::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/); #[extrinsic_call] _(RawOrigin::Root, 1u16/*netuid*/, 100u16/*max_registrations*/)/*sudo_set_max_registrations_per_block*/; @@ -183,7 +183,7 @@ mod benchmarks { #[benchmark] fn sudo_set_max_burn() { - T::Subtensor::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/); + pallet_subtensor::Pallet::::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/); #[extrinsic_call] _(RawOrigin::Root, 1u16/*netuid*/, 10u64/*max_burn*/)/*sudo_set_max_burn*/; @@ -191,7 +191,7 @@ mod benchmarks { #[benchmark] fn sudo_set_min_burn() { - T::Subtensor::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/); + pallet_subtensor::Pallet::::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/); #[extrinsic_call] _(RawOrigin::Root, 1u16/*netuid*/, 10u64/*min_burn*/)/*sudo_set_min_burn*/; @@ -199,7 +199,7 @@ mod benchmarks { #[benchmark] fn sudo_set_network_registration_allowed() { - T::Subtensor::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/); + pallet_subtensor::Pallet::::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/); #[extrinsic_call] _(RawOrigin::Root, 1u16/*netuid*/, true/*registration_allowed*/)/*sudo_set_network_registration_allowed*/; @@ -212,13 +212,13 @@ mod benchmarks { let tempo: u16 = 15; let modality: u16 = 0; - T::Subtensor::init_new_network(netuid, tempo); + pallet_subtensor::Pallet::::init_new_network(netuid, tempo); }: sudo_set_tempo(RawOrigin::>::Root, netuid, tempo) */ #[benchmark] fn sudo_set_tempo() { - T::Subtensor::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/); + pallet_subtensor::Pallet::::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/); #[extrinsic_call] _(RawOrigin::Root, 1u16/*netuid*/, 1u16/*tempo*/)/*sudo_set_tempo*/; @@ -226,7 +226,7 @@ mod benchmarks { #[benchmark] fn sudo_set_commit_reveal_weights_interval() { - T::Subtensor::init_new_network(1u16 /*netuid*/, 1u16 /*sudo_tempo*/); + pallet_subtensor::Pallet::::init_new_network(1u16 /*netuid*/, 1u16 /*sudo_tempo*/); #[extrinsic_call] _(RawOrigin::Root, 1u16/*netuid*/, 3u64/*interval*/)/*set_commit_reveal_weights_interval()*/; @@ -234,7 +234,7 @@ mod benchmarks { #[benchmark] fn sudo_set_commit_reveal_weights_enabled() { - T::Subtensor::init_new_network(1u16 /*netuid*/, 1u16 /*sudo_tempo*/); + pallet_subtensor::Pallet::::init_new_network(1u16 /*netuid*/, 1u16 /*sudo_tempo*/); #[extrinsic_call] _(RawOrigin::Root, 1u16/*netuid*/, true/*enabled*/)/*set_commit_reveal_weights_enabled*/; From 06013f87ea9eb3884f4300c8bc0d151623266a38 Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Fri, 2 Aug 2024 14:38:52 +0400 Subject: [PATCH 073/177] chore: remove childkey take removal --- pallets/admin-utils/tests/mock.rs | 5 +- pallets/subtensor/src/staking/set_children.rs | 5 -- pallets/subtensor/tests/children.rs | 52 ------------------- 3 files changed, 2 insertions(+), 60 deletions(-) diff --git a/pallets/admin-utils/tests/mock.rs b/pallets/admin-utils/tests/mock.rs index 0142a435a..acb9c8a4a 100644 --- a/pallets/admin-utils/tests/mock.rs +++ b/pallets/admin-utils/tests/mock.rs @@ -79,9 +79,8 @@ parameter_types! { pub const InitialFoundationDistribution: u64 = 0; pub const InitialDefaultDelegateTake: u16 = 11_796; // 18% honest number. pub const InitialMinDelegateTake: u16 = 5_898; // 9%; - pub const InitialDefaultChildKeyTake: u16 = 11_796; // 18% honest number. - pub const InitialMinChildKeyTake: u16 = 5_898; // 9%; - pub const InitialMinTake: u16 = 5_898; // 9%; + pub const InitialDefaultChildKeyTake: u16 = 0; // Allow 0 % + pub const InitialMinChildKeyTake: u16 = 0; // Allow 0 % pub const InitialWeightsVersionKey: u16 = 0; pub const InitialServingRateLimit: u64 = 0; // No limit. pub const InitialTxRateLimit: u64 = 0; // Disable rate limit for testing diff --git a/pallets/subtensor/src/staking/set_children.rs b/pallets/subtensor/src/staking/set_children.rs index f60298d57..fda0ae27b 100644 --- a/pallets/subtensor/src/staking/set_children.rs +++ b/pallets/subtensor/src/staking/set_children.rs @@ -130,11 +130,6 @@ impl Pallet { // --- 7.1. Insert my new children + proportion list into the map. ChildKeys::::insert(hotkey.clone(), netuid, children.clone()); - if children.is_empty() { - // If there are no children, remove the ChildkeyTake value - ChildkeyTake::::remove(hotkey.clone(), netuid); - } - // --- 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. diff --git a/pallets/subtensor/tests/children.rs b/pallets/subtensor/tests/children.rs index 2a15d05d6..6a37b5bea 100644 --- a/pallets/subtensor/tests/children.rs +++ b/pallets/subtensor/tests/children.rs @@ -1622,55 +1622,3 @@ fn test_get_parents_chain() { ); }); } - -// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_childkey_take_removal_on_empty_children --exact --nocapture -#[test] -fn test_childkey_take_removal_on_empty_children() { - 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 a child and childkey take - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey), - hotkey, - netuid, - vec![(proportion, child)] - )); - - let take: u16 = u16::MAX / 10; // 10% take - assert_ok!(SubtensorModule::set_childkey_take( - RuntimeOrigin::signed(coldkey), - hotkey, - netuid, - take - )); - - // Verify childkey take is set - assert_eq!(SubtensorModule::get_childkey_take(&hotkey, netuid), take); - - // Remove all children - assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey), - hotkey, - netuid, - vec![] - )); - - // Verify children are removed - let children = SubtensorModule::get_children(&hotkey, netuid); - assert!(children.is_empty()); - - // Verify childkey take is removed - assert_eq!(SubtensorModule::get_childkey_take(&hotkey, netuid), 0); - // Verify childkey take storage is empty - assert_eq!(ChildkeyTake::::get(hotkey, netuid), 0); - }); -} From 7a935f9853a87b095cc84b009c45677f2d682a19 Mon Sep 17 00:00:00 2001 From: Keith Date: Fri, 2 Aug 2024 22:28:44 +0900 Subject: [PATCH 074/177] cargo fmt --- pallets/admin-utils/src/benchmarking.rs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/pallets/admin-utils/src/benchmarking.rs b/pallets/admin-utils/src/benchmarking.rs index 59f16f6c4..f12836af9 100644 --- a/pallets/admin-utils/src/benchmarking.rs +++ b/pallets/admin-utils/src/benchmarking.rs @@ -135,7 +135,10 @@ mod benchmarks { #[benchmark] fn sudo_set_kappa() { - pallet_subtensor::Pallet::::init_new_network(1u16 /*netuid*/, 1u16 /*sudo_tempo*/); + pallet_subtensor::Pallet::::init_new_network( + 1u16, /*netuid*/ + 1u16, /*sudo_tempo*/ + ); #[extrinsic_call] _(RawOrigin::Root, 1u16/*netuid*/, 3u16/*kappa*/)/*set_kappa*/; @@ -226,7 +229,10 @@ mod benchmarks { #[benchmark] fn sudo_set_commit_reveal_weights_interval() { - pallet_subtensor::Pallet::::init_new_network(1u16 /*netuid*/, 1u16 /*sudo_tempo*/); + pallet_subtensor::Pallet::::init_new_network( + 1u16, /*netuid*/ + 1u16, /*sudo_tempo*/ + ); #[extrinsic_call] _(RawOrigin::Root, 1u16/*netuid*/, 3u64/*interval*/)/*set_commit_reveal_weights_interval()*/; @@ -234,7 +240,10 @@ mod benchmarks { #[benchmark] fn sudo_set_commit_reveal_weights_enabled() { - pallet_subtensor::Pallet::::init_new_network(1u16 /*netuid*/, 1u16 /*sudo_tempo*/); + pallet_subtensor::Pallet::::init_new_network( + 1u16, /*netuid*/ + 1u16, /*sudo_tempo*/ + ); #[extrinsic_call] _(RawOrigin::Root, 1u16/*netuid*/, true/*enabled*/)/*set_commit_reveal_weights_enabled*/; From d719cf6508589256e900f7eafb9b87d95cca50e5 Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Sun, 4 Aug 2024 12:46:34 +0400 Subject: [PATCH 075/177] chore: fmt --- pallets/admin-utils/src/lib.rs | 2 +- runtime/src/lib.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pallets/admin-utils/src/lib.rs b/pallets/admin-utils/src/lib.rs index c29323e4c..c9dddad19 100644 --- a/pallets/admin-utils/src/lib.rs +++ b/pallets/admin-utils/src/lib.rs @@ -1128,7 +1128,7 @@ pub mod pallet { Ok(()) } - } + } } impl sp_runtime::BoundToRuntimeAppPublic for Pallet { diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index b08ddf539..3ba2ac180 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -16,7 +16,7 @@ use frame_support::traits::Imbalance; use frame_support::{ dispatch::DispatchResultWithPostInfo, genesis_builder_helper::{build_config, create_default_config}, - pallet_prelude::{DispatchError, Get}, + pallet_prelude::Get, traits::{fungible::HoldConsideration, Contains, LinearStoragePrice, OnUnbalanced}, }; use frame_system::{EnsureNever, EnsureRoot, EnsureRootWithSuccess, RawOrigin}; @@ -141,7 +141,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: 192, + spec_version: 193, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1, From d35d20bcfdad66731fdb2e4d090551e279ec6f1f Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Sun, 4 Aug 2024 12:50:33 +0400 Subject: [PATCH 076/177] chore: bump spec --- 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 303e7040f..fd23d1fd3 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: 193, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1, From 02325f3620fba06bc405e986b7acfc4c1514f469 Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Sun, 4 Aug 2024 13:08:13 +0400 Subject: [PATCH 077/177] bump spec , formats --- pallets/subtensor/src/lib.rs | 10 --- pallets/subtensor/tests/root.rs | 104 ----------------------------- pallets/subtensor/tests/staking.rs | 3 - 3 files changed, 117 deletions(-) diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index dd6948c56..6388e0331 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -1347,20 +1347,10 @@ where priority: Self::get_priority_vanilla(), ..Default::default() }), -<<<<<<< HEAD - - Ok(ValidTransaction { - priority: Self::get_priority_vanilla(), - ..Default::default() - }) - } - } -======= Some(Call::dissolve_network { .. }) => Ok(ValidTransaction { priority: Self::get_priority_vanilla(), ..Default::default() }), ->>>>>>> origin/devnet-ready _ => Ok(ValidTransaction { priority: Self::get_priority_vanilla(), ..Default::default() diff --git a/pallets/subtensor/tests/root.rs b/pallets/subtensor/tests/root.rs index 9cc694a52..84df71d83 100644 --- a/pallets/subtensor/tests/root.rs +++ b/pallets/subtensor/tests/root.rs @@ -7,10 +7,6 @@ use frame_system::{EventRecord, Phase}; use pallet_subtensor::migrations; use pallet_subtensor::Error; use sp_core::{Get, H256, U256}; -use sp_runtime::{ - traits::{DispatchInfoOf, SignedExtension}, - transaction_validity::{InvalidTransaction, TransactionValidityError}, -}; mod mock; @@ -983,103 +979,3 @@ fn test_dissolve_network_does_not_exist_err() { ); }); } - -#[test] -fn test_dissolve_network_validate() { - 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; - } - } - // Testing the signed extension validate function - // correctly filters the `dissolve_network` transaction. - - new_test_ext(0).execute_with(|| { - let netuid: u16 = 1; - let delegate_coldkey = U256::from(1); - let delegate_hotkey = U256::from(2); - let new_coldkey = U256::from(3); - 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 - let delegator = U256::from(4); - SubtensorModule::add_balance_to_coldkey_account(&delegator, stake_amount); - assert_ok!(SubtensorModule::add_stake( - RuntimeOrigin::signed(delegator), - delegate_hotkey, - stake_amount - )); - - // Ensure the 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()), - ); - - // Schedule coldkey swap - assert_ok!(SubtensorModule::do_schedule_coldkey_swap( - &delegate_coldkey, - &new_coldkey, - work.to_fixed_bytes().to_vec(), - current_block, - nonce, - )); - - // Verify that the swap was scheduled - assert_eq!( - ColdkeySwapDestinations::::get(delegate_coldkey), - vec![new_coldkey] - ); - - // Check if the coldkey is in arbitration - assert!( - SubtensorModule::coldkey_in_arbitration(&delegate_coldkey), - "Delegate coldkey should be in arbitration after swap" - ); - - let who = delegate_coldkey; // The coldkey signs this transaction - let call = RuntimeCall::SubtensorModule(SubtensorCall::dissolve_network { netuid }); - - let info: DispatchInfo = - DispatchInfoOf::<::RuntimeCall>::default(); - - let extension = pallet_subtensor::SubtensorSignedExtension::::new(); - - // Submit to the signed extension validate function - let result_in_arbitration = extension.validate(&who, &call.clone(), &info, 10); - // Should fail with InvalidTransaction::Custom(6) because coldkey is in arbitration - assert_err!( - result_in_arbitration, - TransactionValidityError::Invalid(InvalidTransaction::Custom(6)) - ); - }); -} diff --git a/pallets/subtensor/tests/staking.rs b/pallets/subtensor/tests/staking.rs index 3cf9609d7..5bf95841a 100644 --- a/pallets/subtensor/tests/staking.rs +++ b/pallets/subtensor/tests/staking.rs @@ -1,9 +1,6 @@ #![allow(clippy::unwrap_used)] #![allow(clippy::arithmetic_side_effects)] -use frame_support::pallet_prelude::{InvalidTransaction, TransactionValidity}; -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; From 22cc4b5f664bfd1d611fff79f2cfdaf8126feb51 Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Wed, 31 Jul 2024 11:40:56 +0400 Subject: [PATCH 078/177] chore: skip wasm builds on test scripts --- scripts/test_specific.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/scripts/test_specific.sh b/scripts/test_specific.sh index 018872d33..85f3ebe30 100755 --- a/scripts/test_specific.sh +++ b/scripts/test_specific.sh @@ -1,6 +1,4 @@ pallet="${3:-pallet-subtensor}" features="${4:-pow-faucet}" -# RUST_LOG="pallet_subtensor=info" cargo test --release --features=$features -p $pallet --test $1 -- $2 --nocapture --exact - -RUST_LOG=INFO cargo test --release --features=$features -p $pallet --test $1 -- $2 --nocapture --exact \ No newline at end of file +SKIP_WASM_BUILD=1 RUST_LOG=DEBUG cargo test --release --features=$features -p $pallet --test $1 -- $2 --nocapture --exact \ No newline at end of file From 21e3c26a5f64c0dd135343c1277a3f19c4e62684 Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Sun, 4 Aug 2024 13:37:53 +0400 Subject: [PATCH 079/177] feat: patch errors and assertions --- pallets/subtensor/src/macros/errors.rs | 4 ++++ pallets/subtensor/src/swap/swap_coldkey.rs | 13 +++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/pallets/subtensor/src/macros/errors.rs b/pallets/subtensor/src/macros/errors.rs index d51469482..9c344ab8d 100644 --- a/pallets/subtensor/src/macros/errors.rs +++ b/pallets/subtensor/src/macros/errors.rs @@ -174,5 +174,9 @@ mod errors { SwapAlreadyScheduled, /// failed to swap coldkey FailedToSchedule, + /// New coldkey is hotkey + NewColdKeyIsHotkey, + /// New coldkey is in arbitration + NewColdkeyIsInArbitration, } } diff --git a/pallets/subtensor/src/swap/swap_coldkey.rs b/pallets/subtensor/src/swap/swap_coldkey.rs index 2b54d4313..5b02d49b5 100644 --- a/pallets/subtensor/src/swap/swap_coldkey.rs +++ b/pallets/subtensor/src/swap/swap_coldkey.rs @@ -35,18 +35,27 @@ impl Pallet { ) -> DispatchResultWithPostInfo { // 2. Initialize the weight for this operation let mut weight: Weight = T::DbWeight::get().reads(2); - // 3. Ensure the new coldkey is not associated with any hotkeys ensure!( StakingHotkeys::::get(new_coldkey).is_empty(), Error::::ColdKeyAlreadyAssociated ); + weight = weight.saturating_add(T::DbWeight::get().reads(1)); // 4. Ensure the new coldkey is not a hotkey ensure!( !Self::hotkey_account_exists(new_coldkey), - Error::::ColdKeyAlreadyAssociated + Error::::NewColdKeyIsHotkey ); + weight = weight.saturating_add(T::DbWeight::get().reads(1)); + + // TODO: Consider adding a check to ensure the new coldkey is not in arbitration + // ensure!( + // !Self::coldkey_in_arbitration(new_coldkey), + // Error::::NewColdkeyIsInArbitration + // ); + + // Note: We might want to add a cooldown period for coldkey swaps to prevent abuse // 5. Calculate the swap cost and ensure sufficient balance let swap_cost = Self::get_key_swap_cost(); From 9b557c43e484cb8feda2a4ccbc95561630fa7a41 Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Mon, 5 Aug 2024 16:54:45 +0400 Subject: [PATCH 080/177] feat: fix child take tests --- pallets/subtensor/src/lib.rs | 6 +- pallets/subtensor/src/macros/dispatches.rs | 2 +- pallets/subtensor/src/staking/set_children.rs | 30 ++-- pallets/subtensor/src/utils/misc.rs | 78 +++++------ pallets/subtensor/src/utils/rate_limiting.rs | 17 ++- pallets/subtensor/tests/children.rs | 132 +++++++++--------- pallets/subtensor/tests/mock.rs | 3 +- runtime/src/lib.rs | 2 +- 8 files changed, 143 insertions(+), 127 deletions(-) diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index 93fa6a6f2..edc9040ac 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -1137,7 +1137,11 @@ pub mod pallet { pub type LastTxBlock = StorageMap<_, Identity, T::AccountId, u64, ValueQuery, DefaultLastTxBlock>; #[pallet::storage] - /// --- MAP ( key ) --> last_block + /// --- MAP ( key ) --> last_tx_block_childkey_take + pub type LastTxBlockChildKeyTake = + StorageMap<_, Identity, T::AccountId, u64, ValueQuery, DefaultLastTxBlock>; + #[pallet::storage] + /// --- MAP ( key ) --> last_tx_block_delegate_take pub type LastTxBlockDelegateTake = StorageMap<_, Identity, T::AccountId, u64, ValueQuery, DefaultLastTxBlock>; #[pallet::storage] diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index f62efd94c..a776cfc4f 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -737,7 +737,7 @@ mod dispatches { /// * `TxChildkeyTakeRateLimitExceeded`: /// - The rate limit for changing childkey take has been exceeded. /// - #[pallet::call_index(68)] + #[pallet::call_index(75)] #[pallet::weight(( Weight::from_parts(34_000, 0) .saturating_add(T::DbWeight::get().reads(4)) diff --git a/pallets/subtensor/src/staking/set_children.rs b/pallets/subtensor/src/staking/set_children.rs index fda0ae27b..402e9fd2a 100644 --- a/pallets/subtensor/src/staking/set_children.rs +++ b/pallets/subtensor/src/staking/set_children.rs @@ -236,26 +236,28 @@ impl Pallet { Error::::InvalidChildkeyTake ); - // Ensure the hotkey passes the rate limit - ensure!( - Self::passes_rate_limit_on_subnet(&TransactionType::SetChildkeyTake, &hotkey, netuid), - Error::::TxChildkeyTakeRateLimitExceeded + // Check if the rate limit has been exceeded + let current_block = Self::get_current_block_as_u64(); + let last_tx_block = + Self::get_last_transaction_block(&hotkey, netuid, &TransactionType::SetChildkeyTake); + let rate_limit = TxChildkeyTakeRateLimit::::get(); + let passes = + Self::passes_rate_limit_on_subnet(&TransactionType::SetChildkeyTake, &hotkey, netuid); + + log::info!( + "Rate limit check: current_block: {}, last_tx_block: {}, rate_limit: {}, passes: {}", + current_block, + last_tx_block, + rate_limit, + passes ); + ensure!(passes, Error::::TxChildkeyTakeRateLimitExceeded); + // Set the new childkey take value for the given hotkey and network ChildkeyTake::::insert(hotkey.clone(), netuid, take); - // TODO: Consider adding a check to ensure the hotkey is registered on the specified network (netuid) - // before setting the childkey take. This could prevent setting takes for non-existent or - // unregistered hotkeys. - - // NOTE: The childkey take is now associated with both the hotkey and the network ID. - // This allows for different take values across different networks for the same hotkey. - // Update the last transaction block - let current_block: u64 = >::block_number() - .try_into() - .unwrap_or(0); Self::set_last_transaction_block( &hotkey, netuid, diff --git a/pallets/subtensor/src/utils/misc.rs b/pallets/subtensor/src/utils/misc.rs index 9155357c0..c75ce1a8d 100644 --- a/pallets/subtensor/src/utils/misc.rs +++ b/pallets/subtensor/src/utils/misc.rs @@ -8,33 +8,6 @@ use sp_core::U256; use sp_runtime::Saturating; 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, @@ -312,17 +285,7 @@ impl Pallet { pub fn coinbase(amount: u64) { TotalIssuance::::put(TotalIssuance::::get().saturating_add(amount)); } - pub fn get_default_take() -> u16 { - // Default to maximum - MaxTake::::get() - } - pub fn set_max_take(default_take: u16) { - MaxTake::::put(default_take); - Self::deposit_event(Event::DefaultTakeSet(default_take)); - } - pub fn get_min_take() -> u16 { - MinTake::::get() - } + pub fn set_subnet_locked_balance(netuid: u16, amount: u64) { SubnetLocked::::insert(netuid, amount); } @@ -357,18 +320,49 @@ impl Pallet { Self::deposit_event(Event::TxDelegateTakeRateLimitSet(tx_rate_limit)); } pub fn set_min_delegate_take(take: u16) { - MinTake::::put(take); + MinDelegateTake::::put(take); Self::deposit_event(Event::MinDelegateTakeSet(take)); } pub fn set_max_delegate_take(take: u16) { - MaxTake::::put(take); + MaxDelegateTake::::put(take); Self::deposit_event(Event::MaxDelegateTakeSet(take)); } pub fn get_min_delegate_take() -> u16 { - MinTake::::get() + MinDelegateTake::::get() } pub fn get_max_delegate_take() -> u16 { - MaxTake::::get() + MaxDelegateTake::::get() + } + pub fn get_default_delegate_take() -> u16 { + // Default to maximum + MaxDelegateTake::::get() + } + // get_default_childkey_take + pub fn get_default_childkey_take() -> u16 { + // Default to maximum + MinChildkeyTake::::get() + } + pub fn get_tx_childkey_take_rate_limit() -> u64 { + TxChildkeyTakeRateLimit::::get() + } + pub fn set_tx_childkey_take_rate_limit(tx_rate_limit: u64) { + TxChildkeyTakeRateLimit::::put(tx_rate_limit); + Self::deposit_event(Event::TxChildKeyTakeRateLimitSet(tx_rate_limit)); + } + pub fn set_min_childkey_take(take: u16) { + MinChildkeyTake::::put(take); + Self::deposit_event(Event::MinChildKeyTakeSet(take)); + } + pub fn set_max_childkey_take(take: u16) { + MaxChildkeyTake::::put(take); + Self::deposit_event(Event::MaxChildKeyTakeSet(take)); + } + pub fn get_min_childkey_take() -> u16 { + MinChildkeyTake::::get() + } + + pub fn get_max_childkey_take() -> u16 { + MaxChildkeyTake::::get() } pub fn get_serving_rate_limit(netuid: u16) -> u64 { diff --git a/pallets/subtensor/src/utils/rate_limiting.rs b/pallets/subtensor/src/utils/rate_limiting.rs index ffd17ca93..b02ad9855 100644 --- a/pallets/subtensor/src/utils/rate_limiting.rs +++ b/pallets/subtensor/src/utils/rate_limiting.rs @@ -5,6 +5,7 @@ use sp_core::Get; #[derive(Copy, Clone)] pub enum TransactionType { SetChildren, + SetChildkeyTake, Unknown, } @@ -13,7 +14,8 @@ impl From for u16 { fn from(tx_type: TransactionType) -> Self { match tx_type { TransactionType::SetChildren => 0, - TransactionType::Unknown => 1, + TransactionType::SetChildkeyTake => 1, + TransactionType::Unknown => 2, } } } @@ -23,6 +25,7 @@ impl From for TransactionType { fn from(value: u16) -> Self { match value { 0 => TransactionType::SetChildren, + 1 => TransactionType::SetChildkeyTake, _ => TransactionType::Unknown, } } @@ -35,6 +38,7 @@ impl Pallet { 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::SetChildkeyTake => TxChildkeyTakeRateLimit::::get(), TransactionType::Unknown => 0, // Default to no limit for unknown types (no limit) } } @@ -48,7 +52,9 @@ impl Pallet { 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 + + // Allow the first transaction (when last_block is 0) or if the rate limit has passed + last_block == 0 || block.saturating_sub(last_block) >= limit } /// Check if a transaction should be rate limited globally @@ -93,6 +99,13 @@ impl Pallet { pub fn get_last_tx_block_delegate_take(key: &T::AccountId) -> u64 { LastTxBlockDelegateTake::::get(key) } + + pub fn set_last_tx_block_childkey_take(key: &T::AccountId, block: u64) { + LastTxBlockChildKeyTake::::insert(key, block) + } + pub fn get_last_tx_block_childkey_take(key: &T::AccountId) -> u64 { + LastTxBlockChildKeyTake::::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 { diff --git a/pallets/subtensor/tests/children.rs b/pallets/subtensor/tests/children.rs index 6a37b5bea..b675ff8e9 100644 --- a/pallets/subtensor/tests/children.rs +++ b/pallets/subtensor/tests/children.rs @@ -2,7 +2,7 @@ use crate::mock::*; use frame_support::{assert_err, assert_noop, assert_ok}; mod mock; -use pallet_subtensor::{utils::TransactionType, *}; +use pallet_subtensor::{utils::rate_limiting::TransactionType, *}; use sp_core::U256; // SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_set_child_singular_success --exact --nocapture @@ -806,12 +806,12 @@ fn test_childkey_take_functionality() { // Test default and max childkey take let default_take = SubtensorModule::get_default_childkey_take(); - let max_take = SubtensorModule::get_max_childkey_take(); - log::info!("Default take: {}, Max take: {}", default_take, max_take); + let min_take = SubtensorModule::get_min_childkey_take(); + log::info!("Default take: {}, Max take: {}", default_take, min_take); // Check if default take and max take are the same assert_eq!( - default_take, max_take, + default_take, min_take, "Default take should be equal to max take" ); @@ -822,7 +822,7 @@ fn test_childkey_take_functionality() { ); // Test setting childkey take - let new_take: u16 = max_take / 2; // 50% of max_take + let new_take: u16 = SubtensorModule::get_max_childkey_take() / 2; // 50% of max_take assert_ok!(SubtensorModule::set_childkey_take( RuntimeOrigin::signed(coldkey), hotkey, @@ -836,7 +836,7 @@ fn test_childkey_take_functionality() { assert_eq!(stored_take, new_take); // Test setting childkey take outside of allowed range - let invalid_take: u16 = max_take + 1; + let invalid_take: u16 = SubtensorModule::get_max_childkey_take() + 1; assert_noop!( SubtensorModule::set_childkey_take( RuntimeOrigin::signed(coldkey), @@ -878,91 +878,75 @@ fn test_childkey_take_rate_limiting() { SubtensorModule::set_tx_childkey_take_rate_limit(rate_limit); log::info!( - "TxChildkeyTakeRateLimit: {:?}", + "Set TxChildkeyTakeRateLimit: {:?}", TxChildkeyTakeRateLimit::::get() ); + // Helper function to log rate limit information + let log_rate_limit_info = || { + let current_block = SubtensorModule::get_current_block_as_u64(); + let last_block = SubtensorModule::get_last_transaction_block( + &hotkey, + netuid, + &TransactionType::SetChildkeyTake, + ); + let passes = SubtensorModule::passes_rate_limit_on_subnet( + &TransactionType::SetChildkeyTake, + &hotkey, + netuid, + ); + let limit = SubtensorModule::get_rate_limit(&TransactionType::SetChildkeyTake); + log::info!( + "Rate limit info: current_block: {}, last_block: {}, limit: {}, passes: {}, diff: {}", + current_block, + last_block, + limit, + passes, + current_block.saturating_sub(last_block) + ); + }; + // First transaction (should succeed) + log_rate_limit_info(); assert_ok!(SubtensorModule::set_childkey_take( RuntimeOrigin::signed(coldkey), hotkey, netuid, 500 )); - - let current_block = SubtensorModule::get_current_block_as_u64(); - let last_block = SubtensorModule::get_last_transaction_block( - &hotkey, - netuid, - &TransactionType::SetChildkeyTake, - ); - log::info!( - "After first transaction: current_block: {}, last_block: {}", - current_block, - last_block - ); + log_rate_limit_info(); // Second transaction (should fail due to rate limit) - let result = - SubtensorModule::set_childkey_take(RuntimeOrigin::signed(coldkey), hotkey, netuid, 600); - log::info!("Second transaction result: {:?}", result); - let current_block = SubtensorModule::get_current_block_as_u64(); - let last_block = SubtensorModule::get_last_transaction_block( - &hotkey, - netuid, - &TransactionType::SetChildkeyTake, - ); - log::info!( - "After second transaction attempt: current_block: {}, last_block: {}", - current_block, - last_block + log_rate_limit_info(); + assert_noop!( + SubtensorModule::set_childkey_take(RuntimeOrigin::signed(coldkey), hotkey, netuid, 600), + Error::::TxChildkeyTakeRateLimitExceeded ); - - assert_noop!(result, Error::::TxChildkeyTakeRateLimitExceeded); + log_rate_limit_info(); // Advance the block number to just before the rate limit - run_to_block(rate_limit); + run_to_block(rate_limit - 1); // Third transaction (should still fail) - let result = - SubtensorModule::set_childkey_take(RuntimeOrigin::signed(coldkey), hotkey, netuid, 650); - log::info!("Third transaction result: {:?}", result); - let current_block = SubtensorModule::get_current_block_as_u64(); - let last_block = SubtensorModule::get_last_transaction_block( - &hotkey, - netuid, - &TransactionType::SetChildkeyTake, - ); - log::info!( - "After third transaction attempt: current_block: {}, last_block: {}", - current_block, - last_block + log_rate_limit_info(); + assert_noop!( + SubtensorModule::set_childkey_take(RuntimeOrigin::signed(coldkey), hotkey, netuid, 650), + Error::::TxChildkeyTakeRateLimitExceeded ); - - assert_noop!(result, Error::::TxChildkeyTakeRateLimitExceeded); + log_rate_limit_info(); // Advance the block number to just after the rate limit - run_to_block(rate_limit * 2); + run_to_block(rate_limit + 1); // Fourth transaction (should succeed) + log_rate_limit_info(); assert_ok!(SubtensorModule::set_childkey_take( RuntimeOrigin::signed(coldkey), hotkey, netuid, 700 )); - - let current_block = SubtensorModule::get_current_block_as_u64(); - let last_block = SubtensorModule::get_last_transaction_block( - &hotkey, - netuid, - &TransactionType::SetChildkeyTake, - ); - log::info!( - "After fourth transaction: current_block: {}, last_block: {}", - current_block, - last_block - ); + log_rate_limit_info(); // Verify the final take was set let stored_take = SubtensorModule::get_childkey_take(&hotkey, netuid); @@ -987,7 +971,7 @@ fn test_multiple_networks_childkey_take() { register_ok_neuron(netuid, hotkey, coldkey, 0); // Set a unique childkey take value for each network - let take_value = (netuid + 1) * 1000; // Values will be 1000, 2000, ..., 10000 + let take_value = (netuid + 1) * 100; // Values will be 200, 300, ..., 1000 assert_ok!(SubtensorModule::set_childkey_take( RuntimeOrigin::signed(coldkey), hotkey, @@ -1019,6 +1003,26 @@ fn test_multiple_networks_childkey_take() { ); } } + + // Attempt to set childkey take again (should fail due to rate limit) + let result = + SubtensorModule::set_childkey_take(RuntimeOrigin::signed(coldkey), hotkey, 1, 1100); + assert_noop!(result, Error::::TxChildkeyTakeRateLimitExceeded); + + // Advance blocks to bypass rate limit + run_to_block(SubtensorModule::get_tx_childkey_take_rate_limit() + 1); + + // Now setting childkey take should succeed + assert_ok!(SubtensorModule::set_childkey_take( + RuntimeOrigin::signed(coldkey), + hotkey, + 1, + 1100 + )); + + // Verify the new take value + let new_take = SubtensorModule::get_childkey_take(&hotkey, 1); + assert_eq!(new_take, 1100, "Childkey take not updated after rate limit"); }); } diff --git a/pallets/subtensor/tests/mock.rs b/pallets/subtensor/tests/mock.rs index 4de74f4ab..4039054e0 100644 --- a/pallets/subtensor/tests/mock.rs +++ b/pallets/subtensor/tests/mock.rs @@ -134,8 +134,7 @@ parameter_types! { pub const InitialDefaultDelegateTake: u16 = 11_796; // 18%, same as in production pub const InitialMinDelegateTake: u16 = 5_898; // 9%; pub const InitialDefaultChildKeyTake: u16 = 11_796; // 18%, same as in production - pub const InitialMinChildKeyTake: u16 = 5_898; // 9%; - pub const InitialMinTake: u16 =5_898; // 9%; + pub const InitialMinChildKeyTake: u16 = 0; // 0 %; pub const InitialWeightsVersionKey: u16 = 0; pub const InitialServingRateLimit: u64 = 0; // No limit. pub const InitialTxRateLimit: u64 = 0; // Disable rate limit for testing diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 4dc0e5d72..dec65f60f 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -873,7 +873,7 @@ parameter_types! { pub const SubtensorInitialDefaultTake: u16 = 11_796; // 18% honest number. pub const SubtensorInitialMinDelegateTake: u16 = 0; // Allow 0% delegate take pub const SubtensorInitialDefaultChildKeyTake: u16 = 0; // Allow 0% childkey take - pub const SubtensorInitialMinChildKeyTake: u16 = 5_898; // 9% + pub const SubtensorInitialMinChildKeyTake: u16 = 0; // 0 % pub const SubtensorInitialWeightsVersionKey: u64 = 0; pub const SubtensorInitialMinDifficulty: u64 = 10_000_000; pub const SubtensorInitialMaxDifficulty: u64 = u64::MAX / 4; From 2625b5da9052d03bc1fb403d180ba99b4c17f9b6 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Mon, 5 Aug 2024 08:58:23 -0400 Subject: [PATCH 081/177] remove unneeded label checks now that we have a simpler process --- .github/workflows/check-rust.yml | 4 ---- .github/workflows/devnet-labels.yml | 19 ------------------- .github/workflows/devnet-ready-labels.yml | 17 ----------------- .github/workflows/testnet-labels.yml | 19 ------------------- .github/workflows/testnet-ready-labels.yml | 17 ----------------- 5 files changed, 76 deletions(-) delete mode 100644 .github/workflows/devnet-labels.yml delete mode 100644 .github/workflows/devnet-ready-labels.yml delete mode 100644 .github/workflows/testnet-labels.yml delete mode 100644 .github/workflows/testnet-ready-labels.yml diff --git a/.github/workflows/check-rust.yml b/.github/workflows/check-rust.yml index e95308861..d36718ef9 100644 --- a/.github/workflows/check-rust.yml +++ b/.github/workflows/check-rust.yml @@ -338,7 +338,3 @@ jobs: - name: Check features run: zepter run check - - - - diff --git a/.github/workflows/devnet-labels.yml b/.github/workflows/devnet-labels.yml deleted file mode 100644 index 85d9e7eed..000000000 --- a/.github/workflows/devnet-labels.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: Tested on Devnet -on: - pull_request: - types: [opened, labeled, unlabeled, synchronize] - branches: [main] -jobs: - check-labels: - runs-on: ubuntu-latest - permissions: - issues: write - pull-requests: write - steps: - - uses: mheap/github-action-required-labels@v5 - with: - mode: minimum - count: 1 - labels: | - devnet-pass - devnet-skip diff --git a/.github/workflows/devnet-ready-labels.yml b/.github/workflows/devnet-ready-labels.yml deleted file mode 100644 index ab53327e7..000000000 --- a/.github/workflows/devnet-ready-labels.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: devnet-companion Label Check -on: - pull_request: - types: [opened, labeled, unlabeled, synchronize] - branches: [devnet-ready] -jobs: - check-labels: - runs-on: ubuntu-latest - permissions: - issues: write - pull-requests: write - steps: - - uses: mheap/github-action-required-labels@v5 - with: - mode: minimum - count: 1 - labels: devnet-companion diff --git a/.github/workflows/testnet-labels.yml b/.github/workflows/testnet-labels.yml deleted file mode 100644 index b4aabd958..000000000 --- a/.github/workflows/testnet-labels.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: Tested on Testnet -on: - pull_request: - types: [opened, labeled, unlabeled, synchronize] - branches: [main] -jobs: - check-labels: - runs-on: ubuntu-latest - permissions: - issues: write - pull-requests: write - steps: - - uses: mheap/github-action-required-labels@v5 - with: - mode: minimum - count: 1 - labels: | - testnet-pass - testnet-skip diff --git a/.github/workflows/testnet-ready-labels.yml b/.github/workflows/testnet-ready-labels.yml deleted file mode 100644 index 8570d2011..000000000 --- a/.github/workflows/testnet-ready-labels.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: testnet-companion Label Check -on: - pull_request: - types: [opened, labeled, unlabeled, synchronize] - branches: [testnet-ready] -jobs: - check-labels: - runs-on: ubuntu-latest - permissions: - issues: write - pull-requests: write - steps: - - uses: mheap/github-action-required-labels@v5 - with: - mode: minimum - count: 1 - labels: testnet-companion From 4dcd6c490fc173b03338aed79f352e4c54b689a1 Mon Sep 17 00:00:00 2001 From: Liam Date: Mon, 5 Aug 2024 15:08:54 +0200 Subject: [PATCH 082/177] 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..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 76541913340687e740d86b171a6371cf9d74c902 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Mon, 5 Aug 2024 09:15:22 -0400 Subject: [PATCH 083/177] update CONTRIBUTING.md --- CONTRIBUTING.md | 131 +++++++++--------------------------------------- 1 file changed, 25 insertions(+), 106 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 132d360b8..8ac806367 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,7 +3,7 @@ ## Lifecycle of a Pull Request 1. Individuals wishing to contribute to subtensor should develop their change/feature/fix in a - [Pull Request](https://github.com/opentensor/subtensor/compare) (PR) targeting the `main` + [Pull Request](https://github.com/opentensor/subtensor/compare) (PR) targeting the `devnet-ready` branch of the subtensor GitHub repository. It is recommended to start your pull request as a draft initially until you are ready to have other developers actively look at it. Any changes to pallet/runtime code should be accompanied by integration and/or unit tests fully @@ -13,69 +13,29 @@ Review" and request review from "Nucleus". 3. Core Nucleus team members will review your PR, possibly requesting changes, and will also add appropriate labels to your PR as shown below. Three positive reviews are required. -4. Once the required passing reviews have been obtained, you are ready to request that your PR - be included in the next `devnet` deploy. To do this, you should open a companion PR merging - a copy of your branch into the `devnet-ready` branch. You must include a link to the parent - PR in the description and preface your PR title with "(Devnet Ready)" or the PR will be - closed/ignored. Your companion PR should have the `devnet-companion` label. -5. A core team administrator will review your "(Devnet Ready)" PR, verifying that it logically - matches the changes introduced in the parent PR (there will sometimes be minor differences - due to merge conflicts) and will either request changes or approve the PR and merge it. Once - your companion PR is merged, the administrator will add the `devnet-ready` label to the - parent PR, indicating that the PR is on the `devnet-ready` branch and will be included in - the next deploy to `devnet`. -6. At some point, a core team administrator will open a PR merging the current `devnet-ready` +4. Once the required passing reviews have been obtained, you or an administrator may merge the + PR into the `devnet-ready` branch. +5. At some point, a core team administrator will open a PR merging the current `devnet-ready` branch into `devnet`, and the CI will enforce some additional safety checks on this PR including a requirement that the new `spec_version` be greater than the current on-chain `spec_version`. The PR should include a bulleted list of all PRs included in the deploy so - they can be easily found after the fact (TODO: automate this). This PR will require two - reviews from the core team as a sanity check. After merging, the administrator will then - need to update all PRs with the `devnet-ready` label to instead have the `on-devnet` label - (TODO: automate this upon merge). The administrator will then deploy `devnet`. -7. Once the `on-devnet` label appears on your PR, if you are a core team member it is your - responsibility to verify that the features/changes/fixes introduced by your PR are - functioning properly on `devnet` by interacting with the live network. If you are an - external contributor, a core team member will be assigned to test this for you. -8. If your feature/change/fix is confirmed working on `devnet`, the `devnet-pass` label should - be added. Otherwise if there are issues, the `devnet-fail` label should be added and you - will need to make changes to your PR and repeat the previous steps in this process. In some - cases a revert PR will need to be created reverting your changes from the `pre-devnet` and - `devnet` branches, respectively. -9. Once `devnet-pass` has been added to your PR, it is eligible for inclusion in the next - `testnet` deploy. We typically run `testnet` deploys every other wednesday. -10. On the appropriate date, an administrator will open a PR merging the current `devnet` + they can be easily found after the fact. +6. Once your feature/change/fix is on `devnet`, it is your responsibility to confirm it is + working properly. If it is not working and additional changes are needed, please coordinate + with a core team administrator and/or open up a new PR into `devnet` either reverting your + changes or making any required changes in order for the feature to function properly. +7. On the appropriate date, an administrator will open a PR merging the current `devnet` branch into `testnet`. This PR should include a bulleted list of all PRs included in the - deploy so they can be easily found after the fact (TODO: automate this). The PR should - exclude any PRs that currently have the `devnet-fail` label via a revert (TODO: enforce via - CI). This PR will require two reviews from the core team as a sanity check. After merging - into `testnet`, the administrator will then need to run the deploy and update all PRs - included in the deploy with the `on-testnet` label (TODO: automate this upon merge). Next - the administrator must cut a (pre-release) release in GitHub for `testnet` (TODO: github - action to generate the release and release notes). -11. Once the `on-testnet` label appears on your PR, if you are a core team member it is your - responsibility to once again verify that the features/changes/fixes introduced by your PR - are functioning properly on `testnet` by interacting with the live network, if applicable. - If you are an external contributor, a core team member may be assigned to do this testing - for you but otherwise it will be your responsibility to show evidence on the PR that the - testing is successful. Once this has been verified, the `testnet-pass` label should be - added. If testing fails, the `testnet-fail` label should be added and PRs should be opened - reverting the change from `devnet-ready`, and then a PR should be opened merging the - modified `devnet` into `testnet`. These revert PRs, if they occur, _must_ be merged before - a new deploy can be run (TODO: enforce this via CI). -12. After the SOP period (1 week on `testnet`) has passed and the `testnet-pass` label has been - added, the CI checks on your PR should now turn all green and a core team member will be - able to merge your PR into `main`. At this point your PR is done and is eligible to be - included in the next `finney` deploy (TODO: track and enforce SOP compliance on a per-PR - basis in CI based on the timestamps of label changes). We typically run `finney` deploys - every other Wednesday, so this will typically happen the Wednesday following the Wednesday - your PR was deployed to `testnet`. An administrator will run this deploy. The process the - administrator follows is to open a PR merging `main` into the `finney` branch, which will - always track the current state of `finney`. This PR automatically has some additional - checks on it such as asserting that the spec_version gets bumped properly and other sanity - checks designed to stop a bad deploy. Once the PR is reviewed and merged, the administrator - will run the actual deploy. Once that is successful, the administrator will cut a new - GitHub release tagged off of the latest `main` branch commit that was included in the - deploy, and announcements will be made regarding the release. + deploy so they can be easily found after the fact (TODO: automate this). This PR is merged, + the administrator will deploy `testnet` and cut a (pre-release) release in GitHub for + `testnet` (TODO: github action to generate the release and release notes). +11. It is now your responsibility to once again check that your feature/change/fix is working + properly, this time on `testnet`. Once again if it is not working or additional changes are + needed, please coordinate with a core team administrator ASAP and/or open up a new PR into + `testnet` either reverting your changes or making any required changes in order for the + feature to function properly. +12. At some point the administrator will merge current `testnet` into `main` and cut a new + deploy to mainnet/finney. ## PR Labels @@ -85,40 +45,24 @@ | `blue-team` | PR is focused on preventative/safety measures and/or dev UX improvements | none | | `runtime` | PR contains substantive changes to runtime / pallet code | none | | `breaking-change` | PR requires synchronized changes with bittensor | Triggers an automatic bot message so the relevant teams are made aware of the change well in advance | -| `migration` | PR contains one or more migrations | none | -| `devnet-companion` | Designates a devnet companion PR | Presence of `devnet-companion` label is checked | -| `devnet-ready` | PR's branch has been merged into the `devnet-ready` branch and will be included in the next `devnet` deploy | none | -| `on-devnet` | PR has been deployed to `devnet` | Removes `devnet-ready` | -| `devnet-pass` | PR has passed manual testing on `devnet` | `devnet-pass` or `devnet-skip` required | -| `devnet-skip` | Allows a critical hotfix PR to skip required testing on `devnet` | `devnet-pass` or `devnet-skip` required | -| `devnet-fail` | PR has failed manual testing on `devnet` and requires modification | none | -| `testnet-companion` | Designates a testnet companion PR | Presence of `testnet-companion` label is checked | -| `on-testnet` | PR has been deployed to `testnet` | none | -| `testnet-pass` | PR has passed manual testing on `testnet` | `testnet-pass` or `testnet-skip` required | -| `testnet-skip` | Allows a critical hotfix PR to skip required manual testing and SOP on `testnet` | `testnet-pass` or `testnet-skip` required | -| `testnet-fail` | PR has failed manual testing on `testnet` and requires modification | none | - ## Branches ### `devnet-ready` -Companion PRs merge into this branch, eventually accumulating into a merge of `devnet-ready` -into `devnet`, coinciding with a deploy of `devnet`. +All new feature/change/fix PRs should merge into this branch. #### Restrictions * no deleting the branch * no force pushes * no direct pushes -* require 1 positive review from an administrator -* new code changes invalidate existing reviews +* require 3 positive review from an administrator +* new code changes do _not_ invalidate existing reviews * only merge commit style merging allowed #### CI-Enforced Restrictions * `check-rust.yml` must pass -* TODO: parent PR must be linked to in description -* TODO: parent PR must have the required number of positive reviews ### `devnet` @@ -164,33 +108,8 @@ tags for `testnet` releases. ### `main` -Default branch for all new PRs. Slightly ahead of what is currently on `finney`. When a PR is all -green and "done", meaning it has been tested on `devnet` and `testnet`, it can be merged into -`main`. Contains tags for `finney` releases. - -#### Restrictions -* no deleting the branch -* no force pushes -* no direct pushes -* require 3 positive reviews from core team members -* new code changes invalidate existing reviews -* all conversations must be resolved -* only merge commit style merging allowed - -#### CI-Enforced Restrictions -* `check-rust.yml` must pass -* `check-labels.yml` must pass -* must have `devnet-skip` or `devnet-pass` label -* must have `testnet-skip` or `testnet-pass` label -* if `breaking-change` label is present, bot will message the appropriate teams -* TODO: when we get auditing, presence of `needs-audit` label = require a review from auditor -* TODO: track SOP on PR based on label age - - -### `finney` - Tracks the current state of what is deployed to `finney` (mainnet). Updated via an -administrator-submitted PR merging `main` into `finney` in concert with a `finney` deploy. +administrator-submitted PR merging `testnet` into `main` in concert with a `finney` deploy. #### Restrictions * no deleting the branch @@ -203,5 +122,5 @@ administrator-submitted PR merging `main` into `finney` in concert with a `finne #### CI-Enforced Restrictions * `check-rust.yml` must pass * `check-finney.yml` must pass -* spec_version must be greater than what is currently on live `finney` +* `spec_version` must be greater than what is currently on live `finney` * TODO: other pre-deploy sanity checks here From d1c40dd1b0d181d301caf9a314c51796d2a4ad2e Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Mon, 5 Aug 2024 09:27:29 -0400 Subject: [PATCH 084/177] run checks more often --- .github/workflows/check-devnet.yml | 6 +++--- .github/workflows/check-testnet.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/check-devnet.yml b/.github/workflows/check-devnet.yml index fcc9809d3..ac45c440c 100644 --- a/.github/workflows/check-devnet.yml +++ b/.github/workflows/check-devnet.yml @@ -2,7 +2,7 @@ name: Devnet Deploy Check on: pull_request: - branches: [devnet] + branches: [devnet, devnet-ready] env: CARGO_TERM_COLOR: always @@ -37,7 +37,7 @@ jobs: echo "network spec_version: $spec_version" if (( $(echo "$local_spec_version <= $spec_version" | bc -l) )); then echo "$local_spec_version ≯ $spec_version ❌"; exit 1; fi echo "$local_spec_version > $spec_version ✅" - + check-devnet-migrations: name: check devnet migrations runs-on: ubuntu-22.04 @@ -51,4 +51,4 @@ jobs: runtime-package: "node-subtensor-runtime" node-uri: "wss://dev.chain.opentensor.ai:443" checks: "pre-and-post" - extra-args: "--disable-spec-version-check --no-weight-warnings" \ No newline at end of file + extra-args: "--disable-spec-version-check --no-weight-warnings" diff --git a/.github/workflows/check-testnet.yml b/.github/workflows/check-testnet.yml index 71c46557c..7b30c631c 100644 --- a/.github/workflows/check-testnet.yml +++ b/.github/workflows/check-testnet.yml @@ -2,7 +2,7 @@ name: Testnet Deploy Check on: pull_request: - branches: [testnet] + branches: [testnet, testnet-ready] env: CARGO_TERM_COLOR: always From d0649dcdaea43a0274091937389ec3f04907f709 Mon Sep 17 00:00:00 2001 From: Liam Date: Tue, 6 Aug 2024 09:24:08 +0200 Subject: [PATCH 085/177] fix clippy collapsible match --- pallets/subtensor/src/lib.rs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index f7824e2a3..2edcb8d50 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -2403,18 +2403,17 @@ where _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)); - } + match call.is_sub_type() { + Some(BalancesCall::transfer_allow_death { .. }) + | Some(BalancesCall::transfer_keep_alive { .. }) + | Some(BalancesCall::transfer_all { .. }) => { + if Pallet::::coldkey_in_arbitration(who) { + return Err(TransactionValidityError::Invalid(InvalidTransaction::Call)); } - _ => {} // Other Balances calls are allowed } + _ => {} // Other Balances calls are allowed } + match call.is_sub_type() { Some(Call::commit_weights { netuid, .. }) => { if Self::check_weights_min_stake(who) { From 67de45c584cc6bcd077329613ff882b03b2293b2 Mon Sep 17 00:00:00 2001 From: open-junius Date: Tue, 6 Aug 2024 15:33:55 +0800 Subject: [PATCH 086/177] add schedule dissolve network --- pallets/admin-utils/tests/mock.rs | 5 + pallets/subtensor/src/benchmarks.rs | 19 ++++ pallets/subtensor/src/lib.rs | 69 +++++++++++-- pallets/subtensor/src/macros/config.rs | 7 +- pallets/subtensor/src/macros/dispatches.rs | 62 +++++++++++- pallets/subtensor/src/macros/events.rs | 9 ++ pallets/subtensor/tests/mock.rs | 5 +- pallets/subtensor/tests/networks.rs | 107 ++++++++++++++++++--- pallets/subtensor/tests/swap_coldkey.rs | 5 +- 9 files changed, 259 insertions(+), 29 deletions(-) diff --git a/pallets/admin-utils/tests/mock.rs b/pallets/admin-utils/tests/mock.rs index 3f3ef843d..077f07804 100644 --- a/pallets/admin-utils/tests/mock.rs +++ b/pallets/admin-utils/tests/mock.rs @@ -118,6 +118,9 @@ parameter_types! { 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 + pub const InitialColdkeySwapScheduleDuration: u64 = 5 * 24 * 60 * 60 / 12; // 5 days + pub const InitialDissolveNetworkScheduleDuration: u64 = 5 * 24 * 60 * 60 / 12; // 5 days + } impl pallet_subtensor::Config for Test { @@ -177,6 +180,8 @@ impl pallet_subtensor::Config for Test { type InitialHotkeyEmissionTempo = InitialHotkeyEmissionTempo; type InitialNetworkMaxStake = InitialNetworkMaxStake; type Preimages = (); + type InitialColdkeySwapScheduleDuration = InitialColdkeySwapScheduleDuration; + type InitialDissolveNetworkScheduleDuration = InitialDissolveNetworkScheduleDuration; } #[derive_impl(frame_system::config_preludes::TestDefaultConfig)] diff --git a/pallets/subtensor/src/benchmarks.rs b/pallets/subtensor/src/benchmarks.rs index 03e087a92..eaa4821ad 100644 --- a/pallets/subtensor/src/benchmarks.rs +++ b/pallets/subtensor/src/benchmarks.rs @@ -429,4 +429,23 @@ reveal_weights { }: reveal_weights(RawOrigin::Signed(hotkey.clone()), netuid, uids, weight_values, salt, version_key) + schedule_swap_coldkey { + let old_coldkey: T::AccountId = account("old_cold", 0, 1); + let new_coldkey: T::AccountId = account("new_cold", 1, 2); + let _ = Subtensor::::schedule_swap_coldkey( + ::RuntimeOrigin::from(RawOrigin::Signed(old_coldkey.clone())), + new_coldkey.clone(), + ); + + }: schedule_swap_coldkey(RawOrigin::Signed(old_coldkey.clone()), new_coldkey.clone()) + + schedule_dissolve_network { + let coldkey: T::AccountId = account("old_cold", 0, 1); + let netuid = 1; + let _ = Subtensor::::schedule_dissolve_network( + ::RuntimeOrigin::from(RawOrigin::Signed(coldkey.clone())), + netuid, + ); + + }: schedule_dissolve_network(RawOrigin::Signed(coldkey.clone()), netuid) } diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index a1002bf66..d77a87b37 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -588,6 +588,26 @@ pub mod pallet { T::InitialNetworkMaxStake::get() } + #[pallet::type_value] + /// Default value for coldkey swap schedule duration + pub fn DefaultColdkeySwapScheduleDuration() -> BlockNumberFor { + T::InitialColdkeySwapScheduleDuration::get() + } + + #[pallet::storage] + pub type ColdkeySwapScheduleDuration = + StorageValue<_, BlockNumberFor, ValueQuery, DefaultColdkeySwapScheduleDuration>; + + #[pallet::type_value] + /// Default value for coldkey swap schedule duration + pub fn DefaultDissolveNetworkScheduleDuration() -> BlockNumberFor { + T::InitialDissolveNetworkScheduleDuration::get() + } + + #[pallet::storage] + pub type DissolveNetworkScheduleDuration = + StorageValue<_, BlockNumberFor, ValueQuery, DefaultDissolveNetworkScheduleDuration>; + #[pallet::storage] pub type SenateRequiredStakePercentage = StorageValue<_, u64, ValueQuery, DefaultSenateRequiredStakePercentage>; @@ -1219,6 +1239,19 @@ pub enum CallType { Other, } +#[derive(Debug, PartialEq)] +pub enum CustomTransactionError { + ColdkeyInSwapSchedule, +} + +impl From for u8 { + fn from(variant: CustomTransactionError) -> u8 { + match variant { + CustomTransactionError::ColdkeyInSwapSchedule => 0, + } + } +} + #[freeze_struct("61e2b893d5ce6701")] #[derive(Encode, Decode, Clone, Eq, PartialEq, TypeInfo)] pub struct SubtensorSignedExtension(pub PhantomData); @@ -1367,14 +1400,34 @@ where 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() - }), + Some(Call::dissolve_network { .. }) => { + InvalidTransaction::Custom(CustomTransactionError::ColdkeyInSwapSchedule.into()) + .into() + } + _ => { + if let Some(balances_call) = call.is_sub_type() { + match balances_call { + BalancesCall::transfer_keep_alive { .. } + | BalancesCall::transfer_all { .. } + | BalancesCall::transfer_allow_death { .. } => { + if ColdkeySwapScheduled::::contains_key(who) { + return InvalidTransaction::Custom( + CustomTransactionError::ColdkeyInSwapSchedule.into(), + ) + .into(); + } + } + // Add other Balances call validations if needed + _ => {} + } + } + + // Default validation for other calls + 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 2f924905d..c5c5ac737 100644 --- a/pallets/subtensor/src/macros/config.rs +++ b/pallets/subtensor/src/macros/config.rs @@ -5,7 +5,6 @@ use frame_support::pallet_macros::pallet_section; /// 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 { @@ -193,5 +192,11 @@ mod config { /// Initial hotkey emission tempo. #[pallet::constant] type InitialHotkeyEmissionTempo: Get; + /// Coldkey swap schedule duartion. + #[pallet::constant] + type InitialColdkeySwapScheduleDuration: Get>; + /// Dissolve network schedule duration + #[pallet::constant] + type InitialDissolveNetworkScheduleDuration: Get>; } } diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 48874fb1b..68d2d70ee 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -957,11 +957,9 @@ mod dispatches { Error::::SwapAlreadyScheduled ); - // Calculate the number of blocks in 5 days - let blocks_in_5_days: u32 = 5 * 24 * 60 * 60 / 12; - - let current_block = >::block_number(); - let when = current_block.saturating_add(BlockNumberFor::::from(blocks_in_5_days)); + let current_block: BlockNumberFor = >::block_number(); + let duration: BlockNumberFor = ColdkeySwapScheduleDuration::::get(); + let when: BlockNumberFor = current_block.saturating_add(duration); let call = Call::::swap_coldkey { old_coldkey: who.clone(), @@ -991,6 +989,60 @@ mod dispatches { Ok(().into()) } + /// Schedule the dissolution of a network at a specified block number. + /// + /// # Arguments + /// + /// * `origin` - The origin of the call, must be signed by the sender. + /// * `netuid` - The u16 network identifier to be dissolved. + /// + /// # 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(74)] + #[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 schedule_dissolve_network( + origin: OriginFor, + netuid: u16, + ) -> DispatchResultWithPostInfo { + let who = ensure_signed(origin)?; + + let current_block: BlockNumberFor = >::block_number(); + let duration: BlockNumberFor = DissolveNetworkScheduleDuration::::get(); + let when: BlockNumberFor = current_block.saturating_add(duration); + + let call = Call::::dissolve_network { netuid }; + + let bound_call = T::Preimages::bound(LocalCallOf::::from(call.clone())) + .map_err(|_| Error::::FailedToSchedule)?; + + T::Scheduler::schedule( + DispatchTime::At(when), + None, + 63, + frame_system::RawOrigin::Signed(who.clone()).into(), + bound_call, + ) + .map_err(|_| Error::::FailedToSchedule)?; + + ColdkeySwapScheduled::::insert(&who, ()); + // Emit the SwapScheduled event + Self::deposit_event(Event::DissolveNetworkScheduled { + account: who.clone(), + netuid: netuid, + execution_block: when, + }); + + Ok(().into()) + } + /// ---- Set prometheus information for the neuron. /// # Args: /// * 'origin': (Origin): diff --git a/pallets/subtensor/src/macros/events.rs b/pallets/subtensor/src/macros/events.rs index 9d771e3e2..2fbffdb7c 100644 --- a/pallets/subtensor/src/macros/events.rs +++ b/pallets/subtensor/src/macros/events.rs @@ -179,5 +179,14 @@ mod events { NetworkMaxStakeSet(u16, u64), /// The identity of a coldkey has been set ChainIdentitySet(T::AccountId), + /// A dissolve network extrinsic scheduled. + DissolveNetworkScheduled { + /// The account ID schedule the dissolve network extrisnic + account: T::AccountId, + /// network ID will be dissolved + netuid: u16, + /// extrinsic execution block number + execution_block: BlockNumberFor, + }, } } diff --git a/pallets/subtensor/tests/mock.rs b/pallets/subtensor/tests/mock.rs index 3497b6d67..17ccfc87d 100644 --- a/pallets/subtensor/tests/mock.rs +++ b/pallets/subtensor/tests/mock.rs @@ -171,7 +171,8 @@ parameter_types! { 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 - + pub const InitialColdkeySwapScheduleDuration: u64 = 5 * 24 * 60 * 60 / 12; // Default as 5 days + pub const InitialDissolveNetworkScheduleDuration: u64 = 5 * 24 * 60 * 60 / 12; // Default as 5 days } // Configure collective pallet for council @@ -390,6 +391,8 @@ impl pallet_subtensor::Config for Test { type InitialHotkeyEmissionTempo = InitialHotkeyEmissionTempo; type InitialNetworkMaxStake = InitialNetworkMaxStake; type Preimages = Preimage; + type InitialColdkeySwapScheduleDuration = InitialColdkeySwapScheduleDuration; + type InitialDissolveNetworkScheduleDuration = InitialDissolveNetworkScheduleDuration; } pub struct OriginPrivilegeCmp; diff --git a/pallets/subtensor/tests/networks.rs b/pallets/subtensor/tests/networks.rs index 93e563683..1929ff543 100644 --- a/pallets/subtensor/tests/networks.rs +++ b/pallets/subtensor/tests/networks.rs @@ -1,14 +1,99 @@ -// DEPRECATED mod mock; -// use frame_support::{ -// assert_ok, -// dispatch::{DispatchClass, DispatchInfo, GetDispatchInfo, Pays}, -// sp_std::vec, -// }; -// use frame_system::Config; -// use frame_system::{EventRecord, Phase}; -// use mock::*; -// use pallet_subtensor::Error; -// use sp_core::{H256, U256}; +use crate::mock::*; +use frame_support::assert_ok; +use frame_system::Config; +use pallet_subtensor::{DissolveNetworkScheduleDuration, Event}; +use sp_core::U256; + +mod mock; + +#[test] +fn test_registration_ok() { + new_test_ext(1).execute_with(|| { + let block_number: u64 = 0; + let netuid: u16 = 2; + let tempo: u16 = 13; + let hotkey_account_id: U256 = U256::from(1); + let coldkey_account_id = U256::from(0); // Neighbour of the beast, har har + let (nonce, work): (u64, Vec) = SubtensorModule::create_work_for_block_number( + netuid, + block_number, + 129123813, + &hotkey_account_id, + ); + + //add network + add_network(netuid, tempo, 0); + + assert_ok!(SubtensorModule::register( + <::RuntimeOrigin>::signed(hotkey_account_id), + netuid, + block_number, + nonce, + work.clone(), + hotkey_account_id, + coldkey_account_id + )); + + assert_ok!(SubtensorModule::user_remove_network( + <::RuntimeOrigin>::signed(coldkey_account_id), + netuid + )); + + assert!(!SubtensorModule::if_subnet_exist(netuid)) + }) +} + +#[test] +fn test_schedule_dissolve_network_execution() { + new_test_ext(1).execute_with(|| { + let block_number: u64 = 0; + let netuid: u16 = 2; + let tempo: u16 = 13; + let hotkey_account_id: U256 = U256::from(1); + let coldkey_account_id = U256::from(0); // Neighbour of the beast, har har + let (nonce, work): (u64, Vec) = SubtensorModule::create_work_for_block_number( + netuid, + block_number, + 129123813, + &hotkey_account_id, + ); + + //add network + add_network(netuid, tempo, 0); + + assert_ok!(SubtensorModule::register( + <::RuntimeOrigin>::signed(hotkey_account_id), + netuid, + block_number, + nonce, + work.clone(), + hotkey_account_id, + coldkey_account_id + )); + + assert!(SubtensorModule::if_subnet_exist(netuid)); + + assert_ok!(SubtensorModule::schedule_dissolve_network( + <::RuntimeOrigin>::signed(coldkey_account_id), + netuid + )); + + let current_block = System::block_number(); + let execution_block = current_block + DissolveNetworkScheduleDuration::::get(); + + System::assert_last_event( + Event::DissolveNetworkScheduled { + account: coldkey_account_id, + netuid, + execution_block, + } + .into(), + ); + + run_to_block(execution_block); + assert!(!SubtensorModule::if_subnet_exist(netuid)); + }) +} // #[allow(dead_code)] // fn record(event: RuntimeEvent) -> EventRecord { diff --git a/pallets/subtensor/tests/swap_coldkey.rs b/pallets/subtensor/tests/swap_coldkey.rs index 48168addc..ec030ebee 100644 --- a/pallets/subtensor/tests/swap_coldkey.rs +++ b/pallets/subtensor/tests/swap_coldkey.rs @@ -10,7 +10,7 @@ use frame_support::traits::schedule::DispatchTime; use frame_support::traits::OnInitialize; use mock::*; use pallet_subtensor::*; -use pallet_subtensor::{Call, Error}; +use pallet_subtensor::{Call, ColdkeySwapScheduleDuration, Error}; use sp_core::H256; use sp_core::U256; use sp_runtime::DispatchError; @@ -1387,8 +1387,7 @@ fn test_schedule_swap_coldkey_execution() { // Get the scheduled execution block let current_block = System::block_number(); - let blocks_in_5_days = 5 * 24 * 60 * 60 / 12; - let execution_block = current_block + blocks_in_5_days; + let execution_block = current_block + ColdkeySwapScheduleDuration::::get(); System::assert_last_event( Event::ColdkeySwapScheduled { From 106df9e84abcd2c31df5c9e3d2dc4b78cb03a54f Mon Sep 17 00:00:00 2001 From: open-junius Date: Tue, 6 Aug 2024 15:52:09 +0800 Subject: [PATCH 087/177] fix clippy --- pallets/subtensor/src/lib.rs | 11 +++++++++-- pallets/subtensor/src/macros/dispatches.rs | 2 +- runtime/src/lib.rs | 4 ++++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index d77a87b37..22fa0514e 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -1401,8 +1401,15 @@ where ..Default::default() }), Some(Call::dissolve_network { .. }) => { - InvalidTransaction::Custom(CustomTransactionError::ColdkeyInSwapSchedule.into()) - .into() + if ColdkeySwapScheduled::::contains_key(who) { + InvalidTransaction::Custom(CustomTransactionError::ColdkeyInSwapSchedule.into()) + .into() + } else { + Ok(ValidTransaction { + priority: Self::get_priority_vanilla(), + ..Default::default() + }) + } } _ => { if let Some(balances_call) = call.is_sub_type() { diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 68d2d70ee..112ef10b5 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -1036,7 +1036,7 @@ mod dispatches { // Emit the SwapScheduled event Self::deposit_event(Event::DissolveNetworkScheduled { account: who.clone(), - netuid: netuid, + netuid, execution_block: when, }); diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index f042c449a..20d565f9a 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -902,6 +902,8 @@ parameter_types! { 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 + pub const InitialColdkeySwapScheduleDuration: BlockNumber = 5 * 24 * 60 * 60 / 12; // 5 days + pub const InitialDissolveNetworkScheduleDuration: BlockNumber = 5 * 24 * 60 * 60 / 12; // 5 days } @@ -962,6 +964,8 @@ impl pallet_subtensor::Config for Runtime { type InitialHotkeyEmissionTempo = SubtensorInitialHotkeyEmissionTempo; type InitialNetworkMaxStake = SubtensorInitialNetworkMaxStake; type Preimages = Preimage; + type InitialColdkeySwapScheduleDuration = InitialColdkeySwapScheduleDuration; + type InitialDissolveNetworkScheduleDuration = InitialDissolveNetworkScheduleDuration; } use sp_runtime::BoundedVec; From cc036e55b1daa35a5d7b5b6777e3ea77d57e3133 Mon Sep 17 00:00:00 2001 From: open-junius Date: Tue, 6 Aug 2024 16:10:49 +0800 Subject: [PATCH 088/177] fix clippy --- pallets/subtensor/src/lib.rs | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index 22fa0514e..f92f1102c 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -1412,24 +1412,19 @@ where } } _ => { - if let Some(balances_call) = call.is_sub_type() { - match balances_call { - BalancesCall::transfer_keep_alive { .. } - | BalancesCall::transfer_all { .. } - | BalancesCall::transfer_allow_death { .. } => { - if ColdkeySwapScheduled::::contains_key(who) { - return InvalidTransaction::Custom( - CustomTransactionError::ColdkeyInSwapSchedule.into(), - ) - .into(); - } - } - // Add other Balances call validations if needed - _ => {} + if let Some( + BalancesCall::transfer_keep_alive { .. } + | BalancesCall::transfer_all { .. } + | BalancesCall::transfer_allow_death { .. }, + ) = call.is_sub_type() + { + if ColdkeySwapScheduled::::contains_key(who) { + return InvalidTransaction::Custom( + CustomTransactionError::ColdkeyInSwapSchedule.into(), + ) + .into(); } } - - // Default validation for other calls Ok(ValidTransaction { priority: Self::get_priority_vanilla(), ..Default::default() From 70f624fad7c5a5eddcc56c6c44c64f45cdc8629e Mon Sep 17 00:00:00 2001 From: open-junius Date: Tue, 6 Aug 2024 22:17:18 +0800 Subject: [PATCH 089/177] udpate comments --- pallets/subtensor/src/benchmarks.rs | 2 +- pallets/subtensor/src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pallets/subtensor/src/benchmarks.rs b/pallets/subtensor/src/benchmarks.rs index eaa4821ad..05d006ab0 100644 --- a/pallets/subtensor/src/benchmarks.rs +++ b/pallets/subtensor/src/benchmarks.rs @@ -440,7 +440,7 @@ reveal_weights { }: schedule_swap_coldkey(RawOrigin::Signed(old_coldkey.clone()), new_coldkey.clone()) schedule_dissolve_network { - let coldkey: T::AccountId = account("old_cold", 0, 1); + let coldkey: T::AccountId = account("coldkey", 0, 1); let netuid = 1; let _ = Subtensor::::schedule_dissolve_network( ::RuntimeOrigin::from(RawOrigin::Signed(coldkey.clone())), diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index f92f1102c..09f1446e7 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -599,7 +599,7 @@ pub mod pallet { StorageValue<_, BlockNumberFor, ValueQuery, DefaultColdkeySwapScheduleDuration>; #[pallet::type_value] - /// Default value for coldkey swap schedule duration + /// Default value for dissolve network schedule duration pub fn DefaultDissolveNetworkScheduleDuration() -> BlockNumberFor { T::InitialDissolveNetworkScheduleDuration::get() } From 47345424ba45026e9b892017525b6e20383045cb Mon Sep 17 00:00:00 2001 From: Liam Date: Tue, 6 Aug 2024 17:28:21 +0200 Subject: [PATCH 090/177] clippy --- pallets/subtensor/tests/difficulty.rs | 1 - pallets/subtensor/tests/epoch.rs | 1 - pallets/subtensor/tests/mock.rs | 4 ++++ pallets/subtensor/tests/neuron_info.rs | 1 - pallets/subtensor/tests/registration.rs | 1 - pallets/subtensor/tests/serving.rs | 2 -- pallets/subtensor/tests/staking.rs | 3 --- pallets/subtensor/tests/weights.rs | 3 --- runtime/src/lib.rs | 2 ++ 9 files changed, 6 insertions(+), 12 deletions(-) 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 676b3cd35..e2b911525 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/mock.rs b/pallets/subtensor/tests/mock.rs index fc784f46f..06bca8aff 100644 --- a/pallets/subtensor/tests/mock.rs +++ b/pallets/subtensor/tests/mock.rs @@ -262,6 +262,7 @@ impl CollectiveInterface for TriumvirateVotes { } // We call pallet_collective TriumvirateCollective +#[allow(unused)] type TriumvirateCollective = pallet_collective::Instance1; impl pallet_collective::Config for Test { type RuntimeOrigin = RuntimeOrigin; @@ -279,6 +280,7 @@ impl pallet_collective::Config for Test { } // We call council members Triumvirate +#[allow(unused)] type TriumvirateMembership = pallet_membership::Instance1; impl pallet_membership::Config for Test { type RuntimeEvent = RuntimeEvent; @@ -295,6 +297,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(unused)] type SenateCollective = pallet_collective::Instance2; impl pallet_collective::Config for Test { type RuntimeOrigin = RuntimeOrigin; @@ -312,6 +315,7 @@ impl pallet_collective::Config for Test { } // We call our top K delegates membership Senate +#[allow(unused)] type SenateMembership = pallet_membership::Instance2; impl pallet_membership::Config for Test { type RuntimeEvent = RuntimeEvent; 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 41e9888cc..b87b7fd10 100644 --- a/pallets/subtensor/tests/serving.rs +++ b/pallets/subtensor/tests/serving.rs @@ -161,7 +161,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); @@ -379,7 +378,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 cb2cac4ef..12d299d8f 100644 --- a/pallets/subtensor/tests/staking.rs +++ b/pallets/subtensor/tests/staking.rs @@ -22,7 +22,6 @@ use sp_runtime::traits::SignedExtension; ************************************************************/ #[test] -#[cfg(not(tarpaulin))] fn test_add_stake_dispatch_info_ok() { new_test_ext(1).execute_with(|| { let hotkey = U256::from(0); @@ -528,7 +527,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); @@ -1201,7 +1199,6 @@ fn test_delegate_stake_division_by_zero_check() { } #[test] -#[cfg(not(tarpaulin))] fn test_full_with_delegating() { new_test_ext(1).execute_with(|| { let netuid = 1; 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]; diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index a4abd124f..475f1e4a7 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -516,6 +516,7 @@ impl pallet_collective::Config for Runtime { } // We call council members Triumvirate +#[allow(unused)] type TriumvirateMembership = pallet_membership::Instance1; impl pallet_membership::Config for Runtime { type RuntimeEvent = RuntimeEvent; @@ -531,6 +532,7 @@ impl pallet_membership::Config for Runtime { } // We call our top K delegates membership Senate +#[allow(unused)] type SenateMembership = pallet_membership::Instance2; impl pallet_membership::Config for Runtime { type RuntimeEvent = RuntimeEvent; From 771b120fc783a737f3b82c97c8dbcf59967f0ba8 Mon Sep 17 00:00:00 2001 From: open-junius Date: Wed, 7 Aug 2024 09:30:38 +0800 Subject: [PATCH 091/177] fix bechmarks --- pallets/subtensor/src/benchmarks.rs | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/pallets/subtensor/src/benchmarks.rs b/pallets/subtensor/src/benchmarks.rs index 05d006ab0..2cb53e62c 100644 --- a/pallets/subtensor/src/benchmarks.rs +++ b/pallets/subtensor/src/benchmarks.rs @@ -432,20 +432,10 @@ reveal_weights { schedule_swap_coldkey { let old_coldkey: T::AccountId = account("old_cold", 0, 1); let new_coldkey: T::AccountId = account("new_cold", 1, 2); - let _ = Subtensor::::schedule_swap_coldkey( - ::RuntimeOrigin::from(RawOrigin::Signed(old_coldkey.clone())), - new_coldkey.clone(), - ); - }: schedule_swap_coldkey(RawOrigin::Signed(old_coldkey.clone()), new_coldkey.clone()) schedule_dissolve_network { let coldkey: T::AccountId = account("coldkey", 0, 1); let netuid = 1; - let _ = Subtensor::::schedule_dissolve_network( - ::RuntimeOrigin::from(RawOrigin::Signed(coldkey.clone())), - netuid, - ); - - }: schedule_dissolve_network(RawOrigin::Signed(coldkey.clone()), netuid) + }: schedule_dissolve_network(RawOrigin::Signed(coldkey.clone()), netuid) } From eb4746f9ab2ad3af897ad673c3061718ed983476 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Wed, 7 Aug 2024 10:11:18 -0400 Subject: [PATCH 092/177] fix warnings --- build.rs | 10 ++-------- lints/dummy_lint.rs | 2 -- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/build.rs b/build.rs index 96bc52b67..7e653ebb3 100644 --- a/build.rs +++ b/build.rs @@ -1,12 +1,6 @@ -use rayon::prelude::*; use std::env; use std::fs; use std::path::{Path, PathBuf}; -use std::process::exit; -use std::sync::mpsc::channel; -use syn::spanned::Spanned; -use syn::Error; -use syn::File; use syn::Result; use walkdir::WalkDir; @@ -50,8 +44,8 @@ fn main() { let end = error.span().end(); let start_line = start.line; let start_col = start.column; - let end_line = end.line; - let end_col = end.column; + let _end_line = end.line; + let _end_col = end.column; let file_path = file.display(); panic!("{}:{}:{}: {}", file_path, start_line, start_col, error); } diff --git a/lints/dummy_lint.rs b/lints/dummy_lint.rs index 4447b66b5..41338b484 100644 --- a/lints/dummy_lint.rs +++ b/lints/dummy_lint.rs @@ -1,5 +1,3 @@ -use syn::{spanned::Spanned, Error}; - use super::*; pub struct DummyLint; From 252fea5f76c91baba9f924e9c60ac9b8d2ec66e2 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Wed, 7 Aug 2024 10:11:32 -0400 Subject: [PATCH 093/177] cargo +nightly fmt --- src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib.rs b/src/lib.rs index e69de29bb..8b1378917 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -0,0 +1 @@ + From b2e5290bb9e8d5d793abfd1ada488990e90e47f0 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Wed, 7 Aug 2024 10:13:24 -0400 Subject: [PATCH 094/177] cargo fix --workspace --- lints/lint.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/lints/lint.rs b/lints/lint.rs index 69047c34c..4a69995d9 100644 --- a/lints/lint.rs +++ b/lints/lint.rs @@ -1,4 +1,3 @@ -use rayon::iter::IntoParallelIterator; use super::*; From 676463328de5d87663332adaaa9cb5cf1997352f Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Wed, 7 Aug 2024 18:16:26 +0400 Subject: [PATCH 095/177] feat: add more childkey tests --- pallets/subtensor/src/epoch/run_epoch.rs | 4 +- pallets/subtensor/src/lib.rs | 2 - pallets/subtensor/tests/children.rs | 1715 +++++++++++++++++++++- pallets/subtensor/tests/mock.rs | 18 + 4 files changed, 1682 insertions(+), 57 deletions(-) diff --git a/pallets/subtensor/src/epoch/run_epoch.rs b/pallets/subtensor/src/epoch/run_epoch.rs index 1cb2c3448..9196bee4b 100644 --- a/pallets/subtensor/src/epoch/run_epoch.rs +++ b/pallets/subtensor/src/epoch/run_epoch.rs @@ -31,12 +31,10 @@ impl Pallet { /// 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); + log::debug!("Initial stake: {:?}", initial_stake); let mut stake_to_children: u64 = 0; let mut stake_from_parents: u64 = 0; diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index edc9040ac..b0fbc9140 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -372,8 +372,6 @@ pub mod pallet { } 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 { diff --git a/pallets/subtensor/tests/children.rs b/pallets/subtensor/tests/children.rs index b675ff8e9..f491e8b64 100644 --- a/pallets/subtensor/tests/children.rs +++ b/pallets/subtensor/tests/children.rs @@ -5,6 +5,7 @@ mod mock; use pallet_subtensor::{utils::rate_limiting::TransactionType, *}; use sp_core::U256; +// 1: Successful setting of a single child // 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() { @@ -33,6 +34,7 @@ fn test_do_set_child_singular_success() { }); } +// 2: Attempt to set child in non-existent network // 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() { @@ -56,6 +58,7 @@ fn test_do_set_child_singular_network_does_not_exist() { }); } +// 3: Attempt to set invalid child (same as hotkey) // 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() { @@ -84,6 +87,7 @@ fn test_do_set_child_singular_invalid_child() { }); } +// 4: Attempt to set child with non-associated coldkey // 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() { @@ -111,6 +115,7 @@ fn test_do_set_child_singular_non_associated_coldkey() { }); } +// 5: Attempt to set child in root network // 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() { @@ -137,6 +142,13 @@ fn test_do_set_child_singular_root_network() { }); } +// 6: Cleanup of old children when setting new ones +// This test verifies that when new children are set, the old ones are properly removed. +// It checks: +// - Setting an initial child +// - Replacing it with a new child +// - Ensuring the old child is no longer associated +// - Confirming the new child is correctly assigned // 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() { @@ -178,7 +190,13 @@ fn test_do_set_child_singular_old_children_cleanup() { }); } -// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_set_child_singular_old_children_cleanup --exact --nocapture +// 7: Verify new children assignment +// This test checks if new children are correctly assigned to a parent. +// It verifies: +// - Setting a child for a parent +// - Confirming the child is correctly listed under the parent +// - Ensuring the parent is correctly listed for the child +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_do_set_child_singular_new_children_assignment --exact --nocapture #[test] fn test_do_set_child_singular_new_children_assignment() { new_test_ext(1).execute_with(|| { @@ -210,6 +228,12 @@ fn test_do_set_child_singular_new_children_assignment() { }); } +// 8: Test edge cases for proportion values +// This test verifies that the system correctly handles minimum and maximum proportion values. +// It checks: +// - Setting a child with the minimum possible proportion (0) +// - Setting a child with the maximum possible proportion (u64::MAX) +// - Confirming both assignments are processed correctly // 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() { @@ -251,6 +275,13 @@ fn test_do_set_child_singular_proportion_edge_cases() { }); } +// 9: Test setting multiple children +// This test verifies that when multiple children are set, only the last one remains. +// It checks: +// - Setting an initial child +// - Setting a second child +// - Confirming only the second child remains associated +// - Verifying the first child is no longer associated // 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() { @@ -296,6 +327,12 @@ fn test_do_set_child_singular_multiple_children() { }); } +// 10: Test adding a singular child with various error conditions +// This test checks different scenarios when adding a child, including: +// - Attempting to set a child in a non-existent network +// - Trying to set a child with an unassociated coldkey +// - Setting an invalid child +// - Successfully setting a valid child // SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_add_singular_child --exact --nocapture #[test] fn test_add_singular_child() { @@ -343,73 +380,67 @@ fn test_add_singular_child() { }) } +// 11: Test getting stake for a hotkey on a subnet +// This test verifies the correct calculation of stake for a parent and child neuron: +// - Sets up a network with a parent and child neuron +// - Stakes tokens to both parent and child from different coldkeys +// - Establishes a parent-child relationship with 100% stake allocation +// - Checks that the parent's stake is correctly transferred to the child +// - Ensures the total stake is preserved in the system // 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); + let parent = U256::from(1); + let child = U256::from(2); + let coldkey1 = U256::from(3); + let coldkey2 = 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 + register_ok_neuron(netuid, parent, coldkey1, 0); + register_ok_neuron(netuid, child, coldkey2, 0); + + // Stake 1000 to parent from coldkey1 + SubtensorModule::increase_stake_on_coldkey_hotkey_account(&coldkey1, &parent, 1000); + // Stake 1000 to parent from coldkey2 + SubtensorModule::increase_stake_on_coldkey_hotkey_account(&coldkey2, &parent, 1000); + // Stake 1000 to child from coldkey1 + SubtensorModule::increase_stake_on_coldkey_hotkey_account(&coldkey1, &child, 1000); + // Stake 1000 to child from coldkey2 + SubtensorModule::increase_stake_on_coldkey_hotkey_account(&coldkey2, &child, 1000); + + // Set parent-child relationship with 100% stake allocation assert_ok!(SubtensorModule::do_set_children( - RuntimeOrigin::signed(coldkey0), - hotkey0, + RuntimeOrigin::signed(coldkey1), + parent, netuid, - vec![(u64::MAX, hotkey1)] + vec![(u64::MAX, child)] )); - // 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); + let parent_stake = SubtensorModule::get_stake_for_hotkey_on_subnet(&parent, netuid); + let child_stake = SubtensorModule::get_stake_for_hotkey_on_subnet(&child, 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)] - )); + println!("Parent stake: {}", parent_stake); + println!("Child stake: {}", child_stake); - // 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); + // The parent should have 0 stake as it's all allocated to the child + assert_eq!(parent_stake, 0); + // The child should have its original stake (2000) plus the parent's stake (2000) + assert_eq!(child_stake, 4000); - assert_eq!(stake0, 1001); - assert!(stake1 >= max_stake - 1 && stake1 <= max_stake); + // Ensure total stake is preserved + assert_eq!(parent_stake + child_stake, 4000); }); } +// 12: Test revoking a singular child successfully +// This test checks the process of revoking a child neuron: +// - Sets up a network with a parent and child neuron +// - Establishes a parent-child relationship +// - Revokes the child relationship +// - Verifies that the child is removed from the parent's children list +// - Ensures the parent is removed from the child's parents list // 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() { @@ -454,6 +485,10 @@ fn test_do_revoke_child_singular_success() { }); } +// 13: Test revoking a child in a non-existent network +// This test verifies that attempting to revoke a child in a non-existent network results in an error: +// - Attempts to revoke a child in a network that doesn't exist +// - Checks that the appropriate error is returned // 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() { @@ -475,6 +510,11 @@ fn test_do_revoke_child_singular_network_does_not_exist() { }); } +// 14: Test revoking a child with a non-associated coldkey +// This test ensures that attempting to revoke a child using an unassociated coldkey results in an error: +// - Sets up a network with a hotkey registered to a different coldkey +// - Attempts to revoke a child using an unassociated coldkey +// - Verifies that the appropriate error is returned // 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() { @@ -500,6 +540,11 @@ fn test_do_revoke_child_singular_non_associated_coldkey() { }); } +// 15: Test revoking a non-associated child +// This test verifies that attempting to revoke a child that is not associated with the parent results in an error: +// - Sets up a network and registers a hotkey +// - Attempts to revoke a child that was never associated with the parent +// - Checks that the appropriate error is returned // 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() { @@ -524,6 +569,12 @@ fn test_do_revoke_child_singular_child_not_associated() { }); } +// 16: Test setting multiple children successfully +// This test verifies that multiple children can be set for a parent successfully: +// - Sets up a network and registers a hotkey +// - Sets multiple children with different proportions +// - Verifies that the children are correctly assigned to the parent +// - Checks that the parent is correctly assigned to each child // 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() { @@ -561,6 +612,10 @@ fn test_do_set_children_multiple_success() { }); } +// 17: Test setting multiple children in a non-existent network +// This test ensures that attempting to set multiple children in a non-existent network results in an error: +// - Attempts to set children in a network that doesn't exist +// - Verifies that the appropriate error is returned // 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() { @@ -584,6 +639,11 @@ fn test_do_set_children_multiple_network_does_not_exist() { }); } +// 18: Test setting multiple children with an invalid child +// This test verifies that attempting to set multiple children with an invalid child (same as parent) results in an error: +// - Sets up a network and registers a hotkey +// - Attempts to set a child that is the same as the parent hotkey +// - Checks that the appropriate error is returned // 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() { @@ -610,6 +670,11 @@ fn test_do_set_children_multiple_invalid_child() { }); } +// 19: Test setting multiple children with a non-associated coldkey +// This test ensures that attempting to set multiple children using an unassociated coldkey results in an error: +// - Sets up a network with a hotkey registered to a different coldkey +// - Attempts to set children using an unassociated coldkey +// - Verifies that the appropriate error is returned // 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() { @@ -637,6 +702,11 @@ fn test_do_set_children_multiple_non_associated_coldkey() { }); } +// 20: Test setting multiple children in root network +// This test verifies that attempting to set children in the root network results in an error: +// - Sets up the root network +// - Attempts to set children in the root network +// - Checks that the appropriate error is returned // 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() { @@ -663,6 +733,13 @@ fn test_do_set_children_multiple_root_network() { }); } +// 21: Test cleanup of old children when setting multiple new ones +// This test ensures that when new children are set, the old ones are properly removed: +// - Sets up a network and registers a hotkey +// - Sets an initial child +// - Replaces it with multiple new children +// - Verifies that the old child is no longer associated +// - Confirms the new children are correctly assigned // 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() { @@ -708,6 +785,11 @@ fn test_do_set_children_multiple_old_children_cleanup() { }); } +// 22: Test setting multiple children with edge case proportions +// This test verifies the behavior when setting multiple children with minimum and maximum proportions: +// - Sets up a network and registers a hotkey +// - Sets two children with minimum and maximum proportions respectively +// - Verifies that the children are correctly assigned with their respective proportions // 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() { @@ -741,6 +823,13 @@ fn test_do_set_children_multiple_proportion_edge_cases() { }); } +// 23: Test overwriting existing children with new ones +// This test ensures that when new children are set, they correctly overwrite the existing ones: +// - Sets up a network and registers a hotkey +// - Sets initial children +// - Overwrites with new children +// - Verifies that the final children assignment is correct +// - Checks that old children are properly removed and new ones are correctly assigned // 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() { @@ -792,6 +881,14 @@ fn test_do_set_children_multiple_overwrite_existing() { }); } +// 24: Test childkey take functionality +// This test verifies the functionality of setting and getting childkey take: +// - Sets up a network and registers a hotkey +// - Checks default and maximum childkey take values +// - Sets a new childkey take value +// - Verifies the new take value is stored correctly +// - Attempts to set an invalid take value and checks for appropriate error +// - Tries to set take with a non-associated coldkey and verifies the error // SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_childkey_take_functionality --exact --nocapture #[test] fn test_childkey_take_functionality() { @@ -861,6 +958,13 @@ fn test_childkey_take_functionality() { }); } +// 25: Test childkey take rate limiting +// This test verifies the rate limiting functionality for setting childkey take: +// - Sets up a network and registers a hotkey +// - Sets a rate limit for childkey take changes +// - Performs multiple attempts to set childkey take +// - Verifies that rate limiting prevents frequent changes +// - Advances blocks to bypass rate limit and confirms successful change // SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_childkey_take_rate_limiting --exact --nocapture #[test] fn test_childkey_take_rate_limiting() { @@ -954,6 +1058,13 @@ fn test_childkey_take_rate_limiting() { }); } +// 26: Test childkey take functionality across multiple networks +// This test verifies the childkey take functionality across multiple networks: +// - Creates multiple networks and sets up neurons +// - Sets unique childkey take values for each network +// - Verifies that each network has a different childkey take value +// - Attempts to set childkey take again (should fail due to rate limit) +// - Advances blocks to bypass rate limit and successfully updates take value // SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_multiple_networks_childkey_take --exact --nocapture #[test] fn test_multiple_networks_childkey_take() { @@ -1026,6 +1137,12 @@ fn test_multiple_networks_childkey_take() { }); } +// 27: Test setting children with an empty list +// This test verifies the behavior of setting an empty children list: +// - Adds a network and registers a hotkey +// - Sets an empty children list for the hotkey +// - Verifies that the children assignment is empty +// 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(|| { @@ -1051,6 +1168,13 @@ fn test_do_set_children_multiple_empty_list() { }); } +// 28: Test revoking multiple children successfully +// This test verifies the successful revocation of multiple children: +// - Adds a network and registers a hotkey +// - Sets multiple children for the hotkey +// - Revokes all children by setting an empty list +// - Verifies that the children list is empty +// - Verifies that the parent-child relationships are removed for both children // 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() { @@ -1096,6 +1220,10 @@ fn test_do_revoke_children_multiple_success() { }); } +// 29: Test revoking children when network does not exist +// This test verifies the behavior when attempting to revoke children on a non-existent network: +// - Attempts to revoke children on a network that doesn't exist +// - Verifies that the operation fails with the correct error // 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() { @@ -1118,6 +1246,11 @@ fn test_do_revoke_children_multiple_network_does_not_exist() { }); } +// 30: Test revoking children with non-associated coldkey +// This test verifies the behavior when attempting to revoke children using a non-associated coldkey: +// - Adds a network and registers a hotkey with a different coldkey +// - Attempts to revoke children using an unassociated coldkey +// - Verifies that the operation fails with the correct error // 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() { @@ -1145,6 +1278,13 @@ fn test_do_revoke_children_multiple_non_associated_coldkey() { }); } +// 31: Test partial revocation of children +// This test verifies the behavior when partially revoking children: +// - Adds a network and registers a hotkey +// - Sets multiple children for the hotkey +// - Revokes one of the children +// - Verifies that the correct children remain and the revoked child is removed +// - Checks the parent-child relationships after partial revocation // 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() { @@ -1195,8 +1335,14 @@ fn test_do_revoke_children_multiple_partial_revocation() { }); } +// 32: Test revoking non-existent children +// This test verifies the behavior when attempting to revoke non-existent children: +// - Adds a network and registers a hotkey +// - Sets one child for the hotkey +// - Attempts to revoke all children (including non-existent ones) +// - Verifies that all children are removed, including the existing one +// - Checks that the parent-child relationship is properly updated // 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(|| { @@ -1236,6 +1382,11 @@ fn test_do_revoke_children_multiple_non_existent_children() { }); } +// 33: Test revoking children with an empty list +// This test verifies the behavior when attempting to revoke children using an empty list: +// - Adds a network and registers a hotkey +// - Attempts to revoke children with an empty list +// - Verifies that no changes occur in the children list // 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() { @@ -1262,6 +1413,13 @@ fn test_do_revoke_children_multiple_empty_list() { }); } +// 34: Test complex scenario for revoking multiple children +// This test verifies a complex scenario involving setting and revoking multiple children: +// - Adds a network and registers a hotkey +// - Sets multiple children with different proportions +// - Revokes one child and verifies the remaining children +// - Revokes all remaining children +// - Verifies that all parent-child relationships are properly updated // 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() { @@ -1328,6 +1486,11 @@ fn test_do_revoke_children_multiple_complex_scenario() { }); } +// 35: Test getting network max stake +// This test verifies the functionality of getting the network max stake: +// - Checks the default max stake value +// - Sets a new max stake value +// - Verifies that the new value is retrieved correctly // SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_get_network_max_stake --exact --nocapture #[test] fn test_get_network_max_stake() { @@ -1350,6 +1513,12 @@ fn test_get_network_max_stake() { }); } +// 36: Test setting network max stake +// This test verifies the functionality of setting the network max stake: +// - Checks the initial max stake value +// - Sets a new max stake value +// - Verifies that the new value is set correctly +// - Checks that the appropriate event is emitted // SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_set_network_max_stake --exact --nocapture #[test] fn test_set_network_max_stake() { @@ -1376,6 +1545,11 @@ fn test_set_network_max_stake() { }); } +// 37: Test setting network max stake for multiple networks +// This test verifies the functionality of setting different max stake values for multiple networks: +// - Sets different max stake values for two networks +// - Verifies that the values are set correctly for each network +// - Checks that the values are different between networks // SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_set_network_max_stake_multiple_networks --exact --nocapture #[test] fn test_set_network_max_stake_multiple_networks() { @@ -1399,6 +1573,12 @@ fn test_set_network_max_stake_multiple_networks() { }); } +// 38: Test updating network max stake +// This test verifies the functionality of updating an existing network max stake value: +// - Sets an initial max stake value +// - Updates the max stake value +// - Verifies that the value is updated correctly +// - Checks that the appropriate event is emitted for the update // SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_set_network_max_stake_update --exact --nocapture #[test] fn test_set_network_max_stake_update() { @@ -1428,6 +1608,13 @@ fn test_set_network_max_stake_update() { }); } +// 39: Test children stake values +// This test verifies the correct distribution of stake among parent and child neurons: +// - Sets up a network with a parent neuron and multiple child neurons +// - Assigns stake to the parent neuron +// - Sets child neurons with specific proportions +// - Verifies that the stake is correctly distributed among parent and child neurons +// - Checks that the total stake remains constant across all neurons // SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_children_stake_values --exact --nocapture #[test] fn test_children_stake_values() { @@ -1493,6 +1680,13 @@ fn test_children_stake_values() { }); } +// 40: Test getting parents chain +// This test verifies the correct implementation of parent-child relationships and the get_parents function: +// - Sets up a network with multiple neurons in a chain of parent-child relationships +// - Verifies that each neuron has the correct parent +// - Tests the root neuron has no parents +// - Tests a neuron with multiple parents +// - Verifies correct behavior when adding a new parent to an existing child // SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test children -- test_get_parents_chain --exact --nocapture #[test] fn test_get_parents_chain() { @@ -1626,3 +1820,1420 @@ fn test_get_parents_chain() { ); }); } + +// 41: Test emission distribution between a childkey and a single parent +// This test verifies the correct distribution of emissions between a child and a single parent: +// - Sets up a network with a parent, child, and weight setter +// - Establishes a parent-child relationship +// - Sets weights on the child +// - Runs an epoch with a hardcoded emission value +// - Checks the emission distribution among parent, child, and weight setter +// - Verifies that all parties received emissions and the weight setter received the most +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test children test_childkey_single_parent_emission -- --nocapture +#[test] +fn test_childkey_single_parent_emission() { + new_test_ext(1).execute_with(|| { + let netuid: u16 = 1; + add_network(netuid, 1, 0); + + // Define hotkeys + let parent: U256 = U256::from(1); + let child: U256 = U256::from(2); + let weight_setter: U256 = U256::from(3); + + // Define coldkeys with more readable names + let coldkey_parent: U256 = U256::from(100); + let coldkey_child: U256 = U256::from(101); + let coldkey_weight_setter: U256 = U256::from(102); + + // Register parent with minimal stake and child with high stake + SubtensorModule::add_balance_to_coldkey_account(&coldkey_parent, 1); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_child, 109_999); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_weight_setter, 1_000_000); + + // Add neurons for parent, child and weight_setter + register_ok_neuron(netuid, parent, coldkey_parent, 1); + register_ok_neuron(netuid, child, coldkey_child, 1); + register_ok_neuron(netuid, weight_setter, coldkey_weight_setter, 1); + + SubtensorModule::increase_stake_on_coldkey_hotkey_account( + &coldkey_parent, + &parent, + 109_999, + ); + SubtensorModule::increase_stake_on_coldkey_hotkey_account( + &coldkey_weight_setter, + &weight_setter, + 1_000_000, + ); + + SubtensorModule::set_weights_set_rate_limit(netuid, 0); + + // Set parent-child relationship + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey_parent), + parent, + netuid, + vec![(u64::MAX, child)] + )); + step_block(7200 + 1); + // Set weights on the child using the weight_setter account + let origin = RuntimeOrigin::signed(weight_setter); + let uids: Vec = vec![1]; // Only set weight for the child (UID 1) + let values: Vec = vec![u16::MAX]; // Use maximum value for u16 + let version_key = SubtensorModule::get_weights_version_key(netuid); + assert_ok!(SubtensorModule::set_weights( + origin, + netuid, + uids, + values, + version_key + )); + + // Run epoch with a hardcoded emission value + let hardcoded_emission: u64 = 1_000_000_000; // 1 TAO + let hotkey_emission: Vec<(U256, u64, u64)> = + SubtensorModule::epoch(netuid, hardcoded_emission); + + // Process the hotkey emission results + for (hotkey, mining_emission, validator_emission) in hotkey_emission { + SubtensorModule::accumulate_hotkey_emission( + &hotkey, + netuid, + validator_emission, + mining_emission, + ); + log::debug!( + "Accumulated emissions on hotkey {:?} for netuid {:?}: mining {:?}, validator {:?}", + hotkey, + netuid, + mining_emission, + validator_emission + ); + } + step_block(7200 + 1); + // Check emission distribution + let parent_stake: u64 = + SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey_parent, &parent); + let parent_stake_on_subnet: u64 = + SubtensorModule::get_stake_for_hotkey_on_subnet(&parent, netuid); + + log::debug!( + "Parent stake: {:?}, Parent stake on subnet: {:?}", + parent_stake, + parent_stake_on_subnet + ); + + let child_stake: u64 = + SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey_child, &child); + let child_stake_on_subnet: u64 = + SubtensorModule::get_stake_for_hotkey_on_subnet(&child, netuid); + + log::debug!( + "Child stake: {:?}, Child stake on subnet: {:?}", + child_stake, + child_stake_on_subnet + ); + + let weight_setter_stake: u64 = SubtensorModule::get_stake_for_coldkey_and_hotkey( + &coldkey_weight_setter, + &weight_setter, + ); + let weight_setter_stake_on_subnet: u64 = + SubtensorModule::get_stake_for_hotkey_on_subnet(&weight_setter, netuid); + + log::debug!( + "Weight setter stake: {:?}, Weight setter stake on subnet: {:?}", + weight_setter_stake, + weight_setter_stake_on_subnet + ); + + assert!(parent_stake > 1, "Parent should have received emission"); + assert!(child_stake > 109_999, "Child should have received emission"); + assert!( + weight_setter_stake > 1_000_000, + "Weight setter should have received emission" + ); + + // Additional assertion to verify that the weight setter received the most emission + assert!( + weight_setter_stake > parent_stake && weight_setter_stake > child_stake, + "Weight setter should have received the most emission" + ); + }); +} + +// 43: Test emission distribution between a childkey and multiple parents +// This test verifies the correct distribution of emissions between a child and multiple parents: +// - Sets up a network with two parents, a child, and a weight setter +// - Establishes parent-child relationships with different stake proportions +// - Sets weights on the child and one parent +// - Runs an epoch with a hardcoded emission value +// - Checks the emission distribution among parents, child, and weight setter +// - Verifies that all parties received emissions and the total stake increased correctly +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test coinbase test_childkey_multiple_parents_emission -- --nocapture +#[test] +fn test_childkey_multiple_parents_emission() { + new_test_ext(1).execute_with(|| { + let netuid: u16 = 1; + add_network(netuid, 1, 0); + + // Set registration parameters and emission tempo + SubtensorModule::set_max_registrations_per_block(netuid, 1000); + SubtensorModule::set_target_registrations_per_interval(netuid, 1000); + SubtensorModule::set_hotkey_emission_tempo(10); + + // Define hotkeys and coldkeys + let parent1: U256 = U256::from(1); + let parent2: U256 = U256::from(2); + let child: U256 = U256::from(3); + let weight_setter: U256 = U256::from(4); + let coldkey_parent1: U256 = U256::from(100); + let coldkey_parent2: U256 = U256::from(101); + let coldkey_child: U256 = U256::from(102); + let coldkey_weight_setter: U256 = U256::from(103); + + // Register neurons and add initial stakes + let initial_stakes: Vec<(U256, U256, u64)> = vec![ + (coldkey_parent1, parent1, 200_000), + (coldkey_parent2, parent2, 150_000), + (coldkey_child, child, 20_000), + (coldkey_weight_setter, weight_setter, 100_000), + ]; + + for (coldkey, hotkey, stake) in initial_stakes.iter() { + SubtensorModule::add_balance_to_coldkey_account(coldkey, *stake); + register_ok_neuron(netuid, *hotkey, *coldkey, 0); + SubtensorModule::increase_stake_on_coldkey_hotkey_account(coldkey, hotkey, *stake); + } + + SubtensorModule::set_weights_set_rate_limit(netuid, 0); + step_block(2); + + // Set parent-child relationships + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey_parent1), + parent1, + netuid, + vec![(100_000, child)] + )); + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey_parent2), + parent2, + netuid, + vec![(75_000, child)] + )); + + // Set weights + let uids: Vec = vec![0, 1, 2]; + let values: Vec = vec![0, 65354, 65354]; + let version_key = SubtensorModule::get_weights_version_key(netuid); + assert_ok!(SubtensorModule::set_weights( + RuntimeOrigin::signed(weight_setter), + netuid, + uids, + values, + version_key + )); + + // Run epoch with a hardcoded emission value + let hardcoded_emission: u64 = 1_000_000_000; // 1 billion + let hotkey_emission: Vec<(U256, u64, u64)> = + SubtensorModule::epoch(netuid, hardcoded_emission); + + // Process the hotkey emission results + for (hotkey, mining_emission, validator_emission) in hotkey_emission { + SubtensorModule::accumulate_hotkey_emission( + &hotkey, + netuid, + validator_emission, + mining_emission, + ); + log::debug!( + "Accumulated emissions on hotkey {:?} for netuid {:?}: mining {:?}, validator {:?}", + hotkey, + netuid, + mining_emission, + validator_emission + ); + } + + step_block(11); + + // Check emission distribution + let stakes: Vec<(U256, U256, &str)> = vec![ + (coldkey_parent1, parent1, "Parent1"), + (coldkey_parent2, parent2, "Parent2"), + (coldkey_child, child, "Child"), + (coldkey_weight_setter, weight_setter, "Weight setter"), + ]; + + for (coldkey, hotkey, name) in stakes.iter() { + let stake = SubtensorModule::get_stake_for_coldkey_and_hotkey(coldkey, hotkey); + let stake_on_subnet = SubtensorModule::get_stake_for_hotkey_on_subnet(hotkey, netuid); + log::debug!( + "{} stake: {:?}, {} stake on subnet: {:?}", + name, + stake, + name, + stake_on_subnet + ); + } + + let parent1_stake = + SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey_parent1, &parent1); + let parent2_stake = + SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey_parent2, &parent2); + let child_stake = SubtensorModule::get_stake_for_coldkey_and_hotkey(&coldkey_child, &child); + let weight_setter_stake = SubtensorModule::get_stake_for_coldkey_and_hotkey( + &coldkey_weight_setter, + &weight_setter, + ); + + assert!( + parent1_stake > 200_000, + "Parent1 should have received emission" + ); + assert!( + parent2_stake > 150_000, + "Parent2 should have received emission" + ); + assert!(child_stake > 20_000, "Child should have received emission"); + assert!( + weight_setter_stake > 100_000, + "Weight setter should have received emission" + ); + + // Check individual stake increases + let parent1_stake_increase = parent1_stake - 200_000; + let parent2_stake_increase = parent2_stake - 150_000; + let child_stake_increase = child_stake - 20_000; + + log::debug!( + "Stake increases - Parent1: {}, Parent2: {}, Child: {}", + parent1_stake_increase, + parent2_stake_increase, + child_stake_increase + ); + + // Assert that all neurons received some emission + assert!( + parent1_stake_increase > 0, + "Parent1 should have received some emission" + ); + assert!( + parent2_stake_increase > 0, + "Parent2 should have received some emission" + ); + assert!( + child_stake_increase > 0, + "Child should have received some emission" + ); + + // Check that the total stake has increased by the hardcoded emission amount + let total_stake = parent1_stake + parent2_stake + child_stake + weight_setter_stake; + let initial_total_stake: u64 = initial_stakes.iter().map(|(_, _, stake)| stake).sum(); + assert_eq!( + total_stake, + initial_total_stake + hardcoded_emission - 2, // U64::MAX normalization rounding error + "Total stake should have increased by the hardcoded emission amount" + ); + }); +} + +// 44: Test with a chain of parent-child relationships (e.g., A -> B -> C) +// This test verifies the correct distribution of emissions in a chain of parent-child relationships: +// - Sets up a network with three neurons A, B, and C in a chain (A -> B -> C) +// - Establishes parent-child relationships with different stake proportions +// - Sets weights for all neurons +// - Runs an epoch with a hardcoded emission value +// - Checks the emission distribution among A, B, and C +// - Verifies that all parties received emissions and the total stake increased correctly +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test coinbase test_parent_child_chain_emission -- --nocapture +#[test] +fn test_parent_child_chain_emission() { + new_test_ext(1).execute_with(|| { + let netuid: u16 = 1; + add_network(netuid, 1, 0); + + // Define hotkeys and coldkeys + let hotkey_a: U256 = U256::from(1); + let hotkey_b: U256 = U256::from(2); + let hotkey_c: U256 = U256::from(3); + let coldkey_a: U256 = U256::from(100); + let coldkey_b: U256 = U256::from(101); + let coldkey_c: U256 = U256::from(102); + + // Register neurons with decreasing stakes + register_ok_neuron(netuid, hotkey_a, coldkey_a, 0); + register_ok_neuron(netuid, hotkey_b, coldkey_b, 0); + register_ok_neuron(netuid, hotkey_c, coldkey_c, 0); + + // Add initial stakes + SubtensorModule::add_balance_to_coldkey_account(&coldkey_a, 300_000); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_b, 100_000); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_c, 50_000); + + SubtensorModule::increase_stake_on_coldkey_hotkey_account(&coldkey_a, &hotkey_a, 300_000); + SubtensorModule::increase_stake_on_coldkey_hotkey_account(&coldkey_b, &hotkey_b, 100_000); + SubtensorModule::increase_stake_on_coldkey_hotkey_account(&coldkey_c, &hotkey_c, 50_000); + + // Set parent-child relationships + // A -> B (50% of A's stake) + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey_a), + hotkey_a, + netuid, + vec![(u64::MAX / 2, hotkey_b)] + )); + // B -> C (50% of B's stake) + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey_b), + hotkey_b, + netuid, + vec![(u64::MAX / 2, hotkey_c)] + )); + + step_block(2); + + // Set weights + let origin = RuntimeOrigin::signed(hotkey_a); + let uids: Vec = vec![0, 1, 2]; // UIDs for hotkey_a, hotkey_b, hotkey_c + let values: Vec = vec![65535, 65535, 65535]; // Set equal weights for all hotkeys + let version_key = SubtensorModule::get_weights_version_key(netuid); + + // Ensure we can set weights without rate limiting + SubtensorModule::set_weights_set_rate_limit(netuid, 0); + + assert_ok!(SubtensorModule::set_weights( + origin, + netuid, + uids, + values, + version_key + )); + + // Run epoch with a hardcoded emission value + let hardcoded_emission: u64 = 1_000_000; // 1 million (adjust as needed) + let hotkey_emission: Vec<(U256, u64, u64)> = + SubtensorModule::epoch(netuid, hardcoded_emission); + + // Process the hotkey emission results + for (hotkey, mining_emission, validator_emission) in hotkey_emission { + SubtensorModule::accumulate_hotkey_emission( + &hotkey, + netuid, + validator_emission, + mining_emission, + ); + } + + // Log PendingEmission Tuple for a, b, c + let pending_emission_a = SubtensorModule::get_pending_hotkey_emission(&hotkey_a); + let pending_emission_b = SubtensorModule::get_pending_hotkey_emission(&hotkey_b); + let pending_emission_c = SubtensorModule::get_pending_hotkey_emission(&hotkey_c); + + println!("Pending Emission for A: {:?}", pending_emission_a); + println!("Pending Emission for B: {:?}", pending_emission_b); + println!("Pending Emission for C: {:?}", pending_emission_c); + + // Assert that pending emissions are non-zero + // A's pending emission: 2/3 of total emission (due to having 2/3 of total stake) + assert!( + pending_emission_a == 666667, + "A should have pending emission of 2/3 of total emission" + ); + // B's pending emission: 2/9 of total emission (1/3 of A's emission + 1/3 of total emission) + assert!( + pending_emission_b == 222222, + "B should have pending emission of 2/9 of total emission" + ); + // C's pending emission: 1/9 of total emission (1/2 of B's emission) + assert!( + pending_emission_c == 111109, + "C should have pending emission of 1/9 of total emission" + ); + + SubtensorModule::set_hotkey_emission_tempo(10); + + step_block(10 + 1); + // Retrieve the current stake for each hotkey on the subnet + let stake_a: u64 = SubtensorModule::get_stake_for_hotkey_on_subnet(&hotkey_a, netuid); + let stake_b: u64 = SubtensorModule::get_stake_for_hotkey_on_subnet(&hotkey_b, netuid); + let stake_c: u64 = SubtensorModule::get_stake_for_hotkey_on_subnet(&hotkey_c, netuid); + + // Log the current stakes for debugging purposes + log::info!("Stake for hotkey A: {:?}", stake_a); + log::info!("Stake for hotkey B: {:?}", stake_b); + log::info!("Stake for hotkey C: {:?}", stake_c); + + // Assert that the stakes have been updated correctly after emission distribution + assert_eq!( + stake_a, 483334, + "A's stake should be 483334 (initial 300_000 + 666667 emission - 483333 given to B)" + ); + assert_eq!( + stake_b, 644445, + "B's stake should be 644445 (initial 100_000 + 222222 emission + 483333 from A - 161110 given to C)" + ); + assert_eq!( + stake_c, 322219, + "C's stake should be 322219 (initial 50_000 + 111109 emission + 161110 from B)" + ); + + // Check that the total stake has increased by the hardcoded emission amount + let total_stake = stake_a + stake_b + stake_c; + let initial_total_stake = 300_000 + 100_000 + 50_000; + let hardcoded_emission = 1_000_000; // Define the hardcoded emission value + assert_eq!( + total_stake, + initial_total_stake + hardcoded_emission - 2, // U64::MAX normalization rounding error + "Total stake should have increased by the hardcoded emission amount" + ); + }); +} + +// 46: Test emission distribution when adding/removing parent-child relationships mid-epoch +// This test verifies the correct distribution of emissions when parent-child relationships change: +// - Sets up a network with three neurons: parent, child1, and child2 +// - Establishes initial parent-child relationship between parent and child1 +// - Runs first epoch and distributes emissions +// - Changes parent-child relationships to include both child1 and child2 +// - Runs second epoch and distributes emissions +// - Checks final emission distribution and stake updates +// - Verifies correct parent-child relationships and stake proportions +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test children -- test_dynamic_parent_child_relationships --exact --nocapture +#[test] +fn test_dynamic_parent_child_relationships() { + new_test_ext(1).execute_with(|| { + let netuid: u16 = 1; + add_network(netuid, 1, 0); + + // Define hotkeys and coldkeys + let parent: U256 = U256::from(1); + let child1: U256 = U256::from(2); + let child2: U256 = U256::from(3); + let coldkey_parent: U256 = U256::from(100); + let coldkey_child1: U256 = U256::from(101); + let coldkey_child2: U256 = U256::from(102); + + // Register neurons with varying stakes + register_ok_neuron(netuid, parent, coldkey_parent, 0); + register_ok_neuron(netuid, child1, coldkey_child1, 0); + register_ok_neuron(netuid, child2, coldkey_child2, 0); + + // Add initial stakes + SubtensorModule::add_balance_to_coldkey_account(&coldkey_parent, 500_000); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_child1, 50_000); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_child2, 30_000); + + SubtensorModule::increase_stake_on_coldkey_hotkey_account(&coldkey_parent, &parent, 500_000); + SubtensorModule::increase_stake_on_coldkey_hotkey_account(&coldkey_child1, &child1, 50_000); + SubtensorModule::increase_stake_on_coldkey_hotkey_account(&coldkey_child2, &child2, 30_000); + + // Set initial parent-child relationship + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey_parent), + parent, + netuid, + vec![(u64::MAX / 2, child1)] + )); + + step_block(2); + + // Set weights + let origin = RuntimeOrigin::signed(parent); + let uids: Vec = vec![0, 1, 2]; // UIDs for parent, child1, child2 + let values: Vec = vec![65535, 65535, 65535]; // Set equal weights for all hotkeys + let version_key = SubtensorModule::get_weights_version_key(netuid); + + // Ensure we can set weights without rate limiting + SubtensorModule::set_weights_set_rate_limit(netuid, 0); + + assert_ok!(SubtensorModule::set_weights( + origin, + netuid, + uids, + values, + version_key + )); + + // Set hotkey emission tempo + SubtensorModule::set_hotkey_emission_tempo(10); + + // Run first epoch + let hardcoded_emission: u64 = 1_000_000; // 1 million (adjust as needed) + let hotkey_emission: Vec<(U256, u64, u64)> = SubtensorModule::epoch(netuid, hardcoded_emission); + + // Process the hotkey emission results + for (hotkey, mining_emission, validator_emission) in hotkey_emission { + SubtensorModule::accumulate_hotkey_emission(&hotkey, netuid, validator_emission, mining_emission); + } + + // Step blocks to allow for emission distribution + step_block(11); + + // Change parent-child relationships + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey_parent), + parent, + netuid, + vec![(u64::MAX / 4, child1), (u64::MAX / 3, child2)] + )); + + // Run second epoch + let hotkey_emission: Vec<(U256, u64, u64)> = SubtensorModule::epoch(netuid, hardcoded_emission); + + // Process the hotkey emission results + for (hotkey, mining_emission, validator_emission) in hotkey_emission { + SubtensorModule::accumulate_hotkey_emission(&hotkey, netuid, validator_emission, mining_emission); + } + + // Step blocks again to allow for emission distribution + step_block(11); + + // Check final emission distribution + let parent_stake: u64 = SubtensorModule::get_stake_for_hotkey_on_subnet(&parent, netuid); + let child1_stake: u64 = SubtensorModule::get_stake_for_hotkey_on_subnet(&child1, netuid); + let child2_stake: u64 = SubtensorModule::get_stake_for_hotkey_on_subnet(&child2, netuid); + + println!("Final stakes:"); + println!("Parent stake: {}", parent_stake); + println!("Child1 stake: {}", child1_stake); + println!("Child2 stake: {}", child2_stake); + + const TOLERANCE: u64 = 5; // Allow for a small discrepancy due to potential rounding + + // Precise assertions with tolerance + assert!( + (parent_stake as i64 - 926725).abs() <= TOLERANCE as i64, + "Parent stake should be close to 926,725, but was {}", + parent_stake + ); + // Parent stake calculation: + // Initial stake: 500,000 + // First epoch: ~862,500 (500,000 + 725,000 * 1/2) + // Second epoch: ~926,725 (862,500 + 725,000 * 5/12) + + assert!( + (child1_stake as i64 - 778446).abs() <= TOLERANCE as i64, + "Child1 stake should be close to 778,446, but was {}", + child1_stake + ); + // Child1 stake calculation: + // Initial stake: 50,000 + // First epoch: ~412,500 (50,000 + 725,000 * 1/2) + // Second epoch: ~778,446 (412,500 + 725,000 * 1/2 * 1/4 + 137,500) + + assert!( + (child2_stake as i64 - 874826).abs() <= TOLERANCE as i64, + "Child2 stake should be close to 874,826, but was {}", + child2_stake + ); + // Child2 stake calculation: + // Initial stake: 30,000 + // First epoch: ~167,500 (30,000 + 137,500) + // Second epoch: ~874,826 (167,500 + 725,000 * 1/2 * 1/3 + 137,500) + + // Check that the total stake has increased by approximately twice the hardcoded emission amount + let total_stake: u64 = parent_stake + child1_stake + child2_stake; + let initial_total_stake: u64 = 500_000 + 50_000 + 30_000; + let total_emission: u64 = 2 * hardcoded_emission; + assert!( + (total_stake as i64 - (initial_total_stake + total_emission) as i64).abs() <= TOLERANCE as i64, + "Total stake should have increased by approximately twice the hardcoded emission amount" + ); + // Total stake calculation: + // Initial total stake: 500,000 + 50,000 + 30,000 = 580,000 + // Total emission: 2 * 1,000,000 = 2,000,000 + // Expected total stake: 580,000 + 2,000,000 = 2,580,000 + + // Additional checks for parent-child relationships + let parent_children: Vec<(u64, U256)> = SubtensorModule::get_children(&parent, netuid); + assert_eq!( + parent_children, + vec![(u64::MAX / 4, child1), (u64::MAX / 3, child2)], + "Parent should have both children with correct proportions" + ); + // Parent-child relationship: + // child1: 1/4 of parent's stake + // child2: 1/3 of parent's stake + + let child1_parents: Vec<(u64, U256)> = SubtensorModule::get_parents(&child1, netuid); + assert_eq!( + child1_parents, + vec![(u64::MAX / 4, parent)], + "Child1 should have parent as its parent with correct proportion" + ); + // Child1-parent relationship: + // parent: 1/4 of child1's stake + + let child2_parents: Vec<(u64, U256)> = SubtensorModule::get_parents(&child2, netuid); + assert_eq!( + child2_parents, + vec![(u64::MAX / 3, parent)], + "Child2 should have parent as its parent with correct proportion" + ); + // Child2-parent relationship: + // parent: 1/3 of child2's stake + + // Check that child2 has received more stake than child1 + assert!( + child2_stake > child1_stake, + "Child2 should have received more emission than Child1 due to higher proportion" + ); + // Child2 stake (874,826) > Child1 stake (778,446) + + // Check the approximate difference between child2 and child1 stakes + let stake_difference: u64 = child2_stake - child1_stake; + assert!( + (stake_difference as i64 - 96_380).abs() <= TOLERANCE as i64, + "The difference between Child2 and Child1 stakes should be close to 96,380, but was {}", + stake_difference + ); + // Stake difference calculation: + // Child2 stake: 874,826 + // Child1 stake: 778,446 + // Difference: 874,826 - 778,446 = 96,380 + }); +} + +// 47: Test basic stake retrieval for a single hotkey on a subnet +/// This test verifies the basic functionality of retrieving stake for a single hotkey on a subnet: +/// - Sets up a network with one neuron +/// - Increases stake for the neuron +/// - Checks if the retrieved stake matches the increased amount +/// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test children -- test_get_stake_for_hotkey_on_subnet_basic --exact --nocapture +#[test] +fn test_get_stake_for_hotkey_on_subnet_basic() { + new_test_ext(1).execute_with(|| { + let netuid: u16 = 1; + let hotkey = U256::from(1); + let coldkey = U256::from(2); + + add_network(netuid, 0, 0); + register_ok_neuron(netuid, hotkey, coldkey, 0); + + SubtensorModule::increase_stake_on_coldkey_hotkey_account(&coldkey, &hotkey, 1000); + + assert_eq!( + SubtensorModule::get_stake_for_hotkey_on_subnet(&hotkey, netuid), + 1000 + ); + }); +} + +// 48: Test stake retrieval for a hotkey with multiple coldkeys on a subnet +/// This test verifies the functionality of retrieving stake for a hotkey with multiple coldkeys on a subnet: +/// - Sets up a network with one neuron and two coldkeys +/// - Increases stake from both coldkeys +/// - Checks if the retrieved stake matches the total increased amount +/// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test children -- test_get_stake_for_hotkey_on_subnet_multiple_coldkeys --exact --nocapture +#[test] +fn test_get_stake_for_hotkey_on_subnet_multiple_coldkeys() { + new_test_ext(1).execute_with(|| { + let netuid: u16 = 1; + let hotkey = U256::from(1); + let coldkey1 = U256::from(2); + let coldkey2 = U256::from(3); + + add_network(netuid, 0, 0); + register_ok_neuron(netuid, hotkey, coldkey1, 0); + + SubtensorModule::increase_stake_on_coldkey_hotkey_account(&coldkey1, &hotkey, 1000); + SubtensorModule::increase_stake_on_coldkey_hotkey_account(&coldkey2, &hotkey, 2000); + + assert_eq!( + SubtensorModule::get_stake_for_hotkey_on_subnet(&hotkey, netuid), + 3000 + ); + }); +} + +// 49: Test stake retrieval for a single parent-child relationship on a subnet +/// This test verifies the functionality of retrieving stake for a single parent-child relationship on a subnet: +/// - Sets up a network with a parent and child neuron +/// - Increases stake for the parent +/// - Sets the child as the parent's only child with 100% stake allocation +/// - Checks if the retrieved stake for both parent and child is correct +/// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test children -- test_get_stake_for_hotkey_on_subnet_single_parent_child --exact --nocapture +#[test] +fn test_get_stake_for_hotkey_on_subnet_single_parent_child() { + new_test_ext(1).execute_with(|| { + let netuid: u16 = 1; + let parent = U256::from(1); + let child = U256::from(2); + let coldkey = U256::from(3); + + add_network(netuid, 0, 0); + register_ok_neuron(netuid, parent, coldkey, 0); + register_ok_neuron(netuid, child, coldkey, 0); + + SubtensorModule::increase_stake_on_coldkey_hotkey_account(&coldkey, &parent, 1000); + + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + parent, + netuid, + vec![(u64::MAX, child)] + )); + + assert_eq!( + SubtensorModule::get_stake_for_hotkey_on_subnet(&parent, netuid), + 0 + ); + assert_eq!( + SubtensorModule::get_stake_for_hotkey_on_subnet(&child, netuid), + 1000 + ); + }); +} + +// 50: Test stake retrieval for multiple parents and a single child on a subnet +/// This test verifies the functionality of retrieving stake for multiple parents and a single child on a subnet: +/// - Sets up a network with two parents and one child neuron +/// - Increases stake for both parents +/// - Sets the child as a 50% stake recipient for both parents +/// - Checks if the retrieved stake for parents and child is correct +/// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test children -- test_get_stake_for_hotkey_on_subnet_multiple_parents_single_child --exact --nocapture +#[test] +fn test_get_stake_for_hotkey_on_subnet_multiple_parents_single_child() { + new_test_ext(1).execute_with(|| { + let netuid: u16 = 1; + let parent1 = U256::from(1); + let parent2 = U256::from(2); + let child = U256::from(3); + let coldkey = U256::from(4); + + add_network(netuid, 0, 0); + register_ok_neuron(netuid, parent1, coldkey, 0); + register_ok_neuron(netuid, parent2, coldkey, 0); + register_ok_neuron(netuid, child, coldkey, 0); + + SubtensorModule::increase_stake_on_coldkey_hotkey_account(&coldkey, &parent1, 1000); + SubtensorModule::increase_stake_on_coldkey_hotkey_account(&coldkey, &parent2, 2000); + + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + parent1, + netuid, + vec![(u64::MAX / 2, child)] + )); + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + parent2, + netuid, + vec![(u64::MAX / 2, child)] + )); + + assert_eq!( + SubtensorModule::get_stake_for_hotkey_on_subnet(&parent1, netuid), + 501 + ); + assert_eq!( + SubtensorModule::get_stake_for_hotkey_on_subnet(&parent2, netuid), + 1001 + ); + assert_eq!( + SubtensorModule::get_stake_for_hotkey_on_subnet(&child, netuid), + 1498 + ); + }); +} + +// 51: Test stake retrieval for a single parent with multiple children on a subnet +/// This test verifies the functionality of retrieving stake for a single parent with multiple children on a subnet: +/// - Sets up a network with one parent and two child neurons +/// - Increases stake for the parent +/// - Sets both children as 1/3 stake recipients of the parent +/// - Checks if the retrieved stake for parent and children is correct and preserves total stake +/// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test children -- test_get_stake_for_hotkey_on_subnet_single_parent_multiple_children --exact --nocapture +#[test] +fn test_get_stake_for_hotkey_on_subnet_single_parent_multiple_children() { + new_test_ext(1).execute_with(|| { + let netuid: u16 = 1; + let parent = U256::from(1); + let child1 = U256::from(2); + let child2 = U256::from(3); + let coldkey = U256::from(4); + + add_network(netuid, 0, 0); + register_ok_neuron(netuid, parent, coldkey, 0); + register_ok_neuron(netuid, child1, coldkey, 0); + register_ok_neuron(netuid, child2, coldkey, 0); + + let total_stake = 3000; + SubtensorModule::increase_stake_on_coldkey_hotkey_account(&coldkey, &parent, total_stake); + + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + parent, + netuid, + vec![(u64::MAX / 3, child1), (u64::MAX / 3, child2)] + )); + + let parent_stake = SubtensorModule::get_stake_for_hotkey_on_subnet(&parent, netuid); + let child1_stake = SubtensorModule::get_stake_for_hotkey_on_subnet(&child1, netuid); + let child2_stake = SubtensorModule::get_stake_for_hotkey_on_subnet(&child2, netuid); + + // Check that the total stake is preserved + assert_eq!(parent_stake + child1_stake + child2_stake, total_stake); + + // Check that the parent stake is slightly higher due to rounding + assert_eq!(parent_stake, 1002); + + // Check that each child gets an equal share of the remaining stake + assert_eq!(child1_stake, 999); + assert_eq!(child2_stake, 999); + + // Log the actual stake values + println!("Parent stake: {}", parent_stake); + println!("Child1 stake: {}", child1_stake); + println!("Child2 stake: {}", child2_stake); + }); +} + +// 52: Test stake retrieval for edge cases on a subnet +/// This test verifies the functionality of retrieving stake for edge cases on a subnet: +/// - Sets up a network with one parent and two child neurons +/// - Increases stake to the network maximum +/// - Sets children with 0% and 100% stake allocation +/// - Checks if the retrieved stake for parent and children is correct and preserves total stake +/// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test children -- test_get_stake_for_hotkey_on_subnet_edge_cases --exact --nocapture +#[test] +fn test_get_stake_for_hotkey_on_subnet_edge_cases() { + new_test_ext(1).execute_with(|| { + let netuid: u16 = 1; + let parent = U256::from(1); + let child1 = U256::from(2); + let child2 = U256::from(3); + let coldkey = U256::from(4); + + add_network(netuid, 0, 0); + register_ok_neuron(netuid, parent, coldkey, 0); + register_ok_neuron(netuid, child1, coldkey, 0); + register_ok_neuron(netuid, child2, coldkey, 0); + + // Set network max stake + let network_max_stake: u64 = 500_000_000_000_000; // 500_000 TAO + SubtensorModule::set_network_max_stake(netuid, network_max_stake); + + // Increase stake to the network max + SubtensorModule::increase_stake_on_coldkey_hotkey_account( + &coldkey, + &parent, + network_max_stake, + ); + + // Test with 0% and 100% stake allocation + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey), + parent, + netuid, + vec![(0, child1), (u64::MAX, child2)] + )); + + let parent_stake = SubtensorModule::get_stake_for_hotkey_on_subnet(&parent, netuid); + let child1_stake = SubtensorModule::get_stake_for_hotkey_on_subnet(&child1, netuid); + let child2_stake = SubtensorModule::get_stake_for_hotkey_on_subnet(&child2, netuid); + + println!("Parent stake: {}", parent_stake); + println!("Child1 stake: {}", child1_stake); + println!("Child2 stake: {}", child2_stake); + + assert_eq!(parent_stake, 0, "Parent should have 0 stake"); + assert_eq!(child1_stake, 0, "Child1 should have 0 stake"); + assert_eq!( + child2_stake, network_max_stake, + "Child2 should have all the stake" + ); + + // Check that the total stake is preserved and equal to the network max stake + assert_eq!( + parent_stake + child1_stake + child2_stake, + network_max_stake, + "Total stake should equal the network max stake" + ); + }); +} + +// 53: Test stake distribution in a complex hierarchy of parent-child relationships +// This test verifies the correct distribution of stake in a multi-level parent-child hierarchy: +// - Sets up a network with four neurons: parent, child1, child2, and grandchild +// - Establishes parent-child relationships between parent and its children, and child1 and grandchild +// - Adds initial stake to the parent +// - Checks stake distribution after setting up the first level of relationships +// - Checks stake distribution after setting up the second level of relationships +// - Verifies correct stake calculations, parent-child relationships, and preservation of total stake +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test children -- test_get_stake_for_hotkey_on_subnet_complex_hierarchy --exact --nocapture + +#[test] +fn test_get_stake_for_hotkey_on_subnet_complex_hierarchy() { + new_test_ext(1).execute_with(|| { + let netuid: u16 = 1; + let parent = U256::from(1); + let child1 = U256::from(2); + let child2 = U256::from(3); + let grandchild = U256::from(4); + let coldkey_parent = U256::from(5); + let coldkey_child1 = U256::from(6); + let coldkey_child2 = U256::from(7); + let coldkey_grandchild = U256::from(8); + + add_network(netuid, 0, 0); + SubtensorModule::set_max_registrations_per_block(netuid, 1000); + SubtensorModule::set_target_registrations_per_interval(netuid, 1000); + register_ok_neuron(netuid, parent, coldkey_parent, 0); + register_ok_neuron(netuid, child1, coldkey_child1, 0); + register_ok_neuron(netuid, child2, coldkey_child2, 0); + register_ok_neuron(netuid, grandchild, coldkey_grandchild, 0); + + let total_stake = 1000; + SubtensorModule::increase_stake_on_coldkey_hotkey_account( + &coldkey_parent, + &parent, + total_stake, + ); + + println!("Initial stakes:"); + println!( + "Parent stake: {}", + SubtensorModule::get_stake_for_hotkey_on_subnet(&parent, netuid) + ); + println!( + "Child1 stake: {}", + SubtensorModule::get_stake_for_hotkey_on_subnet(&child1, netuid) + ); + println!( + "Child2 stake: {}", + SubtensorModule::get_stake_for_hotkey_on_subnet(&child2, netuid) + ); + println!( + "Grandchild stake: {}", + SubtensorModule::get_stake_for_hotkey_on_subnet(&grandchild, netuid) + ); + + // Step 1: Set children for parent + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey_parent), + parent, + netuid, + vec![(u64::MAX / 2, child1), (u64::MAX / 2, child2)] + )); + + println!("After setting parent's children:"); + println!( + "Parent's children: {:?}", + SubtensorModule::get_children(&parent, netuid) + ); + println!( + "Child1's parents: {:?}", + SubtensorModule::get_parents(&child1, netuid) + ); + println!( + "Child2's parents: {:?}", + SubtensorModule::get_parents(&child2, netuid) + ); + + let parent_stake_1 = SubtensorModule::get_stake_for_hotkey_on_subnet(&parent, netuid); + let child1_stake_1 = SubtensorModule::get_stake_for_hotkey_on_subnet(&child1, netuid); + let child2_stake_1 = SubtensorModule::get_stake_for_hotkey_on_subnet(&child2, netuid); + + println!("Parent stake: {}", parent_stake_1); + println!("Child1 stake: {}", child1_stake_1); + println!("Child2 stake: {}", child2_stake_1); + + assert_eq!( + parent_stake_1, 2, + "Parent should have 2 stake due to rounding" + ); + assert_eq!(child1_stake_1, 499, "Child1 should have 499 stake"); + assert_eq!(child2_stake_1, 499, "Child2 should have 499 stake"); + + // Step 2: Set children for child1 + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(coldkey_child1), + child1, + netuid, + vec![(u64::MAX, grandchild)] + )); + + println!("After setting child1's children:"); + println!( + "Child1's children: {:?}", + SubtensorModule::get_children(&child1, netuid) + ); + println!( + "Grandchild's parents: {:?}", + SubtensorModule::get_parents(&grandchild, netuid) + ); + + let parent_stake_2 = SubtensorModule::get_stake_for_hotkey_on_subnet(&parent, netuid); + let child1_stake_2 = SubtensorModule::get_stake_for_hotkey_on_subnet(&child1, netuid); + let child2_stake_2 = SubtensorModule::get_stake_for_hotkey_on_subnet(&child2, netuid); + let grandchild_stake = SubtensorModule::get_stake_for_hotkey_on_subnet(&grandchild, netuid); + + println!("Parent stake: {}", parent_stake_2); + println!("Child1 stake: {}", child1_stake_2); + println!("Child2 stake: {}", child2_stake_2); + println!("Grandchild stake: {}", grandchild_stake); + + assert_eq!(parent_stake_2, 2, "Parent stake should remain 2"); + assert_eq!( + child1_stake_2, 499, + "Child1 stake should be be the same , as it doesnt have owned stake" + ); + assert_eq!(child2_stake_2, 499, "Child2 should still have 499 stake"); + assert_eq!( + grandchild_stake, 0, + "Grandchild should have 0 , as child1 doesnt have any owned stake" + ); + + // Check that the total stake is preserved + assert_eq!( + parent_stake_2 + child1_stake_2 + child2_stake_2 + grandchild_stake, + total_stake, + "Total stake should equal the initial stake" + ); + + // Additional checks + println!("Final parent-child relationships:"); + println!( + "Parent's children: {:?}", + SubtensorModule::get_children(&parent, netuid) + ); + println!( + "Child1's parents: {:?}", + SubtensorModule::get_parents(&child1, netuid) + ); + println!( + "Child2's parents: {:?}", + SubtensorModule::get_parents(&child2, netuid) + ); + println!( + "Child1's children: {:?}", + SubtensorModule::get_children(&child1, netuid) + ); + println!( + "Grandchild's parents: {:?}", + SubtensorModule::get_parents(&grandchild, netuid) + ); + + // Check if the parent-child relationships are correct + assert_eq!( + SubtensorModule::get_children(&parent, netuid), + vec![(u64::MAX / 2, child1), (u64::MAX / 2, child2)], + "Parent should have both children" + ); + assert_eq!( + SubtensorModule::get_parents(&child1, netuid), + vec![(u64::MAX / 2, parent)], + "Child1 should have parent as its parent" + ); + assert_eq!( + SubtensorModule::get_parents(&child2, netuid), + vec![(u64::MAX / 2, parent)], + "Child2 should have parent as its parent" + ); + assert_eq!( + SubtensorModule::get_children(&child1, netuid), + vec![(u64::MAX, grandchild)], + "Child1 should have grandchild as its child" + ); + assert_eq!( + SubtensorModule::get_parents(&grandchild, netuid), + vec![(u64::MAX, child1)], + "Grandchild should have child1 as its parent" + ); + }); +} + +// 54: Test stake distribution across multiple networks +// This test verifies the correct distribution of stake for a single neuron across multiple networks: +// - Sets up two networks with a single neuron registered on both +// - Adds initial stake to the neuron +// - Checks that the stake is correctly reflected on both networks +// - Verifies that changes in stake are consistently applied across all networks +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test children -- test_get_stake_for_hotkey_on_subnet_multiple_networks --exact --nocapture + +#[test] +fn test_get_stake_for_hotkey_on_subnet_multiple_networks() { + new_test_ext(1).execute_with(|| { + let netuid1: u16 = 1; + let netuid2: u16 = 2; + let hotkey = U256::from(1); + let coldkey = U256::from(2); + + add_network(netuid1, 0, 0); + add_network(netuid2, 0, 0); + register_ok_neuron(netuid1, hotkey, coldkey, 0); + register_ok_neuron(netuid2, hotkey, coldkey, 0); + + SubtensorModule::increase_stake_on_coldkey_hotkey_account(&coldkey, &hotkey, 1000); + + assert_eq!( + SubtensorModule::get_stake_for_hotkey_on_subnet(&hotkey, netuid1), + 1000 + ); + assert_eq!( + SubtensorModule::get_stake_for_hotkey_on_subnet(&hotkey, netuid2), + 1000 + ); + }); +} + +/// 55: Test rank, trust, and incentive calculation with parent-child relationships +/// +/// This test verifies the correct calculation and distribution of rank, trust, incentive, and dividends +/// in a network with parent-child relationships: +/// - Sets up a network with validators (including a parent-child pair) and miners +/// - Establishes initial stakes and weights for all validators +/// - Runs a first epoch to establish baseline metrics +/// - Sets up a parent-child relationship +/// - Runs a second epoch to observe changes in metrics +/// - Verifies that the child's metrics improve relative to its initial state and other validators +/// +/// # Test Steps: +/// 1. Initialize test environment with validators (including parent and child) and miners +/// 2. Set up network parameters and register all neurons +/// 3. Set initial stakes for validators +/// 4. Set initial weights for all validators +/// 5. Run first epoch and process emissions +/// 6. Record initial metrics for the child +/// 7. Establish parent-child relationship +/// 8. Run second epoch and process emissions +/// 9. Record final metrics for the child +/// 10. Compare child's initial and final metrics +/// 11. Compare child's final metrics with other validators +/// +/// # Expected Results: +/// - Child's rank should improve (decrease) +/// - Child's trust should increase or remain the same +/// - Child's dividends should increase +/// - Child's final metrics should be better than or equal to other validators' +/// +/// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test children -- test_rank_trust_incentive_calculation_with_parent_child --exact --nocapture +#[test] +fn test_rank_trust_incentive_calculation_with_parent_child() { + new_test_ext(1).execute_with(|| { + // Initialize test environment + let netuid: u16 = 1; + let parent_hotkey: U256 = U256::from(1); + let parent_coldkey: U256 = U256::from(101); + let child_hotkey: U256 = U256::from(2); + let child_coldkey: U256 = U256::from(102); + let other_validators: Vec<(U256, U256)> = (3..6) + .map(|i| (U256::from(i), U256::from(100 + i))) + .collect(); + let miners: Vec<(U256, U256)> = (6..16) + .map(|i| (U256::from(i), U256::from(100 + i))) + .collect(); // 10 miners + + // Setup network and set registration parameters + add_network(netuid, 1, 0); + SubtensorModule::set_max_registrations_per_block(netuid, 1000); + SubtensorModule::set_target_registrations_per_interval(netuid, 1000); + SubtensorModule::set_weights_set_rate_limit(netuid, 0); + SubtensorModule::set_hotkey_emission_tempo(10); + + // Register neurons (validators and miners) + register_ok_neuron(netuid, parent_hotkey, parent_coldkey, 0); + register_ok_neuron(netuid, child_hotkey, child_coldkey, 0); + for (hotkey, coldkey) in &other_validators { + register_ok_neuron(netuid, *hotkey, *coldkey, 0); + } + for (hotkey, coldkey) in &miners { + register_ok_neuron(netuid, *hotkey, *coldkey, 0); + } + + step_block(2); + + // Set initial stakes for validators only + let initial_stake: u64 = 1_000_000_000; // 1000 TAO + SubtensorModule::add_balance_to_coldkey_account(&parent_coldkey, initial_stake); + SubtensorModule::increase_stake_on_coldkey_hotkey_account( + &parent_coldkey, + &parent_hotkey, + initial_stake, + ); + SubtensorModule::add_balance_to_coldkey_account(&child_coldkey, initial_stake); + SubtensorModule::increase_stake_on_coldkey_hotkey_account( + &child_coldkey, + &child_hotkey, + initial_stake, + ); + for (hotkey, coldkey) in &other_validators { + SubtensorModule::add_balance_to_coldkey_account(coldkey, initial_stake); + SubtensorModule::increase_stake_on_coldkey_hotkey_account( + coldkey, + hotkey, + initial_stake, + ); + } + + step_block(2); + + // Set initial weights for all validators + let all_uids: Vec = (0..15).collect(); // 0-4 are validators, 5-14 are miners + let validator_weights: Vec = vec![u16::MAX / 5; 5] // Equal weights for validators + .into_iter() + .chain(vec![u16::MAX / 10; 10]) // Equal weights for miners + .collect(); + + for hotkey in std::iter::once(&parent_hotkey) + .chain(other_validators.iter().map(|(h, _)| h)) + .chain(std::iter::once(&child_hotkey)) + { + assert_ok!(SubtensorModule::set_weights( + RuntimeOrigin::signed(*hotkey), + netuid, + all_uids.clone(), + validator_weights.clone(), + 0 + )); + } + + step_block(10); + + // Run first epoch + let rao_emission: u64 = 1_000_000_000; + let initial_emission = SubtensorModule::epoch(netuid, rao_emission); + + // Process initial emission + for (hotkey, mining_emission, validator_emission) in initial_emission { + SubtensorModule::accumulate_hotkey_emission( + &hotkey, + netuid, + validator_emission, + mining_emission, + ); + } + + step_block(11); + + // Get initial rank, trust, incentive, and dividends for the child + let initial_child_rank: u16 = SubtensorModule::get_rank_for_uid(netuid, 1); + let initial_child_trust: u16 = SubtensorModule::get_trust_for_uid(netuid, 1); + let initial_child_incentive: u16 = SubtensorModule::get_incentive_for_uid(netuid, 1); + let initial_child_dividends: u16 = SubtensorModule::get_dividends_for_uid(netuid, 1); + + log::debug!("Initial child rank: {:?}", initial_child_rank); + log::debug!("Initial child trust: {:?}", initial_child_trust); + log::debug!("Initial child incentive: {:?}", initial_child_incentive); + log::debug!("Initial child dividends: {:?}", initial_child_dividends); + + // Parent sets the child with 100% of its weight + assert_ok!(SubtensorModule::do_set_children( + RuntimeOrigin::signed(parent_coldkey), + parent_hotkey, + netuid, + vec![(u64::MAX, child_hotkey)] + )); + + // Child now sets weights as a validator + assert_ok!(SubtensorModule::set_weights( + RuntimeOrigin::signed(child_hotkey), + netuid, + all_uids.clone(), + validator_weights.clone(), + 1 + )); + + step_block(10); + + // Run second epoch + let final_emission = SubtensorModule::epoch(netuid, rao_emission); + + // Process final emission + for (hotkey, mining_emission, validator_emission) in final_emission { + SubtensorModule::accumulate_hotkey_emission( + &hotkey, + netuid, + validator_emission, + mining_emission, + ); + } + + step_block(11); + + // Get final rank, trust, incentive, and dividends for the child + let final_child_rank: u16 = SubtensorModule::get_rank_for_uid(netuid, 1); + let final_child_trust: u16 = SubtensorModule::get_trust_for_uid(netuid, 1); + let final_child_incentive: u16 = SubtensorModule::get_incentive_for_uid(netuid, 1); + let final_child_dividends: u16 = SubtensorModule::get_dividends_for_uid(netuid, 1); + + log::debug!("Final child rank: {:?}", final_child_rank); + log::debug!("Final child trust: {:?}", final_child_trust); + log::debug!("Final child incentive: {:?}", final_child_incentive); + log::debug!("Final child dividends: {:?}", final_child_dividends); + + // Print ranks for all validators + for i in 0..5 { + log::debug!( + "Validator {} rank: {:?}", + i, + SubtensorModule::get_rank_for_uid(netuid, i) + ); + } + + // Assert that rank has improved (decreased) for the child + assert!( + final_child_rank < initial_child_rank, + "Child rank should have improved (decreased). Initial: {}, Final: {}", + initial_child_rank, + final_child_rank + ); + + // Assert that trust has increased or remained the same for the child + assert!( + final_child_trust >= initial_child_trust, + "Child trust should have increased or remained the same. Initial: {}, Final: {}", + initial_child_trust, + final_child_trust + ); + + + // Assert that dividends have increased for the child + assert!( + final_child_dividends > initial_child_dividends, + "Child dividends should have increased. Initial: {}, Final: {}", + initial_child_dividends, + final_child_dividends + ); + + // Compare child's final values with other validators + for i in 2..5 { + let other_rank: u16 = SubtensorModule::get_rank_for_uid(netuid, i); + let other_trust: u16 = SubtensorModule::get_trust_for_uid(netuid, i); + let other_incentive: u16 = SubtensorModule::get_incentive_for_uid(netuid, i); + let other_dividends: u16 = SubtensorModule::get_dividends_for_uid(netuid, i); + + log::debug!( + "Validator {} - Rank: {}, Trust: {}, Incentive: {}, Dividends: {}", + i, other_rank, other_trust, other_incentive, other_dividends + ); + + assert!( + final_child_rank <= other_rank, + "Child rank should be better than or equal to other validators. Child: {}, Other: {}", + final_child_rank, + other_rank + ); + + assert!( + final_child_trust >= other_trust, + "Child trust should be greater than or equal to other validators. Child: {}, Other: {}", + final_child_trust, + other_trust + ); + + assert!( + final_child_dividends >= other_dividends, + "Child dividends should be greater than or equal to other validators. Child: {}, Other: {}", + final_child_dividends, + other_dividends + ); + } + + }); +} diff --git a/pallets/subtensor/tests/mock.rs b/pallets/subtensor/tests/mock.rs index 4039054e0..022849c56 100644 --- a/pallets/subtensor/tests/mock.rs +++ b/pallets/subtensor/tests/mock.rs @@ -507,3 +507,21 @@ pub fn add_network(netuid: u16, tempo: u16, _modality: u16) { SubtensorModule::set_network_registration_allowed(netuid, true); SubtensorModule::set_network_pow_registration_allowed(netuid, true); } + +// Helper function to set up a neuron with stake +#[allow(dead_code)] +pub fn setup_neuron_with_stake(netuid: u16, hotkey: U256, coldkey: U256, stake: u64) { + register_ok_neuron(netuid, hotkey, coldkey, stake); + SubtensorModule::increase_stake_on_coldkey_hotkey_account(&coldkey, &hotkey, stake); +} + +// Helper function to check if a value is within tolerance of an expected value +#[allow(dead_code)] +pub fn is_within_tolerance(actual: u64, expected: u64, tolerance: u64) -> bool { + let difference = if actual > expected { + actual - expected + } else { + expected - actual + }; + difference <= tolerance +} From 932e7b238bc4968ec0f2724797805f6d5935ab5c Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Wed, 7 Aug 2024 10:32:14 -0400 Subject: [PATCH 096/177] compiling but overflowing stack --- build.rs | 42 ++++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/build.rs b/build.rs index 7e653ebb3..970b1a88c 100644 --- a/build.rs +++ b/build.rs @@ -1,6 +1,8 @@ +use rayon::prelude::*; use std::env; use std::fs; use std::path::{Path, PathBuf}; +use std::sync::Mutex; use syn::Result; use walkdir::WalkDir; @@ -15,39 +17,43 @@ fn main() { // Collect all Rust source files in the workspace let rust_files = collect_rust_files(workspace_root); - let mut found_error = None; + let found_error = Mutex::new(None); - // Parse each Rust file with syn - for file in rust_files { - if found_error.is_some() { - break; + // Parse each rust file with syn and run the linting suite on it in parallel + rust_files.par_iter().for_each(|file| { + if found_error.lock().unwrap().is_some() { + return; } let Ok(content) = fs::read_to_string(&file) else { - continue; + return; }; let Ok(parsed_file) = syn::parse_file(&content) else { - continue; + return; }; let track_lint = |result: Result<()>| { let Err(error) = result else { return; }; - found_error = Some((error, file)); + *found_error.lock().unwrap() = Some((error, file.clone())); }; track_lint(DummyLint::lint(parsed_file)); - } + }); - if let Some((error, file)) = found_error { - let start = error.span().start(); - let end = error.span().end(); - let start_line = start.line; - let start_col = start.column; - let _end_line = end.line; - let _end_col = end.column; - let file_path = file.display(); - panic!("{}:{}:{}: {}", file_path, start_line, start_col, error); + // Use a separate scope to ensure the lock is released before the function exits + { + let guard = found_error.lock().expect("mutex was poisoned"); + if let Some((error, file)) = &*guard { + let start = error.span().start(); + let end = error.span().end(); + let start_line = start.line; + let start_col = start.column; + let _end_line = end.line; + let _end_col = end.column; + let file_path = file.display(); + panic!("{}:{}:{}: {}", file_path, start_line, start_col, error); + } } } From 4a87650b4abda9ee37191615db75d26a8d4cc368 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Wed, 7 Aug 2024 10:37:24 -0400 Subject: [PATCH 097/177] working in parallel :tada: --- build.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/build.rs b/build.rs index 970b1a88c..cb66f2894 100644 --- a/build.rs +++ b/build.rs @@ -57,7 +57,7 @@ fn main() { } } -// Recursively collects all Rust files in the given directory +/// Recursively collects all Rust files in the given directory fn collect_rust_files(dir: &Path) -> Vec { let mut rust_files = Vec::new(); @@ -65,7 +65,12 @@ fn collect_rust_files(dir: &Path) -> Vec { let entry = entry.unwrap(); let path = entry.path(); - if path.ends_with("target") || path.ends_with("build.rs") { + // Skip any path that contains "target" directory + if path + .components() + .any(|component| component.as_os_str() == "target") + || path.ends_with("build.rs") + { continue; } From 60f04ad56b2e0f84a4dfb9d3d04e1c02a0c8ed53 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Wed, 7 Aug 2024 10:55:22 -0400 Subject: [PATCH 098/177] use channels, warning syntax 100% working --- build.rs | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/build.rs b/build.rs index cb66f2894..32288c306 100644 --- a/build.rs +++ b/build.rs @@ -2,7 +2,7 @@ use rayon::prelude::*; use std::env; use std::fs; use std::path::{Path, PathBuf}; -use std::sync::Mutex; +use std::sync::mpsc::channel; use syn::Result; use walkdir::WalkDir; @@ -17,13 +17,10 @@ fn main() { // Collect all Rust source files in the workspace let rust_files = collect_rust_files(workspace_root); - let found_error = Mutex::new(None); + let (tx, rx) = channel(); // Parse each rust file with syn and run the linting suite on it in parallel - rust_files.par_iter().for_each(|file| { - if found_error.lock().unwrap().is_some() { - return; - } + rust_files.par_iter().for_each_with(tx.clone(), |tx, file| { let Ok(content) = fs::read_to_string(&file) else { return; }; @@ -35,25 +32,28 @@ fn main() { let Err(error) = result else { return; }; - *found_error.lock().unwrap() = Some((error, file.clone())); + tx.send((error, file.clone())).unwrap(); }; track_lint(DummyLint::lint(parsed_file)); }); - // Use a separate scope to ensure the lock is released before the function exits - { - let guard = found_error.lock().expect("mutex was poisoned"); - if let Some((error, file)) = &*guard { - let start = error.span().start(); - let end = error.span().end(); - let start_line = start.line; - let start_col = start.column; - let _end_line = end.line; - let _end_col = end.column; - let file_path = file.display(); - panic!("{}:{}:{}: {}", file_path, start_line, start_col, error); - } + // Collect and print all errors after the parallel processing is done + drop(tx); // Close the sending end of the channel + + for (error, file) in rx { + let relative_path = file.strip_prefix(workspace_root).unwrap_or(file.as_path()); + let start = error.span().start(); + let end = error.span().end(); + let start_line = start.line; + let start_col = start.column; + let _end_line = end.line; + let _end_col = end.column; + let file_path = relative_path.display(); + println!( + "cargo:warning={}:{}:{}: {}", + file_path, start_line, start_col, error + ); } } From 3de5b038307d3553e7999b47e960deab2bcc9a39 Mon Sep 17 00:00:00 2001 From: John Reed <87283488+JohnReedV@users.noreply.github.com> Date: Wed, 7 Aug 2024 07:56:25 -0700 Subject: [PATCH 099/177] Update run_coinbase.rs --- pallets/subtensor/src/coinbase/run_coinbase.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pallets/subtensor/src/coinbase/run_coinbase.rs b/pallets/subtensor/src/coinbase/run_coinbase.rs index 442a9f085..f7fa3b2a2 100644 --- a/pallets/subtensor/src/coinbase/run_coinbase.rs +++ b/pallets/subtensor/src/coinbase/run_coinbase.rs @@ -131,6 +131,11 @@ impl Pallet { log::debug!("Accumulated emissions on hotkey {:?} for netuid {:?}: mining {:?}, validator {:?}", hotkey, *netuid, mining_emission, validator_emission); } } else { + // 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), + ); log::debug!("Tempo not reached for subnet: {:?}", *netuid); } } From 037b76db2637d2e47970f3909ea1e4ab5256bf19 Mon Sep 17 00:00:00 2001 From: John Reed <87283488+JohnReedV@users.noreply.github.com> Date: Wed, 7 Aug 2024 09:13:58 -0700 Subject: [PATCH 100/177] add test_blocks_since_last_step --- .../subtensor/src/coinbase/run_coinbase.rs | 2 +- pallets/subtensor/tests/epoch.rs | 47 +++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/pallets/subtensor/src/coinbase/run_coinbase.rs b/pallets/subtensor/src/coinbase/run_coinbase.rs index f7fa3b2a2..723edc423 100644 --- a/pallets/subtensor/src/coinbase/run_coinbase.rs +++ b/pallets/subtensor/src/coinbase/run_coinbase.rs @@ -131,7 +131,7 @@ impl Pallet { log::debug!("Accumulated emissions on hotkey {:?} for netuid {:?}: mining {:?}, validator {:?}", hotkey, *netuid, mining_emission, validator_emission); } } else { - // No epoch, increase blocks since last step and continue, + // 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), diff --git a/pallets/subtensor/tests/epoch.rs b/pallets/subtensor/tests/epoch.rs index b639a4ac4..9c4bf87cc 100644 --- a/pallets/subtensor/tests/epoch.rs +++ b/pallets/subtensor/tests/epoch.rs @@ -2703,6 +2703,53 @@ fn test_get_set_alpha() { }); } +#[test] +fn test_blocks_since_last_step() { + new_test_ext(1).execute_with(|| { + System::set_block_number(0); + + let netuid: u16 = 1; + let tempo: u16 = 7200; + add_network(netuid, tempo, 0); + + let original_blocks: u64 = SubtensorModule::get_blocks_since_last_step(netuid); + + step_block(5); + + let new_blocks: u64 = SubtensorModule::get_blocks_since_last_step(netuid); + + assert!(new_blocks > original_blocks); + assert_eq!(new_blocks, 5); + + let blocks_to_step: u16 = SubtensorModule::blocks_until_next_epoch( + netuid, + tempo, + SubtensorModule::get_current_block_as_u64(), + ) as u16 + + 10; + step_block(blocks_to_step); + + let post_blocks: u64 = SubtensorModule::get_blocks_since_last_step(netuid); + + assert_eq!(post_blocks, 10); + + let blocks_to_step: u16 = SubtensorModule::blocks_until_next_epoch( + netuid, + tempo, + SubtensorModule::get_current_block_as_u64(), + ) as u16 + + 20; + step_block(blocks_to_step); + + let new_post_blocks: u64 = SubtensorModule::get_blocks_since_last_step(netuid); + + assert_eq!(new_post_blocks, 20); + + step_block(7); + + assert_eq!(SubtensorModule::get_blocks_since_last_step(netuid), 27); + }); +} // // Map the retention graph for consensus guarantees with an single epoch on a graph with 512 nodes, of which the first 64 are validators, the graph is split into a major and minor set, each setting specific weight on itself and the complement on the other. // // // // ```import torch From 75857e94628b0d50899bd036a5a7295713965a68 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Wed, 7 Aug 2024 12:33:11 -0400 Subject: [PATCH 101/177] freeze struct lint scaffold --- build.rs | 3 ++- lints/dummy_lint.rs | 2 +- lints/lint.rs | 3 +-- lints/mod.rs | 3 +++ lints/require_freeze_struct.rs | 9 +++++++++ 5 files changed, 16 insertions(+), 4 deletions(-) create mode 100644 lints/require_freeze_struct.rs diff --git a/build.rs b/build.rs index 32288c306..6b7d52e41 100644 --- a/build.rs +++ b/build.rs @@ -35,7 +35,8 @@ fn main() { tx.send((error, file.clone())).unwrap(); }; - track_lint(DummyLint::lint(parsed_file)); + track_lint(DummyLint::lint(&parsed_file)); + track_lint(RequireFreezeStruct::lint(&parsed_file)); }); // Collect and print all errors after the parallel processing is done diff --git a/lints/dummy_lint.rs b/lints/dummy_lint.rs index 41338b484..5364f2741 100644 --- a/lints/dummy_lint.rs +++ b/lints/dummy_lint.rs @@ -3,7 +3,7 @@ use super::*; pub struct DummyLint; impl Lint for DummyLint { - fn lint(_source: File) -> Result<()> { + fn lint(_source: &File) -> Result<()> { Ok(()) } } diff --git a/lints/lint.rs b/lints/lint.rs index 4a69995d9..16ce15f5d 100644 --- a/lints/lint.rs +++ b/lints/lint.rs @@ -1,4 +1,3 @@ - use super::*; /// A trait that defines custom lints that can be run within our workspace. @@ -8,5 +7,5 @@ use super::*; /// there are no errors. pub trait Lint: Send + Sync { /// Lints the given Rust source file, returning a compile error if any issues are found. - fn lint(source: File) -> Result<()>; + fn lint(source: &File) -> Result<()>; } diff --git a/lints/mod.rs b/lints/mod.rs index d2f9bb1e7..2a4a7103f 100644 --- a/lints/mod.rs +++ b/lints/mod.rs @@ -4,4 +4,7 @@ pub mod lint; pub use lint::*; mod dummy_lint; +mod require_freeze_struct; + pub use dummy_lint::DummyLint; +pub use require_freeze_struct::RequireFreezeStruct; diff --git a/lints/require_freeze_struct.rs b/lints/require_freeze_struct.rs new file mode 100644 index 000000000..0f2383a41 --- /dev/null +++ b/lints/require_freeze_struct.rs @@ -0,0 +1,9 @@ +use super::*; + +pub struct RequireFreezeStruct; + +impl Lint for RequireFreezeStruct { + fn lint(_source: &File) -> Result<()> { + Ok(()) + } +} From a9200bcfda3490133b0cea46275c6e6811aa4b10 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Wed, 7 Aug 2024 14:28:04 -0400 Subject: [PATCH 102/177] working! cleaning up now --- Cargo.lock | 1 + Cargo.toml | 1 + build.rs | 2 ++ lints/require_freeze_struct.rs | 62 +++++++++++++++++++++++++++++++++- pallets/collective/src/lib.rs | 1 + 5 files changed, 66 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index c24eca909..43a041c2f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9191,6 +9191,7 @@ dependencies = [ "pallet-commitments", "pallet-subtensor", "proc-macro2", + "quote", "rayon", "subtensor-macros", "syn 2.0.71", diff --git a/Cargo.toml b/Cargo.toml index bec2d95e3..12e92e813 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ subtensor-macros = { path = "support/macros", version = "0.1.0" } [build-dependencies] syn.workspace = true +quote.workspace = true proc-macro2.workspace = true walkdir.workspace = true rayon = "1.10" diff --git a/build.rs b/build.rs index 6b7d52e41..387a71d9d 100644 --- a/build.rs +++ b/build.rs @@ -17,6 +17,8 @@ fn main() { // Collect all Rust source files in the workspace let rust_files = collect_rust_files(workspace_root); + // Channel used to communicate errors back to the main thread from the parallel processing + // as we process each Rust file let (tx, rx) = channel(); // Parse each rust file with syn and run the linting suite on it in parallel diff --git a/lints/require_freeze_struct.rs b/lints/require_freeze_struct.rs index 0f2383a41..46f370dd1 100644 --- a/lints/require_freeze_struct.rs +++ b/lints/require_freeze_struct.rs @@ -1,9 +1,69 @@ use super::*; +use syn::parse_quote; +use syn::punctuated::Punctuated; +use syn::{visit::Visit, Attribute, ItemStruct, Meta, MetaList, Path, Result, Token}; pub struct RequireFreezeStruct; impl Lint for RequireFreezeStruct { - fn lint(_source: &File) -> Result<()> { + fn lint(source: &syn::File) -> Result<()> { + let mut visitor = EncodeDecodeVisitor::default(); + visitor.visit_file(source); + + if !visitor.errors.is_empty() { + for error in visitor.errors { + return Err(error); + } + } + Ok(()) } } + +#[derive(Default)] +struct EncodeDecodeVisitor { + errors: Vec, +} + +impl<'ast> Visit<'ast> for EncodeDecodeVisitor { + fn visit_item_struct(&mut self, node: &'ast ItemStruct) { + let has_encode_decode = node.attrs.iter().any(|attr| { + let result = is_derive_encode_or_decode(attr); + result + }); + let has_freeze_struct = node.attrs.iter().any(|attr| { + let result = is_freeze_struct(attr); + result + }); + + if has_encode_decode && !has_freeze_struct { + self.errors.push(syn::Error::new_spanned( + &node.ident, + "Struct with Encode/Decode derive must also have #[freeze_struct(..)] attribute.", + )); + } + + syn::visit::visit_item_struct(self, node); + } +} + +fn is_freeze_struct(attr: &Attribute) -> bool { + if let Meta::Path(ref path) = attr.meta { + path.is_ident("freeze_struct") + } else { + false + } +} + +fn is_derive_encode_or_decode(attr: &Attribute) -> bool { + if let Meta::List(MetaList { path, tokens, .. }) = &attr.meta { + if path.is_ident("derive") { + let nested: Punctuated = parse_quote!(#tokens); + return nested.iter().any(|nested| { + nested.segments.iter().any(|seg| seg.ident == "Encode") + || nested.segments.iter().any(|seg| seg.ident == "Decode") + }); + } + } + false +} diff --git a/pallets/collective/src/lib.rs b/pallets/collective/src/lib.rs index 6aae3c85e..823e92663 100644 --- a/pallets/collective/src/lib.rs +++ b/pallets/collective/src/lib.rs @@ -165,6 +165,7 @@ pub struct Votes { /// The hard end time of this vote. end: BlockNumber, } + #[deny(missing_docs)] #[frame_support::pallet] pub mod pallet { From 323f5ef432f395d51979052456e9e639349337e5 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Wed, 7 Aug 2024 14:38:35 -0400 Subject: [PATCH 103/177] now actually working, before had false positives --- lints/require_freeze_struct.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lints/require_freeze_struct.rs b/lints/require_freeze_struct.rs index 46f370dd1..00f9322f0 100644 --- a/lints/require_freeze_struct.rs +++ b/lints/require_freeze_struct.rs @@ -48,11 +48,12 @@ impl<'ast> Visit<'ast> for EncodeDecodeVisitor { } fn is_freeze_struct(attr: &Attribute) -> bool { - if let Meta::Path(ref path) = attr.meta { - path.is_ident("freeze_struct") - } else { - false + if let Meta::List(meta_list) = &attr.meta { + if meta_list.path.is_ident("freeze_struct") && !meta_list.tokens.is_empty() { + return true; + } } + false } fn is_derive_encode_or_decode(attr: &Attribute) -> bool { From a71a3a08eb9a873fe31a3def8662a6da55a4eefc Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Wed, 7 Aug 2024 16:03:53 -0400 Subject: [PATCH 104/177] WIP --- Cargo.toml | 2 +- build.rs | 15 +++------ lints/mod.rs | 60 ++++++++++++++++++++++++++++++++++ lints/require_freeze_struct.rs | 2 +- 4 files changed, 67 insertions(+), 12 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 12e92e813..dba517984 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -63,7 +63,7 @@ smallvec = "1.13.2" litep2p = { git = "https://github.com/paritytech/litep2p", branch = "master" } syn = { version = "2", features = ["full", "visit-mut", "extra-traits"] } quote = "1" -proc-macro2 = "1" +proc-macro2 = { version = "1", features = ["span-locations"] } walkdir = "2" subtensor-macros = { path = "support/macros" } diff --git a/build.rs b/build.rs index 387a71d9d..14684b5eb 100644 --- a/build.rs +++ b/build.rs @@ -34,7 +34,7 @@ fn main() { let Err(error) = result else { return; }; - tx.send((error, file.clone())).unwrap(); + tx.send((error, file.clone(), content.to_string())).unwrap(); }; track_lint(DummyLint::lint(&parsed_file)); @@ -44,18 +44,13 @@ fn main() { // Collect and print all errors after the parallel processing is done drop(tx); // Close the sending end of the channel - for (error, file) in rx { + for (error, file, content) in rx { let relative_path = file.strip_prefix(workspace_root).unwrap_or(file.as_path()); - let start = error.span().start(); - let end = error.span().end(); - let start_line = start.line; - let start_col = start.column; - let _end_line = end.line; - let _end_col = end.column; + let loc = error.span().location(&content); let file_path = relative_path.display(); println!( - "cargo:warning={}:{}:{}: {}", - file_path, start_line, start_col, error + "cargo:warning={}:{}:{}: {} (ends at {}:{})", + file_path, loc.start_line, loc.start_col, error, loc.end_line, loc.end_col ); } } diff --git a/lints/mod.rs b/lints/mod.rs index 2a4a7103f..91aa89ced 100644 --- a/lints/mod.rs +++ b/lints/mod.rs @@ -8,3 +8,63 @@ mod require_freeze_struct; pub use dummy_lint::DummyLint; pub use require_freeze_struct::RequireFreezeStruct; + +#[derive(Copy, Clone, Debug)] +pub struct SpanLocation { + pub start_line: usize, + pub start_col: usize, + pub end_line: usize, + pub end_col: usize, +} + +impl Default for SpanLocation { + fn default() -> Self { + Self { + start_line: 1, + start_col: 0, + end_line: 1, + end_col: 0, + } + } +} + +pub trait SpanHack { + fn location(&self, source: &str) -> SpanLocation; +} + +impl SpanHack for proc_macro2::Span { + fn location(&self, source: &str) -> SpanLocation { + let range = self.byte_range(); + + let mut start_line = 1; + let mut start_col = 0; + let mut end_line = 1; + let mut end_col = 0; + let mut current_col = 0; + + for (i, c) in source.chars().enumerate() { + if i == range.start { + start_line = end_line; + start_col = current_col; + } + if i == range.end { + end_line = end_line; + end_col = current_col; + break; + } + if c == '\n' { + current_col = 0; + end_line += 1; + } else { + current_col += 1; + } + } + + SpanLocation { + start_line, + start_col, + end_line, + end_col, + } + } +} diff --git a/lints/require_freeze_struct.rs b/lints/require_freeze_struct.rs index 00f9322f0..b18519ebc 100644 --- a/lints/require_freeze_struct.rs +++ b/lints/require_freeze_struct.rs @@ -38,7 +38,7 @@ impl<'ast> Visit<'ast> for EncodeDecodeVisitor { if has_encode_decode && !has_freeze_struct { self.errors.push(syn::Error::new_spanned( - &node.ident, + &node, "Struct with Encode/Decode derive must also have #[freeze_struct(..)] attribute.", )); } From dad50ac80d64be0c95dc67facde68da9e4c782c1 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Wed, 7 Aug 2024 17:43:07 -0400 Subject: [PATCH 105/177] ALMOST --- build.rs | 23 ++++++++++--------- lints/dummy_lint.rs | 4 +++- lints/lint.rs | 4 +++- lints/mod.rs | 41 ++++++++-------------------------- lints/require_freeze_struct.rs | 14 ++++++++---- 5 files changed, 38 insertions(+), 48 deletions(-) diff --git a/build.rs b/build.rs index 14684b5eb..fb8f2f50a 100644 --- a/build.rs +++ b/build.rs @@ -2,6 +2,7 @@ use rayon::prelude::*; use std::env; use std::fs; use std::path::{Path, PathBuf}; +use std::str::FromStr; use std::sync::mpsc::channel; use syn::Result; use walkdir::WalkDir; @@ -26,7 +27,7 @@ fn main() { let Ok(content) = fs::read_to_string(&file) else { return; }; - let Ok(parsed_file) = syn::parse_file(&content) else { + let Ok(parsed_file) = proc_macro2::TokenStream::from_str(&content) else { return; }; @@ -34,7 +35,14 @@ fn main() { let Err(error) = result else { return; }; - tx.send((error, file.clone(), content.to_string())).unwrap(); + let relative_path = file.strip_prefix(workspace_root).unwrap_or(file.as_path()); + let loc = error.span().location(); + let file_path = relative_path.display(); + tx.send(format!( + "cargo:warning={}:{}:{}: {} (ends at {}:{})", + file_path, loc.start_line, loc.start_col, error, loc.end_line, loc.end_col + )) + .unwrap(); }; track_lint(DummyLint::lint(&parsed_file)); @@ -44,15 +52,10 @@ fn main() { // Collect and print all errors after the parallel processing is done drop(tx); // Close the sending end of the channel - for (error, file, content) in rx { - let relative_path = file.strip_prefix(workspace_root).unwrap_or(file.as_path()); - let loc = error.span().location(&content); - let file_path = relative_path.display(); - println!( - "cargo:warning={}:{}:{}: {} (ends at {}:{})", - file_path, loc.start_line, loc.start_col, error, loc.end_line, loc.end_col - ); + for (error) in rx { + println!("{error}"); } + panic!("hey"); } /// Recursively collects all Rust files in the given directory diff --git a/lints/dummy_lint.rs b/lints/dummy_lint.rs index 5364f2741..3c046f4a2 100644 --- a/lints/dummy_lint.rs +++ b/lints/dummy_lint.rs @@ -1,9 +1,11 @@ +use proc_macro2::TokenStream; + use super::*; pub struct DummyLint; impl Lint for DummyLint { - fn lint(_source: &File) -> Result<()> { + fn lint(_source: &TokenStream) -> Result<()> { Ok(()) } } diff --git a/lints/lint.rs b/lints/lint.rs index 16ce15f5d..1cd4c9721 100644 --- a/lints/lint.rs +++ b/lints/lint.rs @@ -1,3 +1,5 @@ +use proc_macro2::TokenStream; + use super::*; /// A trait that defines custom lints that can be run within our workspace. @@ -7,5 +9,5 @@ use super::*; /// there are no errors. pub trait Lint: Send + Sync { /// Lints the given Rust source file, returning a compile error if any issues are found. - fn lint(source: &File) -> Result<()>; + fn lint(source: &TokenStream) -> Result<()>; } diff --git a/lints/mod.rs b/lints/mod.rs index 91aa89ced..e5a77fc3b 100644 --- a/lints/mod.rs +++ b/lints/mod.rs @@ -29,42 +29,19 @@ impl Default for SpanLocation { } pub trait SpanHack { - fn location(&self, source: &str) -> SpanLocation; + fn location(&self) -> SpanLocation; } impl SpanHack for proc_macro2::Span { - fn location(&self, source: &str) -> SpanLocation { - let range = self.byte_range(); - - let mut start_line = 1; - let mut start_col = 0; - let mut end_line = 1; - let mut end_col = 0; - let mut current_col = 0; - - for (i, c) in source.chars().enumerate() { - if i == range.start { - start_line = end_line; - start_col = current_col; - } - if i == range.end { - end_line = end_line; - end_col = current_col; - break; - } - if c == '\n' { - current_col = 0; - end_line += 1; - } else { - current_col += 1; - } - } - + fn location(&self) -> SpanLocation { + //println!("{:#?}", self); + let start = self.start(); + let end = self.end(); SpanLocation { - start_line, - start_col, - end_line, - end_col, + start_line: start.line, + start_col: start.column, + end_line: end.line, + end_col: end.column, } } } diff --git a/lints/require_freeze_struct.rs b/lints/require_freeze_struct.rs index b18519ebc..cdc190143 100644 --- a/lints/require_freeze_struct.rs +++ b/lints/require_freeze_struct.rs @@ -1,14 +1,20 @@ use super::*; +use proc_macro2::TokenStream; use syn::parse_quote; use syn::punctuated::Punctuated; +use syn::spanned::Spanned; use syn::{visit::Visit, Attribute, ItemStruct, Meta, MetaList, Path, Result, Token}; pub struct RequireFreezeStruct; impl Lint for RequireFreezeStruct { - fn lint(source: &syn::File) -> Result<()> { + fn lint(source: &TokenStream) -> Result<()> { let mut visitor = EncodeDecodeVisitor::default(); - visitor.visit_file(source); + + //println!("{:#?}", source.span()); + let file = syn::parse2::(source.clone()).unwrap(); + //println!("{:#?}", file.span()); + visitor.visit_file(&file); if !visitor.errors.is_empty() { for error in visitor.errors { @@ -37,8 +43,8 @@ impl<'ast> Visit<'ast> for EncodeDecodeVisitor { }); if has_encode_decode && !has_freeze_struct { - self.errors.push(syn::Error::new_spanned( - &node, + self.errors.push(syn::Error::new( + node.span(), "Struct with Encode/Decode derive must also have #[freeze_struct(..)] attribute.", )); } From 303db90596284fee336e3665b0d5395889cf5cdb Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Wed, 7 Aug 2024 23:28:30 -0400 Subject: [PATCH 106/177] add new proxy types --- runtime/src/lib.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index d047288dd..029a15687 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -620,6 +620,8 @@ pub enum ProxyType { Owner, // Subnet owner Calls NonCritical, NonTransfer, + Transfer, + SmallTransfer, Senate, NonFungibile, // Nothing involving moving TAO Triumvirate, @@ -627,6 +629,8 @@ pub enum ProxyType { Staking, Registration, } +// Transfers below SMALL_TRANSFER_LIMIT are considered small transfers +pub const SMALL_TRANSFER_LIMIT: Balance = 500_000_000; // 0.5 TAO impl Default for ProxyType { fn default() -> Self { Self::Any @@ -645,6 +649,22 @@ impl InstanceFilter for ProxyType { | RuntimeCall::SubtensorModule(pallet_subtensor::Call::burned_register { .. }) | RuntimeCall::SubtensorModule(pallet_subtensor::Call::root_register { .. }) ), + ProxyType::Transfer => matches!( + c, + RuntimeCall::Balances(pallet_balances::Call::transfer_keep_alive { .. }) + | RuntimeCall::Balances(pallet_balances::Call::transfer_allow_death { .. }) + | RuntimeCall::Balances(pallet_balances::Call::transfer_all { .. }) + ), + ProxyType::SmallTransfer => match c { + RuntimeCall::Balances(pallet_balances::Call::transfer_keep_alive { + value, .. + }) => *value < SMALL_TRANSFER_LIMIT, + RuntimeCall::Balances(pallet_balances::Call::transfer_allow_death { + value, + .. + }) => *value < SMALL_TRANSFER_LIMIT, + _ => false, + }, ProxyType::Owner => matches!(c, RuntimeCall::AdminUtils(..)), ProxyType::NonCritical => !matches!( c, From 8a86e360348c0c483d2a9c49794eeea76f714760 Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Wed, 7 Aug 2024 23:42:27 -0400 Subject: [PATCH 107/177] add supersets --- runtime/src/lib.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 029a15687..5ed1131af 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -701,8 +701,12 @@ impl InstanceFilter for ProxyType { (x, y) if x == y => true, (ProxyType::Any, _) => true, (_, ProxyType::Any) => false, - (ProxyType::NonTransfer, _) => true, + (ProxyType::NonTransfer, _) => { + // NonTransfer is NOT a superset of Transfer or SmallTransfer + !matches!(o, ProxyType::Transfer | ProxyType::SmallTransfer) + } (ProxyType::Governance, ProxyType::Triumvirate | ProxyType::Senate) => true, + (ProxyType::Transfer, ProxyType::SmallTransfer) => true, _ => false, } } From 43dbb6c9e8affb6aa6c33bcbed6560beee5f6794 Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Wed, 7 Aug 2024 23:42:31 -0400 Subject: [PATCH 108/177] add test --- runtime/tests/pallet_proxy.rs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/runtime/tests/pallet_proxy.rs b/runtime/tests/pallet_proxy.rs index 796dfc471..eea250938 100644 --- a/runtime/tests/pallet_proxy.rs +++ b/runtime/tests/pallet_proxy.rs @@ -200,3 +200,30 @@ fn test_proxy_pallet() { } } } + +#[test] +fn test_non_transfer_cannot_transfer() { + new_test_ext().execute_with(|| { + assert_ok!(Proxy::add_proxy( + RuntimeOrigin::signed(AccountId::from(ACCOUNT)), + AccountId::from(DELEGATE).into(), + ProxyType::NonTransfer, + 0 + )); + + let call = call_transfer(); + assert_ok!(Proxy::proxy( + RuntimeOrigin::signed(AccountId::from(DELEGATE)), + AccountId::from(ACCOUNT).into(), + None, + Box::new(call.clone()), + )); + + System::assert_last_event( + pallet_proxy::Event::ProxyExecuted { + result: Err(SystemError::CallFiltered.into()), + } + .into(), + ); + }); +} From e1ba277e4e004942f1412581340fb996196ae29b Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Thu, 8 Aug 2024 00:23:10 -0400 Subject: [PATCH 109/177] clean up --- build.rs | 11 +++++----- lints/mod.rs | 39 +--------------------------------- lints/require_freeze_struct.rs | 9 ++------ 3 files changed, 9 insertions(+), 50 deletions(-) diff --git a/build.rs b/build.rs index fb8f2f50a..587817090 100644 --- a/build.rs +++ b/build.rs @@ -36,11 +36,13 @@ fn main() { return; }; let relative_path = file.strip_prefix(workspace_root).unwrap_or(file.as_path()); - let loc = error.span().location(); + let loc = error.span().start(); let file_path = relative_path.display(); + // note that spans can't go across thread boundaries without losing their location + // info so we we serialize here and send a String tx.send(format!( - "cargo:warning={}:{}:{}: {} (ends at {}:{})", - file_path, loc.start_line, loc.start_col, error, loc.end_line, loc.end_col + "cargo:warning={}:{}:{}: {}", + file_path, loc.line, loc.column, error, )) .unwrap(); }; @@ -52,10 +54,9 @@ fn main() { // Collect and print all errors after the parallel processing is done drop(tx); // Close the sending end of the channel - for (error) in rx { + for error in rx { println!("{error}"); } - panic!("hey"); } /// Recursively collects all Rust files in the given directory diff --git a/lints/mod.rs b/lints/mod.rs index e5a77fc3b..741278ab3 100644 --- a/lints/mod.rs +++ b/lints/mod.rs @@ -1,4 +1,4 @@ -use syn::{File, Result}; +use syn::Result; pub mod lint; pub use lint::*; @@ -8,40 +8,3 @@ mod require_freeze_struct; pub use dummy_lint::DummyLint; pub use require_freeze_struct::RequireFreezeStruct; - -#[derive(Copy, Clone, Debug)] -pub struct SpanLocation { - pub start_line: usize, - pub start_col: usize, - pub end_line: usize, - pub end_col: usize, -} - -impl Default for SpanLocation { - fn default() -> Self { - Self { - start_line: 1, - start_col: 0, - end_line: 1, - end_col: 0, - } - } -} - -pub trait SpanHack { - fn location(&self) -> SpanLocation; -} - -impl SpanHack for proc_macro2::Span { - fn location(&self) -> SpanLocation { - //println!("{:#?}", self); - let start = self.start(); - let end = self.end(); - SpanLocation { - start_line: start.line, - start_col: start.column, - end_line: end.line, - end_col: end.column, - } - } -} diff --git a/lints/require_freeze_struct.rs b/lints/require_freeze_struct.rs index cdc190143..825ce34e8 100644 --- a/lints/require_freeze_struct.rs +++ b/lints/require_freeze_struct.rs @@ -1,9 +1,6 @@ use super::*; use proc_macro2::TokenStream; -use syn::parse_quote; -use syn::punctuated::Punctuated; -use syn::spanned::Spanned; -use syn::{visit::Visit, Attribute, ItemStruct, Meta, MetaList, Path, Result, Token}; +use syn::{punctuated::Punctuated, parse_quote, visit::Visit, Attribute, ItemStruct, Meta, MetaList, Path, Result, Token}; pub struct RequireFreezeStruct; @@ -11,9 +8,7 @@ impl Lint for RequireFreezeStruct { fn lint(source: &TokenStream) -> Result<()> { let mut visitor = EncodeDecodeVisitor::default(); - //println!("{:#?}", source.span()); let file = syn::parse2::(source.clone()).unwrap(); - //println!("{:#?}", file.span()); visitor.visit_file(&file); if !visitor.errors.is_empty() { @@ -44,7 +39,7 @@ impl<'ast> Visit<'ast> for EncodeDecodeVisitor { if has_encode_decode && !has_freeze_struct { self.errors.push(syn::Error::new( - node.span(), + node.ident.span(), "Struct with Encode/Decode derive must also have #[freeze_struct(..)] attribute.", )); } From 0d486ba8f00dccdeb5064973eb15b6d51821ce2a Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Thu, 8 Aug 2024 00:28:34 -0400 Subject: [PATCH 110/177] reorder so enum doesnt change --- runtime/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 5ed1131af..75471d164 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -620,14 +620,14 @@ pub enum ProxyType { Owner, // Subnet owner Calls NonCritical, NonTransfer, - Transfer, - SmallTransfer, Senate, NonFungibile, // Nothing involving moving TAO Triumvirate, Governance, // Both above governance Staking, Registration, + Transfer, + SmallTransfer, } // Transfers below SMALL_TRANSFER_LIMIT are considered small transfers pub const SMALL_TRANSFER_LIMIT: Balance = 500_000_000; // 0.5 TAO From 13db9e6b2b65a5a8419ef49086d450e1680593fd Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Thu, 8 Aug 2024 01:01:46 -0400 Subject: [PATCH 111/177] add missing freeze_struct to Registration --- pallets/commitments/src/types.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/pallets/commitments/src/types.rs b/pallets/commitments/src/types.rs index 912a474c0..06bafcaac 100644 --- a/pallets/commitments/src/types.rs +++ b/pallets/commitments/src/types.rs @@ -299,6 +299,7 @@ pub struct CommitmentInfo> { /// /// NOTE: This is stored separately primarily to facilitate the addition of extra fields in a /// backwards compatible way through a specialized `Decode` impl. +#[freeze_struct("632f12850e51c420")] #[derive( CloneNoBound, Encode, Eq, MaxEncodedLen, PartialEqNoBound, RuntimeDebugNoBound, TypeInfo, )] From a6d13f62adec87aff6b7598a65103c7a19f19f1d Mon Sep 17 00:00:00 2001 From: Greg Zaitsev Date: Thu, 8 Aug 2024 13:55:28 -0400 Subject: [PATCH 112/177] Add short default tempo to fast-blocks feature --- runtime/src/lib.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index dec65f60f..f5db5d1ed 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -848,6 +848,12 @@ impl pallet_commitments::Config for Runtime { type RateLimit = CommitmentRateLimit; } +#[cfg(not(feature = "fast-blocks"))] +pub const INITIAL_SUBNET_TEMPO: u16 = 99; + +#[cfg(feature = "fast-blocks")] +pub const INITIAL_SUBNET_TEMPO: u16 = 10; + // Configure the pallet subtensor. parameter_types! { pub const SubtensorInitialRho: u16 = 10; @@ -860,7 +866,7 @@ parameter_types! { pub const SubtensorInitialValidatorPruneLen: u64 = 1; pub const SubtensorInitialScalingLawPower: u16 = 50; // 0.5 pub const SubtensorInitialMaxAllowedValidators: u16 = 128; - pub const SubtensorInitialTempo: u16 = 99; + pub const SubtensorInitialTempo: u16 = INITIAL_SUBNET_TEMPO; pub const SubtensorInitialDifficulty: u64 = 10_000_000; pub const SubtensorInitialAdjustmentInterval: u16 = 100; pub const SubtensorInitialAdjustmentAlpha: u64 = 0; // no weight to previous value. From 6a792ce655e2aff22550319c3b2ddd8a4e1bce69 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Thu, 8 Aug 2024 15:33:59 -0400 Subject: [PATCH 113/177] add missing freeze_structs + confirm detection issue with crate::freeze_struct --- pallets/registry/src/types.rs | 1 + pallets/subtensor/src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/pallets/registry/src/types.rs b/pallets/registry/src/types.rs index 0badd5669..58cc5ed19 100644 --- a/pallets/registry/src/types.rs +++ b/pallets/registry/src/types.rs @@ -367,6 +367,7 @@ impl> IdentityInfo { /// /// NOTE: This is stored separately primarily to facilitate the addition of extra fields in a /// backwards compatible way through a specialized `Decode` impl. +#[freeze_struct("797b69e82710bb21")] #[derive( CloneNoBound, Encode, Eq, MaxEncodedLen, PartialEqNoBound, RuntimeDebugNoBound, TypeInfo, )] diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index b305661f7..e2d194401 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -59,7 +59,6 @@ extern crate alloc; #[import_section(config::config)] #[frame_support::pallet] pub mod pallet { - use crate::migrations; use frame_support::{ dispatch::GetDispatchInfo, @@ -96,6 +95,7 @@ pub mod pallet { pub type AxonInfoOf = AxonInfo; /// Data structure for Axon information. + #[crate::freeze_struct("3545cfb0cac4c1f5")] #[derive(Encode, Decode, Default, TypeInfo, Clone, PartialEq, Eq, Debug)] pub struct AxonInfo { /// Axon serving block. From b3485c94ac57e689f472ad9a604409f1aa740b82 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Thu, 8 Aug 2024 15:37:02 -0400 Subject: [PATCH 114/177] fix detection issue --- lints/require_freeze_struct.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lints/require_freeze_struct.rs b/lints/require_freeze_struct.rs index 825ce34e8..0dae59262 100644 --- a/lints/require_freeze_struct.rs +++ b/lints/require_freeze_struct.rs @@ -1,6 +1,9 @@ use super::*; use proc_macro2::TokenStream; -use syn::{punctuated::Punctuated, parse_quote, visit::Visit, Attribute, ItemStruct, Meta, MetaList, Path, Result, Token}; +use syn::{ + parse_quote, punctuated::Punctuated, visit::Visit, Attribute, ItemStruct, Meta, MetaList, Path, + Result, Token, +}; pub struct RequireFreezeStruct; @@ -50,7 +53,10 @@ impl<'ast> Visit<'ast> for EncodeDecodeVisitor { fn is_freeze_struct(attr: &Attribute) -> bool { if let Meta::List(meta_list) = &attr.meta { - if meta_list.path.is_ident("freeze_struct") && !meta_list.tokens.is_empty() { + let Some(seg) = meta_list.path.segments.last() else { + return false; + }; + if seg.ident == "freeze_struct" && !meta_list.tokens.is_empty() { return true; } } From a76484c0096b32a8de7442ef140c8aaf8271370a Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Thu, 8 Aug 2024 16:06:58 -0400 Subject: [PATCH 115/177] fix rerun-if logic --- build.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/build.rs b/build.rs index 587817090..a1f1a0ddb 100644 --- a/build.rs +++ b/build.rs @@ -11,6 +11,14 @@ mod lints; use lints::*; fn main() { + // need to list all rust directories here + println!("cargo:rerun-if-changed=pallets"); + println!("cargo:rerun-if-changed=node"); + println!("cargo:rerun-if-changed=runtime"); + println!("cargo:rerun-if-changed=lints"); + println!("cargo:rerun-if-changed=build.rs"); + println!("cargo:rerun-if-changed=src"); + println!("cargo:rerun-if-changed=support"); // Get the root directory of the workspace let workspace_root = env::var("CARGO_MANIFEST_DIR").unwrap(); let workspace_root = Path::new(&workspace_root); From f704724df5b61a0e9c16971f737a2beb47579c6a Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Thu, 8 Aug 2024 16:07:11 -0400 Subject: [PATCH 116/177] add missing freeze_struct to PrometheusInfo --- pallets/subtensor/src/lib.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index e2d194401..466ecf966 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -118,7 +118,9 @@ pub mod pallet { /// Struct for Prometheus. pub type PrometheusInfoOf = PrometheusInfo; + /// Data structure for Prometheus information. + #[crate::freeze_struct("5dde687e63baf0cd")] #[derive(Encode, Decode, Default, TypeInfo, Clone, PartialEq, Eq, Debug)] pub struct PrometheusInfo { /// Prometheus serving block. @@ -135,7 +137,9 @@ pub mod pallet { /// Struct for Prometheus. pub type ChainIdentityOf = ChainIdentity; + /// Data structure for Prometheus information. + #[crate::freeze_struct("bbfd00438dbe2b58")] #[derive(Encode, Decode, Default, TypeInfo, Clone, PartialEq, Eq, Debug)] pub struct ChainIdentity { /// The name of the chain identity From 955ee84f95a06373df97834b0995eb53eff2365e Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Thu, 8 Aug 2024 16:42:51 -0400 Subject: [PATCH 117/177] hack: include linting framework in main crate so we can test it --- build.rs | 5 +++-- {lints => src/lints}/dummy_lint.rs | 0 {lints => src/lints}/lint.rs | 0 {lints => src/lints}/mod.rs | 0 {lints => src/lints}/require_freeze_struct.rs | 0 src/mod.rs | 1 + tests/lint_tests.rs | 1 + 7 files changed, 5 insertions(+), 2 deletions(-) rename {lints => src/lints}/dummy_lint.rs (100%) rename {lints => src/lints}/lint.rs (100%) rename {lints => src/lints}/mod.rs (100%) rename {lints => src/lints}/require_freeze_struct.rs (100%) create mode 100644 src/mod.rs create mode 100644 tests/lint_tests.rs diff --git a/build.rs b/build.rs index a1f1a0ddb..74cc1a9fc 100644 --- a/build.rs +++ b/build.rs @@ -7,8 +7,9 @@ use std::sync::mpsc::channel; use syn::Result; use walkdir::WalkDir; -mod lints; -use lints::*; +// HACK: let's us have tests for our linting framework but still be part of the build script +mod src; +use src::lints::*; fn main() { // need to list all rust directories here diff --git a/lints/dummy_lint.rs b/src/lints/dummy_lint.rs similarity index 100% rename from lints/dummy_lint.rs rename to src/lints/dummy_lint.rs diff --git a/lints/lint.rs b/src/lints/lint.rs similarity index 100% rename from lints/lint.rs rename to src/lints/lint.rs diff --git a/lints/mod.rs b/src/lints/mod.rs similarity index 100% rename from lints/mod.rs rename to src/lints/mod.rs diff --git a/lints/require_freeze_struct.rs b/src/lints/require_freeze_struct.rs similarity index 100% rename from lints/require_freeze_struct.rs rename to src/lints/require_freeze_struct.rs diff --git a/src/mod.rs b/src/mod.rs new file mode 100644 index 000000000..2d9270d07 --- /dev/null +++ b/src/mod.rs @@ -0,0 +1 @@ +pub mod lints; diff --git a/tests/lint_tests.rs b/tests/lint_tests.rs new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/tests/lint_tests.rs @@ -0,0 +1 @@ + From 19aa49fb1b19a446c8819301a71175ad482a27b7 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Thu, 8 Aug 2024 17:04:54 -0400 Subject: [PATCH 118/177] refactor to enable testing, separate linting crate --- Cargo.lock | 10 ++++++++++ Cargo.toml | 7 ++++++- build.rs | 4 +--- src/mod.rs | 1 - support/linting/Cargo.toml | 12 ++++++++++++ {src/lints => support/linting/src}/dummy_lint.rs | 0 src/lints/mod.rs => support/linting/src/lib.rs | 0 {src/lints => support/linting/src}/lint.rs | 0 .../linting/src}/require_freeze_struct.rs | 0 tests/lint_tests.rs | 1 - 10 files changed, 29 insertions(+), 6 deletions(-) delete mode 100644 src/mod.rs create mode 100644 support/linting/Cargo.toml rename {src/lints => support/linting/src}/dummy_lint.rs (100%) rename src/lints/mod.rs => support/linting/src/lib.rs (100%) rename {src/lints => support/linting/src}/lint.rs (100%) rename {src/lints => support/linting/src}/require_freeze_struct.rs (100%) delete mode 100644 tests/lint_tests.rs diff --git a/Cargo.lock b/Cargo.lock index 43a041c2f..417aeeca9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4114,6 +4114,15 @@ dependencies = [ "nalgebra", ] +[[package]] +name = "linting" +version = "0.1.0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.71", +] + [[package]] name = "linux-raw-sys" version = "0.1.4" @@ -9186,6 +9195,7 @@ dependencies = [ name = "subtensor" version = "0.1.0" dependencies = [ + "linting", "node-subtensor", "node-subtensor-runtime", "pallet-commitments", diff --git a/Cargo.toml b/Cargo.toml index dba517984..d93e99505 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,7 @@ node-subtensor-runtime = { path = "runtime", version = "4.0.0-dev" } subtensor-macros = { path = "support/macros", version = "0.1.0" } [build-dependencies] +linting = { path = "support/linting", version = "0.1.0" } syn.workspace = true quote.workspace = true proc-macro2.workspace = true @@ -28,8 +29,12 @@ members = [ "node", "pallets/commitments", "pallets/subtensor", + "pallets/admin-utils", + "pallets/collective", + "pallets/registry", "runtime", "support/macros", + "support/linting", ] resolver = "2" @@ -61,7 +66,7 @@ serde_json = { version = "1.0.116", default-features = false } serde_with = { version = "=2.0.0", default-features = false } smallvec = "1.13.2" litep2p = { git = "https://github.com/paritytech/litep2p", branch = "master" } -syn = { version = "2", features = ["full", "visit-mut", "extra-traits"] } +syn = { version = "2", features = ["full", "visit-mut", "visit", "extra-traits", "parsing"] } quote = "1" proc-macro2 = { version = "1", features = ["span-locations"] } walkdir = "2" diff --git a/build.rs b/build.rs index 74cc1a9fc..b13b5bb6b 100644 --- a/build.rs +++ b/build.rs @@ -7,9 +7,7 @@ use std::sync::mpsc::channel; use syn::Result; use walkdir::WalkDir; -// HACK: let's us have tests for our linting framework but still be part of the build script -mod src; -use src::lints::*; +use linting::*; fn main() { // need to list all rust directories here diff --git a/src/mod.rs b/src/mod.rs deleted file mode 100644 index 2d9270d07..000000000 --- a/src/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod lints; diff --git a/support/linting/Cargo.toml b/support/linting/Cargo.toml new file mode 100644 index 000000000..f76b638e0 --- /dev/null +++ b/support/linting/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "linting" +version = "0.1.0" +edition = "2021" + +[dependencies] +syn.workspace = true +quote.workspace = true +proc-macro2.workspace = true + +[lints] +workspace = true diff --git a/src/lints/dummy_lint.rs b/support/linting/src/dummy_lint.rs similarity index 100% rename from src/lints/dummy_lint.rs rename to support/linting/src/dummy_lint.rs diff --git a/src/lints/mod.rs b/support/linting/src/lib.rs similarity index 100% rename from src/lints/mod.rs rename to support/linting/src/lib.rs diff --git a/src/lints/lint.rs b/support/linting/src/lint.rs similarity index 100% rename from src/lints/lint.rs rename to support/linting/src/lint.rs diff --git a/src/lints/require_freeze_struct.rs b/support/linting/src/require_freeze_struct.rs similarity index 100% rename from src/lints/require_freeze_struct.rs rename to support/linting/src/require_freeze_struct.rs diff --git a/tests/lint_tests.rs b/tests/lint_tests.rs deleted file mode 100644 index 8b1378917..000000000 --- a/tests/lint_tests.rs +++ /dev/null @@ -1 +0,0 @@ - From 2abb31936ea035d0a0a62b5288ab28572dd9a01b Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Thu, 8 Aug 2024 17:30:40 -0400 Subject: [PATCH 119/177] tests for freeze struct lint --- Cargo.lock | 20 ++-- Cargo.toml | 2 +- build.rs | 2 +- support/linting/Cargo.toml | 2 +- support/linting/src/require_freeze_struct.rs | 118 +++++++++++++++++++ 5 files changed, 131 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 417aeeca9..350831723 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4114,15 +4114,6 @@ dependencies = [ "nalgebra", ] -[[package]] -name = "linting" -version = "0.1.0" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.71", -] - [[package]] name = "linux-raw-sys" version = "0.1.4" @@ -9195,7 +9186,6 @@ dependencies = [ name = "subtensor" version = "0.1.0" dependencies = [ - "linting", "node-subtensor", "node-subtensor-runtime", "pallet-commitments", @@ -9203,6 +9193,7 @@ dependencies = [ "proc-macro2", "quote", "rayon", + "subtensor-linting", "subtensor-macros", "syn 2.0.71", "walkdir", @@ -9233,6 +9224,15 @@ dependencies = [ "sp-api", ] +[[package]] +name = "subtensor-linting" +version = "0.1.0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.71", +] + [[package]] name = "subtensor-macros" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index d93e99505..36a87755b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ node-subtensor-runtime = { path = "runtime", version = "4.0.0-dev" } subtensor-macros = { path = "support/macros", version = "0.1.0" } [build-dependencies] -linting = { path = "support/linting", version = "0.1.0" } +subtensor-linting = { path = "support/linting", version = "0.1.0" } syn.workspace = true quote.workspace = true proc-macro2.workspace = true diff --git a/build.rs b/build.rs index b13b5bb6b..780b43cc1 100644 --- a/build.rs +++ b/build.rs @@ -7,7 +7,7 @@ use std::sync::mpsc::channel; use syn::Result; use walkdir::WalkDir; -use linting::*; +use subtensor_linting::*; fn main() { // need to list all rust directories here diff --git a/support/linting/Cargo.toml b/support/linting/Cargo.toml index f76b638e0..1e37d8163 100644 --- a/support/linting/Cargo.toml +++ b/support/linting/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "linting" +name = "subtensor-linting" version = "0.1.0" edition = "2021" diff --git a/support/linting/src/require_freeze_struct.rs b/support/linting/src/require_freeze_struct.rs index 0dae59262..deafc93cb 100644 --- a/support/linting/src/require_freeze_struct.rs +++ b/support/linting/src/require_freeze_struct.rs @@ -75,3 +75,121 @@ fn is_derive_encode_or_decode(attr: &Attribute) -> bool { } false } + +#[cfg(test)] +mod tests { + use super::*; + + fn lint_struct(input: &str) -> Result<()> { + let item_struct: ItemStruct = syn::parse_str(input).unwrap(); + let mut visitor = EncodeDecodeVisitor::default(); + visitor.visit_item_struct(&item_struct); + if visitor.errors.is_empty() { + Ok(()) + } else { + Err(visitor.errors[0].clone()) + } + } + + #[test] + fn test_no_attributes() { + let input = r#" + pub struct Test { + field: u32, + } + "#; + assert!(lint_struct(input).is_ok()); + } + + #[test] + fn test_freeze_struct_only() { + let input = r#" + #[freeze_struct("12345")] + pub struct Test { + field: u32, + } + "#; + assert!(lint_struct(input).is_ok()); + } + + #[test] + fn test_encode_only() { + let input = r#" + #[derive(Encode)] + pub struct Test { + field: u32, + } + "#; + assert!(lint_struct(input).is_err()); + } + + #[test] + fn test_decode_only() { + let input = r#" + #[derive(Decode)] + pub struct Test { + field: u32, + } + "#; + assert!(lint_struct(input).is_err()); + } + + #[test] + fn test_encode_and_freeze_struct() { + let input = r#" + #[freeze_struct("12345")] + #[derive(Encode)] + pub struct Test { + field: u32, + } + "#; + assert!(lint_struct(input).is_ok()); + } + + #[test] + fn test_decode_and_freeze_struct() { + let input = r#" + #[freeze_struct("12345")] + #[derive(Decode)] + pub struct Test { + field: u32, + } + "#; + assert!(lint_struct(input).is_ok()); + } + + #[test] + fn test_encode_decode_without_freeze_struct() { + let input = r#" + #[derive(Encode, Decode)] + pub struct Test { + field: u32, + } + "#; + assert!(lint_struct(input).is_err()); + } + + #[test] + fn test_encode_decode_with_freeze_struct() { + let input = r#" + #[freeze_struct("12345")] + #[derive(Encode, Decode)] + pub struct Test { + field: u32, + } + "#; + assert!(lint_struct(input).is_ok()); + } + + #[test] + fn test_temporary_freeze_struct() { + let input = r#" + #[freeze_struct] + #[derive(Encode, Decode)] + pub struct Test { + field: u32, + } + "#; + assert!(lint_struct(input).is_err()); + } +} From c34d72b23579c611a3368ae2932604353794f9b6 Mon Sep 17 00:00:00 2001 From: VectorChat Date: Thu, 8 Aug 2024 16:41:13 -0500 Subject: [PATCH 120/177] neuron pruning changes, initial tests --- pallets/subtensor/src/registration.rs | 80 ++++++++--------- pallets/subtensor/src/utils.rs | 7 ++ pallets/subtensor/tests/registration.rs | 115 ++++++++++++++++++++++++ 3 files changed, 158 insertions(+), 44 deletions(-) diff --git a/pallets/subtensor/src/registration.rs b/pallets/subtensor/src/registration.rs index 6b73f2fc3..1ece0e9ca 100644 --- a/pallets/subtensor/src/registration.rs +++ b/pallets/subtensor/src/registration.rs @@ -423,65 +423,57 @@ impl Pallet { } /// Determine which peer to prune from the network by finding the element with the lowest pruning score out of - /// immunity period. If all neurons are in immunity period, return node with lowest prunning score. - /// This function will always return an element to prune. + /// immunity period. If there is a tie for lowest pruning score, the neuron registered earliest is pruned. + /// If all neurons are in immunity period, the neuron with the lowest pruning score is pruned. If there is a tie for + /// the lowest pruning score, the immune neuron registered earliest is pruned. + /// Ties for earliest registration are broken by the neuron with the lowest uid. pub fn get_neuron_to_prune(netuid: u16) -> u16 { let mut min_score: u16 = u16::MAX; - let mut min_score_in_immunity_period = u16::MAX; - let mut uid_with_min_score = 0; - let mut uid_with_min_score_in_immunity_period: u16 = 0; + let mut min_score_in_immunity: u16 = u16::MAX; + let mut earliest_registration: u64 = u64::MAX; + let mut earliest_registration_in_immunity: u64 = u64::MAX; + let mut uid_to_prune: u16 = 0; + let mut uid_to_prune_in_immunity: u16 = 0; + let mut found_non_immune = false; let neurons_n = Self::get_subnetwork_n(netuid); if neurons_n == 0 { return 0; // If there are no neurons in this network. } - let current_block: u64 = Self::get_current_block_as_u64(); - let immunity_period: u64 = Self::get_immunity_period(netuid) as u64; - for neuron_uid_i in 0..neurons_n { - let pruning_score: u16 = Self::get_pruning_score_for_uid(netuid, neuron_uid_i); + for neuron_uid in 0..neurons_n { + let pruning_score: u16 = Self::get_pruning_score_for_uid(netuid, neuron_uid); let block_at_registration: u64 = - Self::get_neuron_block_at_registration(netuid, neuron_uid_i); - #[allow(clippy::comparison_chain)] - if min_score == pruning_score { - if current_block.saturating_sub(block_at_registration) < immunity_period { - //neuron is in immunity period - if min_score_in_immunity_period > pruning_score { - min_score_in_immunity_period = pruning_score; - uid_with_min_score_in_immunity_period = neuron_uid_i; - } - } else { - uid_with_min_score = neuron_uid_i; + Self::get_neuron_block_at_registration(netuid, neuron_uid); + let is_immune = Self::get_neuron_is_immune(netuid, neuron_uid); + + if is_immune { + if pruning_score < min_score_in_immunity + || (pruning_score == min_score_in_immunity + && block_at_registration < earliest_registration_in_immunity) + { + min_score_in_immunity = pruning_score; + earliest_registration_in_immunity = block_at_registration; + uid_to_prune_in_immunity = neuron_uid; } - } - // Find min pruning score. - else if min_score > pruning_score { - if current_block.saturating_sub(block_at_registration) < immunity_period { - //neuron is in immunity period - if min_score_in_immunity_period > pruning_score { - min_score_in_immunity_period = pruning_score; - uid_with_min_score_in_immunity_period = neuron_uid_i; - } - } else { + } else { + found_non_immune = true; + if pruning_score < min_score + || (pruning_score == min_score && block_at_registration < earliest_registration) + { min_score = pruning_score; - uid_with_min_score = neuron_uid_i; + earliest_registration = block_at_registration; + uid_to_prune = neuron_uid; } } } - if min_score == u16::MAX { - //all neuorns are in immunity period - Self::set_pruning_score_for_uid( - netuid, - uid_with_min_score_in_immunity_period, - u16::MAX, - ); - uid_with_min_score_in_immunity_period + + if found_non_immune { + Self::set_pruning_score_for_uid(netuid, uid_to_prune, u16::MAX); + uid_to_prune } else { - // We replace the pruning score here with u16 max to ensure that all peers always have a - // pruning score. In the event that every peer has been pruned this function will prune - // the last element in the network continually. - Self::set_pruning_score_for_uid(netuid, uid_with_min_score, u16::MAX); - uid_with_min_score + Self::set_pruning_score_for_uid(netuid, uid_to_prune_in_immunity, u16::MAX); + uid_to_prune_in_immunity } } diff --git a/pallets/subtensor/src/utils.rs b/pallets/subtensor/src/utils.rs index c61133e94..d12a8a01a 100644 --- a/pallets/subtensor/src/utils.rs +++ b/pallets/subtensor/src/utils.rs @@ -461,6 +461,13 @@ impl Pallet { Self::deposit_event(Event::ImmunityPeriodSet(netuid, immunity_period)); } + pub fn get_neuron_is_immune(netuid: u16, uid: u16) -> bool { + let registered_at = Self::get_neuron_block_at_registration(netuid, uid); + let current_block = Self::get_current_block_as_u64(); + let immunity_period = Self::get_immunity_period(netuid); + current_block.saturating_sub(registered_at) < u64::from(immunity_period) + } + pub fn get_min_allowed_weights(netuid: u16) -> u16 { MinAllowedWeights::::get(netuid) } diff --git a/pallets/subtensor/tests/registration.rs b/pallets/subtensor/tests/registration.rs index 7d6e8ea65..98963f61c 100644 --- a/pallets/subtensor/tests/registration.rs +++ b/pallets/subtensor/tests/registration.rs @@ -1,6 +1,9 @@ #![allow(clippy::unwrap_used)] +use std::u16; + use frame_support::traits::Currency; +use substrate_fixed::types::extra::True; use crate::mock::*; use frame_support::dispatch::{DispatchClass, DispatchInfo, GetDispatchInfo, Pays}; @@ -538,6 +541,118 @@ fn test_burn_adjustment() { }); } +#[test] +fn test_burn_registration_pruning_scenarios() { + new_test_ext(1).execute_with(|| { + let netuid: u16 = 1; + let tempo: u16 = 13; + let burn_cost = 1000; + let coldkey_account_id = U256::from(667); + let max_allowed_uids = 6; + let immunity_period = 5000; + + SubtensorModule::set_burn(netuid, burn_cost); + SubtensorModule::set_max_allowed_uids(netuid, max_allowed_uids); + SubtensorModule::set_target_registrations_per_interval(netuid, max_allowed_uids); + SubtensorModule::set_immunity_period(netuid, immunity_period); + + // SubtensorModule::set_immunity_period(netuid, immunity_period); + + add_network(netuid, tempo, 0); + + let mint_balance = burn_cost * u64::from(max_allowed_uids) + 1_000_000_000; + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, mint_balance); + + // Register first half of neurons + for i in 0..3 { + assert_ok!(SubtensorModule::burned_register( + <::RuntimeOrigin>::signed(coldkey_account_id), + netuid, + U256::from(i) + )); + step_block(1); + } + + // Note: pruning score is set to u16::MAX after getting neuron to prune + + // 1. Test all immune neurons + assert_eq!(SubtensorModule::get_neuron_is_immune(netuid, 0), true); + assert_eq!(SubtensorModule::get_neuron_is_immune(netuid, 1), true); + assert_eq!(SubtensorModule::get_neuron_is_immune(netuid, 2), true); + + SubtensorModule::set_pruning_score_for_uid(netuid, 0, 100); + SubtensorModule::set_pruning_score_for_uid(netuid, 1, 75); + SubtensorModule::set_pruning_score_for_uid(netuid, 2, 50); + + // The immune neuron with the lowest score should be pruned + assert_eq!(SubtensorModule::get_neuron_to_prune(netuid), 2); + + // 2. Test tie-breaking for immune neurons + SubtensorModule::set_pruning_score_for_uid(netuid, 1, 50); + SubtensorModule::set_pruning_score_for_uid(netuid, 2, 50); + + // Should get the oldest neuron + assert_eq!(SubtensorModule::get_neuron_to_prune(netuid), 1); + + // 3. Test no immune neurons + step_block(immunity_period); + + assert_eq!(SubtensorModule::get_neuron_is_immune(netuid, 0), false); + assert_eq!(SubtensorModule::get_neuron_is_immune(netuid, 1), false); + assert_eq!(SubtensorModule::get_neuron_is_immune(netuid, 2), false); + + SubtensorModule::set_pruning_score_for_uid(netuid, 0, 100); + SubtensorModule::set_pruning_score_for_uid(netuid, 1, 50); + SubtensorModule::set_pruning_score_for_uid(netuid, 2, 75); + + // The non-immune neuron with the lowest score should be pruned + assert_eq!(SubtensorModule::get_neuron_to_prune(netuid), 1); + + // 4. Test tie-breaking for non-immune neurons + SubtensorModule::set_pruning_score_for_uid(netuid, 1, 50); + SubtensorModule::set_pruning_score_for_uid(netuid, 2, 50); + + // Should get the oldest non-immune neuron + assert_eq!(SubtensorModule::get_neuron_to_prune(netuid), 1); + + // 5. Test mixed immunity + // Register second batch of neurons (these will be non-immune) + for i in 3..6 { + assert_ok!(SubtensorModule::burned_register( + <::RuntimeOrigin>::signed(coldkey_account_id), + netuid, + U256::from(i) + )); + step_block(1); + } + + assert_eq!(SubtensorModule::get_neuron_is_immune(netuid, 3), true); + assert_eq!(SubtensorModule::get_neuron_is_immune(netuid, 4), true); + assert_eq!(SubtensorModule::get_neuron_is_immune(netuid, 5), true); + + // Set pruning scores for all neurons + SubtensorModule::set_pruning_score_for_uid(netuid, 0, 75); // non-immune + SubtensorModule::set_pruning_score_for_uid(netuid, 1, 50); // non-immune + SubtensorModule::set_pruning_score_for_uid(netuid, 2, 60); // non-immune + SubtensorModule::set_pruning_score_for_uid(netuid, 3, 40); // immune + SubtensorModule::set_pruning_score_for_uid(netuid, 4, 55); // immune + SubtensorModule::set_pruning_score_for_uid(netuid, 5, 45); // immune + + // The non-immune neuron with the lowest score should be pruned + assert_eq!(SubtensorModule::get_neuron_to_prune(netuid), 1); + + // If we remove the lowest non-immune neuron, it should choose the next lowest non-immune + SubtensorModule::set_pruning_score_for_uid(netuid, 1, u16::MAX); + assert_eq!(SubtensorModule::get_neuron_to_prune(netuid), 2); + + // If we make all non-immune neurons have high scores, it should choose the oldest non-immune neuron + SubtensorModule::set_pruning_score_for_uid(netuid, 0, u16::MAX); + SubtensorModule::set_pruning_score_for_uid(netuid, 1, u16::MAX); + SubtensorModule::set_pruning_score_for_uid(netuid, 2, u16::MAX); + assert_eq!(SubtensorModule::get_neuron_to_prune(netuid), 0); + }); +} + #[test] fn test_registration_too_many_registrations_per_block() { new_test_ext(1).execute_with(|| { From 069a33d064e5296b6a1f667879c384bb0d93a57e Mon Sep 17 00:00:00 2001 From: VectorChat Date: Thu, 8 Aug 2024 17:11:51 -0500 Subject: [PATCH 121/177] adding comments --- pallets/subtensor/src/registration.rs | 10 ++++++++++ pallets/subtensor/src/utils.rs | 2 +- pallets/subtensor/tests/registration.rs | 11 ++++++----- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/pallets/subtensor/src/registration.rs b/pallets/subtensor/src/registration.rs index 1ece0e9ca..8c28c176e 100644 --- a/pallets/subtensor/src/registration.rs +++ b/pallets/subtensor/src/registration.rs @@ -434,6 +434,10 @@ impl Pallet { let mut earliest_registration_in_immunity: u64 = u64::MAX; let mut uid_to_prune: u16 = 0; let mut uid_to_prune_in_immunity: u16 = 0; + + // This boolean is used instead of checking if min_score == u16::MAX, to avoid the case + // where all non-immune neurons have pruning score u16::MAX + // This may be unlikely in practice. let mut found_non_immune = false; let neurons_n = Self::get_subnetwork_n(netuid); @@ -448,6 +452,9 @@ impl Pallet { let is_immune = Self::get_neuron_is_immune(netuid, neuron_uid); if is_immune { + // if the immune neuron has a lower pruning score than the minimum for immune neurons, + // or, if the pruning scores are equal and the immune neuron was registered earlier than the current minimum for immune neurons, + // then update the minimum pruning score and the uid to prune for immune neurons if pruning_score < min_score_in_immunity || (pruning_score == min_score_in_immunity && block_at_registration < earliest_registration_in_immunity) @@ -458,6 +465,9 @@ impl Pallet { } } else { found_non_immune = true; + // if the non-immune neuron has a lower pruning score than the minimum for non-immune neurons, + // or, if the pruning scores are equal and the non-immune neuron was registered earlier than the current minimum for non-immune neurons, + // then update the minimum pruning score and the uid to prune for non-immune neurons if pruning_score < min_score || (pruning_score == min_score && block_at_registration < earliest_registration) { diff --git a/pallets/subtensor/src/utils.rs b/pallets/subtensor/src/utils.rs index d12a8a01a..f88ef6865 100644 --- a/pallets/subtensor/src/utils.rs +++ b/pallets/subtensor/src/utils.rs @@ -460,7 +460,7 @@ impl Pallet { ImmunityPeriod::::insert(netuid, immunity_period); Self::deposit_event(Event::ImmunityPeriodSet(netuid, immunity_period)); } - + /// Check if a neuron is in immunity based on the current block pub fn get_neuron_is_immune(netuid: u16, uid: u16) -> bool { let registered_at = Self::get_neuron_block_at_registration(netuid, uid); let current_block = Self::get_current_block_as_u64(); diff --git a/pallets/subtensor/tests/registration.rs b/pallets/subtensor/tests/registration.rs index 98963f61c..f644680c3 100644 --- a/pallets/subtensor/tests/registration.rs +++ b/pallets/subtensor/tests/registration.rs @@ -551,13 +551,12 @@ fn test_burn_registration_pruning_scenarios() { let max_allowed_uids = 6; let immunity_period = 5000; + // Initial setup SubtensorModule::set_burn(netuid, burn_cost); SubtensorModule::set_max_allowed_uids(netuid, max_allowed_uids); SubtensorModule::set_target_registrations_per_interval(netuid, max_allowed_uids); SubtensorModule::set_immunity_period(netuid, immunity_period); - // SubtensorModule::set_immunity_period(netuid, immunity_period); - add_network(netuid, tempo, 0); let mint_balance = burn_cost * u64::from(max_allowed_uids) + 1_000_000_000; @@ -575,7 +574,7 @@ fn test_burn_registration_pruning_scenarios() { // Note: pruning score is set to u16::MAX after getting neuron to prune - // 1. Test all immune neurons + // 1. Test if all immune neurons assert_eq!(SubtensorModule::get_neuron_is_immune(netuid, 0), true); assert_eq!(SubtensorModule::get_neuron_is_immune(netuid, 1), true); assert_eq!(SubtensorModule::get_neuron_is_immune(netuid, 2), true); @@ -591,12 +590,13 @@ fn test_burn_registration_pruning_scenarios() { SubtensorModule::set_pruning_score_for_uid(netuid, 1, 50); SubtensorModule::set_pruning_score_for_uid(netuid, 2, 50); - // Should get the oldest neuron + // Should get the oldest neuron (i.e., neuron that was registered first) assert_eq!(SubtensorModule::get_neuron_to_prune(netuid), 1); - // 3. Test no immune neurons + // 3. Test if no immune neurons step_block(immunity_period); + // ensure all neurons are non-immune assert_eq!(SubtensorModule::get_neuron_is_immune(netuid, 0), false); assert_eq!(SubtensorModule::get_neuron_is_immune(netuid, 1), false); assert_eq!(SubtensorModule::get_neuron_is_immune(netuid, 2), false); @@ -626,6 +626,7 @@ fn test_burn_registration_pruning_scenarios() { step_block(1); } + // Ensure all new neurons are immune assert_eq!(SubtensorModule::get_neuron_is_immune(netuid, 3), true); assert_eq!(SubtensorModule::get_neuron_is_immune(netuid, 4), true); assert_eq!(SubtensorModule::get_neuron_is_immune(netuid, 5), true); From 10114250d90bd385d9b5ee480a3524169b00490b Mon Sep 17 00:00:00 2001 From: Greg Zaitsev Date: Thu, 8 Aug 2024 18:15:33 -0400 Subject: [PATCH 122/177] Add short InitialTxChildkeyTakeRateLimit to fast-blocks feature --- runtime/src/lib.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index f5db5d1ed..45ebee849 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -854,6 +854,12 @@ pub const INITIAL_SUBNET_TEMPO: u16 = 99; #[cfg(feature = "fast-blocks")] pub const INITIAL_SUBNET_TEMPO: u16 = 10; +#[cfg(not(feature = "fast-blocks"))] +pub const INITIAL_CHILDKEY_TAKE_RATELIMIT: u64 = 216000; // 30 days at 12 seconds per block + +#[cfg(feature = "fast-blocks")] +pub const INITIAL_CHILDKEY_TAKE_RATELIMIT: u64 = 5; + // Configure the pallet subtensor. parameter_types! { pub const SubtensorInitialRho: u16 = 10; @@ -889,7 +895,7 @@ parameter_types! { pub const SubtensorInitialMaxBurn: u64 = 100_000_000_000; // 100 tao pub const SubtensorInitialTxRateLimit: u64 = 1000; pub const SubtensorInitialTxDelegateTakeRateLimit: u64 = 216000; // 30 days at 12 seconds per block - pub const SubtensorInitialTxChildKeyTakeRateLimit: u64 = 216000; // 30 days at 12 seconds per block + pub const SubtensorInitialTxChildKeyTakeRateLimit: u64 = INITIAL_CHILDKEY_TAKE_RATELIMIT; pub const SubtensorInitialRAORecycledForRegistration: u64 = 0; // 0 rao pub const SubtensorInitialSenateRequiredStakePercentage: u64 = 1; // 1 percent of total stake pub const SubtensorInitialNetworkImmunity: u64 = 7 * 7200; From 4e976a1f473a628662407468478b75c73dd4e1d0 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Thu, 8 Aug 2024 18:24:32 -0400 Subject: [PATCH 123/177] ensure no warnings allowed / re-enable cargo check --workspace job --- .github/workflows/check-rust.yml | 48 ++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/.github/workflows/check-rust.yml b/.github/workflows/check-rust.yml index d36718ef9..cdd9b59a0 100644 --- a/.github/workflows/check-rust.yml +++ b/.github/workflows/check-rust.yml @@ -113,6 +113,54 @@ jobs: - name: cargo clippy --workspace --all-targets -- -D warnings run: cargo clippy --workspace --all-targets -- -D warnings + cargo-check-lints: + name: cargo check + lints + runs-on: SubtensorCI + strategy: + matrix: + rust-branch: + - stable + rust-target: + - x86_64-unknown-linux-gnu + # - x86_64-apple-darwin + os: + - ubuntu-latest + # - macos-latest + include: + - os: ubuntu-latest + # - os: macos-latest + env: + RELEASE_NAME: development + RUSTV: ${{ matrix.rust-branch }} + RUSTFLAGS: -D warnings + RUST_BACKTRACE: full + RUST_BIN_DIR: target/${{ matrix.rust-target }} + SKIP_WASM_BUILD: 1 + TARGET: ${{ matrix.rust-target }} + steps: + - name: Check-out repository under $GITHUB_WORKSPACE + uses: actions/checkout@v4 + + - name: Install dependencies + run: | + sudo apt-get update && + sudo apt-get install -y clang curl libssl-dev llvm libudev-dev protobuf-compiler + + - name: Install Rust ${{ matrix.rust-branch }} + uses: actions-rs/toolchain@v1.0.6 + with: + toolchain: ${{ matrix.rust-branch }} + components: rustfmt, clippy + profile: minimal + + - name: Utilize Shared Rust Cache + uses: Swatinem/rust-cache@v2.2.1 + with: + key: ${{ matrix.os }}-${{ env.RUST_BIN_DIR }} + + - name: cargo check --workspace (no warnings allowed) + run: cargo check --workspace + cargo-clippy-all-features: name: cargo clippy --all-features runs-on: SubtensorCI From 583c6a7f7d9f7b3f28a397692c9ac54158eefff9 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Thu, 8 Aug 2024 19:52:53 -0400 Subject: [PATCH 124/177] cargo clippy --fix --workspace --- build.rs | 2 +- support/linting/src/require_freeze_struct.rs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build.rs b/build.rs index 780b43cc1..9c7ce59f8 100644 --- a/build.rs +++ b/build.rs @@ -31,7 +31,7 @@ fn main() { // Parse each rust file with syn and run the linting suite on it in parallel rust_files.par_iter().for_each_with(tx.clone(), |tx, file| { - let Ok(content) = fs::read_to_string(&file) else { + let Ok(content) = fs::read_to_string(file) else { return; }; let Ok(parsed_file) = proc_macro2::TokenStream::from_str(&content) else { diff --git a/support/linting/src/require_freeze_struct.rs b/support/linting/src/require_freeze_struct.rs index deafc93cb..6cf8412ed 100644 --- a/support/linting/src/require_freeze_struct.rs +++ b/support/linting/src/require_freeze_struct.rs @@ -32,12 +32,12 @@ struct EncodeDecodeVisitor { impl<'ast> Visit<'ast> for EncodeDecodeVisitor { fn visit_item_struct(&mut self, node: &'ast ItemStruct) { let has_encode_decode = node.attrs.iter().any(|attr| { - let result = is_derive_encode_or_decode(attr); - result + + is_derive_encode_or_decode(attr) }); let has_freeze_struct = node.attrs.iter().any(|attr| { - let result = is_freeze_struct(attr); - result + + is_freeze_struct(attr) }); if has_encode_decode && !has_freeze_struct { From 34ca8a9ba28f23630b83a4dcbccffc23be40b57e Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Thu, 8 Aug 2024 19:53:30 -0400 Subject: [PATCH 125/177] cargo +nightly fmt --- support/linting/src/require_freeze_struct.rs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/support/linting/src/require_freeze_struct.rs b/support/linting/src/require_freeze_struct.rs index 6cf8412ed..52df95854 100644 --- a/support/linting/src/require_freeze_struct.rs +++ b/support/linting/src/require_freeze_struct.rs @@ -31,14 +31,11 @@ struct EncodeDecodeVisitor { impl<'ast> Visit<'ast> for EncodeDecodeVisitor { fn visit_item_struct(&mut self, node: &'ast ItemStruct) { - let has_encode_decode = node.attrs.iter().any(|attr| { - - is_derive_encode_or_decode(attr) - }); - let has_freeze_struct = node.attrs.iter().any(|attr| { - - is_freeze_struct(attr) - }); + let has_encode_decode = node + .attrs + .iter() + .any(|attr| is_derive_encode_or_decode(attr)); + let has_freeze_struct = node.attrs.iter().any(|attr| is_freeze_struct(attr)); if has_encode_decode && !has_freeze_struct { self.errors.push(syn::Error::new( From 3c4903e3e2ab76a0024f4b0881845bdfb76bd084 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Thu, 8 Aug 2024 19:54:32 -0400 Subject: [PATCH 126/177] check that CI fails successfully --- pallets/commitments/src/types.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/commitments/src/types.rs b/pallets/commitments/src/types.rs index 06bafcaac..334c12565 100644 --- a/pallets/commitments/src/types.rs +++ b/pallets/commitments/src/types.rs @@ -299,7 +299,7 @@ pub struct CommitmentInfo> { /// /// NOTE: This is stored separately primarily to facilitate the addition of extra fields in a /// backwards compatible way through a specialized `Decode` impl. -#[freeze_struct("632f12850e51c420")] +// #[freeze_struct("632f12850e51c420")] #[derive( CloneNoBound, Encode, Eq, MaxEncodedLen, PartialEqNoBound, RuntimeDebugNoBound, TypeInfo, )] From b98133d6429be7c31f4f926f8b2a81b6869351f8 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Fri, 9 Aug 2024 06:05:14 -0400 Subject: [PATCH 127/177] test warning detection in CI --- .github/workflows/check-rust.yml | 2 +- support/linting/src/require_freeze_struct.rs | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/check-rust.yml b/.github/workflows/check-rust.yml index cdd9b59a0..76f03afbd 100644 --- a/.github/workflows/check-rust.yml +++ b/.github/workflows/check-rust.yml @@ -114,7 +114,7 @@ jobs: run: cargo clippy --workspace --all-targets -- -D warnings cargo-check-lints: - name: cargo check + lints + name: no warnings or custom lint failures runs-on: SubtensorCI strategy: matrix: diff --git a/support/linting/src/require_freeze_struct.rs b/support/linting/src/require_freeze_struct.rs index 52df95854..861388b56 100644 --- a/support/linting/src/require_freeze_struct.rs +++ b/support/linting/src/require_freeze_struct.rs @@ -7,6 +7,8 @@ use syn::{ pub struct RequireFreezeStruct; +fn meh() {} + impl Lint for RequireFreezeStruct { fn lint(source: &TokenStream) -> Result<()> { let mut visitor = EncodeDecodeVisitor::default(); From af6435a911f8e22307025c3e206d9aad90ea9b65 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Fri, 9 Aug 2024 06:17:28 -0400 Subject: [PATCH 128/177] proper check for custom lint failures --- .github/workflows/check-rust.yml | 18 +++++++++++++++--- support/linting/src/require_freeze_struct.rs | 2 -- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/.github/workflows/check-rust.yml b/.github/workflows/check-rust.yml index 76f03afbd..803e07ba8 100644 --- a/.github/workflows/check-rust.yml +++ b/.github/workflows/check-rust.yml @@ -114,7 +114,7 @@ jobs: run: cargo clippy --workspace --all-targets -- -D warnings cargo-check-lints: - name: no warnings or custom lint failures + name: check custom lints runs-on: SubtensorCI strategy: matrix: @@ -158,8 +158,20 @@ jobs: with: key: ${{ matrix.os }}-${{ env.RUST_BIN_DIR }} - - name: cargo check --workspace (no warnings allowed) - run: cargo check --workspace + - name: check lints + # regular cargo check is sufficient here as we only need to trigger the build script + # which will nevertheless check the whole workspace + run: | + set -e # Fail the script if any command fails + cargo check 2>&1 | tee build_output.log + warnings=$(grep "cargo:warning=" build_output.log || true) + if [ -n "$warnings" ]; then + echo "The following custom lints have failed ❌:" + echo "$warnings" + exit 1 + else + echo "All custom lints passed ✅" + fi cargo-clippy-all-features: name: cargo clippy --all-features diff --git a/support/linting/src/require_freeze_struct.rs b/support/linting/src/require_freeze_struct.rs index 861388b56..52df95854 100644 --- a/support/linting/src/require_freeze_struct.rs +++ b/support/linting/src/require_freeze_struct.rs @@ -7,8 +7,6 @@ use syn::{ pub struct RequireFreezeStruct; -fn meh() {} - impl Lint for RequireFreezeStruct { fn lint(source: &TokenStream) -> Result<()> { let mut visitor = EncodeDecodeVisitor::default(); From e47f2def1b7885d0b14ceee4dfda8b25de8c82e4 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Fri, 9 Aug 2024 06:21:57 -0400 Subject: [PATCH 129/177] clippy fixes --- support/linting/src/require_freeze_struct.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/support/linting/src/require_freeze_struct.rs b/support/linting/src/require_freeze_struct.rs index 52df95854..3e9c4e539 100644 --- a/support/linting/src/require_freeze_struct.rs +++ b/support/linting/src/require_freeze_struct.rs @@ -34,8 +34,8 @@ impl<'ast> Visit<'ast> for EncodeDecodeVisitor { let has_encode_decode = node .attrs .iter() - .any(|attr| is_derive_encode_or_decode(attr)); - let has_freeze_struct = node.attrs.iter().any(|attr| is_freeze_struct(attr)); + .any(is_derive_encode_or_decode); + let has_freeze_struct = node.attrs.iter().any(is_freeze_struct); if has_encode_decode && !has_freeze_struct { self.errors.push(syn::Error::new( From 3398adcaf3f39caddfa2dbc761c2e14527b31c1e Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Fri, 9 Aug 2024 06:45:03 -0400 Subject: [PATCH 130/177] tweak --- .github/workflows/check-rust.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/check-rust.yml b/.github/workflows/check-rust.yml index 803e07ba8..5f102d646 100644 --- a/.github/workflows/check-rust.yml +++ b/.github/workflows/check-rust.yml @@ -164,7 +164,7 @@ jobs: run: | set -e # Fail the script if any command fails cargo check 2>&1 | tee build_output.log - warnings=$(grep "cargo:warning=" build_output.log || true) + warnings=$(grep "warning: " build_output.log || true) if [ -n "$warnings" ]; then echo "The following custom lints have failed ❌:" echo "$warnings" From 63da5afa7b3a7560ba2c48a3eeab8e3ec79b1318 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Fri, 9 Aug 2024 06:53:06 -0400 Subject: [PATCH 131/177] try again --- .github/workflows/check-rust.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/check-rust.yml b/.github/workflows/check-rust.yml index 5f102d646..bb382a861 100644 --- a/.github/workflows/check-rust.yml +++ b/.github/workflows/check-rust.yml @@ -163,7 +163,7 @@ jobs: # which will nevertheless check the whole workspace run: | set -e # Fail the script if any command fails - cargo check 2>&1 | tee build_output.log + cargo check | tee build_output.log warnings=$(grep "warning: " build_output.log || true) if [ -n "$warnings" ]; then echo "The following custom lints have failed ❌:" From fad9f691bb1b1c92510da32f4447cd7cde4aea08 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Fri, 9 Aug 2024 07:06:09 -0400 Subject: [PATCH 132/177] tweak again --- .github/workflows/check-rust.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/check-rust.yml b/.github/workflows/check-rust.yml index bb382a861..9925bb863 100644 --- a/.github/workflows/check-rust.yml +++ b/.github/workflows/check-rust.yml @@ -163,14 +163,14 @@ jobs: # which will nevertheless check the whole workspace run: | set -e # Fail the script if any command fails - cargo check | tee build_output.log - warnings=$(grep "warning: " build_output.log || true) + cargo check 2>&1 | tee build_output.log + warnings=$(grep "^warning:" build_output.log || true) if [ -n "$warnings" ]; then - echo "The following custom lints have failed ❌:" + echo "Build emitted the following warnings:" echo "$warnings" exit 1 else - echo "All custom lints passed ✅" + echo "No warnings found." fi cargo-clippy-all-features: From 4b79e6141b57df01e18a9cd229b517e54d5d0b3a Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Fri, 9 Aug 2024 07:13:49 -0400 Subject: [PATCH 133/177] try again --- .github/workflows/check-rust.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/check-rust.yml b/.github/workflows/check-rust.yml index 9925bb863..b3e656c33 100644 --- a/.github/workflows/check-rust.yml +++ b/.github/workflows/check-rust.yml @@ -162,12 +162,11 @@ jobs: # regular cargo check is sufficient here as we only need to trigger the build script # which will nevertheless check the whole workspace run: | - set -e # Fail the script if any command fails + set -o pipefail # Ensure the pipeline fails if any command in the pipeline fails cargo check 2>&1 | tee build_output.log - warnings=$(grep "^warning:" build_output.log || true) - if [ -n "$warnings" ]; then + if grep -q "^warning:" build_output.log; then echo "Build emitted the following warnings:" - echo "$warnings" + grep "^warning:" build_output.log exit 1 else echo "No warnings found." From a4ac8b64004e17d1cbd8d7141672ee09773da5c6 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Fri, 9 Aug 2024 07:18:44 -0400 Subject: [PATCH 134/177] try echoing the file --- .github/workflows/check-rust.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/check-rust.yml b/.github/workflows/check-rust.yml index b3e656c33..c724ecd1a 100644 --- a/.github/workflows/check-rust.yml +++ b/.github/workflows/check-rust.yml @@ -163,7 +163,8 @@ jobs: # which will nevertheless check the whole workspace run: | set -o pipefail # Ensure the pipeline fails if any command in the pipeline fails - cargo check 2>&1 | tee build_output.log + cargo check 2>&1 | build_output.log + cat build_output.log if grep -q "^warning:" build_output.log; then echo "Build emitted the following warnings:" grep "^warning:" build_output.log From 4021d60cb1f9da283851dcfb8b97d324a3d201d1 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Fri, 9 Aug 2024 07:33:38 -0400 Subject: [PATCH 135/177] warning detection should be working in CI now --- .github/workflows/check-rust.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/check-rust.yml b/.github/workflows/check-rust.yml index c724ecd1a..ce1aa4785 100644 --- a/.github/workflows/check-rust.yml +++ b/.github/workflows/check-rust.yml @@ -163,7 +163,7 @@ jobs: # which will nevertheless check the whole workspace run: | set -o pipefail # Ensure the pipeline fails if any command in the pipeline fails - cargo check 2>&1 | build_output.log + cargo check 2>&1 | tee build_output.log cat build_output.log if grep -q "^warning:" build_output.log; then echo "Build emitted the following warnings:" From dbe2a894643dc6eb298e9e4e3a4c0e099f1512b3 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Fri, 9 Aug 2024 07:45:02 -0400 Subject: [PATCH 136/177] but actually now --- .github/workflows/check-rust.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/check-rust.yml b/.github/workflows/check-rust.yml index ce1aa4785..ffef13274 100644 --- a/.github/workflows/check-rust.yml +++ b/.github/workflows/check-rust.yml @@ -164,11 +164,10 @@ jobs: run: | set -o pipefail # Ensure the pipeline fails if any command in the pipeline fails cargo check 2>&1 | tee build_output.log - cat build_output.log if grep -q "^warning:" build_output.log; then echo "Build emitted the following warnings:" - grep "^warning:" build_output.log - exit 1 + >&2 echo `grep "^warning:" build_output.log` + else echo "No warnings found." fi From fe0d6ad188bf3122fe3674f45825d55ba5e33a97 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Fri, 9 Aug 2024 07:52:44 -0400 Subject: [PATCH 137/177] try catting --- .github/workflows/check-rust.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/check-rust.yml b/.github/workflows/check-rust.yml index ffef13274..faba74f8d 100644 --- a/.github/workflows/check-rust.yml +++ b/.github/workflows/check-rust.yml @@ -164,10 +164,10 @@ jobs: run: | set -o pipefail # Ensure the pipeline fails if any command in the pipeline fails cargo check 2>&1 | tee build_output.log + cat build_output.log if grep -q "^warning:" build_output.log; then echo "Build emitted the following warnings:" >&2 echo `grep "^warning:" build_output.log` - else echo "No warnings found." fi From 68ec4c66ae263f1ee343b6b8f752ada467bff9fb Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Fri, 9 Aug 2024 16:13:14 +0400 Subject: [PATCH 138/177] feat: bump network max stake --- pallets/admin-utils/tests/mock.rs | 2 +- runtime/src/lib.rs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pallets/admin-utils/tests/mock.rs b/pallets/admin-utils/tests/mock.rs index acb9c8a4a..5575bd560 100644 --- a/pallets/admin-utils/tests/mock.rs +++ b/pallets/admin-utils/tests/mock.rs @@ -118,7 +118,7 @@ parameter_types! { pub const InitialAlphaLow: u16 = 45875; // Represents 0.7 as per the production default pub const InitialLiquidAlphaOn: bool = false; // Default value for LiquidAlphaOn pub const InitialHotkeyEmissionTempo: u64 = 1; - pub const InitialNetworkMaxStake: u64 = 500_000_000_000_000; // 500_000 TAO + pub const InitialNetworkMaxStake: u64 = u64::MAX; // Maximum possible value for u64, this make the make stake infinity } impl pallet_subtensor::Config for Test { diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index dec65f60f..80818f7e4 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -899,7 +899,8 @@ parameter_types! { pub const InitialAlphaLow: u16 = 45875; // Represents 0.7 as per the production default pub const InitialLiquidAlphaOn: bool = false; // Default value for LiquidAlphaOn pub const SubtensorInitialHotkeyEmissionTempo: u64 = 7200; // Drain every day. - pub const SubtensorInitialNetworkMaxStake: u64 = 500_000_000_000_000; // 500_000 TAO + pub const SubtensorInitialNetworkMaxStake: u64 = u64::MAX; // Maximum possible value for u64, this make the make stake infinity + } impl pallet_subtensor::Config for Runtime { From 9c3690bd94d6eb34382afe4b585e3654084c7846 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Fri, 9 Aug 2024 08:23:52 -0400 Subject: [PATCH 139/177] strip color codes --- .github/workflows/check-rust.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/check-rust.yml b/.github/workflows/check-rust.yml index faba74f8d..52032b21e 100644 --- a/.github/workflows/check-rust.yml +++ b/.github/workflows/check-rust.yml @@ -164,7 +164,8 @@ jobs: run: | set -o pipefail # Ensure the pipeline fails if any command in the pipeline fails cargo check 2>&1 | tee build_output.log - cat build_output.log + # Strip ANSI color codes + sed -r "s/\x1B\[[0-9;]*[mK]//g" build_output.log > clean_output.log if grep -q "^warning:" build_output.log; then echo "Build emitted the following warnings:" >&2 echo `grep "^warning:" build_output.log` From 370ca7f6aae429fef45062a850702dc4e655b4dc Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Fri, 9 Aug 2024 10:22:29 -0400 Subject: [PATCH 140/177] whoops --- .github/workflows/check-rust.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/check-rust.yml b/.github/workflows/check-rust.yml index 52032b21e..996fd9454 100644 --- a/.github/workflows/check-rust.yml +++ b/.github/workflows/check-rust.yml @@ -166,9 +166,9 @@ jobs: cargo check 2>&1 | tee build_output.log # Strip ANSI color codes sed -r "s/\x1B\[[0-9;]*[mK]//g" build_output.log > clean_output.log - if grep -q "^warning:" build_output.log; then + if grep -q "^warning:" clean_output.log; then echo "Build emitted the following warnings:" - >&2 echo `grep "^warning:" build_output.log` + >&2 echo `grep "^warning:" clean_output.log` else echo "No warnings found." fi From 75df9970cf6b8537e1091ae7c3c8eb587c9be3c8 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Fri, 9 Aug 2024 10:37:00 -0400 Subject: [PATCH 141/177] working, now proper error message at the end --- .github/workflows/check-rust.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/check-rust.yml b/.github/workflows/check-rust.yml index 996fd9454..1d2f686c1 100644 --- a/.github/workflows/check-rust.yml +++ b/.github/workflows/check-rust.yml @@ -169,6 +169,7 @@ jobs: if grep -q "^warning:" clean_output.log; then echo "Build emitted the following warnings:" >&2 echo `grep "^warning:" clean_output.log` + exit "Some custom lints failed, see above for details." else echo "No warnings found." fi From 567696f127963b8c740d5cf7f7dcd17b6e03e19d Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Fri, 9 Aug 2024 10:51:38 -0400 Subject: [PATCH 142/177] fix exit status --- .github/workflows/check-rust.yml | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/.github/workflows/check-rust.yml b/.github/workflows/check-rust.yml index 1d2f686c1..797ad4df4 100644 --- a/.github/workflows/check-rust.yml +++ b/.github/workflows/check-rust.yml @@ -122,13 +122,10 @@ jobs: - stable rust-target: - x86_64-unknown-linux-gnu - # - x86_64-apple-darwin + # - x86_64-apple-darwin os: - ubuntu-latest # - macos-latest - include: - - os: ubuntu-latest - # - os: macos-latest env: RELEASE_NAME: development RUSTV: ${{ matrix.rust-branch }} @@ -159,20 +156,10 @@ jobs: key: ${{ matrix.os }}-${{ env.RUST_BIN_DIR }} - name: check lints - # regular cargo check is sufficient here as we only need to trigger the build script - # which will nevertheless check the whole workspace run: | set -o pipefail # Ensure the pipeline fails if any command in the pipeline fails - cargo check 2>&1 | tee build_output.log - # Strip ANSI color codes - sed -r "s/\x1B\[[0-9;]*[mK]//g" build_output.log > clean_output.log - if grep -q "^warning:" clean_output.log; then - echo "Build emitted the following warnings:" - >&2 echo `grep "^warning:" clean_output.log` - exit "Some custom lints failed, see above for details." - else - echo "No warnings found." - fi + cargo check 2>&1 | sed -r "s/\x1B\[[0-9;]*[mK]//g" | tee /dev/tty | grep -q "^warning:" && \ + (echo "Build emitted the following warnings:" >&2 && exit 1) || echo "No warnings found." cargo-clippy-all-features: name: cargo clippy --all-features From 7aa4dc8d83e4cd23265f5971fac1cab2b568a187 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Fri, 9 Aug 2024 10:53:47 -0400 Subject: [PATCH 143/177] fix unwrap --- support/linting/src/require_freeze_struct.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/support/linting/src/require_freeze_struct.rs b/support/linting/src/require_freeze_struct.rs index 3e9c4e539..aa84b6d5c 100644 --- a/support/linting/src/require_freeze_struct.rs +++ b/support/linting/src/require_freeze_struct.rs @@ -31,10 +31,7 @@ struct EncodeDecodeVisitor { impl<'ast> Visit<'ast> for EncodeDecodeVisitor { fn visit_item_struct(&mut self, node: &'ast ItemStruct) { - let has_encode_decode = node - .attrs - .iter() - .any(is_derive_encode_or_decode); + let has_encode_decode = node.attrs.iter().any(is_derive_encode_or_decode); let has_freeze_struct = node.attrs.iter().any(is_freeze_struct); if has_encode_decode && !has_freeze_struct { @@ -78,7 +75,7 @@ mod tests { use super::*; fn lint_struct(input: &str) -> Result<()> { - let item_struct: ItemStruct = syn::parse_str(input).unwrap(); + let item_struct: ItemStruct = syn::parse_str(input).expect("should only use on a struct"); let mut visitor = EncodeDecodeVisitor::default(); visitor.visit_item_struct(&item_struct); if visitor.errors.is_empty() { From ae40d0f64e8773f1c1c750e1ff2bdaff3ba38df6 Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Fri, 9 Aug 2024 18:57:47 +0400 Subject: [PATCH 144/177] chore: add sudo calls for setting min/max childkey takes --- pallets/subtensor/src/macros/dispatches.rs | 47 ++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index a776cfc4f..2d6c5bde0 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -786,6 +786,53 @@ mod dispatches { Ok(()) } + /// Sets the minimum allowed childkey take. + /// + /// This function can only be called by the root origin. + /// + /// # Arguments: + /// * `origin` - The origin of the call, must be root. + /// * `take` - The new minimum childkey take value. + /// + /// # Errors: + /// * `BadOrigin` - If the origin is not root. + /// + #[pallet::call_index(76)] + #[pallet::weight(( + Weight::from_parts(6_000, 0) + .saturating_add(T::DbWeight::get().writes(1)), + DispatchClass::Operational, + Pays::No + ))] + pub fn sudo_set_min_childkey_take(origin: OriginFor, take: u16) -> DispatchResult { + ensure_root(origin)?; + Self::set_min_childkey_take(take); + Ok(()) + } + + /// Sets the maximum allowed childkey take. + /// + /// This function can only be called by the root origin. + /// + /// # Arguments: + /// * `origin` - The origin of the call, must be root. + /// * `take` - The new maximum childkey take value. + /// + /// # Errors: + /// * `BadOrigin` - If the origin is not root. + /// + #[pallet::call_index(77)] + #[pallet::weight(( + Weight::from_parts(6_000, 0) + .saturating_add(T::DbWeight::get().writes(1)), + DispatchClass::Operational, + Pays::No + ))] + pub fn sudo_set_max_childkey_take(origin: OriginFor, take: u16) -> DispatchResult { + ensure_root(origin)?; + Self::set_max_childkey_take(take); + Ok(()) + } // ================================== // ==== Parameter Sudo calls ======== // ================================== From 320aecfe83487bafbb64e513ddc59af6dc0e80fc Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Fri, 9 Aug 2024 10:58:23 -0400 Subject: [PATCH 145/177] fix clippy warning --- support/linting/src/require_freeze_struct.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/support/linting/src/require_freeze_struct.rs b/support/linting/src/require_freeze_struct.rs index aa84b6d5c..ca6232297 100644 --- a/support/linting/src/require_freeze_struct.rs +++ b/support/linting/src/require_freeze_struct.rs @@ -78,11 +78,10 @@ mod tests { let item_struct: ItemStruct = syn::parse_str(input).expect("should only use on a struct"); let mut visitor = EncodeDecodeVisitor::default(); visitor.visit_item_struct(&item_struct); - if visitor.errors.is_empty() { - Ok(()) - } else { - Err(visitor.errors[0].clone()) + if let Some(error) = visitor.errors.first() { + return Err(error.clone()); } + Ok(()) } #[test] From 70729713cb059b682d889ee345d3c6c465272422 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Fri, 9 Aug 2024 13:02:58 -0400 Subject: [PATCH 146/177] last remaining warning --- pallets/commitments/src/types.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/commitments/src/types.rs b/pallets/commitments/src/types.rs index 334c12565..06bafcaac 100644 --- a/pallets/commitments/src/types.rs +++ b/pallets/commitments/src/types.rs @@ -299,7 +299,7 @@ pub struct CommitmentInfo> { /// /// NOTE: This is stored separately primarily to facilitate the addition of extra fields in a /// backwards compatible way through a specialized `Decode` impl. -// #[freeze_struct("632f12850e51c420")] +#[freeze_struct("632f12850e51c420")] #[derive( CloneNoBound, Encode, Eq, MaxEncodedLen, PartialEqNoBound, RuntimeDebugNoBound, TypeInfo, )] From 15366cf21150064b4bb69d5d76d2f9cbecdfd53c Mon Sep 17 00:00:00 2001 From: VectorChat Date: Fri, 9 Aug 2024 15:41:33 -0500 Subject: [PATCH 147/177] clippy --- pallets/subtensor/tests/registration.rs | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/pallets/subtensor/tests/registration.rs b/pallets/subtensor/tests/registration.rs index f644680c3..6a2b9be0b 100644 --- a/pallets/subtensor/tests/registration.rs +++ b/pallets/subtensor/tests/registration.rs @@ -3,7 +3,6 @@ use std::u16; use frame_support::traits::Currency; -use substrate_fixed::types::extra::True; use crate::mock::*; use frame_support::dispatch::{DispatchClass, DispatchInfo, GetDispatchInfo, Pays}; @@ -551,6 +550,9 @@ fn test_burn_registration_pruning_scenarios() { let max_allowed_uids = 6; let immunity_period = 5000; + const IS_IMMUNE: bool = true; + const NOT_IMMUNE: bool = false; + // Initial setup SubtensorModule::set_burn(netuid, burn_cost); SubtensorModule::set_max_allowed_uids(netuid, max_allowed_uids); @@ -575,9 +577,9 @@ fn test_burn_registration_pruning_scenarios() { // Note: pruning score is set to u16::MAX after getting neuron to prune // 1. Test if all immune neurons - assert_eq!(SubtensorModule::get_neuron_is_immune(netuid, 0), true); - assert_eq!(SubtensorModule::get_neuron_is_immune(netuid, 1), true); - assert_eq!(SubtensorModule::get_neuron_is_immune(netuid, 2), true); + assert_eq!(SubtensorModule::get_neuron_is_immune(netuid, 0), IS_IMMUNE); + assert_eq!(SubtensorModule::get_neuron_is_immune(netuid, 1), IS_IMMUNE); + assert_eq!(SubtensorModule::get_neuron_is_immune(netuid, 2), IS_IMMUNE); SubtensorModule::set_pruning_score_for_uid(netuid, 0, 100); SubtensorModule::set_pruning_score_for_uid(netuid, 1, 75); @@ -597,9 +599,9 @@ fn test_burn_registration_pruning_scenarios() { step_block(immunity_period); // ensure all neurons are non-immune - assert_eq!(SubtensorModule::get_neuron_is_immune(netuid, 0), false); - assert_eq!(SubtensorModule::get_neuron_is_immune(netuid, 1), false); - assert_eq!(SubtensorModule::get_neuron_is_immune(netuid, 2), false); + assert_eq!(SubtensorModule::get_neuron_is_immune(netuid, 0), NOT_IMMUNE); + assert_eq!(SubtensorModule::get_neuron_is_immune(netuid, 1), NOT_IMMUNE); + assert_eq!(SubtensorModule::get_neuron_is_immune(netuid, 2), NOT_IMMUNE); SubtensorModule::set_pruning_score_for_uid(netuid, 0, 100); SubtensorModule::set_pruning_score_for_uid(netuid, 1, 50); @@ -627,9 +629,9 @@ fn test_burn_registration_pruning_scenarios() { } // Ensure all new neurons are immune - assert_eq!(SubtensorModule::get_neuron_is_immune(netuid, 3), true); - assert_eq!(SubtensorModule::get_neuron_is_immune(netuid, 4), true); - assert_eq!(SubtensorModule::get_neuron_is_immune(netuid, 5), true); + assert_eq!(SubtensorModule::get_neuron_is_immune(netuid, 3), IS_IMMUNE); + assert_eq!(SubtensorModule::get_neuron_is_immune(netuid, 4), IS_IMMUNE); + assert_eq!(SubtensorModule::get_neuron_is_immune(netuid, 5), IS_IMMUNE); // Set pruning scores for all neurons SubtensorModule::set_pruning_score_for_uid(netuid, 0, 75); // non-immune From 681097b529dda69acd91cdbcb3753114fef57be8 Mon Sep 17 00:00:00 2001 From: VectorChat Date: Fri, 9 Aug 2024 21:41:54 -0500 Subject: [PATCH 148/177] more clippy --- pallets/subtensor/tests/registration.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/pallets/subtensor/tests/registration.rs b/pallets/subtensor/tests/registration.rs index 6a2b9be0b..536aa2688 100644 --- a/pallets/subtensor/tests/registration.rs +++ b/pallets/subtensor/tests/registration.rs @@ -1,7 +1,5 @@ #![allow(clippy::unwrap_used)] -use std::u16; - use frame_support::traits::Currency; use crate::mock::*; From 2cb7ef4d8cfdd0e7665296f342b8b87179293159 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Sat, 10 Aug 2024 20:24:26 -0400 Subject: [PATCH 149/177] allow multiple linting errors per file --- build.rs | 36 +++++++++++--------- support/linting/src/dummy_lint.rs | 2 +- support/linting/src/lib.rs | 2 -- support/linting/src/lint.rs | 4 +-- support/linting/src/require_freeze_struct.rs | 14 ++++---- 5 files changed, 28 insertions(+), 30 deletions(-) diff --git a/build.rs b/build.rs index 9c7ce59f8..cc98ea32d 100644 --- a/build.rs +++ b/build.rs @@ -1,10 +1,10 @@ use rayon::prelude::*; -use std::env; -use std::fs; -use std::path::{Path, PathBuf}; -use std::str::FromStr; -use std::sync::mpsc::channel; -use syn::Result; +use std::{ + env, fs, + path::{Path, PathBuf}, + str::FromStr, + sync::mpsc::channel, +}; use walkdir::WalkDir; use subtensor_linting::*; @@ -38,20 +38,22 @@ fn main() { return; }; - let track_lint = |result: Result<()>| { - let Err(error) = result else { + let track_lint = |result: Result| { + let Err(errors) = result else { return; }; let relative_path = file.strip_prefix(workspace_root).unwrap_or(file.as_path()); - let loc = error.span().start(); - let file_path = relative_path.display(); - // note that spans can't go across thread boundaries without losing their location - // info so we we serialize here and send a String - tx.send(format!( - "cargo:warning={}:{}:{}: {}", - file_path, loc.line, loc.column, error, - )) - .unwrap(); + for error in errors { + let loc = error.span().start(); + let file_path = relative_path.display(); + // note that spans can't go across thread boundaries without losing their location + // info so we we serialize here and send a String + tx.send(format!( + "cargo:warning={}:{}:{}: {}", + file_path, loc.line, loc.column, error, + )) + .unwrap(); + } }; track_lint(DummyLint::lint(&parsed_file)); diff --git a/support/linting/src/dummy_lint.rs b/support/linting/src/dummy_lint.rs index 3c046f4a2..2fb0a5c2c 100644 --- a/support/linting/src/dummy_lint.rs +++ b/support/linting/src/dummy_lint.rs @@ -5,7 +5,7 @@ use super::*; pub struct DummyLint; impl Lint for DummyLint { - fn lint(_source: &TokenStream) -> Result<()> { + fn lint(_source: &TokenStream) -> Result { Ok(()) } } diff --git a/support/linting/src/lib.rs b/support/linting/src/lib.rs index 741278ab3..0d0df8a44 100644 --- a/support/linting/src/lib.rs +++ b/support/linting/src/lib.rs @@ -1,5 +1,3 @@ -use syn::Result; - pub mod lint; pub use lint::*; diff --git a/support/linting/src/lint.rs b/support/linting/src/lint.rs index 1cd4c9721..985e2ecc0 100644 --- a/support/linting/src/lint.rs +++ b/support/linting/src/lint.rs @@ -1,6 +1,6 @@ use proc_macro2::TokenStream; -use super::*; +pub type Result = core::result::Result<(), Vec>; /// A trait that defines custom lints that can be run within our workspace. /// @@ -9,5 +9,5 @@ use super::*; /// there are no errors. pub trait Lint: Send + Sync { /// Lints the given Rust source file, returning a compile error if any issues are found. - fn lint(source: &TokenStream) -> Result<()>; + fn lint(source: &TokenStream) -> Result; } diff --git a/support/linting/src/require_freeze_struct.rs b/support/linting/src/require_freeze_struct.rs index ca6232297..14569bd2f 100644 --- a/support/linting/src/require_freeze_struct.rs +++ b/support/linting/src/require_freeze_struct.rs @@ -2,22 +2,20 @@ use super::*; use proc_macro2::TokenStream; use syn::{ parse_quote, punctuated::Punctuated, visit::Visit, Attribute, ItemStruct, Meta, MetaList, Path, - Result, Token, + Token, }; pub struct RequireFreezeStruct; impl Lint for RequireFreezeStruct { - fn lint(source: &TokenStream) -> Result<()> { + fn lint(source: &TokenStream) -> Result { let mut visitor = EncodeDecodeVisitor::default(); let file = syn::parse2::(source.clone()).unwrap(); visitor.visit_file(&file); if !visitor.errors.is_empty() { - for error in visitor.errors { - return Err(error); - } + return Err(visitor.errors); } Ok(()) @@ -74,12 +72,12 @@ fn is_derive_encode_or_decode(attr: &Attribute) -> bool { mod tests { use super::*; - fn lint_struct(input: &str) -> Result<()> { + fn lint_struct(input: &str) -> Result { let item_struct: ItemStruct = syn::parse_str(input).expect("should only use on a struct"); let mut visitor = EncodeDecodeVisitor::default(); visitor.visit_item_struct(&item_struct); - if let Some(error) = visitor.errors.first() { - return Err(error.clone()); + if !visitor.errors.is_empty() { + return Err(visitor.errors); } Ok(()) } From 3b8cab18baea2439dd71661f4f0a3c75633ff7db Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Sat, 10 Aug 2024 20:34:43 -0400 Subject: [PATCH 150/177] change Lint trait to take a syn::File instead --- build.rs | 5 ++++- support/linting/src/dummy_lint.rs | 4 ++-- support/linting/src/lint.rs | 4 ++-- support/linting/src/require_freeze_struct.rs | 10 ++++------ 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/build.rs b/build.rs index cc98ea32d..cc495ec13 100644 --- a/build.rs +++ b/build.rs @@ -34,7 +34,10 @@ fn main() { let Ok(content) = fs::read_to_string(file) else { return; }; - let Ok(parsed_file) = proc_macro2::TokenStream::from_str(&content) else { + let Ok(parsed_tokens) = proc_macro2::TokenStream::from_str(&content) else { + return; + }; + let Ok(parsed_file) = syn::parse2::(parsed_tokens) else { return; }; diff --git a/support/linting/src/dummy_lint.rs b/support/linting/src/dummy_lint.rs index 2fb0a5c2c..1c5e7bc3f 100644 --- a/support/linting/src/dummy_lint.rs +++ b/support/linting/src/dummy_lint.rs @@ -1,11 +1,11 @@ -use proc_macro2::TokenStream; +use syn::File; use super::*; pub struct DummyLint; impl Lint for DummyLint { - fn lint(_source: &TokenStream) -> Result { + fn lint(_source: &File) -> Result { Ok(()) } } diff --git a/support/linting/src/lint.rs b/support/linting/src/lint.rs index 985e2ecc0..3c099d40c 100644 --- a/support/linting/src/lint.rs +++ b/support/linting/src/lint.rs @@ -1,4 +1,4 @@ -use proc_macro2::TokenStream; +use syn::File; pub type Result = core::result::Result<(), Vec>; @@ -9,5 +9,5 @@ pub type Result = core::result::Result<(), Vec>; /// there are no errors. pub trait Lint: Send + Sync { /// Lints the given Rust source file, returning a compile error if any issues are found. - fn lint(source: &TokenStream) -> Result; + fn lint(source: &File) -> Result; } diff --git a/support/linting/src/require_freeze_struct.rs b/support/linting/src/require_freeze_struct.rs index 14569bd2f..2fa5db5ac 100644 --- a/support/linting/src/require_freeze_struct.rs +++ b/support/linting/src/require_freeze_struct.rs @@ -1,18 +1,16 @@ use super::*; -use proc_macro2::TokenStream; use syn::{ - parse_quote, punctuated::Punctuated, visit::Visit, Attribute, ItemStruct, Meta, MetaList, Path, - Token, + parse_quote, punctuated::Punctuated, visit::Visit, Attribute, File, ItemStruct, Meta, MetaList, + Path, Token, }; pub struct RequireFreezeStruct; impl Lint for RequireFreezeStruct { - fn lint(source: &TokenStream) -> Result { + fn lint(source: &File) -> Result { let mut visitor = EncodeDecodeVisitor::default(); - let file = syn::parse2::(source.clone()).unwrap(); - visitor.visit_file(&file); + visitor.visit_file(&source); if !visitor.errors.is_empty() { return Err(visitor.errors); From ee1422ea58dd63e9748d58b3bad4b13882c59fc5 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Sat, 10 Aug 2024 20:35:54 -0400 Subject: [PATCH 151/177] cargo clippy --fix --workspace --all-features --- support/linting/src/require_freeze_struct.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/support/linting/src/require_freeze_struct.rs b/support/linting/src/require_freeze_struct.rs index 2fa5db5ac..8f02e2697 100644 --- a/support/linting/src/require_freeze_struct.rs +++ b/support/linting/src/require_freeze_struct.rs @@ -10,7 +10,7 @@ impl Lint for RequireFreezeStruct { fn lint(source: &File) -> Result { let mut visitor = EncodeDecodeVisitor::default(); - visitor.visit_file(&source); + visitor.visit_file(source); if !visitor.errors.is_empty() { return Err(visitor.errors); From fec737d56497f13bf54533d7c5e2967a2547f0e8 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Sat, 10 Aug 2024 20:57:20 -0400 Subject: [PATCH 152/177] 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 d047288dd..507747e8c 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -141,7 +141,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: 192, + spec_version: 193, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1, From bbd1b5fc181e36ceabed90ae1d253fbd9655c49f Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Sat, 10 Aug 2024 22:23:04 -0400 Subject: [PATCH 153/177] fix localnet.sh to use production profile + sane workspace setup --- scripts/localnet.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/localnet.sh b/scripts/localnet.sh index 2856603e0..4c15a3334 100755 --- a/scripts/localnet.sh +++ b/scripts/localnet.sh @@ -48,26 +48,26 @@ fi if [[ $BUILD_BINARY == "1" ]]; then echo "*** Building substrate binary..." - cargo build --release --features "$FEATURES" --manifest-path "$BASE_DIR/Cargo.toml" + cargo build --workspace --profile=production --features "$FEATURES" --manifest-path "$BASE_DIR/Cargo.toml" echo "*** Binary compiled" fi echo "*** Building chainspec..." -"$BASE_DIR/target/release/node-subtensor" build-spec --disable-default-bootnode --raw --chain $CHAIN >$FULL_PATH +"$BASE_DIR/target/production/node-subtensor" build-spec --disable-default-bootnode --raw --chain $CHAIN >$FULL_PATH echo "*** Chainspec built and output to file" 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 + "$BASE_DIR/target/production/node-subtensor" purge-chain -y --base-path /tmp/bob --chain="$FULL_PATH" >/dev/null 2>&1 + "$BASE_DIR/target/production/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=( - "$BASE_DIR/target/release/node-subtensor" + "$BASE_DIR/target/production/node-subtensor" --base-path /tmp/alice --chain="$FULL_PATH" --alice @@ -80,7 +80,7 @@ alice_start=( ) bob_start=( - "$BASE_DIR"/target/release/node-subtensor + "$BASE_DIR"/target/production/node-subtensor --base-path /tmp/bob --chain="$FULL_PATH" --bob From 9ef28bf25c01967a686eb5e276904c48129f83d2 Mon Sep 17 00:00:00 2001 From: John Reed <87283488+JohnReedV@users.noreply.github.com> Date: Mon, 12 Aug 2024 10:34:22 -0700 Subject: [PATCH 154/177] add line --- pallets/subtensor/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index 6388e0331..9fab3be0e 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -1356,6 +1356,7 @@ where ..Default::default() }), } + } // NOTE: Add later when we put in a pre and post dispatch step. From 58196b18babd28089f8d1bbdd35dd6d002762828 Mon Sep 17 00:00:00 2001 From: John Reed <87283488+JohnReedV@users.noreply.github.com> Date: Mon, 12 Aug 2024 10:34:30 -0700 Subject: [PATCH 155/177] remove line --- pallets/subtensor/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index 9fab3be0e..6388e0331 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -1356,7 +1356,6 @@ where ..Default::default() }), } - } // NOTE: Add later when we put in a pre and post dispatch step. From 144be21efcc86577a952a034e6f6259f6f98d945 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Tue, 13 Aug 2024 10:21:25 -0400 Subject: [PATCH 156/177] initial script --- .github/workflows/benchmark-weights.yml | 0 scripts/benchmark_all.sh | 24 ++++++++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 .github/workflows/benchmark-weights.yml create mode 100755 scripts/benchmark_all.sh diff --git a/.github/workflows/benchmark-weights.yml b/.github/workflows/benchmark-weights.yml new file mode 100644 index 000000000..e69de29bb diff --git a/scripts/benchmark_all.sh b/scripts/benchmark_all.sh new file mode 100755 index 000000000..277c39e74 --- /dev/null +++ b/scripts/benchmark_all.sh @@ -0,0 +1,24 @@ +#!/bin/sh + +# List of pallets you want to benchmark +pallets=("admin-utils", "collective", "commitments", "registry", "subtensor") + +# Chain spec and output directory +chain_spec="dev" # or your specific chain spec + +for pallet in "${pallets[@]}" +do + echo "Benchmarking $pallet..." + cargo run --profile=production --features=runtime-benchmarks -- benchmark pallet \ + --chain $chain_spec \ + --execution=wasm \ + --wasm-execution=compiled \ + --pallet $pallet \ + --extrinsic '*' \ + --steps 50 \ + --repeat 20 \ + --output "pallets/$pallet/src/$pallet.rs" \ + --template ./.maintain/frame-weight-template.hbs # Adjust this path to your template file +done + +echo "All pallets have been benchmarked and weights updated." From 0323d506fdb3fe0e0808d97a6941274b29b5f4cb Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Tue, 13 Aug 2024 13:25:18 -0400 Subject: [PATCH 157/177] working but running into commit reveal issues --- scripts/benchmark_all.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/benchmark_all.sh b/scripts/benchmark_all.sh index 277c39e74..580e5425e 100755 --- a/scripts/benchmark_all.sh +++ b/scripts/benchmark_all.sh @@ -1,23 +1,23 @@ #!/bin/sh +set -ex # List of pallets you want to benchmark -pallets=("admin-utils", "collective", "commitments", "registry", "subtensor") +pallets=("pallet_subtensor" "pallet_collective" "pallet_commitments" "pallet_registry" "pallet_admin_utils") # Chain spec and output directory -chain_spec="dev" # or your specific chain spec +chain_spec="finney" # or your specific chain spec for pallet in "${pallets[@]}" do echo "Benchmarking $pallet..." - cargo run --profile=production --features=runtime-benchmarks -- benchmark pallet \ + cargo run --profile=production --features=runtime-benchmarks,try-runtime --bin node-subtensor -- benchmark pallet \ --chain $chain_spec \ - --execution=wasm \ --wasm-execution=compiled \ --pallet $pallet \ --extrinsic '*' \ --steps 50 \ - --repeat 20 \ - --output "pallets/$pallet/src/$pallet.rs" \ + --repeat 5 \ + --output "pallets/$pallet/src/weights.rs" \ --template ./.maintain/frame-weight-template.hbs # Adjust this path to your template file done From 46f32879fc4c781299caf1c1fbfd8b29e75e8fdb Mon Sep 17 00:00:00 2001 From: Liam Date: Tue, 13 Aug 2024 20:36:18 +0200 Subject: [PATCH 158/177] debug runtime log level --- pallets/admin-utils/src/lib.rs | 80 +++++++++---------- pallets/subtensor/src/coinbase/root.rs | 22 ++--- pallets/subtensor/src/epoch/run_epoch.rs | 2 +- pallets/subtensor/src/macros/hooks.rs | 2 +- .../subtensor/src/rpc_info/delegate_info.rs | 2 +- pallets/subtensor/src/staking/add_stake.rs | 4 +- .../subtensor/src/staking/become_delegate.rs | 4 +- .../subtensor/src/staking/decrease_take.rs | 4 +- .../subtensor/src/staking/increase_take.rs | 4 +- pallets/subtensor/src/staking/remove_stake.rs | 4 +- pallets/subtensor/src/subnets/registration.rs | 20 ++--- pallets/subtensor/src/subnets/serving.rs | 4 +- pallets/subtensor/src/subnets/weights.rs | 10 +-- pallets/subtensor/src/utils/identity.rs | 2 +- pallets/subtensor/src/utils/misc.rs | 6 +- 15 files changed, 85 insertions(+), 85 deletions(-) diff --git a/pallets/admin-utils/src/lib.rs b/pallets/admin-utils/src/lib.rs index 59b0ed44a..4636bbce0 100644 --- a/pallets/admin-utils/src/lib.rs +++ b/pallets/admin-utils/src/lib.rs @@ -87,7 +87,7 @@ pub mod pallet { T::Aura::change_authorities(new_authorities.clone()); - log::info!("Aura authorities changed: {:?}", new_authorities); + log::debug!("Aura authorities changed: {:?}", new_authorities); // Return a successful DispatchResultWithPostInfo Ok(()) @@ -101,7 +101,7 @@ pub mod pallet { pub fn sudo_set_default_take(origin: OriginFor, default_take: u16) -> DispatchResult { ensure_root(origin)?; T::Subtensor::set_max_delegate_take(default_take); - log::info!("DefaultTakeSet( default_take: {:?} ) ", default_take); + log::debug!("DefaultTakeSet( default_take: {:?} ) ", default_take); Ok(()) } @@ -113,7 +113,7 @@ pub mod pallet { pub fn sudo_set_tx_rate_limit(origin: OriginFor, tx_rate_limit: u64) -> DispatchResult { ensure_root(origin)?; T::Subtensor::set_tx_rate_limit(tx_rate_limit); - log::info!("TxRateLimitSet( tx_rate_limit: {:?} ) ", tx_rate_limit); + log::debug!("TxRateLimitSet( tx_rate_limit: {:?} ) ", tx_rate_limit); Ok(()) } @@ -130,7 +130,7 @@ pub mod pallet { T::Subtensor::ensure_subnet_owner_or_root(origin, netuid)?; T::Subtensor::set_serving_rate_limit(netuid, serving_rate_limit); - log::info!( + log::debug!( "ServingRateLimitSet( serving_rate_limit: {:?} ) ", serving_rate_limit ); @@ -154,7 +154,7 @@ pub mod pallet { Error::::SubnetDoesNotExist ); T::Subtensor::set_min_difficulty(netuid, min_difficulty); - log::info!( + log::debug!( "MinDifficultySet( netuid: {:?} min_difficulty: {:?} ) ", netuid, min_difficulty @@ -179,7 +179,7 @@ pub mod pallet { Error::::SubnetDoesNotExist ); T::Subtensor::set_max_difficulty(netuid, max_difficulty); - log::info!( + log::debug!( "MaxDifficultySet( netuid: {:?} max_difficulty: {:?} ) ", netuid, max_difficulty @@ -204,7 +204,7 @@ pub mod pallet { Error::::SubnetDoesNotExist ); T::Subtensor::set_weights_version_key(netuid, weights_version_key); - log::info!( + log::debug!( "WeightsVersionKeySet( netuid: {:?} weights_version_key: {:?} ) ", netuid, weights_version_key @@ -229,7 +229,7 @@ pub mod pallet { Error::::SubnetDoesNotExist ); T::Subtensor::set_weights_set_rate_limit(netuid, weights_set_rate_limit); - log::info!( + log::debug!( "WeightsSetRateLimitSet( netuid: {:?} weights_set_rate_limit: {:?} ) ", netuid, weights_set_rate_limit @@ -254,7 +254,7 @@ pub mod pallet { Error::::SubnetDoesNotExist ); T::Subtensor::set_adjustment_interval(netuid, adjustment_interval); - log::info!( + log::debug!( "AdjustmentIntervalSet( netuid: {:?} adjustment_interval: {:?} ) ", netuid, adjustment_interval @@ -285,7 +285,7 @@ pub mod pallet { Error::::SubnetDoesNotExist ); T::Subtensor::set_adjustment_alpha(netuid, adjustment_alpha); - log::info!( + log::debug!( "AdjustmentAlphaSet( adjustment_alpha: {:?} ) ", adjustment_alpha ); @@ -309,7 +309,7 @@ pub mod pallet { Error::::SubnetDoesNotExist ); T::Subtensor::set_max_weight_limit(netuid, max_weight_limit); - log::info!( + log::debug!( "MaxWeightLimitSet( netuid: {:?} max_weight_limit: {:?} ) ", netuid, max_weight_limit @@ -334,7 +334,7 @@ pub mod pallet { ); T::Subtensor::set_immunity_period(netuid, immunity_period); - log::info!( + log::debug!( "ImmunityPeriodSet( netuid: {:?} immunity_period: {:?} ) ", netuid, immunity_period @@ -359,7 +359,7 @@ pub mod pallet { Error::::SubnetDoesNotExist ); T::Subtensor::set_min_allowed_weights(netuid, min_allowed_weights); - log::info!( + log::debug!( "MinAllowedWeightSet( netuid: {:?} min_allowed_weights: {:?} ) ", netuid, min_allowed_weights @@ -387,7 +387,7 @@ pub mod pallet { Error::::MaxAllowedUIdsLessThanCurrentUIds ); T::Subtensor::set_max_allowed_uids(netuid, max_allowed_uids); - log::info!( + log::debug!( "MaxAllowedUidsSet( netuid: {:?} max_allowed_uids: {:?} ) ", netuid, max_allowed_uids @@ -408,7 +408,7 @@ pub mod pallet { Error::::SubnetDoesNotExist ); T::Subtensor::set_kappa(netuid, kappa); - log::info!("KappaSet( netuid: {:?} kappa: {:?} ) ", netuid, kappa); + log::debug!("KappaSet( netuid: {:?} kappa: {:?} ) ", netuid, kappa); Ok(()) } @@ -425,7 +425,7 @@ pub mod pallet { Error::::SubnetDoesNotExist ); T::Subtensor::set_rho(netuid, rho); - log::info!("RhoSet( netuid: {:?} rho: {:?} ) ", netuid, rho); + log::debug!("RhoSet( netuid: {:?} rho: {:?} ) ", netuid, rho); Ok(()) } @@ -446,7 +446,7 @@ pub mod pallet { Error::::SubnetDoesNotExist ); T::Subtensor::set_activity_cutoff(netuid, activity_cutoff); - log::info!( + log::debug!( "ActivityCutoffSet( netuid: {:?} activity_cutoff: {:?} ) ", netuid, activity_cutoff @@ -473,7 +473,7 @@ pub mod pallet { T::Subtensor::ensure_subnet_owner_or_root(origin, netuid)?; T::Subtensor::set_network_registration_allowed(netuid, registration_allowed); - log::info!( + log::debug!( "NetworkRegistrationAllowed( registration_allowed: {:?} ) ", registration_allowed ); @@ -498,7 +498,7 @@ pub mod pallet { T::Subtensor::ensure_subnet_owner_or_root(origin, netuid)?; T::Subtensor::set_network_pow_registration_allowed(netuid, registration_allowed); - log::info!( + log::debug!( "NetworkPowRegistrationAllowed( registration_allowed: {:?} ) ", registration_allowed ); @@ -525,7 +525,7 @@ pub mod pallet { netuid, target_registrations_per_interval, ); - log::info!( + log::debug!( "RegistrationPerIntervalSet( netuid: {:?} target_registrations_per_interval: {:?} ) ", netuid, target_registrations_per_interval @@ -550,7 +550,7 @@ pub mod pallet { Error::::SubnetDoesNotExist ); T::Subtensor::set_min_burn(netuid, min_burn); - log::info!( + log::debug!( "MinBurnSet( netuid: {:?} min_burn: {:?} ) ", netuid, min_burn @@ -575,7 +575,7 @@ pub mod pallet { Error::::SubnetDoesNotExist ); T::Subtensor::set_max_burn(netuid, max_burn); - log::info!( + log::debug!( "MaxBurnSet( netuid: {:?} max_burn: {:?} ) ", netuid, max_burn @@ -599,7 +599,7 @@ pub mod pallet { Error::::SubnetDoesNotExist ); T::Subtensor::set_difficulty(netuid, difficulty); - log::info!( + log::debug!( "DifficultySet( netuid: {:?} difficulty: {:?} ) ", netuid, difficulty @@ -628,7 +628,7 @@ pub mod pallet { ); T::Subtensor::set_max_allowed_validators(netuid, max_allowed_validators); - log::info!( + log::debug!( "MaxAllowedValidatorsSet( netuid: {:?} max_allowed_validators: {:?} ) ", netuid, max_allowed_validators @@ -653,7 +653,7 @@ pub mod pallet { Error::::SubnetDoesNotExist ); T::Subtensor::set_bonds_moving_average(netuid, bonds_moving_average); - log::info!( + log::debug!( "BondsMovingAverageSet( netuid: {:?} bonds_moving_average: {:?} ) ", netuid, bonds_moving_average @@ -678,7 +678,7 @@ pub mod pallet { Error::::SubnetDoesNotExist ); T::Subtensor::set_max_registrations_per_block(netuid, max_registrations_per_block); - log::info!( + log::debug!( "MaxRegistrationsPerBlock( netuid: {:?} max_registrations_per_block: {:?} ) ", netuid, max_registrations_per_block @@ -702,7 +702,7 @@ pub mod pallet { ) -> DispatchResult { ensure_root(origin)?; T::Subtensor::set_subnet_owner_cut(subnet_owner_cut); - log::info!( + log::debug!( "SubnetOwnerCut( subnet_owner_cut: {:?} ) ", subnet_owner_cut ); @@ -725,7 +725,7 @@ pub mod pallet { ) -> DispatchResult { ensure_root(origin)?; T::Subtensor::set_network_rate_limit(rate_limit); - log::info!("NetworkRateLimit( rate_limit: {:?} ) ", rate_limit); + log::debug!("NetworkRateLimit( rate_limit: {:?} ) ", rate_limit); Ok(()) } @@ -741,7 +741,7 @@ pub mod pallet { Error::::SubnetDoesNotExist ); T::Subtensor::set_tempo(netuid, tempo); - log::info!("TempoSet( netuid: {:?} tempo: {:?} ) ", netuid, tempo); + log::debug!("TempoSet( netuid: {:?} tempo: {:?} ) ", netuid, tempo); Ok(()) } @@ -779,7 +779,7 @@ pub mod pallet { T::Subtensor::set_network_immunity_period(immunity_period); - log::info!("NetworkImmunityPeriod( period: {:?} ) ", immunity_period); + log::debug!("NetworkImmunityPeriod( period: {:?} ) ", immunity_period); Ok(()) } @@ -802,7 +802,7 @@ pub mod pallet { T::Subtensor::set_network_min_lock(lock_cost); - log::info!("NetworkMinLockCost( lock_cost: {:?} ) ", lock_cost); + log::debug!("NetworkMinLockCost( lock_cost: {:?} ) ", lock_cost); Ok(()) } @@ -821,7 +821,7 @@ pub mod pallet { ensure_root(origin)?; T::Subtensor::set_subnet_limit(max_subnets); - log::info!("SubnetLimit( max_subnets: {:?} ) ", max_subnets); + log::debug!("SubnetLimit( max_subnets: {:?} ) ", max_subnets); Ok(()) } @@ -844,7 +844,7 @@ pub mod pallet { T::Subtensor::set_lock_reduction_interval(interval); - log::info!("NetworkLockReductionInterval( interval: {:?} ) ", interval); + log::debug!("NetworkLockReductionInterval( interval: {:?} ) ", interval); Ok(()) } @@ -912,7 +912,7 @@ pub mod pallet { ) -> DispatchResult { ensure_root(origin)?; T::Subtensor::set_tx_delegate_take_rate_limit(tx_rate_limit); - log::info!( + log::debug!( "TxRateLimitDelegateTakeSet( tx_delegate_take_rate_limit: {:?} ) ", tx_rate_limit ); @@ -927,7 +927,7 @@ pub mod pallet { pub fn sudo_set_min_delegate_take(origin: OriginFor, take: u16) -> DispatchResult { ensure_root(origin)?; T::Subtensor::set_min_delegate_take(take); - log::info!("TxMinDelegateTakeSet( tx_min_delegate_take: {:?} ) ", take); + log::debug!("TxMinDelegateTakeSet( tx_min_delegate_take: {:?} ) ", take); Ok(()) } @@ -942,7 +942,7 @@ pub mod pallet { ) -> DispatchResult { ensure_root(origin)?; T::Subtensor::set_target_stakes_per_interval(target_stakes_per_interval); - log::info!( + log::debug!( "TxTargetStakesPerIntervalSet( set_target_stakes_per_interval: {:?} ) ", target_stakes_per_interval ); @@ -967,7 +967,7 @@ pub mod pallet { ); T::Subtensor::set_commit_reveal_weights_interval(netuid, interval); - log::info!( + log::debug!( "SetWeightCommitInterval( netuid: {:?}, interval: {:?} ) ", netuid, interval @@ -993,7 +993,7 @@ pub mod pallet { ); T::Subtensor::set_commit_reveal_weights_enabled(netuid, enabled); - log::info!("ToggleSetWeightsCommitReveal( netuid: {:?} ) ", netuid); + log::debug!("ToggleSetWeightsCommitReveal( netuid: {:?} ) ", netuid); Ok(()) } @@ -1015,7 +1015,7 @@ pub mod pallet { ) -> DispatchResult { T::Subtensor::ensure_subnet_owner_or_root(origin, netuid)?; T::Subtensor::set_liquid_alpha_enabled(netuid, enabled); - log::info!( + log::debug!( "LiquidAlphaEnableToggled( netuid: {:?}, Enabled: {:?} ) ", netuid, enabled @@ -1059,7 +1059,7 @@ pub mod pallet { ) -> DispatchResult { ensure_root(origin)?; T::Subtensor::set_hotkey_emission_tempo(emission_tempo); - log::info!( + log::debug!( "HotkeyEmissionTempoSet( emission_tempo: {:?} )", emission_tempo ); diff --git a/pallets/subtensor/src/coinbase/root.rs b/pallets/subtensor/src/coinbase/root.rs index 974931e8f..39f745b93 100644 --- a/pallets/subtensor/src/coinbase/root.rs +++ b/pallets/subtensor/src/coinbase/root.rs @@ -486,7 +486,7 @@ 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)?; - log::info!( + log::debug!( "do_root_register( coldkey: {:?}, hotkey: {:?} )", coldkey, hotkey @@ -529,7 +529,7 @@ impl Pallet { // --- 12.1.2 Add the new account and make them a member of the Senate. Self::append_neuron(root_netuid, &hotkey, current_block_number); - log::info!("add new neuron: {:?} on uid {:?}", hotkey, subnetwork_uid); + log::debug!("add new neuron: {:?} on uid {:?}", hotkey, subnetwork_uid); } else { // --- 13.1.1 The network is full. Perform replacement. // Find the neuron with the lowest stake value to replace. @@ -562,7 +562,7 @@ impl Pallet { // Replace the neuron account with new information. Self::replace_neuron(root_netuid, lowest_uid, &hotkey, current_block_number); - log::info!( + log::debug!( "replace neuron: {:?} with {:?} on uid {:?}", replaced_hotkey, hotkey, @@ -588,7 +588,7 @@ impl Pallet { RegistrationsThisBlock::::mutate(root_netuid, |val| *val += 1); // --- 16. Log and announce the successful registration. - log::info!( + log::debug!( "RootRegistered(netuid:{:?} uid:{:?} hotkey:{:?})", root_netuid, subnetwork_uid, @@ -622,7 +622,7 @@ 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)?; - log::info!( + log::debug!( "do_root_register( coldkey: {:?}, hotkey: {:?} )", coldkey, hotkey @@ -652,7 +652,7 @@ impl Pallet { } // --- 5. Log and announce the successful Senate adjustment. - log::info!( + log::debug!( "SenateAdjusted(old_hotkey:{:?} hotkey:{:?})", replaced, hotkey @@ -733,7 +733,7 @@ impl Pallet { ) -> dispatch::DispatchResult { // Check the caller's signature. This is the coldkey of a registered account. let coldkey = ensure_signed(origin)?; - log::info!( + log::debug!( "do_set_root_weights( origin:{:?} netuid:{:?}, uids:{:?}, values:{:?})", coldkey, netuid, @@ -834,7 +834,7 @@ impl Pallet { Self::set_last_update_for_uid(netuid, neuron_uid, current_block); // Emit the tracking event. - log::info!( + log::debug!( "RootWeightsSet( netuid:{:?}, neuron_uid:{:?} )", netuid, neuron_uid @@ -968,7 +968,7 @@ impl Pallet { SubnetOwner::::insert(netuid_to_register, coldkey); // --- 8. Emit the NetworkAdded event. - log::info!( + log::debug!( "NetworkAdded( netuid:{:?}, modality:{:?} )", netuid_to_register, 0 @@ -1012,7 +1012,7 @@ impl Pallet { Self::remove_network(netuid); // --- 5. Emit the NetworkRemoved event. - log::info!("NetworkRemoved( netuid:{:?} )", netuid); + log::debug!("NetworkRemoved( netuid:{:?} )", netuid); Self::deposit_event(Event::NetworkRemoved(netuid)); // --- 6. Return success. @@ -1274,7 +1274,7 @@ impl Pallet { } }); - log::info!("Netuids Order: {:?}", netuids); + log::debug!("Netuids Order: {:?}", netuids); match netuids.last() { Some(netuid) => *netuid, diff --git a/pallets/subtensor/src/epoch/run_epoch.rs b/pallets/subtensor/src/epoch/run_epoch.rs index 1cb2c3448..c96ea05e2 100644 --- a/pallets/subtensor/src/epoch/run_epoch.rs +++ b/pallets/subtensor/src/epoch/run_epoch.rs @@ -1310,7 +1310,7 @@ impl Pallet { AlphaValues::::insert(netuid, (alpha_low, alpha_high)); - log::info!( + log::debug!( "AlphaValuesSet( netuid: {:?}, AlphaLow: {:?}, AlphaHigh: {:?} ) ", netuid, alpha_low, diff --git a/pallets/subtensor/src/macros/hooks.rs b/pallets/subtensor/src/macros/hooks.rs index f2556d506..76f140002 100644 --- a/pallets/subtensor/src/macros/hooks.rs +++ b/pallets/subtensor/src/macros/hooks.rs @@ -19,7 +19,7 @@ mod hooks { match block_step_result { Ok(_) => { // --- If the block step was successful, return the weight. - log::info!("Successfully ran block step."); + log::debug!("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)) diff --git a/pallets/subtensor/src/rpc_info/delegate_info.rs b/pallets/subtensor/src/rpc_info/delegate_info.rs index 56b25d230..a41b6e17e 100644 --- a/pallets/subtensor/src/rpc_info/delegate_info.rs +++ b/pallets/subtensor/src/rpc_info/delegate_info.rs @@ -148,7 +148,7 @@ impl Pallet { } } - log::info!( + log::debug!( "Total delegated stake for coldkey {:?}: {}", coldkey, total_delegated diff --git a/pallets/subtensor/src/staking/add_stake.rs b/pallets/subtensor/src/staking/add_stake.rs index f62fd7cd2..c9cbd7e04 100644 --- a/pallets/subtensor/src/staking/add_stake.rs +++ b/pallets/subtensor/src/staking/add_stake.rs @@ -37,7 +37,7 @@ impl Pallet { ) -> 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!( + log::debug!( "do_add_stake( origin:{:?} hotkey:{:?}, stake_to_be_added:{:?} )", coldkey, hotkey, @@ -102,7 +102,7 @@ impl Pallet { stakes_this_interval.saturating_add(1), block, ); - log::info!( + log::debug!( "StakeAdded( hotkey:{:?}, stake_to_be_added:{:?} )", hotkey, actual_amount_to_stake diff --git a/pallets/subtensor/src/staking/become_delegate.rs b/pallets/subtensor/src/staking/become_delegate.rs index 064f47c12..a75716653 100644 --- a/pallets/subtensor/src/staking/become_delegate.rs +++ b/pallets/subtensor/src/staking/become_delegate.rs @@ -34,7 +34,7 @@ impl Pallet { ) -> dispatch::DispatchResult { // --- 1. We check the coldkey signuture. let coldkey = ensure_signed(origin)?; - log::info!( + log::debug!( "do_become_delegate( origin:{:?} hotkey:{:?}, take:{:?} )", coldkey, hotkey, @@ -72,7 +72,7 @@ impl Pallet { Self::set_last_tx_block_delegate_take(&coldkey, block); // --- 7. Emit the staking event. - log::info!( + log::debug!( "DelegateAdded( coldkey:{:?}, hotkey:{:?}, take:{:?} )", coldkey, hotkey, diff --git a/pallets/subtensor/src/staking/decrease_take.rs b/pallets/subtensor/src/staking/decrease_take.rs index 9e48bac91..d08c41e6d 100644 --- a/pallets/subtensor/src/staking/decrease_take.rs +++ b/pallets/subtensor/src/staking/decrease_take.rs @@ -34,7 +34,7 @@ impl Pallet { ) -> dispatch::DispatchResult { // --- 1. We check the coldkey signature. let coldkey = ensure_signed(origin)?; - log::info!( + log::debug!( "do_decrease_take( origin:{:?} hotkey:{:?}, take:{:?} )", coldkey, hotkey, @@ -58,7 +58,7 @@ impl Pallet { Delegates::::insert(hotkey.clone(), take); // --- 5. Emit the take value. - log::info!( + log::debug!( "TakeDecreased( coldkey:{:?}, hotkey:{:?}, take:{:?} )", coldkey, hotkey, diff --git a/pallets/subtensor/src/staking/increase_take.rs b/pallets/subtensor/src/staking/increase_take.rs index aa6dd443c..9362c9378 100644 --- a/pallets/subtensor/src/staking/increase_take.rs +++ b/pallets/subtensor/src/staking/increase_take.rs @@ -37,7 +37,7 @@ impl Pallet { ) -> dispatch::DispatchResult { // --- 1. We check the coldkey signature. let coldkey = ensure_signed(origin)?; - log::info!( + log::debug!( "do_increase_take( origin:{:?} hotkey:{:?}, take:{:?} )", coldkey, hotkey, @@ -74,7 +74,7 @@ impl Pallet { Delegates::::insert(hotkey.clone(), take); // --- 7. Emit the take value. - log::info!( + log::debug!( "TakeIncreased( coldkey:{:?}, hotkey:{:?}, take:{:?} )", coldkey, hotkey, diff --git a/pallets/subtensor/src/staking/remove_stake.rs b/pallets/subtensor/src/staking/remove_stake.rs index a6f3db08d..4118e8d07 100644 --- a/pallets/subtensor/src/staking/remove_stake.rs +++ b/pallets/subtensor/src/staking/remove_stake.rs @@ -37,7 +37,7 @@ impl Pallet { ) -> 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!( + log::debug!( "do_remove_stake( origin:{:?} hotkey:{:?}, stake_to_be_removed:{:?} )", coldkey, hotkey, @@ -96,7 +96,7 @@ impl Pallet { unstakes_this_interval.saturating_add(1), block, ); - log::info!( + log::debug!( "StakeRemoved( hotkey:{:?}, stake_to_be_removed:{:?} )", hotkey, stake_to_be_removed diff --git a/pallets/subtensor/src/subnets/registration.rs b/pallets/subtensor/src/subnets/registration.rs index 9319adcd1..dc321f8dd 100644 --- a/pallets/subtensor/src/subnets/registration.rs +++ b/pallets/subtensor/src/subnets/registration.rs @@ -41,7 +41,7 @@ impl Pallet { ) -> DispatchResult { // --- 1. Check that the caller has signed the transaction. (the coldkey of the pairing) let coldkey = ensure_signed(origin)?; - log::info!( + log::debug!( "do_registration( coldkey:{:?} netuid:{:?} hotkey:{:?} )", coldkey, netuid, @@ -131,7 +131,7 @@ impl Pallet { // --- 12.1.2 Expand subnetwork with new account. Self::append_neuron(netuid, &hotkey, current_block_number); - log::info!("add new neuron account"); + log::debug!("add new neuron account"); } else { // --- 13.1.1 Replacement required. // We take the neuron with the lowest pruning score here. @@ -139,7 +139,7 @@ impl Pallet { // --- 13.1.1 Replace the neuron account with the new info. Self::replace_neuron(netuid, subnetwork_uid, &hotkey, current_block_number); - log::info!("prune neuron"); + log::debug!("prune neuron"); } // --- 14. Record the registration and increment block and interval counters. @@ -149,7 +149,7 @@ impl Pallet { Self::increase_rao_recycled(netuid, Self::get_burn_as_u64(netuid)); // --- 15. Deposit successful event. - log::info!( + log::debug!( "NeuronRegistered( netuid:{:?} uid:{:?} hotkey:{:?} ) ", netuid, subnetwork_uid, @@ -220,7 +220,7 @@ impl Pallet { // --- 1. Check that the caller has signed the transaction. // TODO( const ): This not be the hotkey signature or else an exterior actor can register the hotkey and potentially control it? let signing_origin = ensure_signed(origin)?; - log::info!( + log::debug!( "do_registration( origin:{:?} netuid:{:?} hotkey:{:?}, coldkey:{:?} )", signing_origin, netuid, @@ -326,7 +326,7 @@ impl Pallet { // --- 11.1.2 Expand subnetwork with new account. Self::append_neuron(netuid, &hotkey, current_block_number); - log::info!("add new neuron account"); + log::debug!("add new neuron account"); } else { // --- 11.1.1 Replacement required. // We take the neuron with the lowest pruning score here. @@ -334,7 +334,7 @@ impl Pallet { // --- 11.1.1 Replace the neuron account with the new info. Self::replace_neuron(netuid, subnetwork_uid, &hotkey, current_block_number); - log::info!("prune neuron"); + log::debug!("prune neuron"); } // --- 12. Record the registration and increment block and interval counters. @@ -343,7 +343,7 @@ impl Pallet { RegistrationsThisBlock::::mutate(netuid, |val| val.saturating_inc()); // --- 13. Deposit successful event. - log::info!( + log::debug!( "NeuronRegistered( netuid:{:?} uid:{:?} hotkey:{:?} ) ", netuid, subnetwork_uid, @@ -366,7 +366,7 @@ impl Pallet { // --- 1. Check that the caller has signed the transaction. let coldkey = ensure_signed(origin)?; - log::info!("do_faucet( coldkey:{:?} )", coldkey); + log::debug!("do_faucet( coldkey:{:?} )", coldkey); // --- 2. Ensure the passed block number is valid, not in the future or too old. // Work must have been done within 3 blocks (stops long range attacks). @@ -400,7 +400,7 @@ impl Pallet { Self::add_balance_to_coldkey_account(&coldkey, balance_to_add); // --- 6. Deposit successful event. - log::info!( + log::debug!( "Faucet( coldkey:{:?} amount:{:?} ) ", coldkey, balance_to_add diff --git a/pallets/subtensor/src/subnets/serving.rs b/pallets/subtensor/src/subnets/serving.rs index eb7fa4369..1a9240c36 100644 --- a/pallets/subtensor/src/subnets/serving.rs +++ b/pallets/subtensor/src/subnets/serving.rs @@ -106,7 +106,7 @@ impl Pallet { Axons::::insert(netuid, hotkey_id.clone(), prev_axon); // We deposit axon served event. - log::info!("AxonServed( hotkey:{:?} ) ", hotkey_id.clone()); + log::debug!("AxonServed( hotkey:{:?} ) ", hotkey_id.clone()); Self::deposit_event(Event::AxonServed(netuid, hotkey_id)); // Return is successful dispatch. @@ -204,7 +204,7 @@ impl Pallet { Prometheus::::insert(netuid, hotkey_id.clone(), prev_prometheus); // We deposit prometheus served event. - log::info!("PrometheusServed( hotkey:{:?} ) ", hotkey_id.clone()); + log::debug!("PrometheusServed( hotkey:{:?} ) ", hotkey_id.clone()); Self::deposit_event(Event::PrometheusServed(netuid, hotkey_id)); // Return is successful dispatch. diff --git a/pallets/subtensor/src/subnets/weights.rs b/pallets/subtensor/src/subnets/weights.rs index 67b1d485e..1a53e44cc 100644 --- a/pallets/subtensor/src/subnets/weights.rs +++ b/pallets/subtensor/src/subnets/weights.rs @@ -28,7 +28,7 @@ impl Pallet { ) -> DispatchResult { let who = ensure_signed(origin)?; - log::info!("do_commit_weights( hotkey:{:?} netuid:{:?})", who, netuid); + log::debug!("do_commit_weights( hotkey:{:?} netuid:{:?})", who, netuid); ensure!( Self::get_commit_reveal_weights_enabled(netuid), @@ -89,7 +89,7 @@ impl Pallet { ) -> DispatchResult { let who = ensure_signed(origin.clone())?; - log::info!("do_reveal_weights( hotkey:{:?} netuid:{:?})", who, netuid); + log::debug!("do_reveal_weights( hotkey:{:?} netuid:{:?})", who, netuid); ensure!( Self::get_commit_reveal_weights_enabled(netuid), @@ -188,7 +188,7 @@ impl Pallet { ) -> dispatch::DispatchResult { // --- 1. Check the caller's signature. This is the hotkey of a registered account. let hotkey = ensure_signed(origin)?; - log::info!( + log::debug!( "do_set_weights( origin:{:?} netuid:{:?}, uids:{:?}, values:{:?})", hotkey, netuid, @@ -289,7 +289,7 @@ impl Pallet { Self::set_last_update_for_uid(netuid, neuron_uid, current_block); // --- 19. Emit the tracking event. - log::info!( + log::debug!( "WeightsSet( netuid:{:?}, neuron_uid:{:?} )", netuid, neuron_uid @@ -308,7 +308,7 @@ impl Pallet { /// pub fn check_version_key(netuid: u16, version_key: u64) -> bool { let network_version_key: u64 = WeightsVersionKey::::get(netuid); - log::info!( + log::debug!( "check_version_key( network_version_key:{:?}, version_key:{:?} )", network_version_key, version_key diff --git a/pallets/subtensor/src/utils/identity.rs b/pallets/subtensor/src/utils/identity.rs index 1c9c3c25d..460bcb838 100644 --- a/pallets/subtensor/src/utils/identity.rs +++ b/pallets/subtensor/src/utils/identity.rs @@ -66,7 +66,7 @@ impl Pallet { Identities::::insert(coldkey.clone(), identity.clone()); // Log the identity set event - log::info!("ChainIdentitySet( coldkey:{:?} ) ", coldkey.clone()); + log::debug!("ChainIdentitySet( coldkey:{:?} ) ", coldkey.clone()); // Emit an event to notify that an identity has been set Self::deposit_event(Event::ChainIdentitySet(coldkey.clone())); diff --git a/pallets/subtensor/src/utils/misc.rs b/pallets/subtensor/src/utils/misc.rs index 9155357c0..cd81060eb 100644 --- a/pallets/subtensor/src/utils/misc.rs +++ b/pallets/subtensor/src/utils/misc.rs @@ -150,12 +150,12 @@ impl Pallet { Active::::insert(netuid, updated_active_vec); } pub fn set_pruning_score_for_uid(netuid: u16, uid: u16, pruning_score: u16) { - log::info!("netuid = {:?}", netuid); - log::info!( + log::debug!("netuid = {:?}", netuid); + log::debug!( "SubnetworkN::::get( netuid ) = {:?}", SubnetworkN::::get(netuid) ); - log::info!("uid = {:?}", uid); + log::debug!("uid = {:?}", uid); assert!(uid < SubnetworkN::::get(netuid)); PruningScores::::mutate(netuid, |v| { if let Some(s) = v.get_mut(uid as usize) { From ce0dfa7ec2c7d2480c9f0ab254e9c020c91ff846 Mon Sep 17 00:00:00 2001 From: Greg Zaitsev Date: Wed, 14 Aug 2024 10:12:21 -0400 Subject: [PATCH 159/177] Fix rate limit for setting children --- pallets/subtensor/src/staking/set_children.rs | 12 +++++++++++- pallets/subtensor/src/utils/rate_limiting.rs | 7 +++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/pallets/subtensor/src/staking/set_children.rs b/pallets/subtensor/src/staking/set_children.rs index 402e9fd2a..ebd8db6bf 100644 --- a/pallets/subtensor/src/staking/set_children.rs +++ b/pallets/subtensor/src/staking/set_children.rs @@ -61,12 +61,22 @@ impl Pallet { // Ensure the hotkey passes the rate limit. ensure!( Self::passes_rate_limit_globally( - &TransactionType::SetChildren, // Set children. &hotkey, // Specific to a hotkey. + netuid, // Specific to a subnet. + &TransactionType::SetChildren, // Set children. ), Error::::TxRateLimitExceeded ); + // Set last transaction block + let current_block = Self::get_current_block_as_u64(); + Self::set_last_transaction_block( + &hotkey, + netuid, + &TransactionType::SetChildren, + current_block + ); + // --- 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/rate_limiting.rs b/pallets/subtensor/src/utils/rate_limiting.rs index b02ad9855..1b75de7d5 100644 --- a/pallets/subtensor/src/utils/rate_limiting.rs +++ b/pallets/subtensor/src/utils/rate_limiting.rs @@ -58,8 +58,11 @@ impl Pallet { } /// 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; + pub fn passes_rate_limit_globally( + hotkey: &T::AccountId, + netuid: u16, + tx_type: &TransactionType, + ) -> 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); From 2c25fa3d420270739159249a7ee911d433f7ac14 Mon Sep 17 00:00:00 2001 From: Keith Date: Wed, 14 Aug 2024 11:16:36 -0400 Subject: [PATCH 160/177] Include the devnet-ready branch when checking for deployment --- .github/workflows/check-finney.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/check-finney.yml b/.github/workflows/check-finney.yml index 3e9fb5994..6a51b3b0c 100644 --- a/.github/workflows/check-finney.yml +++ b/.github/workflows/check-finney.yml @@ -2,7 +2,7 @@ name: Finney Deploy Check on: pull_request: - branches: [finney, main] + branches: [finney, main, devnet-ready] env: CARGO_TERM_COLOR: always From 5d1e951ecb58d2f5084a0f380f0c96c407399f88 Mon Sep 17 00:00:00 2001 From: Keith Date: Wed, 14 Aug 2024 11:50:59 -0400 Subject: [PATCH 161/177] Check for devnet-ready as well --- .github/workflows/check-devnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/check-devnet.yml b/.github/workflows/check-devnet.yml index fcc9809d3..4396d8660 100644 --- a/.github/workflows/check-devnet.yml +++ b/.github/workflows/check-devnet.yml @@ -2,7 +2,7 @@ name: Devnet Deploy Check on: pull_request: - branches: [devnet] + branches: [devnet, devnet-ready] env: CARGO_TERM_COLOR: always From 9509ce9158f959a41610dc3ad13da0492600aaab Mon Sep 17 00:00:00 2001 From: Keith Date: Wed, 14 Aug 2024 12:03:41 -0400 Subject: [PATCH 162/177] Skip spec_version bump if 'no-spec-version-bump' label exists --- .github/workflows/check-devnet.yml | 1 + .github/workflows/check-finney.yml | 2 +- .github/workflows/check-testnet.yml | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/check-devnet.yml b/.github/workflows/check-devnet.yml index 4396d8660..bf8f89735 100644 --- a/.github/workflows/check-devnet.yml +++ b/.github/workflows/check-devnet.yml @@ -11,6 +11,7 @@ jobs: check-spec-version: name: Check spec_version bump runs-on: SubtensorCI + if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-spec-version-bump') }} steps: - name: Dependencies run: | diff --git a/.github/workflows/check-finney.yml b/.github/workflows/check-finney.yml index 6a51b3b0c..3e9fb5994 100644 --- a/.github/workflows/check-finney.yml +++ b/.github/workflows/check-finney.yml @@ -2,7 +2,7 @@ name: Finney Deploy Check on: pull_request: - branches: [finney, main, devnet-ready] + branches: [finney, main] env: CARGO_TERM_COLOR: always diff --git a/.github/workflows/check-testnet.yml b/.github/workflows/check-testnet.yml index 71c46557c..2978156b4 100644 --- a/.github/workflows/check-testnet.yml +++ b/.github/workflows/check-testnet.yml @@ -11,6 +11,7 @@ jobs: check-spec-version: name: Check spec_version bump runs-on: SubtensorCI + if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-spec-version-bump') }} steps: - name: Dependencies run: | From 9b0d246d7b91f3afcd52d12833ad6c3f537936b1 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Fri, 16 Aug 2024 10:45:36 -0400 Subject: [PATCH 163/177] switch localnet back to release --- scripts/localnet.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/localnet.sh b/scripts/localnet.sh index 4c15a3334..850a314d8 100755 --- a/scripts/localnet.sh +++ b/scripts/localnet.sh @@ -48,26 +48,26 @@ fi if [[ $BUILD_BINARY == "1" ]]; then echo "*** Building substrate binary..." - cargo build --workspace --profile=production --features "$FEATURES" --manifest-path "$BASE_DIR/Cargo.toml" + cargo build --workspace --profile=release --features "$FEATURES" --manifest-path "$BASE_DIR/Cargo.toml" echo "*** Binary compiled" fi echo "*** Building chainspec..." -"$BASE_DIR/target/production/node-subtensor" build-spec --disable-default-bootnode --raw --chain $CHAIN >$FULL_PATH +"$BASE_DIR/target/release/node-subtensor" build-spec --disable-default-bootnode --raw --chain $CHAIN >$FULL_PATH echo "*** Chainspec built and output to file" if [ $NO_PURGE -eq 1 ]; then echo "*** Purging previous state skipped..." else echo "*** Purging previous state..." - "$BASE_DIR/target/production/node-subtensor" purge-chain -y --base-path /tmp/bob --chain="$FULL_PATH" >/dev/null 2>&1 - "$BASE_DIR/target/production/node-subtensor" purge-chain -y --base-path /tmp/alice --chain="$FULL_PATH" >/dev/null 2>&1 + "$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=( - "$BASE_DIR/target/production/node-subtensor" + "$BASE_DIR/target/release/node-subtensor" --base-path /tmp/alice --chain="$FULL_PATH" --alice @@ -80,7 +80,7 @@ alice_start=( ) bob_start=( - "$BASE_DIR"/target/production/node-subtensor + "$BASE_DIR"/target/release/node-subtensor --base-path /tmp/bob --chain="$FULL_PATH" --bob From 6333edd31ced5b9cf02b3a3153e7dc62372253b8 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Fri, 16 Aug 2024 10:53:48 -0400 Subject: [PATCH 164/177] strip out DummyLint --- build.rs | 1 - support/linting/src/dummy_lint.rs | 11 ----------- support/linting/src/lib.rs | 2 -- 3 files changed, 14 deletions(-) delete mode 100644 support/linting/src/dummy_lint.rs diff --git a/build.rs b/build.rs index cc495ec13..10cac0ea7 100644 --- a/build.rs +++ b/build.rs @@ -59,7 +59,6 @@ fn main() { } }; - track_lint(DummyLint::lint(&parsed_file)); track_lint(RequireFreezeStruct::lint(&parsed_file)); }); diff --git a/support/linting/src/dummy_lint.rs b/support/linting/src/dummy_lint.rs deleted file mode 100644 index 1c5e7bc3f..000000000 --- a/support/linting/src/dummy_lint.rs +++ /dev/null @@ -1,11 +0,0 @@ -use syn::File; - -use super::*; - -pub struct DummyLint; - -impl Lint for DummyLint { - fn lint(_source: &File) -> Result { - Ok(()) - } -} diff --git a/support/linting/src/lib.rs b/support/linting/src/lib.rs index 0d0df8a44..d02a70a2b 100644 --- a/support/linting/src/lib.rs +++ b/support/linting/src/lib.rs @@ -1,8 +1,6 @@ pub mod lint; pub use lint::*; -mod dummy_lint; mod require_freeze_struct; -pub use dummy_lint::DummyLint; pub use require_freeze_struct::RequireFreezeStruct; From d6790a3972d3fe90fa5351e3c2483ba6da75ac70 Mon Sep 17 00:00:00 2001 From: Greg Zaitsev Date: Fri, 16 Aug 2024 12:03:03 -0400 Subject: [PATCH 165/177] Use passes_rate_limit_on_subnet for setting children --- pallets/subtensor/src/staking/set_children.rs | 4 ++-- pallets/subtensor/src/utils/rate_limiting.rs | 7 ++----- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/pallets/subtensor/src/staking/set_children.rs b/pallets/subtensor/src/staking/set_children.rs index ebd8db6bf..31bf96f52 100644 --- a/pallets/subtensor/src/staking/set_children.rs +++ b/pallets/subtensor/src/staking/set_children.rs @@ -60,10 +60,10 @@ impl Pallet { // Ensure the hotkey passes the rate limit. ensure!( - Self::passes_rate_limit_globally( + Self::passes_rate_limit_on_subnet( + &TransactionType::SetChildren, // Set children. &hotkey, // Specific to a hotkey. netuid, // Specific to a subnet. - &TransactionType::SetChildren, // Set children. ), Error::::TxRateLimitExceeded ); diff --git a/pallets/subtensor/src/utils/rate_limiting.rs b/pallets/subtensor/src/utils/rate_limiting.rs index 1b75de7d5..b02ad9855 100644 --- a/pallets/subtensor/src/utils/rate_limiting.rs +++ b/pallets/subtensor/src/utils/rate_limiting.rs @@ -58,11 +58,8 @@ impl Pallet { } /// Check if a transaction should be rate limited globally - pub fn passes_rate_limit_globally( - hotkey: &T::AccountId, - netuid: u16, - tx_type: &TransactionType, - ) -> bool { + 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); From f1866df8e497717c7e551944e1e3ded25ce0785e Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Fri, 9 Aug 2024 19:58:43 +0400 Subject: [PATCH 166/177] draft take tests --- pallets/subtensor/tests/children.rs | 303 ++++++++++++++++++++++++---- 1 file changed, 263 insertions(+), 40 deletions(-) diff --git a/pallets/subtensor/tests/children.rs b/pallets/subtensor/tests/children.rs index f491e8b64..f66c88441 100644 --- a/pallets/subtensor/tests/children.rs +++ b/pallets/subtensor/tests/children.rs @@ -421,8 +421,8 @@ fn test_get_stake_for_hotkey_on_subnet() { let parent_stake = SubtensorModule::get_stake_for_hotkey_on_subnet(&parent, netuid); let child_stake = SubtensorModule::get_stake_for_hotkey_on_subnet(&child, netuid); - println!("Parent stake: {}", parent_stake); - println!("Child stake: {}", child_stake); + log::info!("Parent stake: {}", parent_stake); + log::info!("Child stake: {}", child_stake); // The parent should have 0 stake as it's all allocated to the child assert_eq!(parent_stake, 0); @@ -2233,9 +2233,9 @@ fn test_parent_child_chain_emission() { let pending_emission_b = SubtensorModule::get_pending_hotkey_emission(&hotkey_b); let pending_emission_c = SubtensorModule::get_pending_hotkey_emission(&hotkey_c); - println!("Pending Emission for A: {:?}", pending_emission_a); - println!("Pending Emission for B: {:?}", pending_emission_b); - println!("Pending Emission for C: {:?}", pending_emission_c); + log::info!("Pending Emission for A: {:?}", pending_emission_a); + log::info!("Pending Emission for B: {:?}", pending_emission_b); + log::info!("Pending Emission for C: {:?}", pending_emission_c); // Assert that pending emissions are non-zero // A's pending emission: 2/3 of total emission (due to having 2/3 of total stake) @@ -2397,10 +2397,10 @@ fn test_dynamic_parent_child_relationships() { let child1_stake: u64 = SubtensorModule::get_stake_for_hotkey_on_subnet(&child1, netuid); let child2_stake: u64 = SubtensorModule::get_stake_for_hotkey_on_subnet(&child2, netuid); - println!("Final stakes:"); - println!("Parent stake: {}", parent_stake); - println!("Child1 stake: {}", child1_stake); - println!("Child2 stake: {}", child2_stake); + log::info!("Final stakes:"); + log::info!("Parent stake: {}", parent_stake); + log::info!("Child1 stake: {}", child1_stake); + log::info!("Child2 stake: {}", child2_stake); const TOLERANCE: u64 = 5; // Allow for a small discrepancy due to potential rounding @@ -2687,9 +2687,9 @@ fn test_get_stake_for_hotkey_on_subnet_single_parent_multiple_children() { assert_eq!(child2_stake, 999); // Log the actual stake values - println!("Parent stake: {}", parent_stake); - println!("Child1 stake: {}", child1_stake); - println!("Child2 stake: {}", child2_stake); + log::info!("Parent stake: {}", parent_stake); + log::info!("Child1 stake: {}", child1_stake); + log::info!("Child2 stake: {}", child2_stake); }); } @@ -2737,9 +2737,9 @@ fn test_get_stake_for_hotkey_on_subnet_edge_cases() { let child1_stake = SubtensorModule::get_stake_for_hotkey_on_subnet(&child1, netuid); let child2_stake = SubtensorModule::get_stake_for_hotkey_on_subnet(&child2, netuid); - println!("Parent stake: {}", parent_stake); - println!("Child1 stake: {}", child1_stake); - println!("Child2 stake: {}", child2_stake); + log::info!("Parent stake: {}", parent_stake); + log::info!("Child1 stake: {}", child1_stake); + log::info!("Child2 stake: {}", child2_stake); assert_eq!(parent_stake, 0, "Parent should have 0 stake"); assert_eq!(child1_stake, 0, "Child1 should have 0 stake"); @@ -2795,20 +2795,20 @@ fn test_get_stake_for_hotkey_on_subnet_complex_hierarchy() { total_stake, ); - println!("Initial stakes:"); - println!( + log::info!("Initial stakes:"); + log::info!( "Parent stake: {}", SubtensorModule::get_stake_for_hotkey_on_subnet(&parent, netuid) ); - println!( + log::info!( "Child1 stake: {}", SubtensorModule::get_stake_for_hotkey_on_subnet(&child1, netuid) ); - println!( + log::info!( "Child2 stake: {}", SubtensorModule::get_stake_for_hotkey_on_subnet(&child2, netuid) ); - println!( + log::info!( "Grandchild stake: {}", SubtensorModule::get_stake_for_hotkey_on_subnet(&grandchild, netuid) ); @@ -2821,16 +2821,16 @@ fn test_get_stake_for_hotkey_on_subnet_complex_hierarchy() { vec![(u64::MAX / 2, child1), (u64::MAX / 2, child2)] )); - println!("After setting parent's children:"); - println!( + log::info!("After setting parent's children:"); + log::info!( "Parent's children: {:?}", SubtensorModule::get_children(&parent, netuid) ); - println!( + log::info!( "Child1's parents: {:?}", SubtensorModule::get_parents(&child1, netuid) ); - println!( + log::info!( "Child2's parents: {:?}", SubtensorModule::get_parents(&child2, netuid) ); @@ -2839,9 +2839,9 @@ fn test_get_stake_for_hotkey_on_subnet_complex_hierarchy() { let child1_stake_1 = SubtensorModule::get_stake_for_hotkey_on_subnet(&child1, netuid); let child2_stake_1 = SubtensorModule::get_stake_for_hotkey_on_subnet(&child2, netuid); - println!("Parent stake: {}", parent_stake_1); - println!("Child1 stake: {}", child1_stake_1); - println!("Child2 stake: {}", child2_stake_1); + log::info!("Parent stake: {}", parent_stake_1); + log::info!("Child1 stake: {}", child1_stake_1); + log::info!("Child2 stake: {}", child2_stake_1); assert_eq!( parent_stake_1, 2, @@ -2858,12 +2858,12 @@ fn test_get_stake_for_hotkey_on_subnet_complex_hierarchy() { vec![(u64::MAX, grandchild)] )); - println!("After setting child1's children:"); - println!( + log::info!("After setting child1's children:"); + log::info!( "Child1's children: {:?}", SubtensorModule::get_children(&child1, netuid) ); - println!( + log::info!( "Grandchild's parents: {:?}", SubtensorModule::get_parents(&grandchild, netuid) ); @@ -2873,10 +2873,10 @@ fn test_get_stake_for_hotkey_on_subnet_complex_hierarchy() { let child2_stake_2 = SubtensorModule::get_stake_for_hotkey_on_subnet(&child2, netuid); let grandchild_stake = SubtensorModule::get_stake_for_hotkey_on_subnet(&grandchild, netuid); - println!("Parent stake: {}", parent_stake_2); - println!("Child1 stake: {}", child1_stake_2); - println!("Child2 stake: {}", child2_stake_2); - println!("Grandchild stake: {}", grandchild_stake); + log::info!("Parent stake: {}", parent_stake_2); + log::info!("Child1 stake: {}", child1_stake_2); + log::info!("Child2 stake: {}", child2_stake_2); + log::info!("Grandchild stake: {}", grandchild_stake); assert_eq!(parent_stake_2, 2, "Parent stake should remain 2"); assert_eq!( @@ -2897,24 +2897,24 @@ fn test_get_stake_for_hotkey_on_subnet_complex_hierarchy() { ); // Additional checks - println!("Final parent-child relationships:"); - println!( + log::info!("Final parent-child relationships:"); + log::info!( "Parent's children: {:?}", SubtensorModule::get_children(&parent, netuid) ); - println!( + log::info!( "Child1's parents: {:?}", SubtensorModule::get_parents(&child1, netuid) ); - println!( + log::info!( "Child2's parents: {:?}", SubtensorModule::get_parents(&child2, netuid) ); - println!( + log::info!( "Child1's children: {:?}", SubtensorModule::get_children(&child1, netuid) ); - println!( + log::info!( "Grandchild's parents: {:?}", SubtensorModule::get_parents(&grandchild, netuid) ); @@ -3237,3 +3237,226 @@ fn test_rank_trust_incentive_calculation_with_parent_child() { }); } + +/// Test normal operation of childkey take +/// +/// This test verifies the correct distribution of rewards between child and parents. +/// +/// # Test Steps: +/// 1. Initialize test environment with a child and multiple parents +/// 2. Set childkey take to 9% (4915 when normalized to u16::MAX) +/// 3. Set up network parameters and register all neurons +/// 4. Set initial stakes for all neurons +/// 5. Run an epoch and process emissions +/// 6. Calculate expected reward distribution +/// 7. Compare actual distribution with expected distribution +/// +/// # Expected Results: +/// - Child should keep 9% of the rewards +/// - Remaining 91% should be distributed among parents proportional to their stake +/// - Total distributed rewards should equal total emissions + +/// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test children -- test_normal_childkey_take_operation --exact --nocapture + +// #[test] +// fn test_normal_childkey_take_operation() { +// new_test_ext(1).execute_with(|| { +// let netuid: u16 = 1; +// let num_neurons: u16 = 5; + +// // Create hotkeys and coldkeys +// let child_coldkey = U256::from(100); +// let child_hotkey = U256::from(0); +// let parent_coldkey = U256::from(101); +// let parent_hotkey = U256::from(1); +// let validator_coldkeys: Vec = (102..105).map(U256::from).collect(); +// let validator_hotkeys: Vec = (2..5).map(U256::from).collect(); + +// // Set childkey take to 9% (4915 when normalized to u16::MAX) +// let childkey_take: u16 = 4915; + +// // Set up network parameters and register neurons +// add_network(netuid, num_neurons, 0); +// SubtensorModule::set_max_registrations_per_block(netuid, 1000); +// SubtensorModule::set_target_registrations_per_interval(netuid, 1000); +// SubtensorModule::set_weights_set_rate_limit(netuid, 0); +// SubtensorModule::set_hotkey_emission_tempo(10); + +// register_ok_neuron(netuid, child_hotkey, child_coldkey, 0); +// register_ok_neuron(netuid, parent_hotkey, parent_coldkey, 0); +// for (&hotkey, &coldkey) in validator_hotkeys.iter().zip(validator_coldkeys.iter()) { +// register_ok_neuron(netuid, hotkey, coldkey, 0); +// } + +// // Set initial stakes +// let child_stake: u64 = 1_000_000; +// let parent_stake: u64 = 2_000_000; +// let validator_stakes: Vec = vec![3_000_000, 4_000_000, 5_000_000]; + +// SubtensorModule::add_balance_to_coldkey_account(&child_coldkey, child_stake); +// SubtensorModule::increase_stake_on_coldkey_hotkey_account( +// &child_coldkey, +// &child_hotkey, +// child_stake, +// ); + +// SubtensorModule::add_balance_to_coldkey_account(&parent_coldkey, parent_stake); +// SubtensorModule::increase_stake_on_coldkey_hotkey_account( +// &parent_coldkey, +// &parent_hotkey, +// parent_stake, +// ); + +// for (i, (&hotkey, &coldkey)) in validator_hotkeys +// .iter() +// .zip(validator_coldkeys.iter()) +// .enumerate() +// { +// SubtensorModule::add_balance_to_coldkey_account(&coldkey, validator_stakes[i]); +// SubtensorModule::increase_stake_on_coldkey_hotkey_account( +// &coldkey, +// &hotkey, +// validator_stakes[i], +// ); +// } + +// // Set up parent-child relationship +// assert_ok!(SubtensorModule::do_set_children( +// RuntimeOrigin::signed(parent_coldkey), +// parent_hotkey, +// netuid, +// vec![(u64::MAX, child_hotkey)] +// )); + +// // Set childkey take +// assert_ok!(SubtensorModule::do_set_childkey_take( +// child_coldkey, +// child_hotkey, +// childkey_take, +// netuid +// )); + +// // Set weights +// let all_uids: Vec = (0..num_neurons).collect(); +// let weights: Vec = vec![u16::MAX / num_neurons; num_neurons as usize]; + +// step_block(2); // Step to ensure weights are set + +// for &hotkey in std::iter::once(&parent_hotkey).chain(validator_hotkeys.iter()) { +// assert_ok!(SubtensorModule::set_weights( +// RuntimeOrigin::signed(hotkey), +// netuid, +// all_uids.clone(), +// weights.clone(), +// 0 +// )); +// } + +// // Run epoch and process emissions +// let rao_emission: u64 = 1_000_000_000; +// let emission = SubtensorModule::epoch(netuid, rao_emission); + +// // Store initial stakes +// let initial_stakes: Vec = [child_hotkey, parent_hotkey] +// .iter() +// .chain(validator_hotkeys.iter()) +// .map(|&hotkey| SubtensorModule::get_stake_for_hotkey_on_subnet(&hotkey, netuid)) +// .collect(); + +// log::info!("Initial stakes:"); +// log::info!("Child: {}", initial_stakes[0]); +// log::info!("Parent: {}", initial_stakes[1]); +// for (i, &stake) in initial_stakes.iter().skip(2).enumerate() { +// log::info!("Validator {}: {}", i, stake); +// } + +// // Accumulate emissions +// for (hotkey, mining_emission, validator_emission) in emission { +// SubtensorModule::accumulate_hotkey_emission( +// &hotkey, +// netuid, +// validator_emission, +// mining_emission, +// ); +// } + +// // Check pending emissions before distribution +// log::info!("\nPending emissions before distribution:"); +// let pending_emissions: Vec = [child_hotkey, parent_hotkey] +// .iter() +// .chain(validator_hotkeys.iter()) +// .map(|&hotkey| SubtensorModule::get_pending_hotkey_emission(&hotkey)) +// .collect(); + +// log::info!("Child: {}", pending_emissions[0]); +// log::info!("Parent: {}", pending_emissions[1]); +// for (i, &emission) in pending_emissions.iter().skip(2).enumerate() { +// log::info!("Validator {}: {}", i, emission); +// } + +// let total_pending_emission: u64 = pending_emissions.iter().sum(); +// log::info!("Total pending emission: {}", total_pending_emission); + +// log::info!("\nChildkey take: {}", childkey_take); + +// // Step block to trigger emission distribution +// step_block(11); + +// // Calculate actual rewards +// let final_stakes: Vec = [child_hotkey, parent_hotkey] +// .iter() +// .chain(validator_hotkeys.iter()) +// .map(|&hotkey| SubtensorModule::get_stake_for_hotkey_on_subnet(&hotkey, netuid)) +// .collect(); + +// let rewards: Vec = final_stakes +// .iter() +// .zip(initial_stakes.iter()) +// .map(|(&final_stake, &initial_stake)| final_stake - initial_stake) +// .collect(); + +// log::info!("\nRewards:"); +// log::info!("Child reward: {}", rewards[0]); +// log::info!("Parent reward: {}", rewards[1]); +// for (i, &reward) in rewards.iter().skip(2).enumerate() { +// log::info!("Validator {} reward: {}", i, reward); +// } + +// // Verify total distributed rewards +// let total_distributed: u64 = rewards.iter().sum(); +// log::info!("\nTotal distributed: {}", total_distributed); +// log::info!("Total emission: {}", total_pending_emission); + +// assert!( +// (total_distributed as i64 - total_pending_emission as i64).abs() <= 10, +// "Total distributed rewards mismatch: distributed {} vs emission {}", +// total_distributed, +// total_pending_emission +// ); + +// // Check that PendingdHotkeyEmission is cleared after distribution +// for &hotkey in [child_hotkey, parent_hotkey] +// .iter() +// .chain(validator_hotkeys.iter()) +// { +// assert_eq!( +// SubtensorModule::get_pending_hotkey_emission(&hotkey), +// 0, +// "Pending emission not cleared for hotkey {:?}", +// hotkey +// ); +// } + +// // Verify childkey take +// let child_reward = rewards[0]; +// let expected_child_reward = +// (total_pending_emission as u128 * childkey_take as u128 / u16::MAX as u128) as u64; +// log::info!("\nExpected child reward: {}", expected_child_reward); +// assert!( +// (child_reward as i64 - expected_child_reward as i64).abs() <= 1, +// "Child reward mismatch: actual {} vs expected {}", +// child_reward, +// expected_child_reward +// ); +// }); +// } From aa1920127852a3966b0041e590126a6c39973adf Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Mon, 19 Aug 2024 07:22:56 +0400 Subject: [PATCH 167/177] chore: make rate limit prettier --- pallets/subtensor/src/staking/set_children.rs | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/pallets/subtensor/src/staking/set_children.rs b/pallets/subtensor/src/staking/set_children.rs index 31bf96f52..ab69c3438 100644 --- a/pallets/subtensor/src/staking/set_children.rs +++ b/pallets/subtensor/src/staking/set_children.rs @@ -246,23 +246,24 @@ impl Pallet { Error::::InvalidChildkeyTake ); - // Check if the rate limit has been exceeded - let current_block = Self::get_current_block_as_u64(); - let last_tx_block = - Self::get_last_transaction_block(&hotkey, netuid, &TransactionType::SetChildkeyTake); - let rate_limit = TxChildkeyTakeRateLimit::::get(); - let passes = - Self::passes_rate_limit_on_subnet(&TransactionType::SetChildkeyTake, &hotkey, netuid); - - log::info!( - "Rate limit check: current_block: {}, last_tx_block: {}, rate_limit: {}, passes: {}", - current_block, - last_tx_block, - rate_limit, - passes + // Ensure the hotkey passes the rate limit. + ensure!( + Self::passes_rate_limit_on_subnet( + &TransactionType::SetChildkeyTake, // Set childkey take. + &hotkey, // Specific to a hotkey. + netuid, // Specific to a subnet. + ), + Error::::TxChildkeyTakeRateLimitExceeded ); - ensure!(passes, Error::::TxChildkeyTakeRateLimitExceeded); + // Set last transaction block + let current_block = Self::get_current_block_as_u64(); + Self::set_last_transaction_block( + &hotkey, + netuid, + &TransactionType::SetChildkeyTake, + current_block + ); // Set the new childkey take value for the given hotkey and network ChildkeyTake::::insert(hotkey.clone(), netuid, take); From c68f4e466e19a2d44d43d72f919f10157f5a5b18 Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Mon, 19 Aug 2024 07:23:07 +0400 Subject: [PATCH 168/177] chore: remove commented test --- pallets/subtensor/tests/children.rs | 222 ---------------------------- 1 file changed, 222 deletions(-) diff --git a/pallets/subtensor/tests/children.rs b/pallets/subtensor/tests/children.rs index f66c88441..e5b5d080c 100644 --- a/pallets/subtensor/tests/children.rs +++ b/pallets/subtensor/tests/children.rs @@ -3238,225 +3238,3 @@ fn test_rank_trust_incentive_calculation_with_parent_child() { }); } -/// Test normal operation of childkey take -/// -/// This test verifies the correct distribution of rewards between child and parents. -/// -/// # Test Steps: -/// 1. Initialize test environment with a child and multiple parents -/// 2. Set childkey take to 9% (4915 when normalized to u16::MAX) -/// 3. Set up network parameters and register all neurons -/// 4. Set initial stakes for all neurons -/// 5. Run an epoch and process emissions -/// 6. Calculate expected reward distribution -/// 7. Compare actual distribution with expected distribution -/// -/// # Expected Results: -/// - Child should keep 9% of the rewards -/// - Remaining 91% should be distributed among parents proportional to their stake -/// - Total distributed rewards should equal total emissions - -/// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test children -- test_normal_childkey_take_operation --exact --nocapture - -// #[test] -// fn test_normal_childkey_take_operation() { -// new_test_ext(1).execute_with(|| { -// let netuid: u16 = 1; -// let num_neurons: u16 = 5; - -// // Create hotkeys and coldkeys -// let child_coldkey = U256::from(100); -// let child_hotkey = U256::from(0); -// let parent_coldkey = U256::from(101); -// let parent_hotkey = U256::from(1); -// let validator_coldkeys: Vec = (102..105).map(U256::from).collect(); -// let validator_hotkeys: Vec = (2..5).map(U256::from).collect(); - -// // Set childkey take to 9% (4915 when normalized to u16::MAX) -// let childkey_take: u16 = 4915; - -// // Set up network parameters and register neurons -// add_network(netuid, num_neurons, 0); -// SubtensorModule::set_max_registrations_per_block(netuid, 1000); -// SubtensorModule::set_target_registrations_per_interval(netuid, 1000); -// SubtensorModule::set_weights_set_rate_limit(netuid, 0); -// SubtensorModule::set_hotkey_emission_tempo(10); - -// register_ok_neuron(netuid, child_hotkey, child_coldkey, 0); -// register_ok_neuron(netuid, parent_hotkey, parent_coldkey, 0); -// for (&hotkey, &coldkey) in validator_hotkeys.iter().zip(validator_coldkeys.iter()) { -// register_ok_neuron(netuid, hotkey, coldkey, 0); -// } - -// // Set initial stakes -// let child_stake: u64 = 1_000_000; -// let parent_stake: u64 = 2_000_000; -// let validator_stakes: Vec = vec![3_000_000, 4_000_000, 5_000_000]; - -// SubtensorModule::add_balance_to_coldkey_account(&child_coldkey, child_stake); -// SubtensorModule::increase_stake_on_coldkey_hotkey_account( -// &child_coldkey, -// &child_hotkey, -// child_stake, -// ); - -// SubtensorModule::add_balance_to_coldkey_account(&parent_coldkey, parent_stake); -// SubtensorModule::increase_stake_on_coldkey_hotkey_account( -// &parent_coldkey, -// &parent_hotkey, -// parent_stake, -// ); - -// for (i, (&hotkey, &coldkey)) in validator_hotkeys -// .iter() -// .zip(validator_coldkeys.iter()) -// .enumerate() -// { -// SubtensorModule::add_balance_to_coldkey_account(&coldkey, validator_stakes[i]); -// SubtensorModule::increase_stake_on_coldkey_hotkey_account( -// &coldkey, -// &hotkey, -// validator_stakes[i], -// ); -// } - -// // Set up parent-child relationship -// assert_ok!(SubtensorModule::do_set_children( -// RuntimeOrigin::signed(parent_coldkey), -// parent_hotkey, -// netuid, -// vec![(u64::MAX, child_hotkey)] -// )); - -// // Set childkey take -// assert_ok!(SubtensorModule::do_set_childkey_take( -// child_coldkey, -// child_hotkey, -// childkey_take, -// netuid -// )); - -// // Set weights -// let all_uids: Vec = (0..num_neurons).collect(); -// let weights: Vec = vec![u16::MAX / num_neurons; num_neurons as usize]; - -// step_block(2); // Step to ensure weights are set - -// for &hotkey in std::iter::once(&parent_hotkey).chain(validator_hotkeys.iter()) { -// assert_ok!(SubtensorModule::set_weights( -// RuntimeOrigin::signed(hotkey), -// netuid, -// all_uids.clone(), -// weights.clone(), -// 0 -// )); -// } - -// // Run epoch and process emissions -// let rao_emission: u64 = 1_000_000_000; -// let emission = SubtensorModule::epoch(netuid, rao_emission); - -// // Store initial stakes -// let initial_stakes: Vec = [child_hotkey, parent_hotkey] -// .iter() -// .chain(validator_hotkeys.iter()) -// .map(|&hotkey| SubtensorModule::get_stake_for_hotkey_on_subnet(&hotkey, netuid)) -// .collect(); - -// log::info!("Initial stakes:"); -// log::info!("Child: {}", initial_stakes[0]); -// log::info!("Parent: {}", initial_stakes[1]); -// for (i, &stake) in initial_stakes.iter().skip(2).enumerate() { -// log::info!("Validator {}: {}", i, stake); -// } - -// // Accumulate emissions -// for (hotkey, mining_emission, validator_emission) in emission { -// SubtensorModule::accumulate_hotkey_emission( -// &hotkey, -// netuid, -// validator_emission, -// mining_emission, -// ); -// } - -// // Check pending emissions before distribution -// log::info!("\nPending emissions before distribution:"); -// let pending_emissions: Vec = [child_hotkey, parent_hotkey] -// .iter() -// .chain(validator_hotkeys.iter()) -// .map(|&hotkey| SubtensorModule::get_pending_hotkey_emission(&hotkey)) -// .collect(); - -// log::info!("Child: {}", pending_emissions[0]); -// log::info!("Parent: {}", pending_emissions[1]); -// for (i, &emission) in pending_emissions.iter().skip(2).enumerate() { -// log::info!("Validator {}: {}", i, emission); -// } - -// let total_pending_emission: u64 = pending_emissions.iter().sum(); -// log::info!("Total pending emission: {}", total_pending_emission); - -// log::info!("\nChildkey take: {}", childkey_take); - -// // Step block to trigger emission distribution -// step_block(11); - -// // Calculate actual rewards -// let final_stakes: Vec = [child_hotkey, parent_hotkey] -// .iter() -// .chain(validator_hotkeys.iter()) -// .map(|&hotkey| SubtensorModule::get_stake_for_hotkey_on_subnet(&hotkey, netuid)) -// .collect(); - -// let rewards: Vec = final_stakes -// .iter() -// .zip(initial_stakes.iter()) -// .map(|(&final_stake, &initial_stake)| final_stake - initial_stake) -// .collect(); - -// log::info!("\nRewards:"); -// log::info!("Child reward: {}", rewards[0]); -// log::info!("Parent reward: {}", rewards[1]); -// for (i, &reward) in rewards.iter().skip(2).enumerate() { -// log::info!("Validator {} reward: {}", i, reward); -// } - -// // Verify total distributed rewards -// let total_distributed: u64 = rewards.iter().sum(); -// log::info!("\nTotal distributed: {}", total_distributed); -// log::info!("Total emission: {}", total_pending_emission); - -// assert!( -// (total_distributed as i64 - total_pending_emission as i64).abs() <= 10, -// "Total distributed rewards mismatch: distributed {} vs emission {}", -// total_distributed, -// total_pending_emission -// ); - -// // Check that PendingdHotkeyEmission is cleared after distribution -// for &hotkey in [child_hotkey, parent_hotkey] -// .iter() -// .chain(validator_hotkeys.iter()) -// { -// assert_eq!( -// SubtensorModule::get_pending_hotkey_emission(&hotkey), -// 0, -// "Pending emission not cleared for hotkey {:?}", -// hotkey -// ); -// } - -// // Verify childkey take -// let child_reward = rewards[0]; -// let expected_child_reward = -// (total_pending_emission as u128 * childkey_take as u128 / u16::MAX as u128) as u64; -// log::info!("\nExpected child reward: {}", expected_child_reward); -// assert!( -// (child_reward as i64 - expected_child_reward as i64).abs() <= 1, -// "Child reward mismatch: actual {} vs expected {}", -// child_reward, -// expected_child_reward -// ); -// }); -// } From dc67f8fbfd0d4fb7035adc1d1e80408283d44d9e Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Mon, 19 Aug 2024 07:28:41 +0400 Subject: [PATCH 169/177] chore: fmt --- pallets/subtensor/src/staking/set_children.rs | 4 ++-- pallets/subtensor/tests/children.rs | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/pallets/subtensor/src/staking/set_children.rs b/pallets/subtensor/src/staking/set_children.rs index ab69c3438..9029d58ca 100644 --- a/pallets/subtensor/src/staking/set_children.rs +++ b/pallets/subtensor/src/staking/set_children.rs @@ -74,7 +74,7 @@ impl Pallet { &hotkey, netuid, &TransactionType::SetChildren, - current_block + current_block, ); // --- 2. Check that this delegation is not on the root network. Child hotkeys are not valid on root. @@ -262,7 +262,7 @@ impl Pallet { &hotkey, netuid, &TransactionType::SetChildkeyTake, - current_block + current_block, ); // Set the new childkey take value for the given hotkey and network diff --git a/pallets/subtensor/tests/children.rs b/pallets/subtensor/tests/children.rs index e5b5d080c..f36c21521 100644 --- a/pallets/subtensor/tests/children.rs +++ b/pallets/subtensor/tests/children.rs @@ -3237,4 +3237,3 @@ fn test_rank_trust_incentive_calculation_with_parent_child() { }); } - From 74fcd80bf535b51ef2b8851d57a7d45a32cc46f8 Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Mon, 19 Aug 2024 08:12:14 +0400 Subject: [PATCH 170/177] chore: tidy --- pallets/subtensor/src/swap/swap_coldkey.rs | 8 -------- runtime/src/lib.rs | 4 ---- 2 files changed, 12 deletions(-) diff --git a/pallets/subtensor/src/swap/swap_coldkey.rs b/pallets/subtensor/src/swap/swap_coldkey.rs index 5b02d49b5..498549e5c 100644 --- a/pallets/subtensor/src/swap/swap_coldkey.rs +++ b/pallets/subtensor/src/swap/swap_coldkey.rs @@ -49,14 +49,6 @@ impl Pallet { ); weight = weight.saturating_add(T::DbWeight::get().reads(1)); - // TODO: Consider adding a check to ensure the new coldkey is not in arbitration - // ensure!( - // !Self::coldkey_in_arbitration(new_coldkey), - // Error::::NewColdkeyIsInArbitration - // ); - - // Note: We might want to add a cooldown period for coldkey swaps to prevent abuse - // 5. Calculate the swap cost and ensure sufficient balance let swap_cost = Self::get_key_swap_cost(); ensure!( diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 20d565f9a..f644d8a2a 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -97,10 +97,6 @@ type MemberCount = u32; pub type Nonce = u32; -/// The scheduler type used for scheduling delayed calls. -// With something like this: -// type Scheduler = pallet_subtensor::Scheduler; - // Method used to calculate the fee of an extrinsic pub const fn deposit(items: u32, bytes: u32) -> Balance { pub const ITEMS_FEE: Balance = 2_000 * 10_000; From ff87b7b541809273bcb5822d47ededd7ad7d7958 Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Mon, 19 Aug 2024 08:35:49 +0400 Subject: [PATCH 171/177] chore: use forked substrate fixed --- Cargo.lock | 2 +- Cargo.toml | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 350831723..f444c9ba9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9115,7 +9115,7 @@ source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=v1.10.0-rc3#8d2 [[package]] name = "substrate-fixed" version = "0.5.9" -source = "git+https://github.com/encointer/substrate-fixed.git?tag=v0.5.9#a4fb461aae6205ffc55bed51254a40c52be04e5d" +source = "git+https://github.com/opentensor/substrate-fixed.git?tag=v0.5.9#a4fb461aae6205ffc55bed51254a40c52be04e5d" dependencies = [ "parity-scale-codec", "scale-info", diff --git a/Cargo.toml b/Cargo.toml index 36a87755b..622570dc2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -66,7 +66,13 @@ serde_json = { version = "1.0.116", default-features = false } serde_with = { version = "=2.0.0", default-features = false } smallvec = "1.13.2" litep2p = { git = "https://github.com/paritytech/litep2p", branch = "master" } -syn = { version = "2", features = ["full", "visit-mut", "visit", "extra-traits", "parsing"] } +syn = { version = "2", features = [ + "full", + "visit-mut", + "visit", + "extra-traits", + "parsing", +] } quote = "1" proc-macro2 = { version = "1", features = ["span-locations"] } walkdir = "2" @@ -76,7 +82,7 @@ subtensor-macros = { path = "support/macros" } 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-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 } @@ -145,7 +151,7 @@ sp-version = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "v1 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-rc3" } -substrate-fixed = { git = "https://github.com/encointer/substrate-fixed.git", tag = "v0.5.9" } +substrate-fixed = { git = "https://github.com/opentensor/substrate-fixed.git", tag = "v0.5.9" } 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" From 8ab4573e79a18f39f7c5251e11c67a6504e7c2b6 Mon Sep 17 00:00:00 2001 From: open-junius Date: Mon, 19 Aug 2024 13:14:51 +0800 Subject: [PATCH 172/177] clean code and fix a bug --- pallets/subtensor/src/macros/dispatches.rs | 31 -- pallets/subtensor/tests/networks.rs | 409 --------------------- 2 files changed, 440 deletions(-) diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 112ef10b5..21668c922 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -687,36 +687,6 @@ mod dispatches { Self::do_swap_coldkey(&old_coldkey, &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 { - Ok(()) - } - // ---- SUDO ONLY FUNCTIONS ------------------------------------------------------------ // ================================== @@ -1032,7 +1002,6 @@ mod dispatches { ) .map_err(|_| Error::::FailedToSchedule)?; - ColdkeySwapScheduled::::insert(&who, ()); // Emit the SwapScheduled event Self::deposit_event(Event::DissolveNetworkScheduled { account: who.clone(), diff --git a/pallets/subtensor/tests/networks.rs b/pallets/subtensor/tests/networks.rs index 1929ff543..b41ff985d 100644 --- a/pallets/subtensor/tests/networks.rs +++ b/pallets/subtensor/tests/networks.rs @@ -94,412 +94,3 @@ fn test_schedule_dissolve_network_execution() { assert!(!SubtensorModule::if_subnet_exist(netuid)); }) } - -// #[allow(dead_code)] -// fn record(event: RuntimeEvent) -> EventRecord { -// EventRecord { -// phase: Phase::Initialization, -// event, -// topics: vec![], -// } -// } - -// /*TO DO SAM: write test for LatuUpdate after it is set */ -// // --- add network tests ---- -// #[test] -// fn test_add_network_dispatch_info_ok() { -// new_test_ext().execute_with(|| { -// let netuid: u16 = 1; -// let modality = 0; -// let tempo: u16 = 13; -// let call = RuntimeCall::SubtensorModule(SubtensorCall::sudo_add_network { -// netuid, -// tempo, -// modality, -// }); -// assert_eq!( -// call.get_dispatch_info(), -// DispatchInfo { -// weight: frame_support::weights::Weight::from_parts(50000000, 0), -// class: DispatchClass::Operational, -// pays_fee: Pays::No -// } -// ); -// }); -// } - -// #[test] -// fn test_add_network() { -// new_test_ext().execute_with(|| { -// let modality = 0; -// let tempo: u16 = 13; -// add_network(10, tempo, modality); -// assert_eq!(SubtensorModule::get_number_of_subnets(), 1); -// add_network(20, tempo, modality); -// assert_eq!(SubtensorModule::get_number_of_subnets(), 2); -// }); -// } - -// #[test] -// fn test_add_network_check_tempo() { -// new_test_ext().execute_with(|| { -// let modality = 0; -// let tempo: u16 = 13; -// assert_eq!(SubtensorModule::get_tempo(1), 0); -// add_network(1, tempo, modality); -// assert_eq!(SubtensorModule::get_tempo(1), 13); -// }); -// } - -// #[test] -// fn test_clear_min_allowed_weight_for_network() { -// new_test_ext().execute_with(|| { -// let netuid: u16 = 1; -// let min_allowed_weight = 2; -// let tempo: u16 = 13; -// add_network(netuid, tempo, 0); -// register_ok_neuron(1, U256::from(55), U256::from(66), 0); -// SubtensorModule::set_min_allowed_weights(netuid, min_allowed_weight); -// assert_eq!(SubtensorModule::get_min_allowed_weights(netuid), 2); -// assert_ok!(SubtensorModule::do_remove_network( -// <::RuntimeOrigin>::root(), -// netuid -// )); -// assert_eq!(SubtensorModule::get_min_allowed_weights(netuid), 0); -// }); -// } - -// #[test] -// fn test_remove_uid_for_network() { -// new_test_ext().execute_with(|| { -// let netuid: u16 = 1; -// let tempo: u16 = 13; -// add_network(netuid, tempo, 0); -// register_ok_neuron(1, U256::from(55), U256::from(66), 0); -// let neuron_id; -// match SubtensorModule::get_uid_for_net_and_hotkey(netuid, &U256::from(55)) { -// Ok(k) => neuron_id = k, -// Err(e) => panic!("Error: {:?}", e), -// } -// assert!(SubtensorModule::get_uid_for_net_and_hotkey(netuid, &U256::from(55)).is_ok()); -// assert_eq!(neuron_id, 0); -// register_ok_neuron(1, U256::from(56), U256::from(67), 300000); -// let neuron_uid = -// SubtensorModule::get_uid_for_net_and_hotkey(netuid, &U256::from(56)).unwrap(); -// assert_eq!(neuron_uid, 1); -// assert_ok!(SubtensorModule::do_remove_network( -// <::RuntimeOrigin>::root(), -// netuid -// )); -// assert!(SubtensorModule::get_uid_for_net_and_hotkey(netuid, &U256::from(55)).is_err()); -// }); -// } - -// #[test] -// fn test_remove_difficulty_for_network() { -// new_test_ext().execute_with(|| { -// let netuid: u16 = 1; -// let difficulty: u64 = 10; -// let tempo: u16 = 13; -// add_network(netuid, tempo, 0); -// register_ok_neuron(1, U256::from(55), U256::from(66), 0); -// assert_ok!(SubtensorModule::sudo_set_difficulty( -// <::RuntimeOrigin>::root(), -// netuid, -// difficulty -// )); -// assert_eq!(SubtensorModule::get_difficulty_as_u64(netuid), difficulty); -// assert_ok!(SubtensorModule::do_remove_network( -// <::RuntimeOrigin>::root(), -// netuid -// )); -// assert_eq!(SubtensorModule::get_difficulty_as_u64(netuid), 10000); -// }); -// } - -// #[test] -// fn test_remove_network_for_all_hotkeys() { -// new_test_ext().execute_with(|| { -// let netuid: u16 = 1; -// let tempo: u16 = 13; -// add_network(netuid, tempo, 0); -// register_ok_neuron(1, U256::from(55), U256::from(66), 0); -// register_ok_neuron(1, U256::from(77), U256::from(88), 65536); -// assert_eq!(SubtensorModule::get_subnetwork_n(netuid), 2); -// assert_ok!(SubtensorModule::do_remove_network( -// <::RuntimeOrigin>::root(), -// netuid -// )); -// assert_eq!(SubtensorModule::get_subnetwork_n(netuid), 0); -// }); -// } - -// #[test] -// fn test_network_set_default_value_for_other_parameters() { -// new_test_ext().execute_with(|| { -// let netuid: u16 = 1; -// let tempo: u16 = 13; -// add_network(netuid, tempo, 0); -// assert_eq!(SubtensorModule::get_min_allowed_weights(netuid), 0); -// assert_eq!(SubtensorModule::get_emission_value(netuid), 0); -// assert_eq!(SubtensorModule::get_max_weight_limit(netuid), u16::MAX); -// assert_eq!(SubtensorModule::get_difficulty_as_u64(netuid), 10000); -// assert_eq!(SubtensorModule::get_immunity_period(netuid), 2); -// }); -// } - -// // --- Set Emission Ratios Tests -// #[test] -// fn test_network_set_emission_ratios_dispatch_info_ok() { -// new_test_ext().execute_with(|| { -// let netuids: Vec = vec![1, 2]; -// let emission: Vec = vec![100000000, 900000000]; -// let call = RuntimeCall::SubtensorModule(SubtensorCall::sudo_set_emission_values { -// netuids, -// emission, -// }); -// assert_eq!( -// call.get_dispatch_info(), -// DispatchInfo { -// weight: frame_support::weights::Weight::from_parts(28000000, 0), -// class: DispatchClass::Operational, -// pays_fee: Pays::No -// } -// ); -// }); -// } - -// #[test] -// fn test_network_set_emission_ratios_ok() { -// new_test_ext().execute_with(|| { -// let netuids: Vec = vec![1, 2]; -// let emission: Vec = vec![100000000, 900000000]; -// add_network(1, 0, 0); -// add_network(2, 0, 0); -// assert_ok!(SubtensorModule::sudo_set_emission_values( -// <::RuntimeOrigin>::root(), -// netuids, -// emission -// )); -// }); -// } - -// #[test] -// fn test_network_set_emission_ratios_fail_summation() { -// new_test_ext().execute_with(|| { -// let netuids: Vec = vec![1, 2]; -// let emission: Vec = vec![100000000, 910000000]; -// add_network(1, 0, 0); -// add_network(2, 0, 0); -// assert_eq!( -// SubtensorModule::sudo_set_emission_values( -// <::RuntimeOrigin>::root(), -// netuids, -// emission -// ), -// Err(Error::::InvalidEmissionValues.into()) -// ); -// }); -// } - -// #[test] -// fn test_network_set_emission_invalid_netuids() { -// new_test_ext().execute_with(|| { -// let netuids: Vec = vec![1, 2]; -// let emission: Vec = vec![100000000, 900000000]; -// add_network(1, 0, 0); -// assert_eq!( -// SubtensorModule::sudo_set_emission_values( -// <::RuntimeOrigin>::root(), -// netuids, -// emission -// ), -// Err(Error::::IncorrectNetuidsLength.into()) -// ); -// }); -// } - -// #[test] -// fn test_network_set_emission_ratios_fail_net() { -// new_test_ext().execute_with(|| { -// let netuids: Vec = vec![1, 2]; -// let emission: Vec = vec![100000000, 900000000]; -// add_network(1, 0, 0); -// add_network(3, 0, 0); -// assert_eq!( -// SubtensorModule::sudo_set_emission_values( -// <::RuntimeOrigin>::root(), -// netuids, -// emission -// ), -// Err(Error::::UidVecContainInvalidOne.into()) -// ); -// }); -// } - -// #[test] -// fn test_add_difficulty_fail() { -// new_test_ext().execute_with(|| { -// let netuid: u16 = 1; -// assert_eq!( -// SubtensorModule::sudo_set_difficulty( -// <::RuntimeOrigin>::root(), -// netuid, -// 120000 -// ), -// Err(Error::::NetworkDoesNotExist.into()) -// ); -// }); -// } - -// #[test] -// fn test_multi_tempo_with_emission() { -// new_test_ext().execute_with(|| { -// let netuid: u16 = 1; -// assert_eq!( -// SubtensorModule::sudo_set_difficulty( -// <::RuntimeOrigin>::root(), -// netuid, -// 120000 -// ), -// Err(Error::::NetworkDoesNotExist.into()) -// ); -// }); -// } - -// #[test] -// // Required by the test otherwise it would panic if compiled in debug mode -// #[allow(arithmetic_overflow)] -// fn test_set_emission_values_errors_on_emission_sum_overflow() { -// new_test_ext().execute_with(|| { -// let netuids: Vec = vec![1, 2]; -// // u64(u64::MAX + 1..000..1) equals to 1_000_000_000 which is the same as -// // the value of Self::get_block_emission() expected by the extrinsic -// let emission: Vec = vec![u64::MAX, 1_000_000_001]; -// add_network(1, 0, 0); -// add_network(2, 0, 0); -// assert_eq!( -// SubtensorModule::sudo_set_emission_values( -// <::RuntimeOrigin>::root(), -// netuids, -// emission -// ), -// Err(Error::::InvalidEmissionValues.into()) -// ); -// }); -// } - -// #[test] -// #[allow(arithmetic_overflow)] -// fn test_set_emission_values_no_errors() { -// new_test_ext().execute_with(|| { -// let netuids: Vec = vec![1, 2]; -// let emission: Vec = vec![600_000_000, 400_000_000]; - -// add_network(1, 0, 0); -// add_network(2, 0, 0); -// assert_eq!( -// SubtensorModule::sudo_set_emission_values( -// <::RuntimeOrigin>::root(), -// netuids, -// emission -// ), -// Ok(()) -// ); -// }); -// } - -// #[test] -// // Required by the test otherwise it would panic if compiled in debug mode -// #[allow(arithmetic_overflow)] -// fn test_set_emission_values_sum_too_large() { -// new_test_ext().execute_with(|| { -// let netuids: Vec = vec![1, 2]; -// // u64(1_000_000_000 + 1) equals to 1_000_000_001 which is more than -// // the value of Self::get_block_emission() expected by the extrinsic -// let emission: Vec = vec![1_000_000_000, 1]; -// add_network(1, 0, 0); -// add_network(2, 0, 0); -// assert_eq!( -// SubtensorModule::sudo_set_emission_values( -// <::RuntimeOrigin>::root(), -// netuids, -// emission -// ), -// Err(Error::::InvalidEmissionValues.into()) -// ); -// }); -// } - -// #[test] -// // Required by the test otherwise it would panic if compiled in debug mode -// #[allow(arithmetic_overflow)] -// fn test_set_emission_values_sum_too_small() { -// new_test_ext().execute_with(|| { -// let netuids: Vec = vec![1, 2]; -// // u64(1 + 2_000) equals to 2_001 which is LESS than -// // the value of Self::get_block_emission() expected by the extrinsic -// let emission: Vec = vec![1, 2_000]; -// add_network(1, 0, 0); -// add_network(2, 0, 0); -// assert_eq!( -// SubtensorModule::sudo_set_emission_values( -// <::RuntimeOrigin>::root(), -// netuids, -// emission -// ), -// Err(Error::::InvalidEmissionValues.into()) -// ); -// }); -// } - -// #[test] -// fn test_set_emission_values_too_many_netuids() { -// new_test_ext().execute_with(|| { -// let netuids: Vec = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; - -// // Sums to 1_000_000_000 and has 10 elements -// let emission: Vec = vec![1_000_000_000, 0, 0, 0, 0, 0, 0, 0, 0, 0]; -// add_network(1, 0, 0); -// add_network(2, 0, 0); -// // We only add 2 networks, so this should fail -// assert_eq!( -// SubtensorModule::sudo_set_emission_values( -// <::RuntimeOrigin>::root(), -// netuids, -// emission -// ), -// Err(Error::::IncorrectNetuidsLength.into()) -// ); -// }); -// } - -// #[test] -// fn test_set_emission_values_over_u16_max_values() { -// new_test_ext().execute_with(|| { -// // Make vec of u16 with length 2^16 + 2 -// let netuids: Vec = vec![0; 0x10002]; -// // This is greater than u16::MAX -// assert!(netuids.len() > u16::MAX as usize); -// // On cast to u16, this will be 2 -// assert!(netuids.len() as u16 == 2); - -// // Sums to 1_000_000_000 and the length is 65536 -// let mut emission: Vec = vec![0; netuids.len()]; -// emission[0] = 1_000_000_000; - -// add_network(1, 0, 0); -// add_network(2, 0, 0); -// // We only add 2 networks, so this should fail -// // but if we cast to u16 during length comparison, -// // the length will be 2 and the check will pass -// assert_eq!( -// SubtensorModule::sudo_set_emission_values( -// <::RuntimeOrigin>::root(), -// netuids, -// emission -// ), -// Err(Error::::IncorrectNetuidsLength.into()) -// ); -// }); -// } From e2f372bc33ec9b4b7a1c9ee69cccd542739abc09 Mon Sep 17 00:00:00 2001 From: open-junius Date: Mon, 19 Aug 2024 13:37:45 +0800 Subject: [PATCH 173/177] remove unused dispatch --- pallets/subtensor/src/macros/dispatches.rs | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 21668c922..b1eda9ea6 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -811,17 +811,6 @@ mod dispatches { 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(()) - } - /// 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. From 9cbc5a21469213bd4cd66223b57a2d3e518ab801 Mon Sep 17 00:00:00 2001 From: Keith Date: Mon, 19 Aug 2024 09:55:49 -0400 Subject: [PATCH 174/177] Fix merge conflict --- pallets/admin-utils/src/benchmarking.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pallets/admin-utils/src/benchmarking.rs b/pallets/admin-utils/src/benchmarking.rs index 46b42fbc9..3f221fd30 100644 --- a/pallets/admin-utils/src/benchmarking.rs +++ b/pallets/admin-utils/src/benchmarking.rs @@ -251,7 +251,7 @@ mod benchmarks { #[benchmark] fn sudo_set_hotkey_emission_tempo() { - T::Subtensor::init_new_network(1u16 /*netuid*/, 1u16 /*sudo_tempo*/); + pallet_subtensor::Pallet::::init_new_network(1u16 /*netuid*/, 1u16 /*sudo_tempo*/); #[extrinsic_call] _(RawOrigin::Root, 1u64/*emission_tempo*/)/*set_hotkey_emission_tempo*/; @@ -259,7 +259,7 @@ mod benchmarks { #[benchmark] fn sudo_set_network_max_stake() { - T::Subtensor::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/); + pallet_subtensor::Pallet::::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/); #[extrinsic_call] _(RawOrigin::Root, 1u16/*netuid*/, 1_000_000_000_000_000u64/*max_stake*/)/*sudo_set_network_max_stake*/; From bb66f09f38a3fb4d0a06906c53b833cb3057f392 Mon Sep 17 00:00:00 2001 From: Keith Date: Mon, 19 Aug 2024 10:01:03 -0400 Subject: [PATCH 175/177] cargo fmt --- pallets/admin-utils/src/benchmarking.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pallets/admin-utils/src/benchmarking.rs b/pallets/admin-utils/src/benchmarking.rs index 3f221fd30..7515525f0 100644 --- a/pallets/admin-utils/src/benchmarking.rs +++ b/pallets/admin-utils/src/benchmarking.rs @@ -251,7 +251,10 @@ mod benchmarks { #[benchmark] fn sudo_set_hotkey_emission_tempo() { - pallet_subtensor::Pallet::::init_new_network(1u16 /*netuid*/, 1u16 /*sudo_tempo*/); + pallet_subtensor::Pallet::::init_new_network( + 1u16, /*netuid*/ + 1u16, /*sudo_tempo*/ + ); #[extrinsic_call] _(RawOrigin::Root, 1u64/*emission_tempo*/)/*set_hotkey_emission_tempo*/; From 90477819b500433e0ceb5feb7816b8644fe1661b Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Mon, 19 Aug 2024 21:49:01 +0400 Subject: [PATCH 176/177] chore: max childkey take --- pallets/admin-utils/tests/mock.rs | 2 ++ pallets/subtensor/src/macros/config.rs | 3 +++ pallets/subtensor/tests/mock.rs | 6 ++++-- runtime/src/lib.rs | 2 ++ 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/pallets/admin-utils/tests/mock.rs b/pallets/admin-utils/tests/mock.rs index 688d666be..24475a8c6 100644 --- a/pallets/admin-utils/tests/mock.rs +++ b/pallets/admin-utils/tests/mock.rs @@ -81,6 +81,7 @@ parameter_types! { pub const InitialMinDelegateTake: u16 = 5_898; // 9%; pub const InitialDefaultChildKeyTake: u16 = 0; // Allow 0 % pub const InitialMinChildKeyTake: u16 = 0; // Allow 0 % + pub const InitialMaxChildKeyTake: u16 = 11_796; // 18 %; pub const InitialWeightsVersionKey: u16 = 0; pub const InitialServingRateLimit: u64 = 0; // No limit. pub const InitialTxRateLimit: u64 = 0; // Disable rate limit for testing @@ -153,6 +154,7 @@ impl pallet_subtensor::Config for Test { type InitialMinDelegateTake = InitialMinDelegateTake; type InitialDefaultChildKeyTake = InitialDefaultChildKeyTake; type InitialMinChildKeyTake = InitialMinChildKeyTake; + type InitialMaxChildKeyTake = InitialMaxChildKeyTake; type InitialWeightsVersionKey = InitialWeightsVersionKey; type InitialMaxDifficulty = InitialMaxDifficulty; type InitialMinDifficulty = InitialMinDifficulty; diff --git a/pallets/subtensor/src/macros/config.rs b/pallets/subtensor/src/macros/config.rs index 2a6d8db00..5b2d0f25e 100644 --- a/pallets/subtensor/src/macros/config.rs +++ b/pallets/subtensor/src/macros/config.rs @@ -122,6 +122,9 @@ mod config { /// Initial minimum childkey take. #[pallet::constant] type InitialMinChildKeyTake: Get; + /// Initial maximum childkey take. + #[pallet::constant] + type InitialMaxChildKeyTake: Get; /// Initial weights version key. #[pallet::constant] type InitialWeightsVersionKey: Get; diff --git a/pallets/subtensor/tests/mock.rs b/pallets/subtensor/tests/mock.rs index 022849c56..6785bdb02 100644 --- a/pallets/subtensor/tests/mock.rs +++ b/pallets/subtensor/tests/mock.rs @@ -133,8 +133,9 @@ parameter_types! { pub const InitialFoundationDistribution: u64 = 0; pub const InitialDefaultDelegateTake: u16 = 11_796; // 18%, same as in production pub const InitialMinDelegateTake: u16 = 5_898; // 9%; - pub const InitialDefaultChildKeyTake: u16 = 11_796; // 18%, same as in production + pub const InitialDefaultChildKeyTake: u16 = 0 ;// 0 % pub const InitialMinChildKeyTake: u16 = 0; // 0 %; + pub const InitialMaxChildKeyTake: u16 = 11_796; // 18 %; pub const InitialWeightsVersionKey: u16 = 0; pub const InitialServingRateLimit: u64 = 0; // No limit. pub const InitialTxRateLimit: u64 = 0; // Disable rate limit for testing @@ -172,7 +173,7 @@ parameter_types! { pub const InitialAlphaLow: u16 = 45875; // Represents 0.7 as per the production default pub const InitialLiquidAlphaOn: bool = false; // Default value for LiquidAlphaOn pub const InitialHotkeyEmissionTempo: u64 = 0; // Defaults to draining every block. - pub const InitialNetworkMaxStake: u64 = 500_000_000_000_000; // 500,000 TAO + pub const InitialNetworkMaxStake: u64 = u64::MAX; // Maximum possible value for u64 } @@ -367,6 +368,7 @@ impl pallet_subtensor::Config for Test { type InitialMinDelegateTake = InitialMinDelegateTake; type InitialDefaultChildKeyTake = InitialDefaultChildKeyTake; type InitialMinChildKeyTake = InitialMinChildKeyTake; + type InitialMaxChildKeyTake = InitialMaxChildKeyTake; type InitialTxChildKeyTakeRateLimit = InitialTxChildKeyTakeRateLimit; type InitialWeightsVersionKey = InitialWeightsVersionKey; type InitialMaxDifficulty = InitialMaxDifficulty; diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 166a686e4..ab88db026 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -910,6 +910,7 @@ parameter_types! { pub const SubtensorInitialMinDelegateTake: u16 = 0; // Allow 0% delegate take pub const SubtensorInitialDefaultChildKeyTake: u16 = 0; // Allow 0% childkey take pub const SubtensorInitialMinChildKeyTake: u16 = 0; // 0 % + pub const SubtensorInitialMaxChildKeyTake: u16 = 11_796; // 18 % pub const SubtensorInitialWeightsVersionKey: u64 = 0; pub const SubtensorInitialMinDifficulty: u64 = 10_000_000; pub const SubtensorInitialMaxDifficulty: u64 = u64::MAX / 4; @@ -981,6 +982,7 @@ impl pallet_subtensor::Config for Runtime { type InitialTxRateLimit = SubtensorInitialTxRateLimit; type InitialTxDelegateTakeRateLimit = SubtensorInitialTxDelegateTakeRateLimit; type InitialTxChildKeyTakeRateLimit = SubtensorInitialTxChildKeyTakeRateLimit; + type InitialMaxChildKeyTake = SubtensorInitialMaxChildKeyTake; type InitialRAORecycledForRegistration = SubtensorInitialRAORecycledForRegistration; type InitialSenateRequiredStakePercentage = SubtensorInitialSenateRequiredStakePercentage; type InitialNetworkImmunityPeriod = SubtensorInitialNetworkImmunity; From b60176d6a1611c75fc73d5566673948b1ac25287 Mon Sep 17 00:00:00 2001 From: Samuel Dare Date: Mon, 19 Aug 2024 22:02:05 +0400 Subject: [PATCH 177/177] chore: add vars --- pallets/subtensor/src/lib.rs | 9 ++++++++- pallets/subtensor/tests/children.rs | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index f264ca323..1966f64ab 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -181,12 +181,19 @@ pub mod pallet { pub fn DefaultMinDelegateTake() -> u16 { T::InitialMinDelegateTake::get() } + #[pallet::type_value] /// Default minimum childkey take. pub fn DefaultMinChildKeyTake() -> u16 { T::InitialMinChildKeyTake::get() } + #[pallet::type_value] + /// Default maximum childkey take. + pub fn DefaultMaxChildKeyTake() -> u16 { + T::InitialMaxChildKeyTake::get() + } + #[pallet::type_value] /// Default account take. pub fn DefaultAccountTake() -> u64 { @@ -619,7 +626,7 @@ pub mod pallet { #[pallet::storage] // --- ITEM ( min_delegate_take ) pub type MinDelegateTake = StorageValue<_, u16, ValueQuery, DefaultMinDelegateTake>; #[pallet::storage] // --- ITEM ( default_childkey_take ) - pub type MaxChildkeyTake = StorageValue<_, u16, ValueQuery, DefaultChildKeyTake>; + pub type MaxChildkeyTake = StorageValue<_, u16, ValueQuery, DefaultMaxChildKeyTake>; #[pallet::storage] // --- ITEM ( min_childkey_take ) pub type MinChildkeyTake = StorageValue<_, u16, ValueQuery, DefaultMinChildKeyTake>; diff --git a/pallets/subtensor/tests/children.rs b/pallets/subtensor/tests/children.rs index f36c21521..2b99030ab 100644 --- a/pallets/subtensor/tests/children.rs +++ b/pallets/subtensor/tests/children.rs @@ -1499,7 +1499,7 @@ fn test_get_network_max_stake() { 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); + assert_eq!(default_max_stake, u64::MAX); // Set a new max stake value let new_max_stake: u64 = 1_000_000;