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]]