diff --git a/CODEOWNERS b/CODEOWNERS index 5fefbd608e..ffc01511bb 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1 +1 @@ -* @sacha-l @lisa-parity +* @unconst diff --git a/README.md b/README.md index 47639b6407..30f36ffab5 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 diff --git a/docs/running-subtensor-locally.md b/docs/running-subtensor-locally.md index 505fe2fb53..82bb87356d 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). diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index b305661f7b..6388e03315 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -1281,7 +1281,7 @@ where ..Default::default() }) } else { - Err(InvalidTransaction::Call.into()) + Err(InvalidTransaction::Custom(1).into()) } } Some(Call::reveal_weights { netuid, .. }) => { @@ -1293,7 +1293,7 @@ where ..Default::default() }) } else { - Err(InvalidTransaction::Call.into()) + Err(InvalidTransaction::Custom(2).into()) } } Some(Call::set_weights { netuid, .. }) => { @@ -1305,7 +1305,7 @@ where ..Default::default() }) } else { - Err(InvalidTransaction::Call.into()) + Err(InvalidTransaction::Custom(3).into()) } } Some(Call::set_root_weights { netuid, hotkey, .. }) => { @@ -1317,7 +1317,7 @@ where ..Default::default() }) } else { - Err(InvalidTransaction::Call.into()) + Err(InvalidTransaction::Custom(4).into()) } } Some(Call::add_stake { .. }) => Ok(ValidTransaction { @@ -1336,7 +1336,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(), diff --git a/pallets/subtensor/tests/registration.rs b/pallets/subtensor/tests/registration.rs index 7d6e8ea654..4d235cb7ee 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); @@ -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::ExhaustsResources - ); + assert_err!(burned_register_result, InvalidTransaction::Custom(5)); let current_registrants = SubtensorModule::get_registrations_this_interval(netuid); assert!(current_registrants <= max_registrants); diff --git a/pallets/subtensor/tests/weights.rs b/pallets/subtensor/tests/weights.rs index 020eb1f6b9..214e3add06 100644 --- a/pallets/subtensor/tests/weights.rs +++ b/pallets/subtensor/tests/weights.rs @@ -107,7 +107,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 @@ -207,7 +207,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 @@ -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 @@ -306,7 +366,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 diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index d047288dd8..507747e8c1 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,