From a2d6bb1071162a2306e58fb55f4e3482ac103379 Mon Sep 17 00:00:00 2001 From: Steve Degosserie <723552+stiiifff@users.noreply.github.com> Date: Mon, 14 Apr 2025 20:38:55 +0200 Subject: [PATCH] Use Genesis config presets (#35) Based on https://github.com/paritytech/polkadot-sdk/pull/5868. Note: this (somehow) breaks the ability to run a local network with the zombienet config. It seems that the config generated by Zombienet that automatically set the balance of validators is leading to an issue (because of the address type). --------- Co-authored-by: Facundo Farall <37149322+ffarall@users.noreply.github.com> --- operator/Cargo.lock | 3 + operator/node/Cargo.toml | 112 ++++----- operator/node/src/chain_spec.rs | 176 +------------- operator/node/src/command.rs | 8 +- operator/runtime/Cargo.toml | 145 ++++++------ operator/runtime/src/apis.rs | 6 +- .../runtime/src/genesis_config_presets.rs | 220 ++++++++++++++++++ operator/runtime/src/lib.rs | 3 + .../test/config/zombie-flamingo-local.toml | 2 +- 9 files changed, 354 insertions(+), 321 deletions(-) create mode 100644 operator/runtime/src/genesis_config_presets.rs diff --git a/operator/Cargo.lock b/operator/Cargo.lock index cb657001..d7d11207 100644 --- a/operator/Cargo.lock +++ b/operator/Cargo.lock @@ -1608,6 +1608,7 @@ dependencies = [ "sp-consensus-beefy", "sp-consensus-grandpa", "sp-core", + "sp-genesis-builder", "sp-inherents", "sp-io", "sp-keyring", @@ -1667,6 +1668,7 @@ dependencies = [ "polkadot-primitives", "polkadot-runtime-common", "scale-info", + "serde_json", "snowbridge-beacon-primitives", "snowbridge-pallet-ethereum-client", "sp-api", @@ -1677,6 +1679,7 @@ dependencies = [ "sp-core", "sp-genesis-builder", "sp-inherents", + "sp-keyring", "sp-offchain", "sp-runtime", "sp-session", diff --git a/operator/node/Cargo.toml b/operator/node/Cargo.toml index a3ac9b7e..9c45feed 100644 --- a/operator/node/Cargo.toml +++ b/operator/node/Cargo.toml @@ -17,91 +17,60 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] clap = { features = ["derive"], workspace = true } codec = { workspace = true } -datahaven-runtime.workspace = true +datahaven-runtime = { workspace = true } flume = { workspace = true } fp-account = { workspace = true } -frame-benchmarking-cli.default-features = true -frame-benchmarking-cli.workspace = true -frame-metadata-hash-extension.default-features = true -frame-metadata-hash-extension.workspace = true +frame-benchmarking-cli = { workspace = true, default-features = true } +frame-metadata-hash-extension = { workspace = true, default-features = true } +frame-system = { workspace = true, default-features = true } frame-system-rpc-runtime-api = { workspace = true } -frame-system.default-features = true -frame-system.workspace = true futures = { features = ["thread-pool"], workspace = true } -hex-literal.workspace = true +hex-literal = { workspace = true } jsonrpsee = { features = ["server"], workspace = true } -pallet-im-online.workspace = true +pallet-im-online = { workspace = true } +pallet-transaction-payment = { workspace = true, default-features = true } +pallet-transaction-payment-rpc = { workspace = true, default-features = true } pallet-transaction-payment-rpc-runtime-api = { workspace = true, features = ["std"] } -pallet-transaction-payment-rpc.default-features = true -pallet-transaction-payment-rpc.workspace = true -pallet-transaction-payment.default-features = true -pallet-transaction-payment.workspace = true -sc-basic-authorship.default-features = true -sc-basic-authorship.workspace = true -sc-cli.default-features = true -sc-cli.workspace = true -sc-client-api.default-features = true -sc-client-api.workspace = true -sc-consensus-babe.default-features = true -sc-consensus-babe.workspace = true -sc-consensus-grandpa.default-features = true -sc-consensus-grandpa.workspace = true -sc-consensus.default-features = true -sc-consensus.workspace = true -sc-executor.default-features = true -sc-executor.workspace = true -sc-network-sync.workspace = true -sc-network.default-features = true -sc-network.workspace = true -sc-offchain.default-features = true -sc-offchain.workspace = true -sc-service.default-features = true -sc-service.workspace = true -sc-telemetry.default-features = true -sc-telemetry.workspace = true -sc-transaction-pool-api.default-features = true -sc-transaction-pool-api.workspace = true -sc-transaction-pool.default-features = true -sc-transaction-pool.workspace = true +sc-basic-authorship = { workspace = true, default-features = true } +sc-cli = { workspace = true, default-features = true } +sc-client-api = { workspace = true, default-features = true } +sc-consensus = { workspace = true, default-features = true } +sc-consensus-babe = { workspace = true, default-features = true } +sc-consensus-grandpa = { workspace = true, default-features = true } +sc-executor = { workspace = true, default-features = true } +sc-network = { workspace = true, default-features = true } +sc-network-sync = { workspace = true } +sc-offchain = { workspace = true, default-features = true } +sc-service = { workspace = true, default-features = true } +sc-telemetry = { workspace = true, default-features = true } +sc-transaction-pool = { workspace = true, default-features = true } +sc-transaction-pool-api = { workspace = true, default-features = true } serde_json = { workspace = true, default-features = true } -sp-api.default-features = true -sp-api.workspace = true -sp-block-builder.default-features = true -sp-block-builder.workspace = true -sp-blockchain.default-features = true -sp-blockchain.workspace = true -sp-consensus-babe.default-features = true -sp-consensus-babe.workspace = true -sp-consensus-beefy.default-features = true -sp-consensus-beefy.workspace = true -sp-consensus-grandpa.default-features = true -sp-consensus-grandpa.workspace = true -sp-core.default-features = true -sp-core.workspace = true -sp-inherents.default-features = true -sp-inherents.workspace = true -sp-io.default-features = true -sp-io.workspace = true -sp-keyring.default-features = true -sp-keyring.workspace = true +sp-api = { workspace = true, default-features = true } +sp-block-builder = { workspace = true, default-features = true } +sp-blockchain = { workspace = true, default-features = true } +sp-consensus-babe = { workspace = true, default-features = true } +sp-consensus-beefy = { workspace = true, default-features = true } +sp-consensus-grandpa = { workspace = true, default-features = true } +sp-core = { workspace = true, default-features = true } +sp-genesis-builder = { workspace = true, default-features = true } +sp-inherents = { workspace = true, default-features = true } +sp-io = { workspace = true, default-features = true } +sp-keyring = { workspace = true, default-features = true } sp-offchain = { workspace = true, features = ["default"] } -sp-runtime.default-features = true -sp-runtime.workspace = true +sp-runtime = { workspace = true, default-features = true } sp-session = { workspace = true, features = ["default"] } -sp-timestamp.default-features = true -sp-timestamp.workspace = true +sp-timestamp = { workspace = true, default-features = true } sp-transaction-pool = { workspace = true, features = ["default"] } -substrate-frame-rpc-system.default-features = true -substrate-frame-rpc-system.workspace = true +substrate-frame-rpc-system = { workspace = true, default-features = true } url = { workspace = true } # RPC sc-rpc = { workspace = true, default-features = true } # Beefy +sc-consensus-beefy = { workspace = true, default-features = true } sc-consensus-beefy-rpc = { workspace = true, default-features = true } -sc-consensus-beefy.default-features = true -sc-consensus-beefy.workspace = true # MMR mmr-rpc = { workspace = true, default-features = true } @@ -119,8 +88,7 @@ fp-rpc = { workspace = true } pallet-ethereum = { workspace = true } [build-dependencies] -substrate-build-script-utils.default-features = true -substrate-build-script-utils.workspace = true +substrate-build-script-utils = { workspace = true, default-features = true } [features] default = ["std"] @@ -130,17 +98,17 @@ std = [ # Dependencies that are only required if runtime benchmarking should be build. runtime-benchmarks = [ + "datahaven-runtime/runtime-benchmarks", "frame-benchmarking-cli/runtime-benchmarks", "frame-system/runtime-benchmarks", "sc-service/runtime-benchmarks", - "datahaven-runtime/runtime-benchmarks", "sp-runtime/runtime-benchmarks", ] # Enable features that allow the runtime to be tried and debugged. Name might be subject to change # in the near future. try-runtime = [ + "datahaven-runtime/try-runtime", "frame-system/try-runtime", "pallet-transaction-payment/try-runtime", - "datahaven-runtime/try-runtime", "sp-runtime/try-runtime", ] diff --git a/operator/node/src/chain_spec.rs b/operator/node/src/chain_spec.rs index 893ac19d..1d3b98cf 100644 --- a/operator/node/src/chain_spec.rs +++ b/operator/node/src/chain_spec.rs @@ -1,14 +1,5 @@ -use datahaven_runtime::{ - configs::BABE_GENESIS_EPOCH_CONFIG, AccountId, SessionKeys, Signature, WASM_BINARY, -}; -use hex_literal::hex; -use pallet_im_online::sr25519::AuthorityId as ImOnlineId; +use datahaven_runtime::WASM_BINARY; use sc_service::ChainType; -use sp_consensus_babe::AuthorityId as BabeId; -use sp_consensus_beefy::ecdsa_crypto::AuthorityId as BeefyId; -use sp_consensus_grandpa::AuthorityId as GrandpaId; -use sp_core::{ecdsa, Pair, Public}; -use sp_runtime::traits::{IdentifyAccount, Verify}; const EVM_CHAIN_ID: u64 = 1289; const SS58_FORMAT: u16 = EVM_CHAIN_ID as u16; @@ -18,58 +9,13 @@ const TOKEN_SYMBOL: &str = "HAVE"; /// Specialized `ChainSpec`. This is a specialization of the general Substrate ChainSpec type. pub type ChainSpec = sc_service::GenericChainSpec; -/// Generate a crypto pair from seed. -pub fn get_from_seed(seed: &str) -> ::Public { - TPublic::Pair::from_string(&format!("//{}", seed), None) - .expect("static values are valid; qed") - .public() -} - -fn session_keys( - babe: BabeId, - grandpa: GrandpaId, - im_online: ImOnlineId, - beefy: BeefyId, -) -> SessionKeys { - SessionKeys { - babe, - grandpa, - im_online, - beefy, - } -} - -type AccountPublic = ::Signer; - -/// Generate an account ID from seed. -pub fn get_account_id_from_seed(seed: &str) -> AccountId -where - AccountPublic: From<::Public>, -{ - AccountPublic::from(get_from_seed::(seed)).into_account() -} - -/// Generate a Babe authority key. -pub fn authority_keys_from_seed(s: &str) -> (AccountId, BabeId, GrandpaId, ImOnlineId, BeefyId) { - ( - get_account_id_from_seed::(s), - get_from_seed::(s), - get_from_seed::(s), - get_from_seed::(s), - get_from_seed::(s), - ) -} - -pub fn development_config() -> Result { - let mut default_funded_accounts = pre_funded_accounts(); - default_funded_accounts.sort(); - default_funded_accounts.dedup(); - +pub fn development_chain_spec() -> Result { // Give the token a unit name and decimal places let mut properties = sc_service::Properties::new(); properties.insert("tokenSymbol".into(), TOKEN_SYMBOL.into()); properties.insert("tokenDecimals".into(), TOKEN_DECIMALS.into()); properties.insert("ss58Format".into(), SS58_FORMAT.into()); + properties.insert("isEthereum".into(), true.into()); Ok(ChainSpec::builder( WASM_BINARY.ok_or_else(|| "Development wasm not available".to_string())?, @@ -78,24 +24,17 @@ pub fn development_config() -> Result { .with_name("Development") .with_id("dev") .with_chain_type(ChainType::Development) - .with_genesis_config_patch(testnet_genesis( - // Initial PoA authorities - vec![authority_keys_from_seed("Alice")], - // Sudo account - alith(), - // Pre-funded accounts - default_funded_accounts.clone(), - true, - )) + .with_genesis_config_preset_name(sp_genesis_builder::DEV_RUNTIME_PRESET) .with_properties(properties) .build()) } -pub fn local_testnet_config() -> Result { +pub fn local_chain_spec() -> Result { let mut properties = sc_service::Properties::new(); properties.insert("tokenSymbol".into(), TOKEN_SYMBOL.into()); properties.insert("tokenDecimals".into(), TOKEN_DECIMALS.into()); properties.insert("ss58Format".into(), SS58_FORMAT.into()); + properties.insert("isEthereum".into(), true.into()); Ok(ChainSpec::builder( WASM_BINARY.ok_or_else(|| "Development wasm not available".to_string())?, @@ -104,108 +43,7 @@ pub fn local_testnet_config() -> Result { .with_name("Local Testnet") .with_id("local_testnet") .with_chain_type(ChainType::Local) - .with_genesis_config_patch(testnet_genesis( - // Initial PoA authorities - vec![ - authority_keys_from_seed("Alice"), - authority_keys_from_seed("Bob"), - authority_keys_from_seed("Charlie"), - authority_keys_from_seed("Dave"), - authority_keys_from_seed("Eve"), - authority_keys_from_seed("Ferdie"), - ], - // Sudo account - alith(), - // Pre-funded accounts - vec![ - alith(), - baltathar(), - charleth(), - dorothy(), - ethan(), - frank(), - ], - true, - )) + .with_genesis_config_preset_name(sp_genesis_builder::LOCAL_TESTNET_RUNTIME_PRESET) .with_properties(properties) .build()) } - -/// Configure initial storage state for FRAME modules. -fn testnet_genesis( - initial_authorities: Vec<(AccountId, BabeId, GrandpaId, ImOnlineId, BeefyId)>, - root_key: AccountId, - endowed_accounts: Vec, - _enable_println: bool, -) -> serde_json::Value { - serde_json::json!({ - "balances": { - // Configure endowed accounts with initial balance of 1 << 60. - "balances": endowed_accounts.iter().cloned().map(|k| (k, 1u64 << 60)).collect::>(), - }, - "babe": { - "epochConfig": Some(BABE_GENESIS_EPOCH_CONFIG), - }, - "grandpa": {}, - "imOnline": {}, - "sudo": { - // Assign network admin rights. - "key": Some(root_key), - }, - "validatorSet": { - "initialValidators": initial_authorities.iter().map(|x| x.0).collect::>(), - }, - "session": { - "keys": initial_authorities.iter().map(|x| { - (x.0, x.0, session_keys(x.1.clone(), x.2.clone(), x.3.clone(), x.4.clone())) - }).collect::>(), - }, - "evmChainId": { - // EVM chain ID - "chainId": EVM_CHAIN_ID, - }, - }) -} - -pub fn alith() -> AccountId { - AccountId::from(hex!("f24FF3a9CF04c71Dbc94D0b566f7A27B94566cac")) -} - -pub fn baltathar() -> AccountId { - AccountId::from(hex!("3Cd0A705a2DC65e5b1E1205896BaA2be8A07c6e0")) -} - -pub fn charleth() -> AccountId { - AccountId::from(hex!("798d4Ba9baf0064Ec19eB4F0a1a45785ae9D6DFc")) -} - -pub fn dorothy() -> AccountId { - AccountId::from(hex!("773539d4Ac0e786233D90A233654ccEE26a613D9")) -} - -pub fn ethan() -> AccountId { - AccountId::from(hex!("Ff64d3F6efE2317EE2807d2235B1ac2AA69d9E87")) -} - -pub fn frank() -> AccountId { - AccountId::from(hex!("C0F0f4ab324C46e55D02D0033343B4Be8A55532d")) -} - -pub fn beacon_relayer() -> AccountId { - AccountId::from(hex!("c46e141b5083721ad5f5056ba1cded69dce4a65f")) -} - -/// Get pre-funded accounts -pub fn pre_funded_accounts() -> Vec { - // These addresses are derived from Substrate's canonical mnemonic: - // bottom drive obey lake curtain smoke basket hold race lonely fit walk - vec![ - alith(), - baltathar(), - charleth(), - dorothy(), - ethan(), - frank(), - beacon_relayer(), - ] -} diff --git a/operator/node/src/command.rs b/operator/node/src/command.rs index 76807daa..8332de90 100644 --- a/operator/node/src/command.rs +++ b/operator/node/src/command.rs @@ -3,11 +3,11 @@ use std::sync::Arc; use crate::service::frontier_database_dir; use crate::{ benchmarking::{inherent_benchmark_data, RemarkBuilder, TransferKeepAliveBuilder}, - chain_spec::{self, alith}, + chain_spec, cli::{Cli, Subcommand}, service, }; -use datahaven_runtime::{Block, EXISTENTIAL_DEPOSIT}; +use datahaven_runtime::{genesis_config_presets::alith, Block, EXISTENTIAL_DEPOSIT}; use frame_benchmarking_cli::{BenchmarkCmd, ExtrinsicFactory, SUBSTRATE_REFERENCE_HARDWARE}; use sc_cli::SubstrateCli; use sc_service::{DatabaseSource, PartialComponents}; @@ -39,8 +39,8 @@ impl SubstrateCli for Cli { fn load_spec(&self, id: &str) -> Result, String> { Ok(match id { - "dev" => Box::new(chain_spec::development_config()?), - "" | "datahaven-local" => Box::new(chain_spec::local_testnet_config()?), + "dev" => Box::new(chain_spec::development_chain_spec()?), + "" | "local" => Box::new(chain_spec::local_chain_spec()?), path => Box::new(chain_spec::ChainSpec::from_json_file( std::path::PathBuf::from(path), )?), diff --git a/operator/runtime/Cargo.toml b/operator/runtime/Cargo.toml index 1fba10bb..7eb16537 100644 --- a/operator/runtime/Cargo.toml +++ b/operator/runtime/Cargo.toml @@ -14,69 +14,68 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { features = ["derive"], workspace = true } -datahaven-runtime-common.workspace = true +datahaven-runtime-common = { workspace = true } fp-account = { workspace = true, features = ["serde"] } fp-evm = { workspace = true, features = ["serde"] } fp-rpc = { workspace = true } fp-self-contained = { workspace = true, features = ["serde", "try-runtime"] } frame-benchmarking = { optional = true, workspace = true } -frame-executive.workspace = true -frame-metadata-hash-extension.workspace = true +frame-executive = { workspace = true } +frame-metadata-hash-extension = { workspace = true } frame-support = { features = ["experimental"], workspace = true } frame-system-benchmarking = { optional = true, workspace = true } -frame-system-rpc-runtime-api.workspace = true -frame-system.workspace = true +frame-system-rpc-runtime-api = { workspace = true } +frame-system = { workspace = true } frame-try-runtime = { optional = true, workspace = true } hex = { workspace = true } -hex-literal.workspace = true -pallet-authorship.workspace = true -pallet-babe.workspace = true -pallet-balances.workspace = true -pallet-beefy-mmr.workspace = true -pallet-beefy.workspace = true -pallet-grandpa.workspace = true -pallet-identity.workspace = true -pallet-im-online.workspace = true -pallet-mmr.workspace = true -pallet-multisig.workspace = true -pallet-offences.workspace = true -pallet-preimage.workspace = true -pallet-scheduler.workspace = true -pallet-session.workspace = true -pallet-sudo.workspace = true -pallet-timestamp.workspace = true -pallet-transaction-payment-rpc-runtime-api.workspace = true -pallet-transaction-payment.workspace = true -pallet-utility.workspace = true -pallet-validator-set.workspace = true -polkadot-primitives.workspace = true -polkadot-runtime-common.workspace = true +hex-literal = { workspace = true } +pallet-authorship = { workspace = true } +pallet-babe = { workspace = true } +pallet-balances = { workspace = true } +pallet-beefy = { workspace = true } +pallet-beefy-mmr = { workspace = true } +pallet-ethereum = { workspace = true } +pallet-evm = { workspace = true } +pallet-evm-chain-id = { workspace = true } +pallet-grandpa = { workspace = true } +pallet-identity = { workspace = true } +pallet-im-online = { workspace = true } +pallet-mmr = { workspace = true } +pallet-multisig = { workspace = true } +pallet-offences = { workspace = true } +pallet-preimage = { workspace = true } +pallet-scheduler = { workspace = true } +pallet-session = { workspace = true } +pallet-sudo = { workspace = true } +pallet-timestamp = { workspace = true } +pallet-transaction-payment = { workspace = true } +pallet-transaction-payment-rpc-runtime-api = { workspace = true } +pallet-utility = { workspace = true } +pallet-validator-set = { workspace = true } +polkadot-primitives = { workspace = true } +polkadot-runtime-common = { workspace = true } scale-info = { features = ["derive", "serde"], workspace = true } -sp-api.workspace = true -sp-block-builder.workspace = true +serde_json = { workspace = true, default-features = false, features = ["alloc"] } +snowbridge-beacon-primitives = { workspace = true } +snowbridge-pallet-ethereum-client = { workspace = true } +sp-api = { workspace = true } +sp-block-builder = { workspace = true } sp-consensus-babe = { features = ["serde"], workspace = true } sp-consensus-beefy = { features = ["serde"], workspace = true } sp-consensus-grandpa = { features = ["serde"], workspace = true } sp-core = { features = ["serde"], workspace = true } -sp-genesis-builder.workspace = true -sp-inherents.workspace = true -sp-offchain.workspace = true +sp-genesis-builder = { workspace = true } +sp-inherents = { workspace = true } +sp-keyring = { workspace = true } +sp-offchain = { workspace = true } sp-runtime = { features = ["serde"], workspace = true } -sp-session.workspace = true -sp-staking.workspace = true -sp-std.workspace = true -sp-storage.workspace = true -sp-transaction-pool.workspace = true +sp-session = { workspace = true } +sp-staking = { workspace = true } +sp-std = { workspace = true } +sp-storage = { workspace = true } +sp-transaction-pool = { workspace = true } sp-version = { features = ["serde"], workspace = true } -pallet-ethereum.workspace = true -pallet-evm-chain-id.workspace = true -pallet-evm.workspace = true - -# Snowbridge -snowbridge-beacon-primitives.workspace = true -snowbridge-pallet-ethereum-client.workspace = true - [build-dependencies] substrate-wasm-builder = { optional = true, workspace = true, default-features = true } @@ -84,26 +83,29 @@ substrate-wasm-builder = { optional = true, workspace = true, default-features = default = ["std"] std = [ "codec/std", - "scale-info/std", + "datahaven-runtime-common/std", + "fp-account/std", + "frame-benchmarking?/std", "frame-executive/std", "frame-metadata-hash-extension/std", "frame-support/std", "frame-system-benchmarking?/std", "frame-system-rpc-runtime-api/std", "frame-system/std", - "frame-benchmarking?/std", "frame-try-runtime?/std", - "datahaven-runtime-common/std", "pallet-authorship/std", "pallet-babe/std", - "pallet-beefy/std", - "pallet-beefy-mmr/std", "pallet-balances/std", - "pallet-im-online/std", + "pallet-beefy-mmr/std", + "pallet-beefy/std", + "pallet-ethereum/std", + "pallet-evm-chain-id/std", + "pallet-evm/std", "pallet-grandpa/std", "pallet-identity/std", - "pallet-multisig/std", + "pallet-im-online/std", "pallet-mmr/std", + "pallet-multisig/std", "pallet-offences/std", "pallet-preimage/std", "pallet-scheduler/std", @@ -116,6 +118,8 @@ std = [ "pallet-validator-set/std", "polkadot-primitives/std", "polkadot-runtime-common/std", + "scale-info/std", + "serde_json/std", "snowbridge-beacon-primitives/std", "snowbridge-pallet-ethereum-client/std", "sp-api/std", @@ -125,31 +129,32 @@ std = [ "sp-core/std", "sp-genesis-builder/std", "sp-inherents/std", + "sp-keyring/std", "sp-offchain/std", "sp-runtime/std", "sp-session/std", "sp-staking/std", - "sp-storage/std", "sp-std/std", + "sp-storage/std", "sp-transaction-pool/std", "sp-version/std", "substrate-wasm-builder", - "fp-account/std", - "pallet-evm/std", - "pallet-evm-chain-id/std", - "pallet-ethereum/std", ] runtime-benchmarks = [ + "datahaven-runtime-common/runtime-benchmarks", "frame-benchmarking/runtime-benchmarks", "frame-support/runtime-benchmarks", "frame-system-benchmarking/runtime-benchmarks", "frame-system/runtime-benchmarks", - "datahaven-runtime-common/runtime-benchmarks", "pallet-balances/runtime-benchmarks", - "pallet-im-online/runtime-benchmarks", + "pallet-beefy-mmr/runtime-benchmarks", + "pallet-ethereum/runtime-benchmarks", + "pallet-evm/runtime-benchmarks", "pallet-grandpa/runtime-benchmarks", "pallet-identity/runtime-benchmarks", + "pallet-im-online/runtime-benchmarks", + "pallet-mmr/runtime-benchmarks", "pallet-multisig/runtime-benchmarks", "pallet-offences/runtime-benchmarks", "pallet-preimage/runtime-benchmarks", @@ -157,17 +162,14 @@ runtime-benchmarks = [ "pallet-sudo/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", "pallet-utility/runtime-benchmarks", - "pallet-beefy-mmr/runtime-benchmarks", - "pallet-mmr/runtime-benchmarks", - "polkadot-runtime-common/runtime-benchmarks", "polkadot-primitives/runtime-benchmarks", + "polkadot-runtime-common/runtime-benchmarks", "snowbridge-pallet-ethereum-client/runtime-benchmarks", "sp-runtime/runtime-benchmarks", - "pallet-evm/runtime-benchmarks", - "pallet-ethereum/runtime-benchmarks", ] try-runtime = [ + "fp-self-contained/try-runtime", "frame-executive/try-runtime", "frame-support/try-runtime", "frame-system/try-runtime", @@ -175,9 +177,14 @@ try-runtime = [ "pallet-authorship/try-runtime", "pallet-babe/try-runtime", "pallet-balances/try-runtime", + "pallet-beefy-mmr/try-runtime", + "pallet-beefy/try-runtime", + "pallet-ethereum/try-runtime", + "pallet-evm/try-runtime", "pallet-grandpa/try-runtime", "pallet-identity/try-runtime", "pallet-im-online/try-runtime", + "pallet-mmr/try-runtime", "pallet-multisig/try-runtime", "pallet-offences/try-runtime", "pallet-preimage/try-runtime", @@ -185,17 +192,11 @@ try-runtime = [ "pallet-session/try-runtime", "pallet-sudo/try-runtime", "pallet-timestamp/try-runtime", - "pallet-utility/try-runtime", "pallet-transaction-payment/try-runtime", - "pallet-beefy/try-runtime", - "pallet-beefy-mmr/try-runtime", - "pallet-mmr/try-runtime", + "pallet-utility/try-runtime", "polkadot-runtime-common/try-runtime", "snowbridge-pallet-ethereum-client/try-runtime", "sp-runtime/try-runtime", - "pallet-evm/try-runtime", - "pallet-ethereum/try-runtime", - "fp-self-contained/try-runtime" ] fast-runtime = [ diff --git a/operator/runtime/src/apis.rs b/operator/runtime/src/apis.rs index aa876931..9b094be3 100644 --- a/operator/runtime/src/apis.rs +++ b/operator/runtime/src/apis.rs @@ -31,7 +31,7 @@ use super::{ }; // External crates imports use crate::configs::BABE_GENESIS_EPOCH_CONFIG; -use alloc::{vec, vec::Vec}; +use alloc::vec::Vec; use codec::Encode; use datahaven_runtime_common::time::EpochDurationInBlocks; use fp_rpc::TransactionStatus; @@ -559,11 +559,11 @@ impl_runtime_apis! { } fn get_preset(id: &Option) -> Option> { - get_preset::(id, |_| None) + get_preset::(id, crate::genesis_config_presets::get_preset) } fn preset_names() -> Vec { - vec![] + crate::genesis_config_presets::preset_names() } } diff --git a/operator/runtime/src/genesis_config_presets.rs b/operator/runtime/src/genesis_config_presets.rs new file mode 100644 index 00000000..18726291 --- /dev/null +++ b/operator/runtime/src/genesis_config_presets.rs @@ -0,0 +1,220 @@ +use crate::{ + configs::BABE_GENESIS_EPOCH_CONFIG, AccountId, BalancesConfig, RuntimeGenesisConfig, + SessionKeys, Signature, SudoConfig, +}; +use alloc::{format, vec, vec::Vec}; +use hex_literal::hex; +use pallet_im_online::sr25519::AuthorityId as ImOnlineId; +use serde_json::Value; +use sp_consensus_babe::AuthorityId as BabeId; +use sp_consensus_beefy::ecdsa_crypto::AuthorityId as BeefyId; +use sp_consensus_grandpa::AuthorityId as GrandpaId; +use sp_core::{ecdsa, Pair, Public}; +use sp_genesis_builder::{self, PresetId}; +use sp_runtime::traits::{IdentifyAccount, Verify}; + +const TESTNET_EVM_CHAIN_ID: u64 = 1283; + +// Returns the genesis config presets populated with given parameters. +fn testnet_genesis( + initial_authorities: Vec<(AccountId, BabeId, GrandpaId, ImOnlineId, BeefyId)>, + root_key: AccountId, + endowed_accounts: Vec, + evm_chain_id: u64, +) -> Value { + let config = RuntimeGenesisConfig { + balances: BalancesConfig { + balances: endowed_accounts + .iter() + .cloned() + .map(|k| (k, 1u128 << 110)) + .collect::>(), + }, + babe: pallet_babe::GenesisConfig { + epoch_config: BABE_GENESIS_EPOCH_CONFIG, + ..Default::default() + }, + evm_chain_id: pallet_evm_chain_id::GenesisConfig { + chain_id: evm_chain_id, + ..Default::default() + }, + session: pallet_session::GenesisConfig { + keys: initial_authorities + .iter() + .map(|(account, babe, grandpa, im_online, beefy)| { + ( + *account, + *account, + session_keys( + babe.clone(), + grandpa.clone(), + im_online.clone(), + beefy.clone(), + ), + ) + }) + .collect::>(), + ..Default::default() + }, + sudo: SudoConfig { + key: Some(root_key), + }, + validator_set: pallet_validator_set::GenesisConfig { + initial_validators: initial_authorities + .iter() + .map(|(account, ..)| *account) + .collect::>() + .try_into() + .expect("Too many initial authorities"), + }, + ..Default::default() + }; + + serde_json::to_value(config).expect("Could not build genesis config.") +} + +/// Return the development genesis config. +pub fn development_config_genesis() -> Value { + let mut endowed_accounts = pre_funded_accounts(); + endowed_accounts.sort(); + + testnet_genesis( + vec![authority_keys_from_seed("Alice")], + alith(), + endowed_accounts, + TESTNET_EVM_CHAIN_ID, + ) +} + +/// Return the local genesis config preset. +pub fn local_config_genesis() -> Value { + let mut endowed_accounts = pre_funded_accounts(); + endowed_accounts.sort(); + + testnet_genesis( + vec![ + authority_keys_from_seed("Alice"), + authority_keys_from_seed("Bob"), + authority_keys_from_seed("Charlie"), + authority_keys_from_seed("Dave"), + authority_keys_from_seed("Eve"), + authority_keys_from_seed("Ferdie"), + ], + alith(), + endowed_accounts, + TESTNET_EVM_CHAIN_ID, + ) +} + +/// Provides the JSON representation of predefined genesis config for given `id`. +pub fn get_preset(id: &PresetId) -> Option> { + let patch = match id.try_into() { + Ok(sp_genesis_builder::DEV_RUNTIME_PRESET) => development_config_genesis(), + Ok(sp_genesis_builder::LOCAL_TESTNET_RUNTIME_PRESET) => local_config_genesis(), + _ => return None, + }; + Some( + serde_json::to_string(&patch) + .expect("serialization to json is expected to work. qed.") + .into_bytes(), + ) +} + +/// List of supported presets. +pub fn preset_names() -> Vec { + vec![ + PresetId::from(sp_genesis_builder::DEV_RUNTIME_PRESET), + PresetId::from(sp_genesis_builder::LOCAL_TESTNET_RUNTIME_PRESET), + ] +} + +/// Generate a crypto pair from seed. +pub fn get_from_seed(seed: &str) -> ::Public { + TPublic::Pair::from_string(&format!("//{}", seed), None) + .expect("static values are valid; qed") + .public() +} + +fn session_keys( + babe: BabeId, + grandpa: GrandpaId, + im_online: ImOnlineId, + beefy: BeefyId, +) -> SessionKeys { + SessionKeys { + babe, + grandpa, + im_online, + beefy, + } +} + +type AccountPublic = ::Signer; + +/// Generate an account ID from seed. +pub fn get_account_id_from_seed(seed: &str) -> AccountId +where + AccountPublic: From<::Public>, +{ + AccountPublic::from(get_from_seed::(seed)).into_account() +} + +/// Generate a Babe authority key. +pub fn authority_keys_from_seed(s: &str) -> (AccountId, BabeId, GrandpaId, ImOnlineId, BeefyId) { + ( + get_account_id_from_seed::(s), + get_from_seed::(s), + get_from_seed::(s), + get_from_seed::(s), + get_from_seed::(s), + ) +} + +pub fn alith() -> AccountId { + AccountId::from(hex!("f24FF3a9CF04c71Dbc94D0b566f7A27B94566cac")) +} + +pub fn baltathar() -> AccountId { + AccountId::from(hex!("3Cd0A705a2DC65e5b1E1205896BaA2be8A07c6e0")) +} + +pub fn charleth() -> AccountId { + AccountId::from(hex!("798d4Ba9baf0064Ec19eB4F0a1a45785ae9D6DFc")) +} + +pub fn dorothy() -> AccountId { + AccountId::from(hex!("773539d4Ac0e786233D90A233654ccEE26a613D9")) +} + +pub fn ethan() -> AccountId { + AccountId::from(hex!("Ff64d3F6efE2317EE2807d2235B1ac2AA69d9E87")) +} + +pub fn frank() -> AccountId { + AccountId::from(hex!("C0F0f4ab324C46e55D02D0033343B4Be8A55532d")) +} + +pub fn beacon_relayer() -> AccountId { + AccountId::from(hex!("c46e141b5083721ad5f5056ba1cded69dce4a65f")) +} + +/// Get pre-funded accounts +pub fn pre_funded_accounts() -> Vec { + // These addresses are derived from Substrate's canonical mnemonic: + // bottom drive obey lake curtain smoke basket hold race lonely fit walk + vec![ + get_account_id_from_seed::("Alice"), + get_account_id_from_seed::("Bob"), + get_account_id_from_seed::("Charlie"), + get_account_id_from_seed::("Dave"), + get_account_id_from_seed::("Eve"), + get_account_id_from_seed::("Ferdie"), + alith(), + baltathar(), + charleth(), + dorothy(), + ethan(), + frank(), + beacon_relayer(), + ] +} diff --git a/operator/runtime/src/lib.rs b/operator/runtime/src/lib.rs index baa241d2..53df70bd 100644 --- a/operator/runtime/src/lib.rs +++ b/operator/runtime/src/lib.rs @@ -27,6 +27,9 @@ pub use pallet_timestamp::Call as TimestampCall; use sp_core::H160; #[cfg(any(feature = "std", test))] pub use sp_runtime::BuildStorage; + +pub mod genesis_config_presets; + /// Opaque types. These are used by the CLI to instantiate machinery that don't need to know /// the specifics of the runtime. They can then be made to be agnostic over specific formats /// of data like extrinsics, allowing for them to continue syncing the network through upgrades diff --git a/operator/test/config/zombie-flamingo-local.toml b/operator/test/config/zombie-flamingo-local.toml index 7704e1f3..f2c11a82 100644 --- a/operator/test/config/zombie-flamingo-local.toml +++ b/operator/test/config/zombie-flamingo-local.toml @@ -3,7 +3,7 @@ timeout = 120 [relaychain] default_command = "${output_bin_dir:-./target/release}/datahaven-node" -chain = "datahaven-local" +chain = "local" default_args = [ "-l=debug", "--pruning=archive", "--enable-offchain-indexing=true", "--offchain-worker=when-authority" ] [[relaychain.nodes]]