subspace_malicious_operator/
chain_spec.rs

1use domain_runtime_primitives::{AccountId20Converter, DEFAULT_EVM_CHAIN_ID, MultiAccountId};
2use evm_domain_runtime::{AccountId as AccountId20, EVMChainIdConfig, EVMConfig, Precompiles};
3use hex_literal::hex;
4use parity_scale_codec::Encode;
5use sc_chain_spec::GenericChainSpec;
6use sc_service::ChainType;
7use sp_core::crypto::AccountId32;
8use sp_core::{Pair, Public, sr25519};
9use sp_domains::storage::RawGenesis;
10use sp_domains::{
11    DomainRuntimeInfo, EvmDomainRuntimeConfig, EvmType, OperatorAllowList, OperatorPublicKey,
12    PermissionedActionAllowedBy, RuntimeType,
13};
14use sp_runtime::traits::{Convert, IdentifyAccount};
15use sp_runtime::{BuildStorage, MultiSigner, Percent};
16use std::marker::PhantomData;
17use std::num::NonZeroU32;
18use subspace_runtime::{
19    AllowAuthoringBy, CouncilConfig, DemocracyConfig, DomainsConfig, EnableRewardsAt,
20    RewardsConfig, RuntimeConfigsConfig, SubspaceConfig,
21};
22use subspace_runtime_primitives::{
23    AI3, AccountId, Balance, BlockNumber, CouncilDemocracyConfigParams, GenesisConfigParams,
24};
25
26fn endowed_accounts() -> Vec<(MultiAccountId, Balance)> {
27    [
28        // Alith key
29        AccountId20::from(hex!("f24FF3a9CF04c71Dbc94D0b566f7A27B94566cac")),
30        // Baltathar key
31        AccountId20::from(hex!("3Cd0A705a2DC65e5b1E1205896BaA2be8A07c6e0")),
32        // Charleth key
33        AccountId20::from(hex!("798d4Ba9baf0064Ec19eB4F0a1a45785ae9D6DFc")),
34        // Dorothy
35        AccountId20::from(hex!("773539d4Ac0e786233D90A233654ccEE26a613D9")),
36    ]
37    .into_iter()
38    .map(|k| (AccountId20Converter::convert(k), 1_000_000 * AI3))
39    .collect()
40}
41
42pub fn domain_dev_config() -> Result<GenericChainSpec, String> {
43    Ok(GenericChainSpec::builder(
44        evm_domain_runtime::WASM_BINARY.expect("WASM binary was not build, please build it!"),
45        None,
46    )
47    .with_name("Development")
48    .with_id("evm_domain_dev")
49    .with_chain_type(ChainType::Development)
50    .with_genesis_config({
51        // This is the simplest bytecode to revert without returning any data.
52        // We will pre-deploy it under all of our precompiles to ensure they can be called from
53        // within contracts.
54        // (PUSH1 0x00 PUSH1 0x00 REVERT)
55        let revert_bytecode = vec![0x60, 0x00, 0x60, 0x00, 0xFD];
56
57        serde_json::to_value(evm_domain_runtime::RuntimeGenesisConfig {
58            system: evm_domain_runtime::SystemConfig::default(),
59            balances: evm_domain_runtime::BalancesConfig::default(),
60            // this is set to default and chain_id will be set into genesis during the domain
61            // instantiation on Consensus runtime.
62            evm_chain_id: EVMChainIdConfig::default(),
63            evm: EVMConfig {
64                // We need _some_ code inserted at the precompile address so that
65                // the evm will actually call the address.
66                accounts: Precompiles::used_addresses()
67                    .map(|addr| {
68                        (
69                            addr.into(),
70                            fp_evm::GenesisAccount {
71                                nonce: Default::default(),
72                                balance: Default::default(),
73                                storage: Default::default(),
74                                code: revert_bytecode.clone(),
75                            },
76                        )
77                    })
78                    .collect(),
79                ..Default::default()
80            },
81            ..Default::default()
82        })
83        .map_err(|error| format!("Failed to serialize genesis config: {error}"))?
84    })
85    .build())
86}
87
88pub(crate) fn consensus_dev_sudo_account() -> AccountId32 {
89    get_account_id_from_seed("Alice")
90}
91
92pub fn create_domain_spec(chain_id: &str) -> Result<Box<dyn sc_cli::ChainSpec>, String> {
93    let chain_spec = match chain_id {
94        "dev" => domain_dev_config()?,
95        path => GenericChainSpec::from_json_file(std::path::PathBuf::from(path))?,
96    };
97    Ok(Box::new(chain_spec))
98}
99
100pub fn load_domain_chain_spec(spec_id: &str) -> Result<Box<dyn sc_cli::ChainSpec>, String> {
101    let chain_spec = match spec_id {
102        "dev" => domain_dev_config()?,
103        path => GenericChainSpec::from_json_file(std::path::PathBuf::from(path))?,
104    };
105    Ok(Box::new(chain_spec))
106}
107
108/// Get public key from keypair seed.
109fn get_public_key_from_seed<TPublic: Public>(
110    seed: &'static str,
111) -> <TPublic::Pair as Pair>::Public {
112    TPublic::Pair::from_string(&format!("//{seed}"), None)
113        .expect("Static values are valid; qed")
114        .public()
115}
116
117/// Generate an account ID from seed.
118fn get_account_id_from_seed(seed: &'static str) -> AccountId32 {
119    MultiSigner::from(get_public_key_from_seed::<sr25519::Public>(seed)).into_account()
120}
121
122/// Additional subspace specific genesis parameters.
123struct GenesisParams {
124    enable_rewards_at: EnableRewardsAt<BlockNumber>,
125    allow_authoring_by: AllowAuthoringBy,
126    pot_slot_iterations: NonZeroU32,
127    enable_domains: bool,
128    enable_dynamic_cost_of_storage: bool,
129    enable_balance_transfers: bool,
130    confirmation_depth_k: u32,
131    rewards_config: RewardsConfig,
132    domain_block_pruning_depth: u32,
133    staking_withdrawal_period: u32,
134}
135
136struct GenesisDomainParams {
137    domain_name: String,
138    operator_allow_list: OperatorAllowList<AccountId>,
139    operator_signing_key: OperatorPublicKey,
140    raw_genesis_storage: Vec<u8>,
141    initial_balances: Vec<(MultiAccountId, Balance)>,
142    permissioned_action_allowed_by: PermissionedActionAllowedBy<AccountId>,
143    domain_runtime_info: DomainRuntimeInfo,
144}
145
146pub fn dev_config() -> Result<GenericChainSpec, String> {
147    let wasm_binary = subspace_runtime::WASM_BINARY
148        .ok_or_else(|| "Development wasm not available".to_string())?;
149
150    let raw_genesis_storage = {
151        let domain_genesis_config = domain_dev_config()?;
152        let storage = domain_genesis_config
153            .build_storage()
154            .expect("Failed to build genesis storage from genesis runtime config");
155        let raw_genesis = RawGenesis::from_storage(storage);
156        raw_genesis.encode()
157    };
158
159    let GenesisConfigParams {
160        confirmation_depth_k,
161        domain_block_pruning_depth,
162        staking_withdrawal_period,
163    } = GenesisConfigParams::dev_params();
164
165    Ok(GenericChainSpec::builder(wasm_binary, None)
166        .with_name("Subspace development")
167        .with_id("subspace_dev")
168        .with_chain_type(ChainType::Development)
169        .with_genesis_config(
170            serde_json::to_value(subspace_genesis_config(
171                // Sudo account
172                get_account_id_from_seed("Alice"),
173                // Pre-funded accounts
174                vec![
175                    (get_account_id_from_seed("Alice"), Balance::MAX / 2),
176                    (get_account_id_from_seed("Bob"), 1_000 * AI3),
177                    (get_account_id_from_seed("Alice//stash"), 1_000 * AI3),
178                    (get_account_id_from_seed("Bob//stash"), 1_000 * AI3),
179                ],
180                GenesisParams {
181                    enable_rewards_at: EnableRewardsAt::Manually,
182                    allow_authoring_by: AllowAuthoringBy::Anyone,
183                    pot_slot_iterations: NonZeroU32::new(100_000_000).expect("Not zero; qed"),
184                    enable_domains: true,
185                    enable_dynamic_cost_of_storage: false,
186                    enable_balance_transfers: true,
187                    confirmation_depth_k,
188                    rewards_config: RewardsConfig {
189                        remaining_issuance: 1_000_000 * AI3,
190                        proposer_subsidy_points: Default::default(),
191                        voter_subsidy_points: Default::default(),
192                    },
193                    domain_block_pruning_depth,
194                    staking_withdrawal_period,
195                },
196                GenesisDomainParams {
197                    domain_name: "evm-domain".to_owned(),
198                    operator_allow_list: OperatorAllowList::Anyone,
199                    operator_signing_key: get_public_key_from_seed::<OperatorPublicKey>("Alice"),
200                    raw_genesis_storage: raw_genesis_storage.clone(),
201                    initial_balances: endowed_accounts(),
202                    permissioned_action_allowed_by: PermissionedActionAllowedBy::Anyone,
203                    domain_runtime_info: (
204                        DEFAULT_EVM_CHAIN_ID,
205                        EvmDomainRuntimeConfig {
206                            evm_type: EvmType::Public,
207                        },
208                    )
209                        .into(),
210                },
211            ))
212            .map_err(|error| format!("Failed to serialize genesis config: {error}"))?,
213        )
214        .build())
215}
216
217/// Configure initial storage state for FRAME modules.
218fn subspace_genesis_config(
219    sudo_account: AccountId,
220    balances: Vec<(AccountId, Balance)>,
221    genesis_params: GenesisParams,
222    genesis_domain_params: GenesisDomainParams,
223) -> subspace_runtime::RuntimeGenesisConfig {
224    let GenesisParams {
225        enable_rewards_at,
226        allow_authoring_by,
227        pot_slot_iterations,
228        enable_domains,
229        enable_dynamic_cost_of_storage,
230        enable_balance_transfers,
231        confirmation_depth_k,
232        rewards_config,
233        domain_block_pruning_depth,
234        staking_withdrawal_period,
235    } = genesis_params;
236
237    subspace_runtime::RuntimeGenesisConfig {
238        system: subspace_runtime::SystemConfig::default(),
239        balances: subspace_runtime::BalancesConfig { balances },
240        transaction_payment: Default::default(),
241        sudo: subspace_runtime::SudoConfig {
242            // Assign network admin rights.
243            key: Some(sudo_account.clone()),
244        },
245        subspace: SubspaceConfig {
246            enable_rewards_at,
247            allow_authoring_by,
248            pot_slot_iterations,
249            phantom: PhantomData,
250        },
251        rewards: rewards_config,
252        council: CouncilConfig::default(),
253        democracy: DemocracyConfig::default(),
254        runtime_configs: RuntimeConfigsConfig {
255            enable_domains,
256            enable_dynamic_cost_of_storage,
257            enable_balance_transfers,
258            confirmation_depth_k,
259            council_democracy_config_params:
260                CouncilDemocracyConfigParams::<BlockNumber>::fast_params(),
261            domain_block_pruning_depth,
262            staking_withdrawal_period,
263        },
264        domains: DomainsConfig {
265            permissioned_action_allowed_by: Some(
266                genesis_domain_params.permissioned_action_allowed_by,
267            ),
268            genesis_domains: vec![sp_domains::GenesisDomain {
269                runtime_name: "evm".to_owned(),
270                runtime_type: RuntimeType::Evm,
271                runtime_version: evm_domain_runtime::VERSION,
272                raw_genesis_storage: genesis_domain_params.raw_genesis_storage,
273
274                // Domain config, mainly for placeholder the concrete value TBD
275                owner_account_id: sudo_account.clone(),
276                domain_name: genesis_domain_params.domain_name,
277                bundle_slot_probability: (1, 1),
278                operator_allow_list: genesis_domain_params.operator_allow_list,
279                signing_key: genesis_domain_params.operator_signing_key,
280                nomination_tax: Percent::from_percent(5),
281                minimum_nominator_stake: 100 * AI3,
282                initial_balances: genesis_domain_params.initial_balances,
283                domain_runtime_info: genesis_domain_params.domain_runtime_info,
284            }],
285        },
286    }
287}