diff --git a/Cargo.lock b/Cargo.lock index ef764199aa..97a0d929ff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8301,6 +8301,7 @@ dependencies = [ "memmap2 0.9.8", "node-subtensor-runtime", "num-traits", + "pallet-balances", "pallet-commitments", "pallet-drand", "pallet-shield", diff --git a/node/Cargo.toml b/node/Cargo.toml index e787009d9a..d067eb19c8 100644 --- a/node/Cargo.toml +++ b/node/Cargo.toml @@ -69,6 +69,7 @@ sp-session.workspace = true frame-metadata-hash-extension.workspace = true frame-system.workspace = true frame-support.workspace = true +pallet-balances.workspace = true pallet-transaction-payment.workspace = true pallet-commitments.workspace = true pallet-drand.workspace = true @@ -167,6 +168,7 @@ runtime-benchmarks = [ "polkadot-sdk/runtime-benchmarks", "pallet-subtensor/runtime-benchmarks", "pallet-shield/runtime-benchmarks", + "pallet-balances/runtime-benchmarks", "subtensor-runtime-common/runtime-benchmarks", ] @@ -185,6 +187,7 @@ try-runtime = [ "polkadot-sdk/try-runtime", "pallet-subtensor/try-runtime", "pallet-shield/try-runtime", + "pallet-balances/try-runtime", ] metadata-hash = ["node-subtensor-runtime/metadata-hash"] diff --git a/node/src/clone_spec.rs b/node/src/clone_spec.rs index 65489d24c6..c18ad3dfef 100644 --- a/node/src/clone_spec.rs +++ b/node/src/clone_spec.rs @@ -432,10 +432,49 @@ fn patch_raw_spec(spec: &mut Value, validators: &[&'static str]) -> CloneResult< ); remove_by_prefix(top, &storage_prefix("Session")); + + set_validator_balances(top, validators); + clear_top_level(spec); Ok(()) } +/// Insert a `System::Account` entry for each validator seed so that dev authorities +/// have enough free balance to produce transactions on the cloned chain. +fn set_validator_balances(top: &mut serde_json::Map, validators: &[&'static str]) { + const FREE_BALANCE: u64 = 1_000_000_000_000_000; // 1M TAO (9 decimals) + + let prefix = frame_support::storage::storage_prefix(b"System", b"Account"); + + for seed in validators { + let account_id = + crate::chain_spec::get_account_id_from_seed::(seed); + let encoded_id = account_id.encode(); + + // Blake2_128Concat = blake2_128(encoded) ++ encoded + let hash = sp_io::hashing::blake2_128(&encoded_id); + let mut full_key = prefix.to_vec(); + full_key.extend_from_slice(&hash); + full_key.extend_from_slice(&encoded_id); + + let account_info = frame_system::AccountInfo { + nonce: 0u32, + consumers: 0u32, + providers: 1u32, // >=1 to keep account alive + sufficients: 0u32, + data: pallet_balances::AccountData { + free: FREE_BALANCE, + ..Default::default() + }, + }; + + top.insert( + to_hex(&full_key), + Value::String(to_hex(&account_info.encode())), + ); + } +} + fn remove_by_prefix(map: &mut serde_json::Map, prefix: &str) { let mut keys_to_remove = VecDeque::new(); for key in map.keys() {