mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-09 20:11:09 +00:00
chain-spec: getting ready for native-runtime-free world (#1256)
This PR prepares chains specs for _native-runtime-free_ world. This PR has following changes: - `substrate`: - adds support for: - JSON based `GenesisConfig` to `ChainSpec` allowing interaction with runtime `GenesisBuilder` API. - interacting with arbitrary runtime wasm blob to[ `chain-spec-builder`](https://github.com/paritytech/substrate/blob/3ef576eaeb3f42610e85daecc464961cf1295570/bin/utils/chain-spec-builder/src/lib.rs#L46) command line util, - removes [`code`](https://github.com/paritytech/substrate/blob/3ef576eaeb3f42610e85daecc464961cf1295570/frame/system/src/lib.rs#L660) from `system_pallet` - adds `code` to the `ChainSpec` - deprecates [`ChainSpec::from_genesis`](https://github.com/paritytech/substrate/blob/3ef576eaeb3f42610e85daecc464961cf1295570/client/chain-spec/src/chain_spec.rs#L263), but also changes the signature of this method extending it with `code` argument. [`ChainSpec::builder()`](https://github.com/paritytech/substrate/blob/20bee680ed098be7239cf7a6b804cd4de267983e/client/chain-spec/src/chain_spec.rs#L507) should be used instead. - `polkadot`: - all references to `RuntimeGenesisConfig` in `node/service` are removed, - all `(kusama|polkadot|versi|rococo|wococo)_(staging|dev)_genesis_config` functions now return the JSON patch for default runtime `GenesisConfig`, - `ChainSpecBuilder` is used, `ChainSpec::from_genesis` is removed, - `cumulus`: - `ChainSpecBuilder` is used, `ChainSpec::from_genesis` is removed, - _JSON_ patch configuration used instead of `RuntimeGenesisConfig struct` in all chain specs. --------- Co-authored-by: command-bot <> Co-authored-by: Javier Viola <javier@parity.io> Co-authored-by: Davide Galassi <davxy@datawok.net> Co-authored-by: Francisco Aguirre <franciscoaguirreperez@gmail.com> Co-authored-by: Kevin Krone <kevin@parity.io> Co-authored-by: Bastian Köcher <git@kchr.de>
This commit is contained in:
committed by
GitHub
parent
c46a7dbb61
commit
8ba7a6aba8
+1
-1
@@ -30,7 +30,7 @@ variables:
|
||||
RUSTY_CACHIER_COMPRESSION_METHOD: zstd
|
||||
NEXTEST_FAILURE_OUTPUT: immediate-final
|
||||
NEXTEST_SUCCESS_OUTPUT: final
|
||||
ZOMBIENET_IMAGE: "docker.io/paritytech/zombienet:v1.3.75"
|
||||
ZOMBIENET_IMAGE: "docker.io/paritytech/zombienet:v1.3.79"
|
||||
DOCKER_IMAGES_VERSION: "${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHORT_SHA}"
|
||||
|
||||
default:
|
||||
|
||||
Generated
+29
@@ -965,6 +965,7 @@ dependencies = [
|
||||
"sp-block-builder",
|
||||
"sp-consensus-aura",
|
||||
"sp-core",
|
||||
"sp-genesis-builder",
|
||||
"sp-inherents",
|
||||
"sp-offchain",
|
||||
"sp-runtime",
|
||||
@@ -4222,6 +4223,7 @@ dependencies = [
|
||||
"sp-api",
|
||||
"sp-block-builder",
|
||||
"sp-core",
|
||||
"sp-genesis-builder",
|
||||
"sp-inherents",
|
||||
"sp-io",
|
||||
"sp-offchain",
|
||||
@@ -4288,6 +4290,7 @@ dependencies = [
|
||||
"sc-transaction-pool",
|
||||
"sc-transaction-pool-api",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sp-api",
|
||||
"sp-arithmetic",
|
||||
"sp-authority-discovery",
|
||||
@@ -6738,7 +6741,9 @@ dependencies = [
|
||||
"polkadot-service",
|
||||
"rococo-runtime",
|
||||
"rococo-runtime-constants",
|
||||
"sc-chain-spec",
|
||||
"sc-consensus-grandpa",
|
||||
"serde_json",
|
||||
"sp-authority-discovery",
|
||||
"sp-consensus-babe",
|
||||
"sp-consensus-beefy",
|
||||
@@ -7159,6 +7164,7 @@ dependencies = [
|
||||
"parity-scale-codec",
|
||||
"primitive-types",
|
||||
"scale-info",
|
||||
"serde_json",
|
||||
"sp-api",
|
||||
"sp-authority-discovery",
|
||||
"sp-block-builder",
|
||||
@@ -8199,6 +8205,7 @@ dependencies = [
|
||||
"sc-telemetry",
|
||||
"sc-transaction-pool",
|
||||
"sc-transaction-pool-api",
|
||||
"serde_json",
|
||||
"sp-api",
|
||||
"sp-block-builder",
|
||||
"sp-blockchain",
|
||||
@@ -8215,6 +8222,7 @@ name = "minimal-runtime"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"frame",
|
||||
"frame-support",
|
||||
"pallet-balances",
|
||||
"pallet-sudo",
|
||||
"pallet-timestamp",
|
||||
@@ -8222,6 +8230,7 @@ dependencies = [
|
||||
"pallet-transaction-payment-rpc-runtime-api",
|
||||
"parity-scale-codec",
|
||||
"scale-info",
|
||||
"sp-genesis-builder",
|
||||
"substrate-wasm-builder",
|
||||
]
|
||||
|
||||
@@ -8679,6 +8688,7 @@ dependencies = [
|
||||
"sc-telemetry",
|
||||
"sc-transaction-pool",
|
||||
"sc-transaction-pool-api",
|
||||
"serde_json",
|
||||
"sp-api",
|
||||
"sp-block-builder",
|
||||
"sp-blockchain",
|
||||
@@ -8730,6 +8740,7 @@ dependencies = [
|
||||
"pallet-transaction-payment-rpc-runtime-api",
|
||||
"parity-scale-codec",
|
||||
"scale-info",
|
||||
"serde_json",
|
||||
"sp-api",
|
||||
"sp-block-builder",
|
||||
"sp-consensus-aura",
|
||||
@@ -11168,6 +11179,7 @@ dependencies = [
|
||||
"sc-transaction-pool",
|
||||
"sc-transaction-pool-api",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sp-api",
|
||||
"sp-block-builder",
|
||||
"sp-blockchain",
|
||||
@@ -12743,6 +12755,7 @@ dependencies = [
|
||||
"sp-runtime",
|
||||
"sp-session",
|
||||
"sp-timestamp",
|
||||
"sp-tracing 10.0.0",
|
||||
"sp-transaction-pool",
|
||||
"staging-xcm",
|
||||
"substrate-build-script-utils",
|
||||
@@ -14783,7 +14796,11 @@ dependencies = [
|
||||
name = "sc-chain-spec"
|
||||
version = "4.0.0-dev"
|
||||
dependencies = [
|
||||
"array-bytes 6.1.0",
|
||||
"docify",
|
||||
"log",
|
||||
"memmap2",
|
||||
"parity-scale-codec",
|
||||
"sc-chain-spec-derive",
|
||||
"sc-client-api",
|
||||
"sc-executor",
|
||||
@@ -14791,10 +14808,16 @@ dependencies = [
|
||||
"sc-telemetry",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sp-application-crypto",
|
||||
"sp-blockchain",
|
||||
"sp-consensus-babe",
|
||||
"sp-core",
|
||||
"sp-genesis-builder",
|
||||
"sp-io",
|
||||
"sp-keyring",
|
||||
"sp-runtime",
|
||||
"sp-state-machine",
|
||||
"substrate-test-runtime",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -17986,11 +18009,15 @@ version = "2.0.0"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"clap 4.4.6",
|
||||
"kitchensink-runtime",
|
||||
"log",
|
||||
"rand 0.8.5",
|
||||
"sc-chain-spec",
|
||||
"sc-keystore",
|
||||
"serde_json",
|
||||
"sp-core",
|
||||
"sp-keystore",
|
||||
"sp-tracing 10.0.0",
|
||||
"staging-node-cli",
|
||||
]
|
||||
|
||||
@@ -18110,6 +18137,7 @@ dependencies = [
|
||||
"parity-scale-codec",
|
||||
"sc-executor",
|
||||
"scale-info",
|
||||
"serde_json",
|
||||
"sp-application-crypto",
|
||||
"sp-consensus-babe",
|
||||
"sp-core",
|
||||
@@ -18339,6 +18367,7 @@ name = "substrate"
|
||||
version = "1.0.0"
|
||||
dependencies = [
|
||||
"frame-support",
|
||||
"sc-chain-spec",
|
||||
"sc-cli",
|
||||
"sc-consensus-aura",
|
||||
"sc-consensus-babe",
|
||||
|
||||
@@ -17,6 +17,7 @@ codec = { package = "parity-scale-codec", version = "3.0.0" }
|
||||
serde = { version = "1.0.188", features = ["derive"] }
|
||||
jsonrpsee = { version = "0.16.2", features = ["server"] }
|
||||
futures = "0.3.28"
|
||||
serde_json = "1.0.104"
|
||||
|
||||
# Local
|
||||
parachain-template-runtime = { path = "../runtime" }
|
||||
|
||||
@@ -7,8 +7,7 @@ use sp_core::{sr25519, Pair, Public};
|
||||
use sp_runtime::traits::{IdentifyAccount, Verify};
|
||||
|
||||
/// Specialized `ChainSpec` for the normal parachain runtime.
|
||||
pub type ChainSpec =
|
||||
sc_service::GenericChainSpec<parachain_template_runtime::RuntimeGenesisConfig, Extensions>;
|
||||
pub type ChainSpec = sc_service::GenericChainSpec<(), Extensions>;
|
||||
|
||||
/// The default XCM version to set in genesis config.
|
||||
const SAFE_XCM_VERSION: u32 = xcm::prelude::XCM_VERSION;
|
||||
@@ -68,53 +67,48 @@ pub fn development_config() -> ChainSpec {
|
||||
properties.insert("tokenDecimals".into(), 12.into());
|
||||
properties.insert("ss58Format".into(), 42.into());
|
||||
|
||||
ChainSpec::from_genesis(
|
||||
// Name
|
||||
"Development",
|
||||
// ID
|
||||
"dev",
|
||||
ChainType::Development,
|
||||
move || {
|
||||
testnet_genesis(
|
||||
// initial collators.
|
||||
vec![
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_collator_keys_from_seed("Alice"),
|
||||
),
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_collator_keys_from_seed("Bob"),
|
||||
),
|
||||
],
|
||||
vec![
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),
|
||||
],
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
1000.into(),
|
||||
)
|
||||
},
|
||||
Vec::new(),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
ChainSpec::builder(
|
||||
parachain_template_runtime::WASM_BINARY
|
||||
.expect("WASM binary was not built, please build it!"),
|
||||
Extensions {
|
||||
relay_chain: "rococo-local".into(), // You MUST set this to the correct network!
|
||||
relay_chain: "rococo-local".into(),
|
||||
// You MUST set this to the correct network!
|
||||
para_id: 1000,
|
||||
},
|
||||
)
|
||||
.with_name("Development")
|
||||
.with_id("dev")
|
||||
.with_chain_type(ChainType::Development)
|
||||
.with_genesis_config_patch(testnet_genesis(
|
||||
// initial collators.
|
||||
vec![
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_collator_keys_from_seed("Alice"),
|
||||
),
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_collator_keys_from_seed("Bob"),
|
||||
),
|
||||
],
|
||||
vec![
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),
|
||||
],
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
1000.into(),
|
||||
))
|
||||
.build()
|
||||
}
|
||||
|
||||
pub fn local_testnet_config() -> ChainSpec {
|
||||
@@ -124,59 +118,51 @@ pub fn local_testnet_config() -> ChainSpec {
|
||||
properties.insert("tokenDecimals".into(), 12.into());
|
||||
properties.insert("ss58Format".into(), 42.into());
|
||||
|
||||
ChainSpec::from_genesis(
|
||||
// Name
|
||||
"Local Testnet",
|
||||
// ID
|
||||
"local_testnet",
|
||||
ChainType::Local,
|
||||
move || {
|
||||
testnet_genesis(
|
||||
// initial collators.
|
||||
vec![
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_collator_keys_from_seed("Alice"),
|
||||
),
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_collator_keys_from_seed("Bob"),
|
||||
),
|
||||
],
|
||||
vec![
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),
|
||||
],
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
1000.into(),
|
||||
)
|
||||
},
|
||||
// Bootnodes
|
||||
Vec::new(),
|
||||
// Telemetry
|
||||
None,
|
||||
// Protocol ID
|
||||
Some("template-local"),
|
||||
// Fork ID
|
||||
None,
|
||||
// Properties
|
||||
Some(properties),
|
||||
// Extensions
|
||||
#[allow(deprecated)]
|
||||
ChainSpec::builder(
|
||||
parachain_template_runtime::WASM_BINARY
|
||||
.expect("WASM binary was not built, please build it!"),
|
||||
Extensions {
|
||||
relay_chain: "rococo-local".into(), // You MUST set this to the correct network!
|
||||
relay_chain: "rococo-local".into(),
|
||||
// You MUST set this to the correct network!
|
||||
para_id: 1000,
|
||||
},
|
||||
)
|
||||
.with_name("Local Testnet")
|
||||
.with_id("local_testnet")
|
||||
.with_chain_type(ChainType::Local)
|
||||
.with_genesis_config_patch(testnet_genesis(
|
||||
// initial collators.
|
||||
vec![
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_collator_keys_from_seed("Alice"),
|
||||
),
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_collator_keys_from_seed("Bob"),
|
||||
),
|
||||
],
|
||||
vec![
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),
|
||||
],
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
1000.into(),
|
||||
))
|
||||
.with_protocol_id("template-local")
|
||||
.with_properties(properties)
|
||||
.build()
|
||||
}
|
||||
|
||||
fn testnet_genesis(
|
||||
@@ -184,28 +170,20 @@ fn testnet_genesis(
|
||||
endowed_accounts: Vec<AccountId>,
|
||||
root: AccountId,
|
||||
id: ParaId,
|
||||
) -> parachain_template_runtime::RuntimeGenesisConfig {
|
||||
parachain_template_runtime::RuntimeGenesisConfig {
|
||||
system: parachain_template_runtime::SystemConfig {
|
||||
code: parachain_template_runtime::WASM_BINARY
|
||||
.expect("WASM binary was not build, please build it!")
|
||||
.to_vec(),
|
||||
..Default::default()
|
||||
) -> serde_json::Value {
|
||||
serde_json::json!({
|
||||
"balances": {
|
||||
"balances": endowed_accounts.iter().cloned().map(|k| (k, 1u64 << 60)).collect::<Vec<_>>(),
|
||||
},
|
||||
balances: parachain_template_runtime::BalancesConfig {
|
||||
balances: endowed_accounts.iter().cloned().map(|k| (k, 1 << 60)).collect(),
|
||||
"parachainInfo": {
|
||||
"parachainId": id,
|
||||
},
|
||||
parachain_info: parachain_template_runtime::ParachainInfoConfig {
|
||||
parachain_id: id,
|
||||
..Default::default()
|
||||
"collatorSelection": {
|
||||
"invulnerables": invulnerables.iter().cloned().map(|(acc, _)| acc).collect::<Vec<_>>(),
|
||||
"candidacyBond": EXISTENTIAL_DEPOSIT * 16,
|
||||
},
|
||||
collator_selection: parachain_template_runtime::CollatorSelectionConfig {
|
||||
invulnerables: invulnerables.iter().cloned().map(|(acc, _)| acc).collect(),
|
||||
candidacy_bond: EXISTENTIAL_DEPOSIT * 16,
|
||||
..Default::default()
|
||||
},
|
||||
session: parachain_template_runtime::SessionConfig {
|
||||
keys: invulnerables
|
||||
"session": {
|
||||
"keys": invulnerables
|
||||
.into_iter()
|
||||
.map(|(acc, aura)| {
|
||||
(
|
||||
@@ -214,18 +192,11 @@ fn testnet_genesis(
|
||||
template_session_keys(aura), // session keys
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
.collect::<Vec<_>>(),
|
||||
},
|
||||
// no need to pass anything to aura, in fact it will panic if we do. Session will take care
|
||||
// of this.
|
||||
aura: Default::default(),
|
||||
aura_ext: Default::default(),
|
||||
parachain_system: Default::default(),
|
||||
polkadot_xcm: parachain_template_runtime::PolkadotXcmConfig {
|
||||
safe_xcm_version: Some(SAFE_XCM_VERSION),
|
||||
..Default::default()
|
||||
"polkadotXcm": {
|
||||
"safeXcmVersion": Some(SAFE_XCM_VERSION),
|
||||
},
|
||||
transaction_payment: Default::default(),
|
||||
sudo: parachain_template_runtime::SudoConfig { key: Some(root) },
|
||||
}
|
||||
"sudo": { "key": Some(root) }
|
||||
})
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ publish = false
|
||||
[dependencies]
|
||||
codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false }
|
||||
paste = "1.0.14"
|
||||
serde_json = "1.0.104"
|
||||
|
||||
# Substrate
|
||||
grandpa = { package = "sc-consensus-grandpa", path = "../../../../../substrate/client/consensus/grandpa" }
|
||||
@@ -24,6 +25,7 @@ pallet-staking = { path = "../../../../../substrate/frame/staking", default-feat
|
||||
pallet-message-queue = { path = "../../../../../substrate/frame/message-queue", default-features = false}
|
||||
pallet-im-online = { path = "../../../../../substrate/frame/im-online", default-features = false}
|
||||
beefy-primitives = { package = "sp-consensus-beefy", path = "../../../../../substrate/primitives/consensus/beefy" }
|
||||
sc-chain-spec = { path = "../../../../../substrate/client/chain-spec", default-features = false }
|
||||
|
||||
# Polkadot
|
||||
polkadot-core-primitives = { path = "../../../../../polkadot/core-primitives", default-features = false}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -45,6 +45,7 @@ sp-block-builder = { path = "../../../../../substrate/primitives/block-builder",
|
||||
sp-consensus-aura = { path = "../../../../../substrate/primitives/consensus/aura", default-features = false}
|
||||
sp-core = { path = "../../../../../substrate/primitives/core", default-features = false}
|
||||
sp-inherents = { path = "../../../../../substrate/primitives/inherents", default-features = false}
|
||||
sp-genesis-builder = { path = "../../../../../substrate/primitives/genesis-builder", default-features = false }
|
||||
sp-offchain = { path = "../../../../../substrate/primitives/offchain", default-features = false}
|
||||
sp-runtime = { path = "../../../../../substrate/primitives/runtime", default-features = false}
|
||||
sp-session = { path = "../../../../../substrate/primitives/session", default-features = false}
|
||||
@@ -230,6 +231,7 @@ std = [
|
||||
"sp-block-builder/std",
|
||||
"sp-consensus-aura/std",
|
||||
"sp-core/std",
|
||||
"sp-genesis-builder/std",
|
||||
"sp-inherents/std",
|
||||
"sp-offchain/std",
|
||||
"sp-runtime/std",
|
||||
|
||||
@@ -60,6 +60,7 @@ use cumulus_primitives_core::ParaId;
|
||||
use frame_support::{
|
||||
construct_runtime,
|
||||
dispatch::DispatchClass,
|
||||
genesis_builder_helper::{build_config, create_default_config},
|
||||
ord_parameter_types, parameter_types,
|
||||
traits::{
|
||||
AsEnsureOriginWithArg, ConstBool, ConstU128, ConstU32, ConstU64, ConstU8, EitherOfDiverse,
|
||||
@@ -1568,6 +1569,16 @@ impl_runtime_apis! {
|
||||
Ok(batches)
|
||||
}
|
||||
}
|
||||
|
||||
impl sp_genesis_builder::GenesisBuilder<Block> for Runtime {
|
||||
fn create_default_config() -> Vec<u8> {
|
||||
create_default_config::<RuntimeGenesisConfig>()
|
||||
}
|
||||
|
||||
fn build_config(config: Vec<u8>) -> sp_genesis_builder::Result {
|
||||
build_config::<RuntimeGenesisConfig>(config)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cumulus_pallet_parachain_system::register_validate_block! {
|
||||
|
||||
@@ -48,6 +48,7 @@ sp-io = { path = "../../substrate/primitives/io" }
|
||||
sp-core = { path = "../../substrate/primitives/core" }
|
||||
sp-session = { path = "../../substrate/primitives/session" }
|
||||
sc-consensus = { path = "../../substrate/client/consensus/common" }
|
||||
sp-tracing = { path = "../../substrate/primitives/tracing" }
|
||||
sc-cli = { path = "../../substrate/client/cli" }
|
||||
sc-client-api = { path = "../../substrate/client/api" }
|
||||
sc-executor = { path = "../../substrate/client/executor" }
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -215,8 +215,7 @@ pub mod rococo {
|
||||
parachains_common::rococo::currency::EXISTENTIAL_DEPOSIT;
|
||||
|
||||
/// Specialized `ChainSpec` for the normal parachain runtime.
|
||||
pub type BridgeHubChainSpec =
|
||||
sc_service::GenericChainSpec<bridge_hub_rococo_runtime::RuntimeGenesisConfig, Extensions>;
|
||||
pub type BridgeHubChainSpec = sc_service::GenericChainSpec<(), Extensions>;
|
||||
|
||||
pub type RuntimeApi = bridge_hub_rococo_runtime::RuntimeApi;
|
||||
|
||||
@@ -235,52 +234,47 @@ pub mod rococo {
|
||||
properties.insert("tokenDecimals".into(), 12.into());
|
||||
modify_props(&mut properties);
|
||||
|
||||
BridgeHubChainSpec::from_genesis(
|
||||
// Name
|
||||
chain_name,
|
||||
// ID
|
||||
super::ensure_id(id).expect("invalid id"),
|
||||
ChainType::Local,
|
||||
move || {
|
||||
genesis(
|
||||
// initial collators.
|
||||
vec![
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_collator_keys_from_seed::<AuraId>("Alice"),
|
||||
),
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_collator_keys_from_seed::<AuraId>("Bob"),
|
||||
),
|
||||
],
|
||||
vec![
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),
|
||||
],
|
||||
para_id,
|
||||
bridges_pallet_owner_seed
|
||||
.as_ref()
|
||||
.map(|seed| get_account_id_from_seed::<sr25519::Public>(seed)),
|
||||
)
|
||||
},
|
||||
Vec::new(),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Some(properties),
|
||||
BridgeHubChainSpec::builder(
|
||||
bridge_hub_rococo_runtime::WASM_BINARY
|
||||
.expect("WASM binary was not built, please build it!"),
|
||||
Extensions { relay_chain: relay_chain.to_string(), para_id: para_id.into() },
|
||||
)
|
||||
.with_name(chain_name)
|
||||
.with_id(super::ensure_id(id).expect("invalid id"))
|
||||
.with_chain_type(ChainType::Local)
|
||||
.with_genesis_config_patch(genesis(
|
||||
// initial collators.
|
||||
vec![
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_collator_keys_from_seed::<AuraId>("Alice"),
|
||||
),
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_collator_keys_from_seed::<AuraId>("Bob"),
|
||||
),
|
||||
],
|
||||
vec![
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),
|
||||
],
|
||||
para_id,
|
||||
bridges_pallet_owner_seed
|
||||
.as_ref()
|
||||
.map(|seed| get_account_id_from_seed::<sr25519::Public>(seed)),
|
||||
))
|
||||
.with_properties(properties)
|
||||
.build()
|
||||
}
|
||||
|
||||
fn genesis(
|
||||
@@ -288,28 +282,20 @@ pub mod rococo {
|
||||
endowed_accounts: Vec<AccountId>,
|
||||
id: ParaId,
|
||||
bridges_pallet_owner: Option<AccountId>,
|
||||
) -> bridge_hub_rococo_runtime::RuntimeGenesisConfig {
|
||||
bridge_hub_rococo_runtime::RuntimeGenesisConfig {
|
||||
system: bridge_hub_rococo_runtime::SystemConfig {
|
||||
code: bridge_hub_rococo_runtime::WASM_BINARY
|
||||
.expect("WASM binary was not build, please build it!")
|
||||
.to_vec(),
|
||||
..Default::default()
|
||||
) -> serde_json::Value {
|
||||
serde_json::json!({
|
||||
"balances": {
|
||||
"balances": endowed_accounts.iter().cloned().map(|k| (k, 1u64 << 60)).collect::<Vec<_>>(),
|
||||
},
|
||||
balances: bridge_hub_rococo_runtime::BalancesConfig {
|
||||
balances: endowed_accounts.iter().cloned().map(|k| (k, 1 << 60)).collect(),
|
||||
"parachainInfo": {
|
||||
"parachainId": id,
|
||||
},
|
||||
parachain_info: bridge_hub_rococo_runtime::ParachainInfoConfig {
|
||||
parachain_id: id,
|
||||
..Default::default()
|
||||
"collatorSelection": {
|
||||
"invulnerables": invulnerables.iter().cloned().map(|(acc, _)| acc).collect::<Vec<_>>(),
|
||||
"candidacyBond": BRIDGE_HUB_ROCOCO_ED * 16,
|
||||
},
|
||||
collator_selection: bridge_hub_rococo_runtime::CollatorSelectionConfig {
|
||||
invulnerables: invulnerables.iter().cloned().map(|(acc, _)| acc).collect(),
|
||||
candidacy_bond: BRIDGE_HUB_ROCOCO_ED * 16,
|
||||
..Default::default()
|
||||
},
|
||||
session: bridge_hub_rococo_runtime::SessionConfig {
|
||||
keys: invulnerables
|
||||
"session": {
|
||||
"keys": invulnerables
|
||||
.into_iter()
|
||||
.map(|(acc, aura)| {
|
||||
(
|
||||
@@ -318,40 +304,31 @@ pub mod rococo {
|
||||
bridge_hub_rococo_runtime::SessionKeys { aura }, // session keys
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
.collect::<Vec<_>>(),
|
||||
},
|
||||
aura: Default::default(),
|
||||
aura_ext: Default::default(),
|
||||
parachain_system: Default::default(),
|
||||
polkadot_xcm: bridge_hub_rococo_runtime::PolkadotXcmConfig {
|
||||
safe_xcm_version: Some(SAFE_XCM_VERSION),
|
||||
..Default::default()
|
||||
"polkadotXcm": {
|
||||
"safeXcmVersion": Some(SAFE_XCM_VERSION),
|
||||
},
|
||||
bridge_wococo_grandpa: bridge_hub_rococo_runtime::BridgeWococoGrandpaConfig {
|
||||
owner: bridges_pallet_owner.clone(),
|
||||
..Default::default()
|
||||
|
||||
"bridgeWococoGrandpa": {
|
||||
"owner": bridges_pallet_owner.clone(),
|
||||
},
|
||||
bridge_westend_grandpa: bridge_hub_rococo_runtime::BridgeWestendGrandpaConfig {
|
||||
owner: bridges_pallet_owner.clone(),
|
||||
..Default::default()
|
||||
"bridgeWestendGrandpa": {
|
||||
"owner": bridges_pallet_owner.clone(),
|
||||
},
|
||||
bridge_rococo_grandpa: bridge_hub_rococo_runtime::BridgeRococoGrandpaConfig {
|
||||
owner: bridges_pallet_owner.clone(),
|
||||
..Default::default()
|
||||
"bridgeRococoGrandpa": {
|
||||
"owner": bridges_pallet_owner.clone(),
|
||||
},
|
||||
bridge_rococo_messages: bridge_hub_rococo_runtime::BridgeRococoMessagesConfig {
|
||||
owner: bridges_pallet_owner.clone(),
|
||||
..Default::default()
|
||||
"bridgeRococoMessages": {
|
||||
"owner": bridges_pallet_owner.clone(),
|
||||
},
|
||||
bridge_wococo_messages: bridge_hub_rococo_runtime::BridgeWococoMessagesConfig {
|
||||
owner: bridges_pallet_owner.clone(),
|
||||
..Default::default()
|
||||
"bridgeWococoMessages": {
|
||||
"owner": bridges_pallet_owner.clone(),
|
||||
},
|
||||
bridge_westend_messages: bridge_hub_rococo_runtime::BridgeWestendMessagesConfig {
|
||||
owner: bridges_pallet_owner.clone(),
|
||||
..Default::default()
|
||||
"bridgeWestendMessages": {
|
||||
"owner": bridges_pallet_owner.clone(),
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -403,8 +380,7 @@ pub mod kusama {
|
||||
parachains_common::kusama::currency::EXISTENTIAL_DEPOSIT;
|
||||
|
||||
/// Specialized `ChainSpec` for the normal parachain runtime.
|
||||
pub type BridgeHubChainSpec =
|
||||
sc_service::GenericChainSpec<bridge_hub_kusama_runtime::RuntimeGenesisConfig, Extensions>;
|
||||
pub type BridgeHubChainSpec = sc_service::GenericChainSpec<(), Extensions>;
|
||||
pub type RuntimeApi = bridge_hub_kusama_runtime::RuntimeApi;
|
||||
|
||||
pub fn local_config(
|
||||
@@ -418,81 +394,68 @@ pub mod kusama {
|
||||
properties.insert("tokenSymbol".into(), "KSM".into());
|
||||
properties.insert("tokenDecimals".into(), 12.into());
|
||||
|
||||
BridgeHubChainSpec::from_genesis(
|
||||
// Name
|
||||
chain_name,
|
||||
// ID
|
||||
super::ensure_id(id).expect("invalid id"),
|
||||
ChainType::Local,
|
||||
move || {
|
||||
genesis(
|
||||
// initial collators.
|
||||
vec![
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_collator_keys_from_seed::<AuraId>("Alice"),
|
||||
),
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_collator_keys_from_seed::<AuraId>("Bob"),
|
||||
),
|
||||
],
|
||||
vec![
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),
|
||||
],
|
||||
para_id,
|
||||
)
|
||||
},
|
||||
Vec::new(),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Some(properties),
|
||||
BridgeHubChainSpec::builder(
|
||||
bridge_hub_kusama_runtime::WASM_BINARY
|
||||
.expect("WASM binary was not built, please build it!"),
|
||||
Extensions { relay_chain: relay_chain.to_string(), para_id: para_id.into() },
|
||||
)
|
||||
.with_name(chain_name)
|
||||
.with_id(super::ensure_id(id).expect("invalid id"))
|
||||
.with_chain_type(ChainType::Local)
|
||||
.with_genesis_config_patch(genesis(
|
||||
// initial collators.
|
||||
vec![
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_collator_keys_from_seed::<AuraId>("Alice"),
|
||||
),
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_collator_keys_from_seed::<AuraId>("Bob"),
|
||||
),
|
||||
],
|
||||
vec![
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),
|
||||
],
|
||||
para_id,
|
||||
))
|
||||
.with_properties(properties)
|
||||
.build()
|
||||
}
|
||||
|
||||
fn genesis(
|
||||
invulnerables: Vec<(AccountId, AuraId)>,
|
||||
endowed_accounts: Vec<AccountId>,
|
||||
id: ParaId,
|
||||
) -> bridge_hub_kusama_runtime::RuntimeGenesisConfig {
|
||||
bridge_hub_kusama_runtime::RuntimeGenesisConfig {
|
||||
system: bridge_hub_kusama_runtime::SystemConfig {
|
||||
code: bridge_hub_kusama_runtime::WASM_BINARY
|
||||
.expect("WASM binary was not build, please build it!")
|
||||
.to_vec(),
|
||||
..Default::default()
|
||||
},
|
||||
balances: bridge_hub_kusama_runtime::BalancesConfig {
|
||||
balances: endowed_accounts
|
||||
) -> serde_json::Value {
|
||||
serde_json::json!({
|
||||
"balances": {
|
||||
"balances": endowed_accounts
|
||||
.iter()
|
||||
.cloned()
|
||||
.map(|k| (k, BRIDGE_HUB_KUSAMA_ED * 524_288))
|
||||
.collect(),
|
||||
.collect::<Vec<_>>(),
|
||||
},
|
||||
parachain_info: bridge_hub_kusama_runtime::ParachainInfoConfig {
|
||||
parachain_id: id,
|
||||
..Default::default()
|
||||
"parachainInfo": {
|
||||
"parachainId": id,
|
||||
},
|
||||
collator_selection: bridge_hub_kusama_runtime::CollatorSelectionConfig {
|
||||
invulnerables: invulnerables.iter().cloned().map(|(acc, _)| acc).collect(),
|
||||
candidacy_bond: BRIDGE_HUB_KUSAMA_ED * 16,
|
||||
..Default::default()
|
||||
"collatorSelection": {
|
||||
"invulnerables": invulnerables.iter().cloned().map(|(acc, _)| acc).collect::<Vec<_>>(),
|
||||
"candidacyBond": BRIDGE_HUB_KUSAMA_ED * 16,
|
||||
},
|
||||
session: bridge_hub_kusama_runtime::SessionConfig {
|
||||
keys: invulnerables
|
||||
"session": {
|
||||
"keys": invulnerables
|
||||
.into_iter()
|
||||
.map(|(acc, aura)| {
|
||||
(
|
||||
@@ -501,16 +464,12 @@ pub mod kusama {
|
||||
bridge_hub_kusama_runtime::SessionKeys { aura }, // session keys
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
.collect::<Vec<_>>(),
|
||||
},
|
||||
aura: Default::default(),
|
||||
aura_ext: Default::default(),
|
||||
parachain_system: Default::default(),
|
||||
polkadot_xcm: bridge_hub_kusama_runtime::PolkadotXcmConfig {
|
||||
safe_xcm_version: Some(SAFE_XCM_VERSION),
|
||||
..Default::default()
|
||||
},
|
||||
}
|
||||
"polkadotXcm": {
|
||||
"safeXcmVersion": Some(SAFE_XCM_VERSION),
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -545,52 +504,47 @@ pub mod westend {
|
||||
properties.insert("tokenSymbol".into(), "WND".into());
|
||||
properties.insert("tokenDecimals".into(), 12.into());
|
||||
|
||||
BridgeHubChainSpec::from_genesis(
|
||||
// Name
|
||||
chain_name,
|
||||
// ID
|
||||
super::ensure_id(id).expect("invalid id"),
|
||||
ChainType::Local,
|
||||
move || {
|
||||
genesis(
|
||||
// initial collators.
|
||||
vec![
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_collator_keys_from_seed::<AuraId>("Alice"),
|
||||
),
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_collator_keys_from_seed::<AuraId>("Bob"),
|
||||
),
|
||||
],
|
||||
vec![
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),
|
||||
],
|
||||
para_id,
|
||||
bridges_pallet_owner_seed
|
||||
.as_ref()
|
||||
.map(|seed| get_account_id_from_seed::<sr25519::Public>(seed)),
|
||||
)
|
||||
},
|
||||
Vec::new(),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Some(properties),
|
||||
BridgeHubChainSpec::builder(
|
||||
bridge_hub_westend_runtime::WASM_BINARY
|
||||
.expect("WASM binary was not build, please build it!"),
|
||||
Extensions { relay_chain: relay_chain.to_string(), para_id: para_id.into() },
|
||||
)
|
||||
.with_name(chain_name)
|
||||
.with_id(super::ensure_id(id).expect("invalid id"))
|
||||
.with_chain_type(ChainType::Local)
|
||||
.with_genesis_config_patch(genesis(
|
||||
// initial collators.
|
||||
vec![
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_collator_keys_from_seed::<AuraId>("Alice"),
|
||||
),
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_collator_keys_from_seed::<AuraId>("Bob"),
|
||||
),
|
||||
],
|
||||
vec![
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),
|
||||
],
|
||||
para_id,
|
||||
bridges_pallet_owner_seed
|
||||
.as_ref()
|
||||
.map(|seed| get_account_id_from_seed::<sr25519::Public>(seed)),
|
||||
))
|
||||
.with_properties(properties)
|
||||
.build()
|
||||
}
|
||||
|
||||
fn genesis(
|
||||
@@ -598,28 +552,20 @@ pub mod westend {
|
||||
endowed_accounts: Vec<AccountId>,
|
||||
id: ParaId,
|
||||
bridges_pallet_owner: Option<AccountId>,
|
||||
) -> bridge_hub_westend_runtime::RuntimeGenesisConfig {
|
||||
bridge_hub_westend_runtime::RuntimeGenesisConfig {
|
||||
system: bridge_hub_westend_runtime::SystemConfig {
|
||||
code: bridge_hub_westend_runtime::WASM_BINARY
|
||||
.expect("WASM binary was not build, please build it!")
|
||||
.to_vec(),
|
||||
..Default::default()
|
||||
) -> serde_json::Value {
|
||||
serde_json::json!({
|
||||
"balances": {
|
||||
"balances": endowed_accounts.iter().cloned().map(|k| (k, 1u64 << 60)).collect::<Vec<_>>(),
|
||||
},
|
||||
balances: bridge_hub_westend_runtime::BalancesConfig {
|
||||
balances: endowed_accounts.iter().cloned().map(|k| (k, 1 << 60)).collect(),
|
||||
"parachainInfo": {
|
||||
"parachainId": id,
|
||||
},
|
||||
parachain_info: bridge_hub_westend_runtime::ParachainInfoConfig {
|
||||
parachain_id: id,
|
||||
..Default::default()
|
||||
"collatorSelection": {
|
||||
"invulnerables": invulnerables.iter().cloned().map(|(acc, _)| acc).collect::<Vec<_>>(),
|
||||
"candidacyBond": BRIDGE_HUB_WESTEND_ED * 16,
|
||||
},
|
||||
collator_selection: bridge_hub_westend_runtime::CollatorSelectionConfig {
|
||||
invulnerables: invulnerables.iter().cloned().map(|(acc, _)| acc).collect(),
|
||||
candidacy_bond: BRIDGE_HUB_WESTEND_ED * 16,
|
||||
..Default::default()
|
||||
},
|
||||
session: bridge_hub_westend_runtime::SessionConfig {
|
||||
keys: invulnerables
|
||||
"session": {
|
||||
"keys": invulnerables
|
||||
.into_iter()
|
||||
.map(|(acc, aura)| {
|
||||
(
|
||||
@@ -628,24 +574,18 @@ pub mod westend {
|
||||
bridge_hub_westend_runtime::SessionKeys { aura }, // session keys
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
.collect::<Vec<_>>(),
|
||||
},
|
||||
aura: Default::default(),
|
||||
aura_ext: Default::default(),
|
||||
parachain_system: Default::default(),
|
||||
polkadot_xcm: bridge_hub_westend_runtime::PolkadotXcmConfig {
|
||||
safe_xcm_version: Some(SAFE_XCM_VERSION),
|
||||
..Default::default()
|
||||
"polkadotXcm": {
|
||||
"safeXcmVersion": Some(SAFE_XCM_VERSION),
|
||||
},
|
||||
bridge_rococo_grandpa: bridge_hub_westend_runtime::BridgeRococoGrandpaConfig {
|
||||
owner: bridges_pallet_owner.clone(),
|
||||
..Default::default()
|
||||
"bridgeRococoGrandpa": {
|
||||
"owner": bridges_pallet_owner.clone(),
|
||||
},
|
||||
bridge_rococo_messages: bridge_hub_westend_runtime::BridgeRococoMessagesConfig {
|
||||
owner: bridges_pallet_owner.clone(),
|
||||
..Default::default()
|
||||
},
|
||||
}
|
||||
"bridgeRococoMessages": {
|
||||
"owner": bridges_pallet_owner.clone(),
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -666,8 +606,7 @@ pub mod polkadot {
|
||||
parachains_common::polkadot::currency::EXISTENTIAL_DEPOSIT;
|
||||
|
||||
/// Specialized `ChainSpec` for the normal parachain runtime.
|
||||
pub type BridgeHubChainSpec =
|
||||
sc_service::GenericChainSpec<bridge_hub_polkadot_runtime::RuntimeGenesisConfig, Extensions>;
|
||||
pub type BridgeHubChainSpec = sc_service::GenericChainSpec<(), Extensions>;
|
||||
pub type RuntimeApi = bridge_hub_polkadot_runtime::RuntimeApi;
|
||||
|
||||
pub fn local_config(
|
||||
@@ -681,81 +620,68 @@ pub mod polkadot {
|
||||
properties.insert("tokenSymbol".into(), "DOT".into());
|
||||
properties.insert("tokenDecimals".into(), 10.into());
|
||||
|
||||
BridgeHubChainSpec::from_genesis(
|
||||
// Name
|
||||
chain_name,
|
||||
// ID
|
||||
super::ensure_id(id).expect("invalid id"),
|
||||
ChainType::Local,
|
||||
move || {
|
||||
genesis(
|
||||
// initial collators.
|
||||
vec![
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_collator_keys_from_seed::<AuraId>("Alice"),
|
||||
),
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_collator_keys_from_seed::<AuraId>("Bob"),
|
||||
),
|
||||
],
|
||||
vec![
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),
|
||||
],
|
||||
para_id,
|
||||
)
|
||||
},
|
||||
Vec::new(),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Some(properties),
|
||||
BridgeHubChainSpec::builder(
|
||||
bridge_hub_polkadot_runtime::WASM_BINARY
|
||||
.expect("WASM binary was not built, please build it!"),
|
||||
Extensions { relay_chain: relay_chain.to_string(), para_id: para_id.into() },
|
||||
)
|
||||
.with_name(chain_name)
|
||||
.with_id(super::ensure_id(id).expect("invalid id"))
|
||||
.with_chain_type(ChainType::Local)
|
||||
.with_genesis_config_patch(genesis(
|
||||
// initial collators.
|
||||
vec![
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_collator_keys_from_seed::<AuraId>("Alice"),
|
||||
),
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_collator_keys_from_seed::<AuraId>("Bob"),
|
||||
),
|
||||
],
|
||||
vec![
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),
|
||||
],
|
||||
para_id,
|
||||
))
|
||||
.with_properties(properties)
|
||||
.build()
|
||||
}
|
||||
|
||||
fn genesis(
|
||||
invulnerables: Vec<(AccountId, AuraId)>,
|
||||
endowed_accounts: Vec<AccountId>,
|
||||
id: ParaId,
|
||||
) -> bridge_hub_polkadot_runtime::RuntimeGenesisConfig {
|
||||
bridge_hub_polkadot_runtime::RuntimeGenesisConfig {
|
||||
system: bridge_hub_polkadot_runtime::SystemConfig {
|
||||
code: bridge_hub_polkadot_runtime::WASM_BINARY
|
||||
.expect("WASM binary was not build, please build it!")
|
||||
.to_vec(),
|
||||
..Default::default()
|
||||
},
|
||||
balances: bridge_hub_polkadot_runtime::BalancesConfig {
|
||||
balances: endowed_accounts
|
||||
) -> serde_json::Value {
|
||||
serde_json::json!({
|
||||
"balances": {
|
||||
"balances": endowed_accounts
|
||||
.iter()
|
||||
.cloned()
|
||||
.map(|k| (k, BRIDGE_HUB_POLKADOT_ED * 4096))
|
||||
.collect(),
|
||||
.collect::<Vec<_>>(),
|
||||
},
|
||||
parachain_info: bridge_hub_polkadot_runtime::ParachainInfoConfig {
|
||||
parachain_id: id,
|
||||
..Default::default()
|
||||
"parachainInfo": {
|
||||
"parachainId": id,
|
||||
},
|
||||
collator_selection: bridge_hub_polkadot_runtime::CollatorSelectionConfig {
|
||||
invulnerables: invulnerables.iter().cloned().map(|(acc, _)| acc).collect(),
|
||||
candidacy_bond: BRIDGE_HUB_POLKADOT_ED * 16,
|
||||
..Default::default()
|
||||
"collatorSelection": {
|
||||
"invulnerables": invulnerables.iter().cloned().map(|(acc, _)| acc).collect::<Vec<_>>(),
|
||||
"candidacyBond": BRIDGE_HUB_POLKADOT_ED * 16,
|
||||
},
|
||||
session: bridge_hub_polkadot_runtime::SessionConfig {
|
||||
keys: invulnerables
|
||||
"session": {
|
||||
"keys": invulnerables
|
||||
.into_iter()
|
||||
.map(|(acc, aura)| {
|
||||
(
|
||||
@@ -764,15 +690,11 @@ pub mod polkadot {
|
||||
bridge_hub_polkadot_runtime::SessionKeys { aura }, // session keys
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
.collect::<Vec<_>>(),
|
||||
},
|
||||
aura: Default::default(),
|
||||
aura_ext: Default::default(),
|
||||
parachain_system: Default::default(),
|
||||
polkadot_xcm: bridge_hub_polkadot_runtime::PolkadotXcmConfig {
|
||||
safe_xcm_version: Some(SAFE_XCM_VERSION),
|
||||
..Default::default()
|
||||
},
|
||||
}
|
||||
"polkadotXcm": {
|
||||
"safeXcmVersion": Some(SAFE_XCM_VERSION),
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,8 +22,7 @@ use parachains_common::{AccountId, AuraId, Balance as CollectivesBalance};
|
||||
use sc_service::ChainType;
|
||||
use sp_core::sr25519;
|
||||
|
||||
pub type CollectivesPolkadotChainSpec =
|
||||
sc_service::GenericChainSpec<collectives_polkadot_runtime::RuntimeGenesisConfig, Extensions>;
|
||||
pub type CollectivesPolkadotChainSpec = sc_service::GenericChainSpec<(), Extensions>;
|
||||
|
||||
const COLLECTIVES_POLKADOT_ED: CollectivesBalance =
|
||||
parachains_common::polkadot::currency::EXISTENTIAL_DEPOSIT;
|
||||
@@ -43,37 +42,33 @@ pub fn collectives_polkadot_development_config() -> CollectivesPolkadotChainSpec
|
||||
properties.insert("tokenSymbol".into(), "DOT".into());
|
||||
properties.insert("tokenDecimals".into(), 10.into());
|
||||
|
||||
CollectivesPolkadotChainSpec::from_genesis(
|
||||
// Name
|
||||
"Polkadot Collectives Development",
|
||||
// ID
|
||||
"collectives_polkadot_dev",
|
||||
ChainType::Local,
|
||||
move || {
|
||||
collectives_polkadot_genesis(
|
||||
// initial collators.
|
||||
vec![(
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_collator_keys_from_seed::<AuraId>("Alice"),
|
||||
)],
|
||||
vec![
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
|
||||
],
|
||||
// 1002 avoids a potential collision with Kusama-1001 (Encointer) should there ever
|
||||
// be a collective para on Kusama.
|
||||
1002.into(),
|
||||
)
|
||||
},
|
||||
Vec::new(),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Some(properties),
|
||||
CollectivesPolkadotChainSpec::builder(
|
||||
collectives_polkadot_runtime::WASM_BINARY
|
||||
.expect("WASM binary was not built, please build it!"),
|
||||
Extensions { relay_chain: "polkadot-dev".into(), para_id: 1002 },
|
||||
)
|
||||
.with_name("Polkadot Collectives Development")
|
||||
.with_id("collectives_polkadot_dev")
|
||||
.with_chain_type(ChainType::Local)
|
||||
.with_genesis_config_patch(collectives_polkadot_genesis(
|
||||
// initial collators.
|
||||
vec![(
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_collator_keys_from_seed::<AuraId>("Alice"),
|
||||
)],
|
||||
vec![
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
|
||||
],
|
||||
// 1002 avoids a potential collision with Kusama-1001 (Encointer) should there ever
|
||||
// be a collective para on Kusama.
|
||||
1002.into(),
|
||||
))
|
||||
.with_boot_nodes(Vec::new())
|
||||
.with_properties(properties)
|
||||
.build()
|
||||
}
|
||||
|
||||
/// Collectives Polkadot Local Config.
|
||||
@@ -83,81 +78,69 @@ pub fn collectives_polkadot_local_config() -> CollectivesPolkadotChainSpec {
|
||||
properties.insert("tokenSymbol".into(), "DOT".into());
|
||||
properties.insert("tokenDecimals".into(), 10.into());
|
||||
|
||||
CollectivesPolkadotChainSpec::from_genesis(
|
||||
// Name
|
||||
"Polkadot Collectives Local",
|
||||
// ID
|
||||
"collectives_polkadot_local",
|
||||
ChainType::Local,
|
||||
move || {
|
||||
collectives_polkadot_genesis(
|
||||
// initial collators.
|
||||
vec![
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_collator_keys_from_seed::<AuraId>("Alice"),
|
||||
),
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_collator_keys_from_seed::<AuraId>("Bob"),
|
||||
),
|
||||
],
|
||||
vec![
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),
|
||||
],
|
||||
1002.into(),
|
||||
)
|
||||
},
|
||||
Vec::new(),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Some(properties),
|
||||
CollectivesPolkadotChainSpec::builder(
|
||||
collectives_polkadot_runtime::WASM_BINARY
|
||||
.expect("WASM binary was not built, please build it!"),
|
||||
Extensions { relay_chain: "polkadot-local".into(), para_id: 1002 },
|
||||
)
|
||||
.with_name("Polkadot Collectives Local")
|
||||
.with_id("collectives_polkadot_local")
|
||||
.with_chain_type(ChainType::Local)
|
||||
.with_genesis_config_patch(collectives_polkadot_genesis(
|
||||
// initial collators.
|
||||
vec![
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_collator_keys_from_seed::<AuraId>("Alice"),
|
||||
),
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_collator_keys_from_seed::<AuraId>("Bob"),
|
||||
),
|
||||
],
|
||||
vec![
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),
|
||||
],
|
||||
1002.into(),
|
||||
))
|
||||
.with_boot_nodes(Vec::new())
|
||||
.with_properties(properties)
|
||||
.build()
|
||||
}
|
||||
|
||||
fn collectives_polkadot_genesis(
|
||||
invulnerables: Vec<(AccountId, AuraId)>,
|
||||
endowed_accounts: Vec<AccountId>,
|
||||
id: ParaId,
|
||||
) -> collectives_polkadot_runtime::RuntimeGenesisConfig {
|
||||
collectives_polkadot_runtime::RuntimeGenesisConfig {
|
||||
system: collectives_polkadot_runtime::SystemConfig {
|
||||
code: collectives_polkadot_runtime::WASM_BINARY
|
||||
.expect("WASM binary was not build, please build it!")
|
||||
.to_vec(),
|
||||
..Default::default()
|
||||
},
|
||||
balances: collectives_polkadot_runtime::BalancesConfig {
|
||||
balances: endowed_accounts
|
||||
) -> serde_json::Value {
|
||||
serde_json::json!( {
|
||||
"balances": {
|
||||
"balances": endowed_accounts
|
||||
.iter()
|
||||
.cloned()
|
||||
.map(|k| (k, COLLECTIVES_POLKADOT_ED * 4096))
|
||||
.collect(),
|
||||
.collect::<Vec<_>>(),
|
||||
},
|
||||
parachain_info: collectives_polkadot_runtime::ParachainInfoConfig {
|
||||
parachain_id: id,
|
||||
..Default::default()
|
||||
"parachainInfo": {
|
||||
"parachainId": id,
|
||||
},
|
||||
collator_selection: collectives_polkadot_runtime::CollatorSelectionConfig {
|
||||
invulnerables: invulnerables.iter().cloned().map(|(acc, _)| acc).collect(),
|
||||
candidacy_bond: COLLECTIVES_POLKADOT_ED * 16,
|
||||
..Default::default()
|
||||
"collatorSelection": {
|
||||
"invulnerables": invulnerables.iter().cloned().map(|(acc, _)| acc).collect::<Vec<_>>(),
|
||||
"candidacyBond": COLLECTIVES_POLKADOT_ED * 16,
|
||||
},
|
||||
session: collectives_polkadot_runtime::SessionConfig {
|
||||
keys: invulnerables
|
||||
"session": {
|
||||
"keys": invulnerables
|
||||
.into_iter()
|
||||
.map(|(acc, aura)| {
|
||||
(
|
||||
@@ -166,18 +149,12 @@ fn collectives_polkadot_genesis(
|
||||
collectives_polkadot_session_keys(aura), // session keys
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
.collect::<Vec<_>>(),
|
||||
},
|
||||
// no need to pass anything to aura, in fact it will panic if we do. Session will take care
|
||||
// of this.
|
||||
aura: Default::default(),
|
||||
aura_ext: Default::default(),
|
||||
parachain_system: Default::default(),
|
||||
polkadot_xcm: collectives_polkadot_runtime::PolkadotXcmConfig {
|
||||
safe_xcm_version: Some(SAFE_XCM_VERSION),
|
||||
..Default::default()
|
||||
"polkadotXcm": {
|
||||
"safeXcmVersion": Some(SAFE_XCM_VERSION),
|
||||
},
|
||||
alliance: Default::default(),
|
||||
alliance_motion: Default::default(),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -23,8 +23,7 @@ use parachains_common::{AccountId, AuraId};
|
||||
use sc_service::ChainType;
|
||||
use sp_core::{crypto::UncheckedInto, sr25519};
|
||||
|
||||
pub type ContractsRococoChainSpec =
|
||||
sc_service::GenericChainSpec<contracts_rococo_runtime::RuntimeGenesisConfig, Extensions>;
|
||||
pub type ContractsRococoChainSpec = sc_service::GenericChainSpec<(), Extensions>;
|
||||
|
||||
/// No relay chain suffix because the id is the same over all relay chains.
|
||||
const CONTRACTS_PARACHAIN_ID: u32 = 1002;
|
||||
@@ -38,52 +37,46 @@ pub fn contracts_rococo_development_config() -> ContractsRococoChainSpec {
|
||||
properties.insert("tokenSymbol".into(), "ROC".into());
|
||||
properties.insert("tokenDecimals".into(), 12.into());
|
||||
|
||||
ContractsRococoChainSpec::from_genesis(
|
||||
// Name
|
||||
"Contracts on Rococo Development",
|
||||
// ID
|
||||
"contracts-rococo-dev",
|
||||
ChainType::Development,
|
||||
move || {
|
||||
contracts_rococo_genesis(
|
||||
// initial collators.
|
||||
vec![
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_collator_keys_from_seed::<contracts_rococo_runtime::AuraId>("Alice"),
|
||||
),
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_collator_keys_from_seed::<contracts_rococo_runtime::AuraId>("Bob"),
|
||||
),
|
||||
],
|
||||
vec![
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),
|
||||
],
|
||||
CONTRACTS_PARACHAIN_ID.into(),
|
||||
)
|
||||
},
|
||||
Vec::new(),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
ContractsRococoChainSpec::builder(
|
||||
contracts_rococo_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"),
|
||||
Extensions {
|
||||
relay_chain: "rococo-local".into(), // You MUST set this to the correct network!
|
||||
para_id: CONTRACTS_PARACHAIN_ID,
|
||||
},
|
||||
)
|
||||
.with_name("Contracts on Rococo Development")
|
||||
.with_id("contracts-rococo-dev")
|
||||
.with_chain_type(ChainType::Development)
|
||||
.with_genesis_config_patch(contracts_rococo_genesis(
|
||||
// initial collators.
|
||||
vec![
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_collator_keys_from_seed::<contracts_rococo_runtime::AuraId>("Alice"),
|
||||
),
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_collator_keys_from_seed::<contracts_rococo_runtime::AuraId>("Bob"),
|
||||
),
|
||||
],
|
||||
vec![
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),
|
||||
],
|
||||
CONTRACTS_PARACHAIN_ID.into(),
|
||||
))
|
||||
.with_boot_nodes(Vec::new())
|
||||
.build()
|
||||
}
|
||||
|
||||
pub fn contracts_rococo_local_config() -> ContractsRococoChainSpec {
|
||||
@@ -91,58 +84,46 @@ pub fn contracts_rococo_local_config() -> ContractsRococoChainSpec {
|
||||
properties.insert("tokenSymbol".into(), "ROC".into());
|
||||
properties.insert("tokenDecimals".into(), 12.into());
|
||||
|
||||
ContractsRococoChainSpec::from_genesis(
|
||||
// Name
|
||||
"Contracts on Rococo",
|
||||
// ID
|
||||
"contracts-rococo-local",
|
||||
ChainType::Local,
|
||||
move || {
|
||||
contracts_rococo_genesis(
|
||||
// initial collators.
|
||||
vec![
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_collator_keys_from_seed::<contracts_rococo_runtime::AuraId>("Alice"),
|
||||
),
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_collator_keys_from_seed::<contracts_rococo_runtime::AuraId>("Bob"),
|
||||
),
|
||||
],
|
||||
vec![
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),
|
||||
],
|
||||
CONTRACTS_PARACHAIN_ID.into(),
|
||||
)
|
||||
},
|
||||
// Bootnodes
|
||||
Vec::new(),
|
||||
// Telemetry
|
||||
None,
|
||||
// Protocol ID
|
||||
None,
|
||||
// Fork ID
|
||||
None,
|
||||
// Properties
|
||||
Some(properties),
|
||||
// Extensions
|
||||
ContractsRococoChainSpec::builder(
|
||||
contracts_rococo_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"),
|
||||
Extensions {
|
||||
relay_chain: "rococo-local".into(), // You MUST set this to the correct network!
|
||||
para_id: CONTRACTS_PARACHAIN_ID,
|
||||
},
|
||||
)
|
||||
.with_name("Contracts on Rococo")
|
||||
.with_id("contracts-rococo-local")
|
||||
.with_chain_type(ChainType::Local)
|
||||
.with_genesis_config_patch(contracts_rococo_genesis(
|
||||
// initial collators.
|
||||
vec![
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_collator_keys_from_seed::<contracts_rococo_runtime::AuraId>("Alice"),
|
||||
),
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_collator_keys_from_seed::<contracts_rococo_runtime::AuraId>("Bob"),
|
||||
),
|
||||
],
|
||||
vec![
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),
|
||||
],
|
||||
CONTRACTS_PARACHAIN_ID.into(),
|
||||
))
|
||||
.with_properties(properties)
|
||||
.build()
|
||||
}
|
||||
|
||||
pub fn contracts_rococo_config() -> ContractsRococoChainSpec {
|
||||
@@ -151,111 +132,92 @@ pub fn contracts_rococo_config() -> ContractsRococoChainSpec {
|
||||
properties.insert("tokenSymbol".into(), "ROC".into());
|
||||
properties.insert("tokenDecimals".into(), 12.into());
|
||||
|
||||
ContractsRococoChainSpec::from_genesis(
|
||||
// Name
|
||||
"Contracts on Rococo",
|
||||
// ID
|
||||
"contracts-rococo",
|
||||
ChainType::Live,
|
||||
move || {
|
||||
contracts_rococo_genesis(
|
||||
vec![
|
||||
// 5GKFbTTgrVS4Vz1UWWHPqMZQNFWZtqo7H2KpCDyYhEL3aS26
|
||||
(
|
||||
hex!["bc09354c12c054c8f6b3da208485eacec4ac648bad348895273b37bab5a0937c"]
|
||||
.into(),
|
||||
hex!["bc09354c12c054c8f6b3da208485eacec4ac648bad348895273b37bab5a0937c"]
|
||||
.unchecked_into(),
|
||||
),
|
||||
// 5EPRJHm2GpABVWcwnAujcrhnrjFZyDGd5TwKFzkBoGgdRyv2
|
||||
(
|
||||
hex!["66be63b7bcbfb91040e5248e2d1ceb822cf219c57848c5924ffa3a1f8e67ba72"]
|
||||
.into(),
|
||||
hex!["66be63b7bcbfb91040e5248e2d1ceb822cf219c57848c5924ffa3a1f8e67ba72"]
|
||||
.unchecked_into(),
|
||||
),
|
||||
// 5GH62vrJrVZxLREcHzm2PR5uTLAT5RQMJitoztCGyaP4o3uM
|
||||
(
|
||||
hex!["ba62886472a0a9f66b5e39f1469ce1c5b3d8cad6be39078daf16f111e89d1e44"]
|
||||
.into(),
|
||||
hex!["ba62886472a0a9f66b5e39f1469ce1c5b3d8cad6be39078daf16f111e89d1e44"]
|
||||
.unchecked_into(),
|
||||
),
|
||||
// 5FHfoJDLdjRYX5KXLRqMDYBbWrwHLMtti21uK4QByUoUAbJF
|
||||
(
|
||||
hex!["8e97f65cda001976311df9bed39e8d0c956089093e94a75ef76fe9347a0eda7b"]
|
||||
.into(),
|
||||
hex!["8e97f65cda001976311df9bed39e8d0c956089093e94a75ef76fe9347a0eda7b"]
|
||||
.unchecked_into(),
|
||||
),
|
||||
],
|
||||
// Warning: The configuration for a production chain should not contain
|
||||
// any endowed accounts here, otherwise it'll be minting extra native tokens
|
||||
// from the relay chain on the parachain.
|
||||
vec![
|
||||
// NOTE: Remove endowed accounts if deployed on other relay chains.
|
||||
// Endowed accounts
|
||||
hex!["baa78c7154c7f82d6d377177e20bcab65d327eca0086513f9964f5a0f6bdad56"].into(),
|
||||
// AccountId of an account which `ink-waterfall` uses for automated testing
|
||||
hex!["0e47e2344d523c3cc5c34394b0d58b9a4200e813a038e6c5a6163cc07d70b069"].into(),
|
||||
],
|
||||
CONTRACTS_PARACHAIN_ID.into(),
|
||||
)
|
||||
},
|
||||
// Bootnodes
|
||||
vec![
|
||||
ContractsRococoChainSpec::builder(
|
||||
contracts_rococo_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"),
|
||||
Extensions { relay_chain: "rococo".into(), para_id: CONTRACTS_PARACHAIN_ID }
|
||||
)
|
||||
.with_name("Contracts on Rococo")
|
||||
.with_id("contracts-rococo")
|
||||
.with_chain_type(ChainType::Live)
|
||||
.with_genesis_config_patch(contracts_rococo_genesis(
|
||||
vec![
|
||||
// 5GKFbTTgrVS4Vz1UWWHPqMZQNFWZtqo7H2KpCDyYhEL3aS26
|
||||
(
|
||||
hex!["bc09354c12c054c8f6b3da208485eacec4ac648bad348895273b37bab5a0937c"]
|
||||
.into(),
|
||||
hex!["bc09354c12c054c8f6b3da208485eacec4ac648bad348895273b37bab5a0937c"]
|
||||
.unchecked_into(),
|
||||
),
|
||||
// 5EPRJHm2GpABVWcwnAujcrhnrjFZyDGd5TwKFzkBoGgdRyv2
|
||||
(
|
||||
hex!["66be63b7bcbfb91040e5248e2d1ceb822cf219c57848c5924ffa3a1f8e67ba72"]
|
||||
.into(),
|
||||
hex!["66be63b7bcbfb91040e5248e2d1ceb822cf219c57848c5924ffa3a1f8e67ba72"]
|
||||
.unchecked_into(),
|
||||
),
|
||||
// 5GH62vrJrVZxLREcHzm2PR5uTLAT5RQMJitoztCGyaP4o3uM
|
||||
(
|
||||
hex!["ba62886472a0a9f66b5e39f1469ce1c5b3d8cad6be39078daf16f111e89d1e44"]
|
||||
.into(),
|
||||
hex!["ba62886472a0a9f66b5e39f1469ce1c5b3d8cad6be39078daf16f111e89d1e44"]
|
||||
.unchecked_into(),
|
||||
),
|
||||
// 5FHfoJDLdjRYX5KXLRqMDYBbWrwHLMtti21uK4QByUoUAbJF
|
||||
(
|
||||
hex!["8e97f65cda001976311df9bed39e8d0c956089093e94a75ef76fe9347a0eda7b"]
|
||||
.into(),
|
||||
hex!["8e97f65cda001976311df9bed39e8d0c956089093e94a75ef76fe9347a0eda7b"]
|
||||
.unchecked_into(),
|
||||
),
|
||||
],
|
||||
// Warning: The configuration for a production chain should not contain
|
||||
// any endowed accounts here, otherwise it'll be minting extra native tokens
|
||||
// from the relay chain on the parachain.
|
||||
vec![
|
||||
// NOTE: Remove endowed accounts if deployed on other relay chains.
|
||||
// Endowed accounts
|
||||
hex!["baa78c7154c7f82d6d377177e20bcab65d327eca0086513f9964f5a0f6bdad56"].into(),
|
||||
// AccountId of an account which `ink-waterfall` uses for automated testing
|
||||
hex!["0e47e2344d523c3cc5c34394b0d58b9a4200e813a038e6c5a6163cc07d70b069"].into(),
|
||||
],
|
||||
CONTRACTS_PARACHAIN_ID.into(),
|
||||
))
|
||||
.with_boot_nodes(vec![
|
||||
"/dns/contracts-collator-0.parity-testnet.parity.io/tcp/30333/p2p/12D3KooWKg3Rpxcr9oJ8n6khoxpGKWztCZydtUZk2cojHqnfLrpj"
|
||||
.parse()
|
||||
.expect("MultiaddrWithPeerId"),
|
||||
.parse()
|
||||
.expect("MultiaddrWithPeerId"),
|
||||
"/dns/contracts-collator-1.parity-testnet.parity.io/tcp/30333/p2p/12D3KooWPEXYrz8tHU3nDtPoPw4V7ou5dzMEWSTuUj7vaWiYVAVh"
|
||||
.parse()
|
||||
.expect("MultiaddrWithPeerId"),
|
||||
.parse()
|
||||
.expect("MultiaddrWithPeerId"),
|
||||
"/dns/contracts-collator-2.parity-testnet.parity.io/tcp/30333/p2p/12D3KooWEVU8AFNary4nP4qEnEcwJaRuy59Wefekzdu9pKbnVEhk"
|
||||
.parse()
|
||||
.expect("MultiaddrWithPeerId"),
|
||||
.parse()
|
||||
.expect("MultiaddrWithPeerId"),
|
||||
"/dns/contracts-collator-3.parity-testnet.parity.io/tcp/30333/p2p/12D3KooWP6pV3ZmcXzGDjv8ZMgA6nZxfAKDxSz4VNiLx6vVCQgJX"
|
||||
.parse()
|
||||
.expect("MultiaddrWithPeerId"),
|
||||
],
|
||||
// Telemetry
|
||||
None,
|
||||
// Protocol ID
|
||||
None,
|
||||
// Fork ID
|
||||
None,
|
||||
// Properties
|
||||
Some(properties),
|
||||
// Extensions
|
||||
Extensions { relay_chain: "rococo".into(), para_id: CONTRACTS_PARACHAIN_ID },
|
||||
)
|
||||
.parse()
|
||||
.expect("MultiaddrWithPeerId"),
|
||||
])
|
||||
.with_properties(properties)
|
||||
.build()
|
||||
}
|
||||
|
||||
fn contracts_rococo_genesis(
|
||||
invulnerables: Vec<(AccountId, AuraId)>,
|
||||
endowed_accounts: Vec<AccountId>,
|
||||
id: ParaId,
|
||||
) -> contracts_rococo_runtime::RuntimeGenesisConfig {
|
||||
contracts_rococo_runtime::RuntimeGenesisConfig {
|
||||
system: contracts_rococo_runtime::SystemConfig {
|
||||
code: contracts_rococo_runtime::WASM_BINARY
|
||||
.expect("WASM binary was not build, please build it!")
|
||||
.to_vec(),
|
||||
..Default::default()
|
||||
) -> serde_json::Value {
|
||||
serde_json::json!( {
|
||||
"balances": {
|
||||
"balances": endowed_accounts.iter().cloned().map(|k| (k, 1u64 << 60)).collect::<Vec<_>>(),
|
||||
},
|
||||
balances: contracts_rococo_runtime::BalancesConfig {
|
||||
balances: endowed_accounts.iter().cloned().map(|k| (k, 1 << 60)).collect(),
|
||||
"parachainInfo": {
|
||||
"parachainId": id,
|
||||
},
|
||||
parachain_info: contracts_rococo_runtime::ParachainInfoConfig {
|
||||
parachain_id: id,
|
||||
..Default::default()
|
||||
"collatorSelection": {
|
||||
"invulnerables": invulnerables.iter().cloned().map(|(acc, _)| acc).collect::<Vec<_>>(),
|
||||
"candidacyBond": CONTRACTS_ROCOCO_ED * 16,
|
||||
},
|
||||
collator_selection: contracts_rococo_runtime::CollatorSelectionConfig {
|
||||
invulnerables: invulnerables.iter().cloned().map(|(acc, _)| acc).collect(),
|
||||
candidacy_bond: CONTRACTS_ROCOCO_ED * 16,
|
||||
..Default::default()
|
||||
},
|
||||
session: contracts_rococo_runtime::SessionConfig {
|
||||
keys: invulnerables
|
||||
"session": {
|
||||
"keys": invulnerables
|
||||
.into_iter()
|
||||
.map(|(acc, aura)| {
|
||||
(
|
||||
@@ -264,21 +226,17 @@ fn contracts_rococo_genesis(
|
||||
contracts_rococo_runtime::SessionKeys { aura }, // session keys
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
.collect::<Vec<_>>(),
|
||||
},
|
||||
// no need to pass anything to aura, in fact it will panic if we do. Session will take care
|
||||
// of this.
|
||||
aura: Default::default(),
|
||||
aura_ext: Default::default(),
|
||||
parachain_system: Default::default(),
|
||||
polkadot_xcm: contracts_rococo_runtime::PolkadotXcmConfig {
|
||||
safe_xcm_version: Some(SAFE_XCM_VERSION),
|
||||
..Default::default()
|
||||
"polkadotXcm": {
|
||||
"safeXcmVersion": Some(SAFE_XCM_VERSION),
|
||||
},
|
||||
sudo: contracts_rococo_runtime::SudoConfig {
|
||||
key: Some(
|
||||
hex!["2681a28014e7d3a5bfb32a003b3571f53c408acbc28d351d6bf58f5028c4ef14"].into(),
|
||||
),
|
||||
"sudo": {
|
||||
"key": Some(sp_runtime::AccountId32::from(hex![
|
||||
"2681a28014e7d3a5bfb32a003b3571f53c408acbc28d351d6bf58f5028c4ef14"
|
||||
])),
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -23,103 +23,72 @@ use sp_core::sr25519;
|
||||
use super::get_collator_keys_from_seed;
|
||||
|
||||
/// Specialized `ChainSpec` for the Glutton parachain runtime.
|
||||
pub type GluttonChainSpec =
|
||||
sc_service::GenericChainSpec<glutton_runtime::RuntimeGenesisConfig, Extensions>;
|
||||
pub type GluttonChainSpec = sc_service::GenericChainSpec<(), Extensions>;
|
||||
|
||||
pub fn glutton_development_config(para_id: ParaId) -> GluttonChainSpec {
|
||||
GluttonChainSpec::from_genesis(
|
||||
// Name
|
||||
"Glutton Development",
|
||||
// ID
|
||||
"glutton_dev",
|
||||
ChainType::Local,
|
||||
move || glutton_genesis(para_id, vec![get_collator_keys_from_seed::<AuraId>("Alice")]),
|
||||
Vec::new(),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
GluttonChainSpec::builder(
|
||||
glutton_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"),
|
||||
Extensions { relay_chain: "kusama-dev".into(), para_id: para_id.into() },
|
||||
)
|
||||
.with_name("Glutton Development")
|
||||
.with_id("glutton_dev")
|
||||
.with_chain_type(ChainType::Local)
|
||||
.with_genesis_config_patch(glutton_genesis(
|
||||
para_id,
|
||||
vec![get_collator_keys_from_seed::<AuraId>("Alice")],
|
||||
))
|
||||
.build()
|
||||
}
|
||||
|
||||
pub fn glutton_local_config(para_id: ParaId) -> GluttonChainSpec {
|
||||
GluttonChainSpec::from_genesis(
|
||||
// Name
|
||||
"Glutton Local",
|
||||
// ID
|
||||
"glutton_local",
|
||||
ChainType::Local,
|
||||
move || {
|
||||
glutton_genesis(
|
||||
para_id,
|
||||
vec![
|
||||
get_collator_keys_from_seed::<AuraId>("Alice"),
|
||||
get_collator_keys_from_seed::<AuraId>("Bob"),
|
||||
],
|
||||
)
|
||||
},
|
||||
Vec::new(),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
GluttonChainSpec::builder(
|
||||
glutton_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"),
|
||||
Extensions { relay_chain: "kusama-local".into(), para_id: para_id.into() },
|
||||
)
|
||||
.with_name("Glutton Local")
|
||||
.with_id("glutton_local")
|
||||
.with_chain_type(ChainType::Local)
|
||||
.with_genesis_config_patch(glutton_genesis(
|
||||
para_id,
|
||||
vec![
|
||||
get_collator_keys_from_seed::<AuraId>("Alice"),
|
||||
get_collator_keys_from_seed::<AuraId>("Bob"),
|
||||
],
|
||||
))
|
||||
.build()
|
||||
}
|
||||
|
||||
pub fn glutton_config(para_id: ParaId) -> GluttonChainSpec {
|
||||
let mut properties = sc_chain_spec::Properties::new();
|
||||
properties.insert("ss58Format".into(), 2.into());
|
||||
|
||||
GluttonChainSpec::from_genesis(
|
||||
// Name
|
||||
format!("Glutton {}", para_id).as_str(),
|
||||
// ID
|
||||
format!("glutton-kusama-{}", para_id).as_str(),
|
||||
ChainType::Live,
|
||||
move || {
|
||||
glutton_genesis(
|
||||
para_id,
|
||||
vec![
|
||||
get_collator_keys_from_seed::<AuraId>("Alice"),
|
||||
get_collator_keys_from_seed::<AuraId>("Bob"),
|
||||
],
|
||||
)
|
||||
},
|
||||
Vec::new(),
|
||||
None,
|
||||
// Protocol ID
|
||||
Some(format!("glutton-kusama-{}", para_id).as_str()),
|
||||
None,
|
||||
Some(properties),
|
||||
GluttonChainSpec::builder(
|
||||
glutton_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"),
|
||||
Extensions { relay_chain: "kusama".into(), para_id: para_id.into() },
|
||||
)
|
||||
.with_name(format!("Glutton {}", para_id).as_str())
|
||||
.with_id(format!("glutton-kusama-{}", para_id).as_str())
|
||||
.with_chain_type(ChainType::Live)
|
||||
.with_genesis_config_patch(glutton_genesis(
|
||||
para_id,
|
||||
vec![
|
||||
get_collator_keys_from_seed::<AuraId>("Alice"),
|
||||
get_collator_keys_from_seed::<AuraId>("Bob"),
|
||||
],
|
||||
))
|
||||
.with_protocol_id(format!("glutton-kusama-{}", para_id).as_str())
|
||||
.with_properties(properties)
|
||||
.build()
|
||||
}
|
||||
|
||||
fn glutton_genesis(
|
||||
parachain_id: ParaId,
|
||||
collators: Vec<AuraId>,
|
||||
) -> glutton_runtime::RuntimeGenesisConfig {
|
||||
glutton_runtime::RuntimeGenesisConfig {
|
||||
system: glutton_runtime::SystemConfig {
|
||||
code: glutton_runtime::WASM_BINARY
|
||||
.expect("WASM binary was not build, please build it!")
|
||||
.to_vec(),
|
||||
..Default::default()
|
||||
fn glutton_genesis(parachain_id: ParaId, collators: Vec<AuraId>) -> serde_json::Value {
|
||||
serde_json::json!( {
|
||||
"parachainInfo": {
|
||||
"parachainId": parachain_id
|
||||
},
|
||||
parachain_info: glutton_runtime::ParachainInfoConfig { parachain_id, ..Default::default() },
|
||||
parachain_system: Default::default(),
|
||||
glutton: glutton_runtime::GluttonConfig {
|
||||
compute: Default::default(),
|
||||
storage: Default::default(),
|
||||
trash_data_count: Default::default(),
|
||||
..Default::default()
|
||||
"sudo": {
|
||||
"key": Some(get_account_id_from_seed::<sr25519::Public>("Alice")),
|
||||
},
|
||||
aura: glutton_runtime::AuraConfig { authorities: collators },
|
||||
aura_ext: Default::default(),
|
||||
sudo: glutton_runtime::SudoConfig {
|
||||
key: Some(get_account_id_from_seed::<sr25519::Public>("Alice")),
|
||||
},
|
||||
}
|
||||
"aura": { "authorities": collators },
|
||||
})
|
||||
}
|
||||
|
||||
@@ -22,8 +22,7 @@ use parachains_common::{AccountId, AuraId};
|
||||
use sc_service::ChainType;
|
||||
use sp_core::sr25519;
|
||||
/// Specialized `ChainSpec` for the normal parachain runtime.
|
||||
pub type PenpalChainSpec =
|
||||
sc_service::GenericChainSpec<penpal_runtime::RuntimeGenesisConfig, Extensions>;
|
||||
pub type PenpalChainSpec = sc_service::GenericChainSpec<(), Extensions>;
|
||||
|
||||
pub fn get_penpal_chain_spec(id: ParaId, relay_chain: &str) -> PenpalChainSpec {
|
||||
// Give your base currency a unit name and decimal places
|
||||
@@ -32,84 +31,69 @@ pub fn get_penpal_chain_spec(id: ParaId, relay_chain: &str) -> PenpalChainSpec {
|
||||
properties.insert("tokenDecimals".into(), 12u32.into());
|
||||
properties.insert("ss58Format".into(), 42u32.into());
|
||||
|
||||
PenpalChainSpec::from_genesis(
|
||||
// Name
|
||||
"Penpal Parachain",
|
||||
// ID
|
||||
&format!("penpal-{}", relay_chain.replace("-local", "")),
|
||||
ChainType::Development,
|
||||
move || {
|
||||
penpal_testnet_genesis(
|
||||
// initial collators.
|
||||
vec![
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_collator_keys_from_seed::<AuraId>("Alice"),
|
||||
),
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_collator_keys_from_seed::<AuraId>("Bob"),
|
||||
),
|
||||
],
|
||||
vec![
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),
|
||||
],
|
||||
id,
|
||||
)
|
||||
},
|
||||
Vec::new(),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
PenpalChainSpec::builder(
|
||||
penpal_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"),
|
||||
Extensions {
|
||||
relay_chain: relay_chain.into(), // You MUST set this to the correct network!
|
||||
para_id: id.into(),
|
||||
},
|
||||
)
|
||||
.with_name("Penpal Parachain")
|
||||
.with_id(&format!("penpal-{}", relay_chain.replace("-local", "")))
|
||||
.with_chain_type(ChainType::Development)
|
||||
.with_genesis_config_patch(penpal_testnet_genesis(
|
||||
// initial collators.
|
||||
vec![
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_collator_keys_from_seed::<AuraId>("Alice"),
|
||||
),
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_collator_keys_from_seed::<AuraId>("Bob"),
|
||||
),
|
||||
],
|
||||
vec![
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),
|
||||
],
|
||||
id,
|
||||
))
|
||||
.build()
|
||||
}
|
||||
|
||||
fn penpal_testnet_genesis(
|
||||
invulnerables: Vec<(AccountId, AuraId)>,
|
||||
endowed_accounts: Vec<AccountId>,
|
||||
id: ParaId,
|
||||
) -> penpal_runtime::RuntimeGenesisConfig {
|
||||
penpal_runtime::RuntimeGenesisConfig {
|
||||
system: penpal_runtime::SystemConfig {
|
||||
code: penpal_runtime::WASM_BINARY
|
||||
.expect("WASM binary was not build, please build it!")
|
||||
.to_vec(),
|
||||
..Default::default()
|
||||
},
|
||||
balances: penpal_runtime::BalancesConfig {
|
||||
balances: endowed_accounts
|
||||
) -> serde_json::Value {
|
||||
serde_json::json!({
|
||||
"balances": {
|
||||
"balances": endowed_accounts
|
||||
.iter()
|
||||
.cloned()
|
||||
.map(|k| (k, penpal_runtime::EXISTENTIAL_DEPOSIT * 4096))
|
||||
.collect(),
|
||||
.collect::<Vec<_>>(),
|
||||
},
|
||||
parachain_info: penpal_runtime::ParachainInfoConfig {
|
||||
parachain_id: id,
|
||||
..Default::default()
|
||||
"parachainInfo": {
|
||||
"parachainId": id,
|
||||
},
|
||||
collator_selection: penpal_runtime::CollatorSelectionConfig {
|
||||
invulnerables: invulnerables.iter().cloned().map(|(acc, _)| acc).collect(),
|
||||
candidacy_bond: penpal_runtime::EXISTENTIAL_DEPOSIT * 16,
|
||||
..Default::default()
|
||||
"collatorSelection": {
|
||||
"invulnerables": invulnerables.iter().cloned().map(|(acc, _)| acc).collect::<Vec<_>>(),
|
||||
"candidacyBond": penpal_runtime::EXISTENTIAL_DEPOSIT * 16,
|
||||
},
|
||||
session: penpal_runtime::SessionConfig {
|
||||
keys: invulnerables
|
||||
"session": {
|
||||
"keys": invulnerables
|
||||
.into_iter()
|
||||
.map(|(acc, aura)| {
|
||||
(
|
||||
@@ -118,21 +102,15 @@ fn penpal_testnet_genesis(
|
||||
penpal_session_keys(aura), // session keys
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
.collect::<Vec<_>>(),
|
||||
},
|
||||
// no need to pass anything to aura, in fact it will panic if we do. Session will take care
|
||||
// of this.
|
||||
aura: Default::default(),
|
||||
aura_ext: Default::default(),
|
||||
parachain_system: Default::default(),
|
||||
polkadot_xcm: penpal_runtime::PolkadotXcmConfig {
|
||||
safe_xcm_version: Some(SAFE_XCM_VERSION),
|
||||
..Default::default()
|
||||
"polkadotXcm": {
|
||||
"safeXcmVersion": Some(SAFE_XCM_VERSION),
|
||||
},
|
||||
sudo: penpal_runtime::SudoConfig {
|
||||
key: Some(get_account_id_from_seed::<sr25519::Public>("Alice")),
|
||||
"sudo": {
|
||||
"key": Some(get_account_id_from_seed::<sr25519::Public>("Alice")),
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Generate the session keys from individual elements.
|
||||
|
||||
@@ -25,73 +25,61 @@ use rococo_parachain_runtime::AuraId;
|
||||
use sc_chain_spec::ChainType;
|
||||
use sp_core::{crypto::UncheckedInto, sr25519};
|
||||
|
||||
pub type RococoParachainChainSpec =
|
||||
sc_service::GenericChainSpec<rococo_parachain_runtime::RuntimeGenesisConfig, Extensions>;
|
||||
pub type RococoParachainChainSpec = sc_service::GenericChainSpec<(), Extensions>;
|
||||
|
||||
pub fn rococo_parachain_local_config() -> RococoParachainChainSpec {
|
||||
RococoParachainChainSpec::from_genesis(
|
||||
"Rococo Parachain Local",
|
||||
"local_testnet",
|
||||
ChainType::Local,
|
||||
move || {
|
||||
testnet_genesis(
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
vec![get_from_seed::<AuraId>("Alice"), get_from_seed::<AuraId>("Bob")],
|
||||
vec![
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),
|
||||
],
|
||||
1000.into(),
|
||||
)
|
||||
},
|
||||
Vec::new(),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
RococoParachainChainSpec::builder(
|
||||
rococo_parachain_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"),
|
||||
Extensions { relay_chain: "rococo-local".into(), para_id: 1000 },
|
||||
)
|
||||
.with_name("Rococo Parachain Local")
|
||||
.with_id("local_testnet")
|
||||
.with_chain_type(ChainType::Local)
|
||||
.with_genesis_config_patch(testnet_genesis(
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
vec![get_from_seed::<AuraId>("Alice"), get_from_seed::<AuraId>("Bob")],
|
||||
vec![
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),
|
||||
],
|
||||
1000.into(),
|
||||
))
|
||||
.build()
|
||||
}
|
||||
|
||||
pub fn staging_rococo_parachain_local_config() -> RococoParachainChainSpec {
|
||||
RococoParachainChainSpec::from_genesis(
|
||||
"Staging Rococo Parachain Local",
|
||||
"staging_testnet",
|
||||
ChainType::Live,
|
||||
move || {
|
||||
testnet_genesis(
|
||||
hex!["9ed7705e3c7da027ba0583a22a3212042f7e715d3c168ba14f1424e2bc111d00"].into(),
|
||||
vec![
|
||||
// $secret//one
|
||||
hex!["aad9fa2249f87a210a0f93400b7f90e47b810c6d65caa0ca3f5af982904c2a33"]
|
||||
.unchecked_into(),
|
||||
// $secret//two
|
||||
hex!["d47753f0cca9dd8da00c70e82ec4fc5501a69c49a5952a643d18802837c88212"]
|
||||
.unchecked_into(),
|
||||
],
|
||||
vec![
|
||||
hex!["9ed7705e3c7da027ba0583a22a3212042f7e715d3c168ba14f1424e2bc111d00"].into()
|
||||
],
|
||||
1000.into(),
|
||||
)
|
||||
},
|
||||
Vec::new(),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
#[allow(deprecated)]
|
||||
RococoParachainChainSpec::builder(
|
||||
rococo_parachain_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"),
|
||||
Extensions { relay_chain: "rococo-local".into(), para_id: 1000 },
|
||||
)
|
||||
.with_name("Staging Rococo Parachain Local")
|
||||
.with_id("staging_testnet")
|
||||
.with_chain_type(ChainType::Live)
|
||||
.with_genesis_config_patch(testnet_genesis(
|
||||
hex!["9ed7705e3c7da027ba0583a22a3212042f7e715d3c168ba14f1424e2bc111d00"].into(),
|
||||
vec![
|
||||
// $secret//one
|
||||
hex!["aad9fa2249f87a210a0f93400b7f90e47b810c6d65caa0ca3f5af982904c2a33"]
|
||||
.unchecked_into(),
|
||||
// $secret//two
|
||||
hex!["d47753f0cca9dd8da00c70e82ec4fc5501a69c49a5952a643d18802837c88212"]
|
||||
.unchecked_into(),
|
||||
],
|
||||
vec![hex!["9ed7705e3c7da027ba0583a22a3212042f7e715d3c168ba14f1424e2bc111d00"].into()],
|
||||
1000.into(),
|
||||
))
|
||||
.build()
|
||||
}
|
||||
|
||||
pub(crate) fn testnet_genesis(
|
||||
@@ -99,28 +87,18 @@ pub(crate) fn testnet_genesis(
|
||||
initial_authorities: Vec<AuraId>,
|
||||
endowed_accounts: Vec<AccountId>,
|
||||
id: ParaId,
|
||||
) -> rococo_parachain_runtime::RuntimeGenesisConfig {
|
||||
rococo_parachain_runtime::RuntimeGenesisConfig {
|
||||
system: rococo_parachain_runtime::SystemConfig {
|
||||
code: rococo_parachain_runtime::WASM_BINARY
|
||||
.expect("WASM binary was not build, please build it!")
|
||||
.to_vec(),
|
||||
..Default::default()
|
||||
) -> serde_json::Value {
|
||||
serde_json::json!({
|
||||
"balances": {
|
||||
"balances": endowed_accounts.iter().cloned().map(|k| (k, 1u64 << 60)).collect::<Vec<_>>(),
|
||||
},
|
||||
balances: rococo_parachain_runtime::BalancesConfig {
|
||||
balances: endowed_accounts.iter().cloned().map(|k| (k, 1 << 60)).collect(),
|
||||
"sudo": { "key": Some(root_key) },
|
||||
"parachainInfo": {
|
||||
"parachainId": id,
|
||||
},
|
||||
sudo: rococo_parachain_runtime::SudoConfig { key: Some(root_key) },
|
||||
parachain_info: rococo_parachain_runtime::ParachainInfoConfig {
|
||||
parachain_id: id,
|
||||
..Default::default()
|
||||
"aura": { "authorities": initial_authorities },
|
||||
"polkadotXcm": {
|
||||
"safeXcmVersion": Some(SAFE_XCM_VERSION),
|
||||
},
|
||||
aura: rococo_parachain_runtime::AuraConfig { authorities: initial_authorities },
|
||||
aura_ext: Default::default(),
|
||||
parachain_system: Default::default(),
|
||||
polkadot_xcm: rococo_parachain_runtime::PolkadotXcmConfig {
|
||||
safe_xcm_version: Some(SAFE_XCM_VERSION),
|
||||
..Default::default()
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -23,49 +23,35 @@ use sp_core::sr25519;
|
||||
use super::get_collator_keys_from_seed;
|
||||
|
||||
/// Specialized `ChainSpec` for the seedling parachain runtime.
|
||||
pub type SeedlingChainSpec =
|
||||
sc_service::GenericChainSpec<seedling_runtime::RuntimeGenesisConfig, Extensions>;
|
||||
pub type SeedlingChainSpec = sc_service::GenericChainSpec<(), Extensions>;
|
||||
|
||||
pub fn get_seedling_chain_spec() -> SeedlingChainSpec {
|
||||
SeedlingChainSpec::from_genesis(
|
||||
"Seedling Local Testnet",
|
||||
"seedling_local_testnet",
|
||||
ChainType::Local,
|
||||
move || {
|
||||
seedling_testnet_genesis(
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
2000.into(),
|
||||
vec![get_collator_keys_from_seed::<AuraId>("Alice")],
|
||||
)
|
||||
},
|
||||
Vec::new(),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
SeedlingChainSpec::builder(
|
||||
seedling_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"),
|
||||
Extensions { relay_chain: "westend".into(), para_id: 2000 },
|
||||
)
|
||||
.with_name("Seedling Local Testnet")
|
||||
.with_id("seedling_local_testnet")
|
||||
.with_chain_type(ChainType::Local)
|
||||
.with_genesis_config_patch(seedling_testnet_genesis(
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
2000.into(),
|
||||
vec![get_collator_keys_from_seed::<AuraId>("Alice")],
|
||||
))
|
||||
.with_boot_nodes(Vec::new())
|
||||
.build()
|
||||
}
|
||||
|
||||
fn seedling_testnet_genesis(
|
||||
root_key: AccountId,
|
||||
parachain_id: ParaId,
|
||||
collators: Vec<AuraId>,
|
||||
) -> seedling_runtime::RuntimeGenesisConfig {
|
||||
seedling_runtime::RuntimeGenesisConfig {
|
||||
system: seedling_runtime::SystemConfig {
|
||||
code: seedling_runtime::WASM_BINARY
|
||||
.expect("WASM binary was not build, please build it!")
|
||||
.to_vec(),
|
||||
..Default::default()
|
||||
) -> serde_json::Value {
|
||||
serde_json::json!({
|
||||
"sudo": { "key": Some(root_key) },
|
||||
"parachainInfo": {
|
||||
"parachainId": parachain_id,
|
||||
},
|
||||
sudo: seedling_runtime::SudoConfig { key: Some(root_key) },
|
||||
parachain_info: seedling_runtime::ParachainInfoConfig {
|
||||
parachain_id,
|
||||
..Default::default()
|
||||
},
|
||||
parachain_system: Default::default(),
|
||||
aura: seedling_runtime::AuraConfig { authorities: collators },
|
||||
aura_ext: Default::default(),
|
||||
}
|
||||
"aura": { "authorities": collators },
|
||||
})
|
||||
}
|
||||
|
||||
@@ -22,40 +22,27 @@ use sc_service::ChainType;
|
||||
use super::get_collator_keys_from_seed;
|
||||
|
||||
/// Specialized `ChainSpec` for the shell parachain runtime.
|
||||
pub type ShellChainSpec =
|
||||
sc_service::GenericChainSpec<shell_runtime::RuntimeGenesisConfig, Extensions>;
|
||||
pub type ShellChainSpec = sc_service::GenericChainSpec<(), Extensions>;
|
||||
|
||||
pub fn get_shell_chain_spec() -> ShellChainSpec {
|
||||
ShellChainSpec::from_genesis(
|
||||
"Shell Local Testnet",
|
||||
"shell_local_testnet",
|
||||
ChainType::Local,
|
||||
move || {
|
||||
shell_testnet_genesis(1000.into(), vec![get_collator_keys_from_seed::<AuraId>("Alice")])
|
||||
},
|
||||
Vec::new(),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
ShellChainSpec::builder(
|
||||
shell_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"),
|
||||
Extensions { relay_chain: "westend".into(), para_id: 1000 },
|
||||
)
|
||||
.with_name("Shell Local Testnet")
|
||||
.with_id("shell_local_testnet")
|
||||
.with_chain_type(ChainType::Local)
|
||||
.with_genesis_config_patch(shell_testnet_genesis(
|
||||
1000.into(),
|
||||
vec![get_collator_keys_from_seed::<AuraId>("Alice")],
|
||||
))
|
||||
.with_boot_nodes(Vec::new())
|
||||
.build()
|
||||
}
|
||||
|
||||
fn shell_testnet_genesis(
|
||||
parachain_id: ParaId,
|
||||
collators: Vec<AuraId>,
|
||||
) -> shell_runtime::RuntimeGenesisConfig {
|
||||
shell_runtime::RuntimeGenesisConfig {
|
||||
system: shell_runtime::SystemConfig {
|
||||
code: shell_runtime::WASM_BINARY
|
||||
.expect("WASM binary was not build, please build it!")
|
||||
.to_vec(),
|
||||
..Default::default()
|
||||
},
|
||||
parachain_info: shell_runtime::ParachainInfoConfig { parachain_id, ..Default::default() },
|
||||
parachain_system: Default::default(),
|
||||
aura: shell_runtime::AuraConfig { authorities: collators },
|
||||
aura_ext: Default::default(),
|
||||
}
|
||||
fn shell_testnet_genesis(parachain_id: ParaId, collators: Vec<AuraId>) -> serde_json::Value {
|
||||
serde_json::json!({
|
||||
"parachainInfo": { "parachainId": parachain_id},
|
||||
"aura": { "authorities": collators },
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1200,35 +1200,30 @@ mod tests {
|
||||
cfg_file_path
|
||||
}
|
||||
|
||||
pub type DummyChainSpec<E> =
|
||||
sc_service::GenericChainSpec<rococo_parachain_runtime::RuntimeGenesisConfig, E>;
|
||||
pub type DummyChainSpec<E> = sc_service::GenericChainSpec<(), E>;
|
||||
|
||||
pub fn create_default_with_extensions<E: Extension>(
|
||||
id: &str,
|
||||
extension: E,
|
||||
) -> DummyChainSpec<E> {
|
||||
DummyChainSpec::from_genesis(
|
||||
"Dummy local testnet",
|
||||
id,
|
||||
ChainType::Local,
|
||||
move || {
|
||||
crate::chain_spec::rococo_parachain::testnet_genesis(
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
vec![
|
||||
get_from_seed::<rococo_parachain_runtime::AuraId>("Alice"),
|
||||
get_from_seed::<rococo_parachain_runtime::AuraId>("Bob"),
|
||||
],
|
||||
vec![get_account_id_from_seed::<sr25519::Public>("Alice")],
|
||||
1000.into(),
|
||||
)
|
||||
},
|
||||
Vec::new(),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
DummyChainSpec::builder(
|
||||
rococo_parachain_runtime::WASM_BINARY
|
||||
.expect("WASM binary was not built, please build it!"),
|
||||
extension,
|
||||
)
|
||||
.with_name("Dummy local testnet")
|
||||
.with_id(id)
|
||||
.with_chain_type(ChainType::Local)
|
||||
.with_genesis_config_patch(crate::chain_spec::rococo_parachain::testnet_genesis(
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
vec![
|
||||
get_from_seed::<rococo_parachain_runtime::AuraId>("Alice"),
|
||||
get_from_seed::<rococo_parachain_runtime::AuraId>("Bob"),
|
||||
],
|
||||
vec![get_account_id_from_seed::<sr25519::Public>("Alice")],
|
||||
1000.into(),
|
||||
))
|
||||
.build()
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -19,13 +19,13 @@
|
||||
mod block_builder;
|
||||
use codec::{Decode, Encode};
|
||||
use runtime::{
|
||||
Balance, Block, BlockHashCount, Runtime, RuntimeCall, RuntimeGenesisConfig, Signature,
|
||||
SignedExtra, SignedPayload, UncheckedExtrinsic, VERSION,
|
||||
Balance, Block, BlockHashCount, Runtime, RuntimeCall, Signature, SignedExtra, SignedPayload,
|
||||
UncheckedExtrinsic, VERSION,
|
||||
};
|
||||
use sc_executor::HeapAllocStrategy;
|
||||
use sc_executor_common::runtime_blob::RuntimeBlob;
|
||||
use sp_blockchain::HeaderBackend;
|
||||
use sp_core::{sr25519, Pair};
|
||||
use sp_core::Pair;
|
||||
use sp_io::TestExternalities;
|
||||
use sp_runtime::{generic::Era, BuildStorage, SaturatedConversion};
|
||||
|
||||
@@ -84,17 +84,12 @@ pub struct GenesisParameters {
|
||||
|
||||
impl substrate_test_client::GenesisInit for GenesisParameters {
|
||||
fn genesis_storage(&self) -> Storage {
|
||||
if self.endowed_accounts.is_empty() {
|
||||
genesis_config().build_storage().unwrap()
|
||||
} else {
|
||||
cumulus_test_service::testnet_genesis(
|
||||
cumulus_test_service::get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
self.endowed_accounts.clone(),
|
||||
None,
|
||||
)
|
||||
.build_storage()
|
||||
.unwrap()
|
||||
}
|
||||
cumulus_test_service::chain_spec::get_chain_spec_with_extra_endowed(
|
||||
None,
|
||||
self.endowed_accounts.clone(),
|
||||
)
|
||||
.build_storage()
|
||||
.expect("Builds test runtime genesis storage")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,10 +122,6 @@ impl DefaultTestClientBuilderExt for TestClientBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
fn genesis_config() -> RuntimeGenesisConfig {
|
||||
cumulus_test_service::testnet_genesis_with_default_endowed(Default::default(), None)
|
||||
}
|
||||
|
||||
/// Create an unsigned extrinsic from a runtime call.
|
||||
pub fn generate_unsigned(function: impl Into<RuntimeCall>) -> UncheckedExtrinsic {
|
||||
UncheckedExtrinsic::new_unsigned(function.into())
|
||||
|
||||
@@ -23,6 +23,7 @@ pallet-transaction-payment = { path = "../../../substrate/frame/transaction-paym
|
||||
sp-api = { path = "../../../substrate/primitives/api", default-features = false}
|
||||
sp-block-builder = { path = "../../../substrate/primitives/block-builder", default-features = false}
|
||||
sp-core = { path = "../../../substrate/primitives/core", default-features = false}
|
||||
sp-genesis-builder = { path = "../../../substrate/primitives/genesis-builder", default-features = false}
|
||||
sp-inherents = { path = "../../../substrate/primitives/inherents", default-features = false}
|
||||
sp-io = { path = "../../../substrate/primitives/io", default-features = false}
|
||||
sp-offchain = { path = "../../../substrate/primitives/offchain", default-features = false}
|
||||
@@ -59,6 +60,7 @@ std = [
|
||||
"sp-api/std",
|
||||
"sp-block-builder/std",
|
||||
"sp-core/std",
|
||||
"sp-genesis-builder/std",
|
||||
"sp-inherents/std",
|
||||
"sp-io/std",
|
||||
"sp-offchain/std",
|
||||
|
||||
@@ -47,6 +47,7 @@ use sp_version::RuntimeVersion;
|
||||
pub use frame_support::{
|
||||
construct_runtime,
|
||||
dispatch::DispatchClass,
|
||||
genesis_builder_helper::{build_config, create_default_config},
|
||||
parameter_types,
|
||||
traits::{ConstU8, Randomness},
|
||||
weights::{
|
||||
@@ -473,6 +474,16 @@ impl_runtime_apis! {
|
||||
ParachainSystem::collect_collation_info(header)
|
||||
}
|
||||
}
|
||||
|
||||
impl sp_genesis_builder::GenesisBuilder<Block> for Runtime {
|
||||
fn create_default_config() -> Vec<u8> {
|
||||
create_default_config::<RuntimeGenesisConfig>()
|
||||
}
|
||||
|
||||
fn build_config(config: Vec<u8>) -> sp_genesis_builder::Result {
|
||||
build_config::<RuntimeGenesisConfig>(config)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cumulus_pallet_parachain_system::register_validate_block! {
|
||||
|
||||
@@ -17,6 +17,7 @@ criterion = { version = "0.5.1", features = [ "async_tokio" ] }
|
||||
jsonrpsee = { version = "0.16.2", features = ["server"] }
|
||||
rand = "0.8.5"
|
||||
serde = { version = "1.0.188", features = ["derive"] }
|
||||
serde_json = "1.0.107"
|
||||
tokio = { version = "1.32.0", features = ["macros"] }
|
||||
tracing = "0.1.37"
|
||||
url = "2.4.0"
|
||||
|
||||
@@ -63,25 +63,25 @@ where
|
||||
/// The given accounts are initialized with funds in addition
|
||||
/// to the default known accounts.
|
||||
pub fn get_chain_spec_with_extra_endowed(
|
||||
id: ParaId,
|
||||
id: Option<ParaId>,
|
||||
extra_endowed_accounts: Vec<AccountId>,
|
||||
) -> ChainSpec {
|
||||
ChainSpec::from_genesis(
|
||||
"Local Testnet",
|
||||
"local_testnet",
|
||||
ChainType::Local,
|
||||
move || testnet_genesis_with_default_endowed(extra_endowed_accounts.clone(), Some(id)),
|
||||
Vec::new(),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Extensions { para_id: id.into() },
|
||||
ChainSpec::builder(
|
||||
cumulus_test_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"),
|
||||
Extensions { para_id: id.unwrap_or(cumulus_test_runtime::PARACHAIN_ID.into()).into() },
|
||||
)
|
||||
.with_name("Local Testnet")
|
||||
.with_id("local_testnet")
|
||||
.with_chain_type(ChainType::Local)
|
||||
.with_genesis_config_patch(testnet_genesis_with_default_endowed(
|
||||
extra_endowed_accounts.clone(),
|
||||
id,
|
||||
))
|
||||
.build()
|
||||
}
|
||||
|
||||
/// Get the chain spec for a specific parachain ID.
|
||||
pub fn get_chain_spec(id: ParaId) -> ChainSpec {
|
||||
pub fn get_chain_spec(id: Option<ParaId>) -> ChainSpec {
|
||||
get_chain_spec_with_extra_endowed(id, Default::default())
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ pub fn get_chain_spec(id: ParaId) -> ChainSpec {
|
||||
pub fn testnet_genesis_with_default_endowed(
|
||||
mut extra_endowed_accounts: Vec<AccountId>,
|
||||
self_para_id: Option<ParaId>,
|
||||
) -> cumulus_test_runtime::RuntimeGenesisConfig {
|
||||
) -> serde_json::Value {
|
||||
let mut endowed = vec![
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
@@ -114,21 +114,12 @@ pub fn testnet_genesis(
|
||||
root_key: AccountId,
|
||||
endowed_accounts: Vec<AccountId>,
|
||||
self_para_id: Option<ParaId>,
|
||||
) -> cumulus_test_runtime::RuntimeGenesisConfig {
|
||||
cumulus_test_runtime::RuntimeGenesisConfig {
|
||||
system: cumulus_test_runtime::SystemConfig {
|
||||
code: cumulus_test_runtime::WASM_BINARY
|
||||
.expect("WASM binary was not build, please build it!")
|
||||
.to_vec(),
|
||||
..Default::default()
|
||||
},
|
||||
glutton: Default::default(),
|
||||
parachain_system: Default::default(),
|
||||
balances: cumulus_test_runtime::BalancesConfig {
|
||||
) -> serde_json::Value {
|
||||
serde_json::json!({
|
||||
"balances": cumulus_test_runtime::BalancesConfig {
|
||||
balances: endowed_accounts.iter().cloned().map(|k| (k, 1 << 60)).collect(),
|
||||
},
|
||||
sudo: cumulus_test_runtime::SudoConfig { key: Some(root_key) },
|
||||
transaction_payment: Default::default(),
|
||||
test_pallet: cumulus_test_runtime::TestPalletConfig { self_para_id, ..Default::default() },
|
||||
}
|
||||
"sudo": cumulus_test_runtime::SudoConfig { key: Some(root_key) },
|
||||
"testPallet": cumulus_test_runtime::TestPalletConfig { self_para_id, ..Default::default() }
|
||||
})
|
||||
}
|
||||
|
||||
@@ -287,8 +287,9 @@ impl SubstrateCli for TestCollatorCli {
|
||||
|
||||
fn load_spec(&self, id: &str) -> std::result::Result<Box<dyn sc_service::ChainSpec>, String> {
|
||||
Ok(match id {
|
||||
"" => Box::new(cumulus_test_service::get_chain_spec(ParaId::from(self.parachain_id)))
|
||||
as Box<_>,
|
||||
"" => Box::new(cumulus_test_service::get_chain_spec(Some(ParaId::from(
|
||||
self.parachain_id,
|
||||
)))) as Box<_>,
|
||||
path => {
|
||||
let chain_spec =
|
||||
cumulus_test_service::chain_spec::ChainSpec::from_json_file(path.into())?;
|
||||
|
||||
@@ -23,7 +23,7 @@ use sp_runtime::traits::Block as BlockT;
|
||||
|
||||
/// Returns the initial head data for a parachain ID.
|
||||
pub fn initial_head_data(para_id: ParaId) -> HeadData {
|
||||
let spec = crate::chain_spec::get_chain_spec(para_id);
|
||||
let spec = crate::chain_spec::get_chain_spec(Some(para_id));
|
||||
let block: Block = generate_genesis_block(&spec, sp_runtime::StateVersion::V1).unwrap();
|
||||
let genesis_state = block.header().encode();
|
||||
genesis_state.into()
|
||||
|
||||
@@ -719,7 +719,7 @@ pub fn node_config(
|
||||
let role = if is_collator { Role::Authority } else { Role::Full };
|
||||
let key_seed = key.to_seed();
|
||||
let mut spec =
|
||||
Box::new(chain_spec::get_chain_spec_with_extra_endowed(para_id, endowed_accounts));
|
||||
Box::new(chain_spec::get_chain_spec_with_extra_endowed(Some(para_id), endowed_accounts));
|
||||
|
||||
let mut storage = spec.as_storage_builder().build_storage().expect("could not build storage");
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ fn main() -> Result<(), sc_cli::Error> {
|
||||
let runner = cli.create_runner(cmd)?;
|
||||
runner.sync_run(|_config| {
|
||||
let parachain_id = ParaId::from(cmd.parachain_id);
|
||||
let spec = cumulus_test_service::get_chain_spec(parachain_id);
|
||||
let spec = cumulus_test_service::get_chain_spec(Some(parachain_id));
|
||||
cmd.base.run(&spec)
|
||||
})
|
||||
},
|
||||
|
||||
@@ -4,7 +4,7 @@ default_command = "polkadot"
|
||||
|
||||
chain = "rococo-local"
|
||||
|
||||
[relaychain.genesis.runtime.configuration.config]
|
||||
[relaychain.genesis.runtimeGenesis.patch.configuration.config]
|
||||
# set parameters such that collators only connect to 1 validator as a backing group
|
||||
max_validators_per_core = 1
|
||||
group_rotation_frequency = 100 # 10 mins
|
||||
|
||||
@@ -32,7 +32,7 @@ cumulus_based = true
|
||||
add_to_genesis = false
|
||||
register_para = false
|
||||
# Set some random value in the genesis state to create a different genesis hash.
|
||||
[parachains.genesis.runtime.sudo]
|
||||
[parachains.genesis.runtimeGenesis.patch.sudo]
|
||||
key = "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty"
|
||||
|
||||
# run the parachain that will be used to return the header of the solo chain.
|
||||
|
||||
@@ -75,7 +75,7 @@ pub type GenericChainSpec = service::GenericChainSpec<(), Extensions>;
|
||||
|
||||
/// The `ChainSpec` parameterized for the westend runtime.
|
||||
#[cfg(feature = "westend-native")]
|
||||
pub type WestendChainSpec = service::GenericChainSpec<westend::RuntimeGenesisConfig, Extensions>;
|
||||
pub type WestendChainSpec = service::GenericChainSpec<(), Extensions>;
|
||||
|
||||
/// The `ChainSpec` parameterized for the westend runtime.
|
||||
// Dummy chain spec, but that is fine when we don't have the native runtime.
|
||||
@@ -84,12 +84,7 @@ pub type WestendChainSpec = GenericChainSpec;
|
||||
|
||||
/// The `ChainSpec` parameterized for the rococo runtime.
|
||||
#[cfg(feature = "rococo-native")]
|
||||
pub type RococoChainSpec = service::GenericChainSpec<rococo::RuntimeGenesisConfig, Extensions>;
|
||||
|
||||
/// The `ChainSpec` parameterized for the `versi` runtime.
|
||||
///
|
||||
/// As of now `Versi` will just be a clone of `Rococo`, until we need it to differ.
|
||||
pub type VersiChainSpec = RococoChainSpec;
|
||||
pub type RococoChainSpec = service::GenericChainSpec<(), Extensions>;
|
||||
|
||||
/// The `ChainSpec` parameterized for the rococo runtime.
|
||||
// Dummy chain spec, but that is fine when we don't have the native runtime.
|
||||
@@ -206,7 +201,7 @@ fn rococo_session_keys(
|
||||
}
|
||||
|
||||
#[cfg(feature = "westend-native")]
|
||||
fn westend_staging_testnet_config_genesis(wasm_binary: &[u8]) -> westend::RuntimeGenesisConfig {
|
||||
fn westend_staging_testnet_config_genesis() -> serde_json::Value {
|
||||
use hex_literal::hex;
|
||||
use sp_core::crypto::UncheckedInto;
|
||||
|
||||
@@ -344,19 +339,16 @@ fn westend_staging_testnet_config_genesis(wasm_binary: &[u8]) -> westend::Runtim
|
||||
const ENDOWMENT: u128 = 1_000_000 * WND;
|
||||
const STASH: u128 = 100 * WND;
|
||||
|
||||
westend::RuntimeGenesisConfig {
|
||||
system: westend::SystemConfig { code: wasm_binary.to_vec(), ..Default::default() },
|
||||
balances: westend::BalancesConfig {
|
||||
balances: endowed_accounts
|
||||
serde_json::json!({
|
||||
"balances": {
|
||||
"balances": endowed_accounts
|
||||
.iter()
|
||||
.map(|k: &AccountId| (k.clone(), ENDOWMENT))
|
||||
.chain(initial_authorities.iter().map(|x| (x.0.clone(), STASH)))
|
||||
.collect(),
|
||||
.collect::<Vec<_>>(),
|
||||
},
|
||||
beefy: Default::default(),
|
||||
indices: westend::IndicesConfig { indices: vec![] },
|
||||
session: westend::SessionConfig {
|
||||
keys: initial_authorities
|
||||
"session": {
|
||||
"keys": initial_authorities
|
||||
.iter()
|
||||
.map(|x| {
|
||||
(
|
||||
@@ -375,51 +367,32 @@ fn westend_staging_testnet_config_genesis(wasm_binary: &[u8]) -> westend::Runtim
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
},
|
||||
staking: westend::StakingConfig {
|
||||
validator_count: 50,
|
||||
minimum_validator_count: 4,
|
||||
stakers: initial_authorities
|
||||
"staking": {
|
||||
"validatorCount": 50,
|
||||
"minimumValidatorCount": 4,
|
||||
"stakers": initial_authorities
|
||||
.iter()
|
||||
.map(|x| (x.0.clone(), x.0.clone(), STASH, westend::StakerStatus::Validator))
|
||||
.collect(),
|
||||
invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect(),
|
||||
force_era: Forcing::ForceNone,
|
||||
slash_reward_fraction: Perbill::from_percent(10),
|
||||
..Default::default()
|
||||
.map(|x| (x.0.clone(), x.0.clone(), STASH, westend::StakerStatus::<AccountId>::Validator))
|
||||
.collect::<Vec<_>>(),
|
||||
"invulnerables": initial_authorities.iter().map(|x| x.0.clone()).collect::<Vec<_>>(),
|
||||
"forceEra": Forcing::ForceNone,
|
||||
"slashRewardFraction": Perbill::from_percent(10),
|
||||
},
|
||||
babe: westend::BabeConfig {
|
||||
authorities: Default::default(),
|
||||
epoch_config: Some(westend::BABE_GENESIS_EPOCH_CONFIG),
|
||||
..Default::default()
|
||||
"babe": {
|
||||
"epochConfig": Some(westend::BABE_GENESIS_EPOCH_CONFIG),
|
||||
},
|
||||
grandpa: Default::default(),
|
||||
im_online: Default::default(),
|
||||
authority_discovery: westend::AuthorityDiscoveryConfig {
|
||||
keys: vec![],
|
||||
..Default::default()
|
||||
"sudo": { "key": Some(endowed_accounts[0].clone()) },
|
||||
"configuration": {
|
||||
"config": default_parachains_host_configuration(),
|
||||
},
|
||||
vesting: westend::VestingConfig { vesting: vec![] },
|
||||
sudo: westend::SudoConfig { key: Some(endowed_accounts[0].clone()) },
|
||||
hrmp: Default::default(),
|
||||
treasury: Default::default(),
|
||||
configuration: westend::ConfigurationConfig {
|
||||
config: default_parachains_host_configuration(),
|
||||
"registrar": {
|
||||
"nextFreeParaId": polkadot_primitives::LOWEST_PUBLIC_ID,
|
||||
},
|
||||
paras: Default::default(),
|
||||
registrar: westend_runtime::RegistrarConfig {
|
||||
next_free_para_id: polkadot_primitives::LOWEST_PUBLIC_ID,
|
||||
..Default::default()
|
||||
},
|
||||
xcm_pallet: Default::default(),
|
||||
nomination_pools: Default::default(),
|
||||
assigned_slots: Default::default(),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(feature = "rococo-native")]
|
||||
fn rococo_staging_testnet_config_genesis(
|
||||
wasm_binary: &[u8],
|
||||
) -> rococo_runtime::RuntimeGenesisConfig {
|
||||
fn rococo_staging_testnet_config_genesis() -> serde_json::Value {
|
||||
use hex_literal::hex;
|
||||
use sp_core::crypto::UncheckedInto;
|
||||
|
||||
@@ -662,19 +635,16 @@ fn rococo_staging_testnet_config_genesis(
|
||||
const ENDOWMENT: u128 = 1_000_000 * ROC;
|
||||
const STASH: u128 = 100 * ROC;
|
||||
|
||||
rococo_runtime::RuntimeGenesisConfig {
|
||||
system: rococo_runtime::SystemConfig { code: wasm_binary.to_vec(), ..Default::default() },
|
||||
balances: rococo_runtime::BalancesConfig {
|
||||
balances: endowed_accounts
|
||||
serde_json::json!({
|
||||
"balances": {
|
||||
"balances": endowed_accounts
|
||||
.iter()
|
||||
.map(|k: &AccountId| (k.clone(), ENDOWMENT))
|
||||
.chain(initial_authorities.iter().map(|x| (x.0.clone(), STASH)))
|
||||
.collect(),
|
||||
.collect::<Vec<_>>(),
|
||||
},
|
||||
beefy: Default::default(),
|
||||
indices: rococo_runtime::IndicesConfig { indices: vec![] },
|
||||
session: rococo_runtime::SessionConfig {
|
||||
keys: initial_authorities
|
||||
"session": {
|
||||
"keys": initial_authorities
|
||||
.iter()
|
||||
.map(|x| {
|
||||
(
|
||||
@@ -693,80 +663,55 @@ fn rococo_staging_testnet_config_genesis(
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
},
|
||||
babe: rococo_runtime::BabeConfig {
|
||||
authorities: Default::default(),
|
||||
epoch_config: Some(rococo_runtime::BABE_GENESIS_EPOCH_CONFIG),
|
||||
..Default::default()
|
||||
"babe": {
|
||||
"epochConfig": Some(rococo_runtime::BABE_GENESIS_EPOCH_CONFIG),
|
||||
},
|
||||
grandpa: Default::default(),
|
||||
im_online: Default::default(),
|
||||
treasury: Default::default(),
|
||||
authority_discovery: rococo_runtime::AuthorityDiscoveryConfig {
|
||||
keys: vec![],
|
||||
..Default::default()
|
||||
"sudo": { "key": Some(endowed_accounts[0].clone()) },
|
||||
"configuration": {
|
||||
"config": default_parachains_host_configuration(),
|
||||
},
|
||||
claims: rococo::ClaimsConfig { claims: vec![], vesting: vec![] },
|
||||
vesting: rococo::VestingConfig { vesting: vec![] },
|
||||
sudo: rococo_runtime::SudoConfig { key: Some(endowed_accounts[0].clone()) },
|
||||
paras: rococo_runtime::ParasConfig { paras: vec![], ..Default::default() },
|
||||
hrmp: Default::default(),
|
||||
configuration: rococo_runtime::ConfigurationConfig {
|
||||
config: default_parachains_host_configuration(),
|
||||
"registrar": {
|
||||
"nextFreeParaId": polkadot_primitives::LOWEST_PUBLIC_ID,
|
||||
},
|
||||
registrar: rococo_runtime::RegistrarConfig {
|
||||
next_free_para_id: polkadot_primitives::LOWEST_PUBLIC_ID,
|
||||
..Default::default()
|
||||
},
|
||||
xcm_pallet: Default::default(),
|
||||
nis_counterpart_balances: Default::default(),
|
||||
assigned_slots: Default::default(),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Westend staging testnet config.
|
||||
#[cfg(feature = "westend-native")]
|
||||
pub fn westend_staging_testnet_config() -> Result<WestendChainSpec, String> {
|
||||
let wasm_binary = westend::WASM_BINARY.ok_or("Westend development wasm not available")?;
|
||||
let boot_nodes = vec![];
|
||||
|
||||
Ok(WestendChainSpec::from_genesis(
|
||||
"Westend Staging Testnet",
|
||||
"westend_staging_testnet",
|
||||
ChainType::Live,
|
||||
move || westend_staging_testnet_config_genesis(wasm_binary),
|
||||
boot_nodes,
|
||||
Some(
|
||||
TelemetryEndpoints::new(vec![(WESTEND_STAGING_TELEMETRY_URL.to_string(), 0)])
|
||||
.expect("Westend Staging telemetry url is valid; qed"),
|
||||
),
|
||||
Some(DEFAULT_PROTOCOL_ID),
|
||||
None,
|
||||
None,
|
||||
Ok(WestendChainSpec::builder(
|
||||
westend::WASM_BINARY.ok_or("Westend development wasm not available")?,
|
||||
Default::default(),
|
||||
))
|
||||
)
|
||||
.with_name("Westend Staging Testnet")
|
||||
.with_id("westend_staging_testnet")
|
||||
.with_chain_type(ChainType::Live)
|
||||
.with_genesis_config_patch(westend_staging_testnet_config_genesis())
|
||||
.with_telemetry_endpoints(
|
||||
TelemetryEndpoints::new(vec![(WESTEND_STAGING_TELEMETRY_URL.to_string(), 0)])
|
||||
.expect("Westend Staging telemetry url is valid; qed"),
|
||||
)
|
||||
.with_protocol_id(DEFAULT_PROTOCOL_ID)
|
||||
.build())
|
||||
}
|
||||
|
||||
/// Rococo staging testnet config.
|
||||
#[cfg(feature = "rococo-native")]
|
||||
pub fn rococo_staging_testnet_config() -> Result<RococoChainSpec, String> {
|
||||
let wasm_binary = rococo::WASM_BINARY.ok_or("Rococo development wasm not available")?;
|
||||
let boot_nodes = vec![];
|
||||
|
||||
Ok(RococoChainSpec::from_genesis(
|
||||
"Rococo Staging Testnet",
|
||||
"rococo_staging_testnet",
|
||||
ChainType::Live,
|
||||
move || rococo_staging_testnet_config_genesis(wasm_binary),
|
||||
boot_nodes,
|
||||
Some(
|
||||
TelemetryEndpoints::new(vec![(ROCOCO_STAGING_TELEMETRY_URL.to_string(), 0)])
|
||||
.expect("Rococo Staging telemetry url is valid; qed"),
|
||||
),
|
||||
Some(DEFAULT_PROTOCOL_ID),
|
||||
None,
|
||||
None,
|
||||
Ok(RococoChainSpec::builder(
|
||||
rococo::WASM_BINARY.ok_or("Rococo development wasm not available")?,
|
||||
Default::default(),
|
||||
))
|
||||
)
|
||||
.with_name("Rococo Staging Testnet")
|
||||
.with_id("rococo_staging_testnet")
|
||||
.with_chain_type(ChainType::Live)
|
||||
.with_genesis_config_patch(rococo_staging_testnet_config_genesis())
|
||||
.with_telemetry_endpoints(
|
||||
TelemetryEndpoints::new(vec![(ROCOCO_STAGING_TELEMETRY_URL.to_string(), 0)])
|
||||
.expect("Rococo Staging telemetry url is valid; qed"),
|
||||
)
|
||||
.with_protocol_id(DEFAULT_PROTOCOL_ID)
|
||||
.build())
|
||||
}
|
||||
|
||||
pub fn versi_chain_spec_properties() -> serde_json::map::Map<String, serde_json::Value> {
|
||||
@@ -783,24 +728,21 @@ pub fn versi_chain_spec_properties() -> serde_json::map::Map<String, serde_json:
|
||||
/// Versi staging testnet config.
|
||||
#[cfg(feature = "rococo-native")]
|
||||
pub fn versi_staging_testnet_config() -> Result<RococoChainSpec, String> {
|
||||
let wasm_binary = rococo::WASM_BINARY.ok_or("Versi development wasm not available")?;
|
||||
let boot_nodes = vec![];
|
||||
|
||||
Ok(RococoChainSpec::from_genesis(
|
||||
"Versi Staging Testnet",
|
||||
"versi_staging_testnet",
|
||||
ChainType::Live,
|
||||
move || rococo_staging_testnet_config_genesis(wasm_binary),
|
||||
boot_nodes,
|
||||
Some(
|
||||
TelemetryEndpoints::new(vec![(VERSI_STAGING_TELEMETRY_URL.to_string(), 0)])
|
||||
.expect("Versi Staging telemetry url is valid; qed"),
|
||||
),
|
||||
Some("versi"),
|
||||
None,
|
||||
Some(versi_chain_spec_properties()),
|
||||
Ok(RococoChainSpec::builder(
|
||||
rococo::WASM_BINARY.ok_or("Versi development wasm not available")?,
|
||||
Default::default(),
|
||||
))
|
||||
)
|
||||
.with_name("Versi Staging Testnet")
|
||||
.with_id("versi_staging_testnet")
|
||||
.with_chain_type(ChainType::Live)
|
||||
.with_genesis_config_patch(rococo_staging_testnet_config_genesis())
|
||||
.with_telemetry_endpoints(
|
||||
TelemetryEndpoints::new(vec![(VERSI_STAGING_TELEMETRY_URL.to_string(), 0)])
|
||||
.expect("Versi Staging telemetry url is valid; qed"),
|
||||
)
|
||||
.with_protocol_id("versi")
|
||||
.with_properties(versi_chain_spec_properties())
|
||||
.build())
|
||||
}
|
||||
|
||||
/// Helper function to generate a crypto pair from seed
|
||||
@@ -879,10 +821,9 @@ fn testnet_accounts() -> Vec<AccountId> {
|
||||
]
|
||||
}
|
||||
|
||||
/// Helper function to create westend `RuntimeGenesisConfig` for testing
|
||||
/// Helper function to create westend runtime `GenesisConfig` patch for testing
|
||||
#[cfg(feature = "westend-native")]
|
||||
pub fn westend_testnet_genesis(
|
||||
wasm_binary: &[u8],
|
||||
initial_authorities: Vec<(
|
||||
AccountId,
|
||||
AccountId,
|
||||
@@ -896,21 +837,18 @@ pub fn westend_testnet_genesis(
|
||||
)>,
|
||||
root_key: AccountId,
|
||||
endowed_accounts: Option<Vec<AccountId>>,
|
||||
) -> westend::RuntimeGenesisConfig {
|
||||
) -> serde_json::Value {
|
||||
let endowed_accounts: Vec<AccountId> = endowed_accounts.unwrap_or_else(testnet_accounts);
|
||||
|
||||
const ENDOWMENT: u128 = 1_000_000 * WND;
|
||||
const STASH: u128 = 100 * WND;
|
||||
|
||||
westend::RuntimeGenesisConfig {
|
||||
system: westend::SystemConfig { code: wasm_binary.to_vec(), ..Default::default() },
|
||||
indices: westend::IndicesConfig { indices: vec![] },
|
||||
balances: westend::BalancesConfig {
|
||||
balances: endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect(),
|
||||
serde_json::json!({
|
||||
"balances": {
|
||||
"balances": endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect::<Vec<_>>(),
|
||||
},
|
||||
beefy: Default::default(),
|
||||
session: westend::SessionConfig {
|
||||
keys: initial_authorities
|
||||
"session": {
|
||||
"keys": initial_authorities
|
||||
.iter()
|
||||
.map(|x| {
|
||||
(
|
||||
@@ -929,51 +867,33 @@ pub fn westend_testnet_genesis(
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
},
|
||||
staking: westend::StakingConfig {
|
||||
minimum_validator_count: 1,
|
||||
validator_count: initial_authorities.len() as u32,
|
||||
stakers: initial_authorities
|
||||
"staking": {
|
||||
"minimumValidatorCount": 1,
|
||||
"validatorCount": initial_authorities.len() as u32,
|
||||
"stakers": initial_authorities
|
||||
.iter()
|
||||
.map(|x| (x.0.clone(), x.0.clone(), STASH, westend::StakerStatus::Validator))
|
||||
.collect(),
|
||||
invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect(),
|
||||
force_era: Forcing::NotForcing,
|
||||
slash_reward_fraction: Perbill::from_percent(10),
|
||||
..Default::default()
|
||||
.map(|x| (x.0.clone(), x.0.clone(), STASH, westend::StakerStatus::<AccountId>::Validator))
|
||||
.collect::<Vec<_>>(),
|
||||
"invulnerables": initial_authorities.iter().map(|x| x.0.clone()).collect::<Vec<_>>(),
|
||||
"forceEra": Forcing::NotForcing,
|
||||
"slashRewardFraction": Perbill::from_percent(10),
|
||||
},
|
||||
babe: westend::BabeConfig {
|
||||
authorities: Default::default(),
|
||||
epoch_config: Some(westend::BABE_GENESIS_EPOCH_CONFIG),
|
||||
..Default::default()
|
||||
"babe": {
|
||||
"epochConfig": Some(westend::BABE_GENESIS_EPOCH_CONFIG),
|
||||
},
|
||||
grandpa: Default::default(),
|
||||
im_online: Default::default(),
|
||||
authority_discovery: westend::AuthorityDiscoveryConfig {
|
||||
keys: vec![],
|
||||
..Default::default()
|
||||
"sudo": { "key": Some(root_key) },
|
||||
"configuration": {
|
||||
"config": default_parachains_host_configuration(),
|
||||
},
|
||||
vesting: westend::VestingConfig { vesting: vec![] },
|
||||
sudo: westend::SudoConfig { key: Some(root_key) },
|
||||
hrmp: Default::default(),
|
||||
treasury: Default::default(),
|
||||
configuration: westend::ConfigurationConfig {
|
||||
config: default_parachains_host_configuration(),
|
||||
"registrar": {
|
||||
"nextFreeParaId": polkadot_primitives::LOWEST_PUBLIC_ID,
|
||||
},
|
||||
paras: Default::default(),
|
||||
registrar: westend_runtime::RegistrarConfig {
|
||||
next_free_para_id: polkadot_primitives::LOWEST_PUBLIC_ID,
|
||||
..Default::default()
|
||||
},
|
||||
xcm_pallet: Default::default(),
|
||||
nomination_pools: Default::default(),
|
||||
assigned_slots: Default::default(),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Helper function to create rococo `RuntimeGenesisConfig` for testing
|
||||
/// Helper function to create rococo runtime `GenesisConfig` patch for testing
|
||||
#[cfg(feature = "rococo-native")]
|
||||
pub fn rococo_testnet_genesis(
|
||||
wasm_binary: &[u8],
|
||||
initial_authorities: Vec<(
|
||||
AccountId,
|
||||
AccountId,
|
||||
@@ -987,20 +907,17 @@ pub fn rococo_testnet_genesis(
|
||||
)>,
|
||||
root_key: AccountId,
|
||||
endowed_accounts: Option<Vec<AccountId>>,
|
||||
) -> rococo_runtime::RuntimeGenesisConfig {
|
||||
) -> serde_json::Value {
|
||||
let endowed_accounts: Vec<AccountId> = endowed_accounts.unwrap_or_else(testnet_accounts);
|
||||
|
||||
const ENDOWMENT: u128 = 1_000_000 * ROC;
|
||||
|
||||
rococo_runtime::RuntimeGenesisConfig {
|
||||
system: rococo_runtime::SystemConfig { code: wasm_binary.to_vec(), ..Default::default() },
|
||||
beefy: Default::default(),
|
||||
indices: rococo_runtime::IndicesConfig { indices: vec![] },
|
||||
balances: rococo_runtime::BalancesConfig {
|
||||
balances: endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect(),
|
||||
serde_json::json!({
|
||||
"balances": {
|
||||
"balances": endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect::<Vec<_>>(),
|
||||
},
|
||||
session: rococo_runtime::SessionConfig {
|
||||
keys: initial_authorities
|
||||
"session": {
|
||||
"keys": initial_authorities
|
||||
.iter()
|
||||
.map(|x| {
|
||||
(
|
||||
@@ -1019,43 +936,25 @@ pub fn rococo_testnet_genesis(
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
},
|
||||
babe: rococo_runtime::BabeConfig {
|
||||
authorities: Default::default(),
|
||||
epoch_config: Some(rococo_runtime::BABE_GENESIS_EPOCH_CONFIG),
|
||||
..Default::default()
|
||||
"babe": {
|
||||
"epochConfig": Some(rococo_runtime::BABE_GENESIS_EPOCH_CONFIG),
|
||||
},
|
||||
grandpa: Default::default(),
|
||||
im_online: Default::default(),
|
||||
treasury: Default::default(),
|
||||
claims: rococo::ClaimsConfig { claims: vec![], vesting: vec![] },
|
||||
vesting: rococo::VestingConfig { vesting: vec![] },
|
||||
authority_discovery: rococo_runtime::AuthorityDiscoveryConfig {
|
||||
keys: vec![],
|
||||
..Default::default()
|
||||
},
|
||||
sudo: rococo_runtime::SudoConfig { key: Some(root_key.clone()) },
|
||||
hrmp: Default::default(),
|
||||
configuration: rococo_runtime::ConfigurationConfig {
|
||||
config: polkadot_runtime_parachains::configuration::HostConfiguration {
|
||||
"sudo": { "key": Some(root_key.clone()) },
|
||||
"configuration": {
|
||||
"config": polkadot_runtime_parachains::configuration::HostConfiguration {
|
||||
max_validators_per_core: Some(1),
|
||||
..default_parachains_host_configuration()
|
||||
},
|
||||
},
|
||||
paras: rococo_runtime::ParasConfig { paras: vec![], ..Default::default() },
|
||||
registrar: rococo_runtime::RegistrarConfig {
|
||||
next_free_para_id: polkadot_primitives::LOWEST_PUBLIC_ID,
|
||||
..Default::default()
|
||||
},
|
||||
xcm_pallet: Default::default(),
|
||||
nis_counterpart_balances: Default::default(),
|
||||
assigned_slots: Default::default(),
|
||||
}
|
||||
"registrar": {
|
||||
"nextFreeParaId": polkadot_primitives::LOWEST_PUBLIC_ID,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(feature = "westend-native")]
|
||||
fn westend_development_config_genesis(wasm_binary: &[u8]) -> westend::RuntimeGenesisConfig {
|
||||
fn westend_development_config_genesis() -> serde_json::Value {
|
||||
westend_testnet_genesis(
|
||||
wasm_binary,
|
||||
vec![get_authority_keys_from_seed("Alice")],
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
None,
|
||||
@@ -1063,9 +962,8 @@ fn westend_development_config_genesis(wasm_binary: &[u8]) -> westend::RuntimeGen
|
||||
}
|
||||
|
||||
#[cfg(feature = "rococo-native")]
|
||||
fn rococo_development_config_genesis(wasm_binary: &[u8]) -> rococo_runtime::RuntimeGenesisConfig {
|
||||
fn rococo_development_config_genesis() -> serde_json::Value {
|
||||
rococo_testnet_genesis(
|
||||
wasm_binary,
|
||||
vec![get_authority_keys_from_seed("Alice")],
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
None,
|
||||
@@ -1075,84 +973,67 @@ fn rococo_development_config_genesis(wasm_binary: &[u8]) -> rococo_runtime::Runt
|
||||
/// Westend development config (single validator Alice)
|
||||
#[cfg(feature = "westend-native")]
|
||||
pub fn westend_development_config() -> Result<WestendChainSpec, String> {
|
||||
let wasm_binary = westend::WASM_BINARY.ok_or("Westend development wasm not available")?;
|
||||
|
||||
Ok(WestendChainSpec::from_genesis(
|
||||
"Development",
|
||||
"westend_dev",
|
||||
ChainType::Development,
|
||||
move || westend_development_config_genesis(wasm_binary),
|
||||
vec![],
|
||||
None,
|
||||
Some(DEFAULT_PROTOCOL_ID),
|
||||
None,
|
||||
None,
|
||||
Ok(WestendChainSpec::builder(
|
||||
westend::WASM_BINARY.ok_or("Westend development wasm not available")?,
|
||||
Default::default(),
|
||||
))
|
||||
)
|
||||
.with_name("Development")
|
||||
.with_id("westend_dev")
|
||||
.with_chain_type(ChainType::Development)
|
||||
.with_genesis_config_patch(westend_development_config_genesis())
|
||||
.with_protocol_id(DEFAULT_PROTOCOL_ID)
|
||||
.build())
|
||||
}
|
||||
|
||||
/// Rococo development config (single validator Alice)
|
||||
#[cfg(feature = "rococo-native")]
|
||||
pub fn rococo_development_config() -> Result<RococoChainSpec, String> {
|
||||
let wasm_binary = rococo::WASM_BINARY.ok_or("Rococo development wasm not available")?;
|
||||
|
||||
Ok(RococoChainSpec::from_genesis(
|
||||
"Development",
|
||||
"rococo_dev",
|
||||
ChainType::Development,
|
||||
move || rococo_development_config_genesis(wasm_binary),
|
||||
vec![],
|
||||
None,
|
||||
Some(DEFAULT_PROTOCOL_ID),
|
||||
None,
|
||||
None,
|
||||
Ok(RococoChainSpec::builder(
|
||||
rococo::WASM_BINARY.ok_or("Rococo development wasm not available")?,
|
||||
Default::default(),
|
||||
))
|
||||
)
|
||||
.with_name("Development")
|
||||
.with_id("rococo_dev")
|
||||
.with_chain_type(ChainType::Development)
|
||||
.with_genesis_config_patch(rococo_development_config_genesis())
|
||||
.with_protocol_id(DEFAULT_PROTOCOL_ID)
|
||||
.build())
|
||||
}
|
||||
|
||||
/// `Versi` development config (single validator Alice)
|
||||
#[cfg(feature = "rococo-native")]
|
||||
pub fn versi_development_config() -> Result<RococoChainSpec, String> {
|
||||
let wasm_binary = rococo::WASM_BINARY.ok_or("Versi development wasm not available")?;
|
||||
|
||||
Ok(RococoChainSpec::from_genesis(
|
||||
"Development",
|
||||
"versi_dev",
|
||||
ChainType::Development,
|
||||
move || rococo_development_config_genesis(wasm_binary),
|
||||
vec![],
|
||||
None,
|
||||
Some("versi"),
|
||||
None,
|
||||
None,
|
||||
Ok(RococoChainSpec::builder(
|
||||
rococo::WASM_BINARY.ok_or("Versi development wasm not available")?,
|
||||
Default::default(),
|
||||
))
|
||||
)
|
||||
.with_name("Development")
|
||||
.with_id("versi_dev")
|
||||
.with_chain_type(ChainType::Development)
|
||||
.with_genesis_config_patch(rococo_development_config_genesis())
|
||||
.with_protocol_id("versi")
|
||||
.build())
|
||||
}
|
||||
|
||||
/// Wococo development config (single validator Alice)
|
||||
#[cfg(feature = "rococo-native")]
|
||||
pub fn wococo_development_config() -> Result<RococoChainSpec, String> {
|
||||
const WOCOCO_DEV_PROTOCOL_ID: &str = "woco";
|
||||
let wasm_binary = rococo::WASM_BINARY.ok_or("Wococo development wasm not available")?;
|
||||
|
||||
Ok(RococoChainSpec::from_genesis(
|
||||
"Development",
|
||||
"wococo_dev",
|
||||
ChainType::Development,
|
||||
move || rococo_development_config_genesis(wasm_binary),
|
||||
vec![],
|
||||
None,
|
||||
Some(WOCOCO_DEV_PROTOCOL_ID),
|
||||
None,
|
||||
None,
|
||||
Ok(RococoChainSpec::builder(
|
||||
rococo::WASM_BINARY.ok_or("Wococo development wasm not available")?,
|
||||
Default::default(),
|
||||
))
|
||||
)
|
||||
.with_name("Development")
|
||||
.with_id("wococo_dev")
|
||||
.with_chain_type(ChainType::Development)
|
||||
.with_genesis_config_patch(rococo_development_config_genesis())
|
||||
.with_protocol_id(WOCOCO_DEV_PROTOCOL_ID)
|
||||
.build())
|
||||
}
|
||||
|
||||
#[cfg(feature = "westend-native")]
|
||||
fn westend_local_testnet_genesis(wasm_binary: &[u8]) -> westend::RuntimeGenesisConfig {
|
||||
fn westend_local_testnet_genesis() -> serde_json::Value {
|
||||
westend_testnet_genesis(
|
||||
wasm_binary,
|
||||
vec![get_authority_keys_from_seed("Alice"), get_authority_keys_from_seed("Bob")],
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
None,
|
||||
@@ -1162,26 +1043,21 @@ fn westend_local_testnet_genesis(wasm_binary: &[u8]) -> westend::RuntimeGenesisC
|
||||
/// Westend local testnet config (multivalidator Alice + Bob)
|
||||
#[cfg(feature = "westend-native")]
|
||||
pub fn westend_local_testnet_config() -> Result<WestendChainSpec, String> {
|
||||
let wasm_binary = westend::WASM_BINARY.ok_or("Westend development wasm not available")?;
|
||||
|
||||
Ok(WestendChainSpec::from_genesis(
|
||||
"Westend Local Testnet",
|
||||
"westend_local_testnet",
|
||||
ChainType::Local,
|
||||
move || westend_local_testnet_genesis(wasm_binary),
|
||||
vec![],
|
||||
None,
|
||||
Some(DEFAULT_PROTOCOL_ID),
|
||||
None,
|
||||
None,
|
||||
Ok(WestendChainSpec::builder(
|
||||
westend::WASM_BINARY.ok_or("Westend development wasm not available")?,
|
||||
Default::default(),
|
||||
))
|
||||
)
|
||||
.with_name("Westend Local Testnet")
|
||||
.with_id("westend_local_testnet")
|
||||
.with_chain_type(ChainType::Local)
|
||||
.with_genesis_config_patch(westend_local_testnet_genesis())
|
||||
.with_protocol_id(DEFAULT_PROTOCOL_ID)
|
||||
.build())
|
||||
}
|
||||
|
||||
#[cfg(feature = "rococo-native")]
|
||||
fn rococo_local_testnet_genesis(wasm_binary: &[u8]) -> rococo_runtime::RuntimeGenesisConfig {
|
||||
fn rococo_local_testnet_genesis() -> serde_json::Value {
|
||||
rococo_testnet_genesis(
|
||||
wasm_binary,
|
||||
vec![get_authority_keys_from_seed("Alice"), get_authority_keys_from_seed("Bob")],
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
None,
|
||||
@@ -1191,27 +1067,22 @@ fn rococo_local_testnet_genesis(wasm_binary: &[u8]) -> rococo_runtime::RuntimeGe
|
||||
/// Rococo local testnet config (multivalidator Alice + Bob)
|
||||
#[cfg(feature = "rococo-native")]
|
||||
pub fn rococo_local_testnet_config() -> Result<RococoChainSpec, String> {
|
||||
let wasm_binary = rococo::WASM_BINARY.ok_or("Rococo development wasm not available")?;
|
||||
|
||||
Ok(RococoChainSpec::from_genesis(
|
||||
"Rococo Local Testnet",
|
||||
"rococo_local_testnet",
|
||||
ChainType::Local,
|
||||
move || rococo_local_testnet_genesis(wasm_binary),
|
||||
vec![],
|
||||
None,
|
||||
Some(DEFAULT_PROTOCOL_ID),
|
||||
None,
|
||||
None,
|
||||
Ok(RococoChainSpec::builder(
|
||||
rococo::WASM_BINARY.ok_or("Rococo development wasm not available")?,
|
||||
Default::default(),
|
||||
))
|
||||
)
|
||||
.with_name("Rococo Local Testnet")
|
||||
.with_id("rococo_local_testnet")
|
||||
.with_chain_type(ChainType::Local)
|
||||
.with_genesis_config_patch(rococo_local_testnet_genesis())
|
||||
.with_protocol_id(DEFAULT_PROTOCOL_ID)
|
||||
.build())
|
||||
}
|
||||
|
||||
/// Wococo is a temporary testnet that uses almost the same runtime as rococo.
|
||||
#[cfg(feature = "rococo-native")]
|
||||
fn wococo_local_testnet_genesis(wasm_binary: &[u8]) -> rococo_runtime::RuntimeGenesisConfig {
|
||||
fn wococo_local_testnet_genesis() -> serde_json::Value {
|
||||
rococo_testnet_genesis(
|
||||
wasm_binary,
|
||||
vec![
|
||||
get_authority_keys_from_seed("Alice"),
|
||||
get_authority_keys_from_seed("Bob"),
|
||||
@@ -1226,27 +1097,22 @@ fn wococo_local_testnet_genesis(wasm_binary: &[u8]) -> rococo_runtime::RuntimeGe
|
||||
/// Wococo local testnet config (multivalidator Alice + Bob + Charlie + Dave)
|
||||
#[cfg(feature = "rococo-native")]
|
||||
pub fn wococo_local_testnet_config() -> Result<RococoChainSpec, String> {
|
||||
let wasm_binary = rococo::WASM_BINARY.ok_or("Wococo development wasm not available")?;
|
||||
|
||||
Ok(RococoChainSpec::from_genesis(
|
||||
"Wococo Local Testnet",
|
||||
"wococo_local_testnet",
|
||||
ChainType::Local,
|
||||
move || wococo_local_testnet_genesis(wasm_binary),
|
||||
vec![],
|
||||
None,
|
||||
Some(DEFAULT_PROTOCOL_ID),
|
||||
None,
|
||||
None,
|
||||
Ok(RococoChainSpec::builder(
|
||||
rococo::WASM_BINARY.ok_or("Rococo development wasm (used for wococo) not available")?,
|
||||
Default::default(),
|
||||
))
|
||||
)
|
||||
.with_name("Wococo Local Testnet")
|
||||
.with_id("wococo_local_testnet")
|
||||
.with_chain_type(ChainType::Local)
|
||||
.with_genesis_config_patch(wococo_local_testnet_genesis())
|
||||
.with_protocol_id(DEFAULT_PROTOCOL_ID)
|
||||
.build())
|
||||
}
|
||||
|
||||
/// `Versi` is a temporary testnet that uses the same runtime as rococo.
|
||||
#[cfg(feature = "rococo-native")]
|
||||
fn versi_local_testnet_genesis(wasm_binary: &[u8]) -> rococo_runtime::RuntimeGenesisConfig {
|
||||
fn versi_local_testnet_genesis() -> serde_json::Value {
|
||||
rococo_testnet_genesis(
|
||||
wasm_binary,
|
||||
vec![
|
||||
get_authority_keys_from_seed("Alice"),
|
||||
get_authority_keys_from_seed("Bob"),
|
||||
@@ -1261,18 +1127,14 @@ fn versi_local_testnet_genesis(wasm_binary: &[u8]) -> rococo_runtime::RuntimeGen
|
||||
/// `Versi` local testnet config (multivalidator Alice + Bob + Charlie + Dave)
|
||||
#[cfg(feature = "rococo-native")]
|
||||
pub fn versi_local_testnet_config() -> Result<RococoChainSpec, String> {
|
||||
let wasm_binary = rococo::WASM_BINARY.ok_or("Versi development wasm not available")?;
|
||||
|
||||
Ok(RococoChainSpec::from_genesis(
|
||||
"Versi Local Testnet",
|
||||
"versi_local_testnet",
|
||||
ChainType::Local,
|
||||
move || versi_local_testnet_genesis(wasm_binary),
|
||||
vec![],
|
||||
None,
|
||||
Some("versi"),
|
||||
None,
|
||||
None,
|
||||
Ok(RococoChainSpec::builder(
|
||||
rococo::WASM_BINARY.ok_or("Rococo development wasm (used for versi) not available")?,
|
||||
Default::default(),
|
||||
))
|
||||
)
|
||||
.with_name("Versi Local Testnet")
|
||||
.with_id("versi_local_testnet")
|
||||
.with_chain_type(ChainType::Local)
|
||||
.with_genesis_config_patch(versi_local_testnet_genesis())
|
||||
.with_protocol_id("versi")
|
||||
.build())
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ pub struct GenesisParameters;
|
||||
|
||||
impl substrate_test_client::GenesisInit for GenesisParameters {
|
||||
fn genesis_storage(&self) -> Storage {
|
||||
polkadot_test_service::chain_spec::polkadot_local_testnet_genesis()
|
||||
polkadot_test_service::chain_spec::polkadot_local_testnet_config()
|
||||
.build_storage()
|
||||
.expect("Builds test runtime genesis storage")
|
||||
}
|
||||
|
||||
@@ -59,7 +59,6 @@ substrate-test-client = { path = "../../../../substrate/test-utils/client" }
|
||||
|
||||
[dev-dependencies]
|
||||
pallet-balances = { path = "../../../../substrate/frame/balances", default-features = false }
|
||||
serde_json = "1.0.107"
|
||||
substrate-test-utils = { path = "../../../../substrate/test-utils" }
|
||||
tokio = { version = "1.24.2", features = ["macros"] }
|
||||
|
||||
|
||||
@@ -31,8 +31,7 @@ use test_runtime_constants::currency::DOTS;
|
||||
const DEFAULT_PROTOCOL_ID: &str = "dot";
|
||||
|
||||
/// The `ChainSpec` parameterized for polkadot test runtime.
|
||||
pub type PolkadotChainSpec =
|
||||
sc_service::GenericChainSpec<polkadot_test_runtime::RuntimeGenesisConfig, Extensions>;
|
||||
pub type PolkadotChainSpec = sc_service::GenericChainSpec<(), Extensions>;
|
||||
|
||||
/// Returns the properties for the [`PolkadotChainSpec`].
|
||||
pub fn polkadot_chain_spec_properties() -> serde_json::map::Map<String, serde_json::Value> {
|
||||
@@ -46,22 +45,21 @@ pub fn polkadot_chain_spec_properties() -> serde_json::map::Map<String, serde_js
|
||||
|
||||
/// Local testnet config (multivalidator Alice + Bob)
|
||||
pub fn polkadot_local_testnet_config() -> PolkadotChainSpec {
|
||||
PolkadotChainSpec::from_genesis(
|
||||
"Local Testnet",
|
||||
"local_testnet",
|
||||
ChainType::Local,
|
||||
|| polkadot_local_testnet_genesis(),
|
||||
vec![],
|
||||
None,
|
||||
Some(DEFAULT_PROTOCOL_ID),
|
||||
None,
|
||||
Some(polkadot_chain_spec_properties()),
|
||||
PolkadotChainSpec::builder(
|
||||
polkadot_test_runtime::WASM_BINARY.expect("Wasm binary must be built for testing"),
|
||||
Default::default(),
|
||||
)
|
||||
.with_name("Local Testnet")
|
||||
.with_id("local_testnet")
|
||||
.with_chain_type(ChainType::Local)
|
||||
.with_genesis_config_patch(polkadot_local_testnet_genesis())
|
||||
.with_protocol_id(DEFAULT_PROTOCOL_ID)
|
||||
.with_properties(polkadot_chain_spec_properties())
|
||||
.build()
|
||||
}
|
||||
|
||||
/// Local testnet genesis config (multivalidator Alice + Bob)
|
||||
pub fn polkadot_local_testnet_genesis() -> polkadot_test_runtime::RuntimeGenesisConfig {
|
||||
pub fn polkadot_local_testnet_genesis() -> serde_json::Value {
|
||||
polkadot_testnet_genesis(
|
||||
vec![get_authority_keys_from_seed("Alice"), get_authority_keys_from_seed("Bob")],
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
@@ -114,7 +112,7 @@ fn polkadot_testnet_genesis(
|
||||
)>,
|
||||
root_key: AccountId,
|
||||
endowed_accounts: Option<Vec<AccountId>>,
|
||||
) -> polkadot_test_runtime::RuntimeGenesisConfig {
|
||||
) -> serde_json::Value {
|
||||
use polkadot_test_runtime as runtime;
|
||||
|
||||
let endowed_accounts: Vec<AccountId> = endowed_accounts.unwrap_or_else(testnet_accounts);
|
||||
@@ -122,17 +120,12 @@ fn polkadot_testnet_genesis(
|
||||
const ENDOWMENT: u128 = 1_000_000 * DOTS;
|
||||
const STASH: u128 = 100 * DOTS;
|
||||
|
||||
runtime::RuntimeGenesisConfig {
|
||||
system: runtime::SystemConfig {
|
||||
code: runtime::WASM_BINARY.expect("Wasm binary must be built for testing").to_vec(),
|
||||
..Default::default()
|
||||
serde_json::json!({
|
||||
"balances": {
|
||||
"balances": endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect::<Vec<_>>(),
|
||||
},
|
||||
indices: runtime::IndicesConfig { indices: vec![] },
|
||||
balances: runtime::BalancesConfig {
|
||||
balances: endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect(),
|
||||
},
|
||||
session: runtime::SessionConfig {
|
||||
keys: initial_authorities
|
||||
"session": {
|
||||
"keys": initial_authorities
|
||||
.iter()
|
||||
.map(|x| {
|
||||
(
|
||||
@@ -149,33 +142,23 @@ fn polkadot_testnet_genesis(
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
},
|
||||
staking: runtime::StakingConfig {
|
||||
minimum_validator_count: 1,
|
||||
validator_count: 2,
|
||||
stakers: initial_authorities
|
||||
"staking": {
|
||||
"minimumValidatorCount": 1,
|
||||
"validatorCount": 2,
|
||||
"stakers": initial_authorities
|
||||
.iter()
|
||||
.map(|x| (x.0.clone(), x.0.clone(), STASH, runtime::StakerStatus::Validator))
|
||||
.collect(),
|
||||
invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect(),
|
||||
force_era: Forcing::NotForcing,
|
||||
slash_reward_fraction: Perbill::from_percent(10),
|
||||
..Default::default()
|
||||
.map(|x| (x.0.clone(), x.0.clone(), STASH, runtime::StakerStatus::<AccountId>::Validator))
|
||||
.collect::<Vec<_>>(),
|
||||
"invulnerables": initial_authorities.iter().map(|x| x.0.clone()).collect::<Vec<_>>(),
|
||||
"forceEra": Forcing::NotForcing,
|
||||
"slashRewardFraction": Perbill::from_percent(10),
|
||||
},
|
||||
babe: runtime::BabeConfig {
|
||||
authorities: vec![],
|
||||
epoch_config: Some(BABE_GENESIS_EPOCH_CONFIG),
|
||||
..Default::default()
|
||||
"babe": {
|
||||
"epochConfig": Some(BABE_GENESIS_EPOCH_CONFIG),
|
||||
},
|
||||
grandpa: Default::default(),
|
||||
authority_discovery: runtime::AuthorityDiscoveryConfig {
|
||||
keys: vec![],
|
||||
..Default::default()
|
||||
},
|
||||
claims: runtime::ClaimsConfig { claims: vec![], vesting: vec![] },
|
||||
vesting: runtime::VestingConfig { vesting: vec![] },
|
||||
sudo: runtime::SudoConfig { key: Some(root_key) },
|
||||
configuration: runtime::ConfigurationConfig {
|
||||
config: polkadot_runtime_parachains::configuration::HostConfiguration {
|
||||
"sudo": { "key": Some(root_key) },
|
||||
"configuration": {
|
||||
"config": polkadot_runtime_parachains::configuration::HostConfiguration {
|
||||
validation_upgrade_cooldown: 10u32,
|
||||
validation_upgrade_delay: 5,
|
||||
code_retention_period: 1200,
|
||||
@@ -188,8 +171,8 @@ fn polkadot_testnet_genesis(
|
||||
minimum_validation_upgrade_delay: 5,
|
||||
..Default::default()
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Can be called for a `Configuration` to check if it is a configuration for the `Test` network.
|
||||
|
||||
@@ -246,7 +246,8 @@ impl sp_runtime::traits::Convert<sp_core::U256, Balance> for U256ToBalance {
|
||||
}
|
||||
|
||||
/// Macro to set a value (e.g. when using the `parameter_types` macro) to either a production value
|
||||
/// or to an environment variable or testing value (in case the `fast-runtime` feature is selected).
|
||||
/// or to an environment variable or testing value (in case the `fast-runtime` feature is selected)
|
||||
/// or one of two testing values depending on feature.
|
||||
/// Note that the environment variable is evaluated _at compile time_.
|
||||
///
|
||||
/// Usage:
|
||||
@@ -255,6 +256,8 @@ impl sp_runtime::traits::Convert<sp_core::U256, Balance> for U256ToBalance {
|
||||
/// // Note that the env variable version parameter cannot be const.
|
||||
/// pub LaunchPeriod: BlockNumber = prod_or_fast!(7 * DAYS, 1, "KSM_LAUNCH_PERIOD");
|
||||
/// pub const VotingPeriod: BlockNumber = prod_or_fast!(7 * DAYS, 1 * MINUTES);
|
||||
/// pub const EpochDuration: BlockNumber =
|
||||
/// prod_or_fast!(1 * HOURS, "fast-runtime", 1 * MINUTES, "fast-runtime-10m", 10 * MINUTES);
|
||||
/// }
|
||||
/// ```
|
||||
#[macro_export]
|
||||
|
||||
@@ -56,6 +56,7 @@ const LOG_TARGET: &str = "runtime::configuration";
|
||||
serde::Serialize,
|
||||
serde::Deserialize,
|
||||
)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct HostConfiguration<BlockNumber> {
|
||||
// NOTE: This structure is used by parachains via merkle proofs. Therefore, this struct
|
||||
// requires special treatment.
|
||||
|
||||
@@ -313,7 +313,7 @@ try-runtime = [
|
||||
]
|
||||
|
||||
# Set timing constants (e.g. session period) to faster versions to speed up testing.
|
||||
fast-runtime = []
|
||||
fast-runtime = [ "rococo-runtime-constants/fast-runtime" ]
|
||||
|
||||
runtime-metrics = [ "runtime-parachains/runtime-metrics", "sp-io/with-tracing" ]
|
||||
|
||||
|
||||
@@ -29,3 +29,6 @@ std = [
|
||||
"sp-weights/std",
|
||||
"xcm/std",
|
||||
]
|
||||
|
||||
# Set timing constants (e.g. session period) to faster versions to speed up testing.
|
||||
fast-runtime = []
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[settings]
|
||||
timeout = 1000
|
||||
|
||||
[relaychain.genesis.runtime.configuration.config]
|
||||
[relaychain.genesis.runtimeGenesis.patch.configuration.config]
|
||||
max_validators_per_core = 5
|
||||
needed_approvals = 8
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
timeout = 1000
|
||||
bootnode = true
|
||||
|
||||
[relaychain.genesis.runtime.configuration.config]
|
||||
[relaychain.genesis.runtimeGenesis.patch.configuration.config]
|
||||
max_validators_per_core = 1
|
||||
needed_approvals = 2
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
timeout = 1000
|
||||
bootnode = true
|
||||
|
||||
[relaychain.genesis.runtime.configuration.config]
|
||||
[relaychain.genesis.runtimeGenesis.patch.configuration.config]
|
||||
max_validators_per_core = 1
|
||||
needed_approvals = 2
|
||||
group_rotation_frequency = 2
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
timeout = 1000
|
||||
bootnode = true
|
||||
|
||||
[relaychain.genesis.runtime.configuration.config]
|
||||
[relaychain.genesis.runtimeGenesis.patch.configuration.config]
|
||||
max_validators_per_core = 1
|
||||
needed_approvals = 3
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0
|
||||
# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json
|
||||
|
||||
title: "`chain-spec`: getting ready for native-runtime-free world"
|
||||
|
||||
doc:
|
||||
- audience: Node Dev
|
||||
description: |
|
||||
- [`ChainSpec::from_genesis`](https://github.com/paritytech/polkadot-sdk/blob/3df6b4d00eb310900de6f4858114baf68239412c/substrate/client/chain-spec/src/chain_spec.rs#L525) becomes deprecated in favor of [`ChainSpec::builder()`](https://github.com/paritytech/polkadot-sdk/blob/3df6b4d00eb310900de6f4858114baf68239412c/substrate/client/chain-spec/src/chain_spec.rs#L432),
|
||||
- The signature of [`ChainSpec::from_genesis`] method was changed by extending it with `code` argument.
|
||||
|
||||
migrations:
|
||||
db: []
|
||||
|
||||
runtime: []
|
||||
|
||||
crates: []
|
||||
|
||||
host_functions: []
|
||||
@@ -17,6 +17,7 @@ subkey = { path = "bin/utils/subkey" }
|
||||
chain-spec-builder = { package = "staging-chain-spec-builder", path = "bin/utils/chain-spec-builder" }
|
||||
|
||||
sc-service = { path = "client/service" }
|
||||
sc-chain-spec = { path = "client/chain-spec" }
|
||||
sc-cli = { path = "client/cli" }
|
||||
sc-consensus-aura = { path = "client/consensus/aura" }
|
||||
sc-consensus-babe = { path = "client/consensus/babe" }
|
||||
|
||||
@@ -21,6 +21,7 @@ clap = { version = "4.0.9", features = ["derive"] }
|
||||
futures = { version = "0.3.21", features = ["thread-pool"] }
|
||||
futures-timer = "3.0.1"
|
||||
jsonrpsee = { version = "0.16.2", features = ["server"] }
|
||||
serde_json = "1.0.107"
|
||||
|
||||
sc-cli = { path = "../../../client/cli" }
|
||||
sc-executor = { path = "../../../client/executor" }
|
||||
|
||||
@@ -15,12 +15,13 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use runtime::{BalancesConfig, RuntimeGenesisConfig, SudoConfig, SystemConfig, WASM_BINARY};
|
||||
use runtime::{BalancesConfig, SudoConfig, WASM_BINARY};
|
||||
use sc_service::{ChainType, Properties};
|
||||
use serde_json::{json, Value};
|
||||
use sp_keyring::AccountKeyring;
|
||||
|
||||
/// This is a specialization of the general Substrate ChainSpec type.
|
||||
pub type ChainSpec = sc_service::GenericChainSpec<RuntimeGenesisConfig>;
|
||||
pub type ChainSpec = sc_service::GenericChainSpec<()>;
|
||||
|
||||
fn props() -> Properties {
|
||||
let mut properties = Properties::new();
|
||||
@@ -30,37 +31,25 @@ fn props() -> Properties {
|
||||
}
|
||||
|
||||
pub fn development_config() -> Result<ChainSpec, String> {
|
||||
let wasm_binary = WASM_BINARY.ok_or_else(|| "Development wasm not available".to_string())?;
|
||||
Ok(ChainSpec::from_genesis(
|
||||
"Development",
|
||||
"dev",
|
||||
ChainType::Development,
|
||||
move || testnet_genesis(wasm_binary),
|
||||
vec![],
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Some(props()),
|
||||
None,
|
||||
))
|
||||
Ok(ChainSpec::builder(WASM_BINARY.expect("Development wasm not available"), Default::default())
|
||||
.with_name("Development")
|
||||
.with_id("dev")
|
||||
.with_chain_type(ChainType::Development)
|
||||
.with_genesis_config_patch(testnet_genesis())
|
||||
.with_properties(props())
|
||||
.build())
|
||||
}
|
||||
|
||||
/// Configure initial storage state for FRAME pallets.
|
||||
fn testnet_genesis(wasm_binary: &[u8]) -> RuntimeGenesisConfig {
|
||||
fn testnet_genesis() -> Value {
|
||||
use frame::traits::Get;
|
||||
use runtime::interface::{Balance, MinimumBalance};
|
||||
let endowment = <MinimumBalance as Get<Balance>>::get().max(1) * 1000;
|
||||
let balances = AccountKeyring::iter()
|
||||
.map(|a| (a.to_account_id(), endowment))
|
||||
.collect::<Vec<_>>();
|
||||
RuntimeGenesisConfig {
|
||||
system: SystemConfig {
|
||||
// Add Wasm runtime to storage.
|
||||
code: wasm_binary.to_vec(),
|
||||
_config: Default::default(),
|
||||
},
|
||||
balances: BalancesConfig { balances },
|
||||
sudo: SudoConfig { key: Some(AccountKeyring::Alice.to_account_id()) },
|
||||
..Default::default()
|
||||
}
|
||||
json!({
|
||||
"balances": BalancesConfig { balances },
|
||||
"sudo": SudoConfig { key: Some(AccountKeyring::Alice.to_account_id()) },
|
||||
})
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ scale-info = { version = "2.6.0", default-features = false }
|
||||
|
||||
# this is a frame-based runtime, thus importing `frame` with runtime feature enabled.
|
||||
frame = { path = "../../../frame", default-features = false, features = ["runtime", "experimental"] }
|
||||
frame-support = { path = "../../../frame/support", default-features = false}
|
||||
|
||||
# pallets that we want to use
|
||||
pallet-balances = { path = "../../../frame/balances", default-features = false }
|
||||
@@ -17,6 +18,9 @@ pallet-timestamp = { path = "../../../frame/timestamp", default-features = false
|
||||
pallet-transaction-payment = { path = "../../../frame/transaction-payment", default-features = false }
|
||||
pallet-transaction-payment-rpc-runtime-api = { path = "../../../frame/transaction-payment/rpc/runtime-api", default-features = false }
|
||||
|
||||
# genesis builder that allows us to interacto with runtime genesis config
|
||||
sp-genesis-builder = { path = "../../../primitives/genesis-builder", default-features = false}
|
||||
|
||||
|
||||
[build-dependencies]
|
||||
substrate-wasm-builder = { path = "../../../utils/wasm-builder", optional = true }
|
||||
|
||||
@@ -31,6 +31,7 @@ use frame::{
|
||||
prelude::*,
|
||||
},
|
||||
};
|
||||
use frame_support::genesis_builder_helper::{build_config, create_default_config};
|
||||
|
||||
#[runtime_version]
|
||||
pub const VERSION: RuntimeVersion = RuntimeVersion {
|
||||
@@ -210,6 +211,16 @@ impl_runtime_apis! {
|
||||
TransactionPayment::length_to_fee(length)
|
||||
}
|
||||
}
|
||||
|
||||
impl sp_genesis_builder::GenesisBuilder<Block> for Runtime {
|
||||
fn create_default_config() -> Vec<u8> {
|
||||
create_default_config::<RuntimeGenesisConfig>()
|
||||
}
|
||||
|
||||
fn build_config(config: Vec<u8>) -> sp_genesis_builder::Result {
|
||||
build_config::<RuntimeGenesisConfig>(config)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Some re-exports that the node side code needs to know. Some are useful in this context as well.
|
||||
|
||||
@@ -19,6 +19,7 @@ name = "node-template"
|
||||
[dependencies]
|
||||
clap = { version = "4.4.6", features = ["derive"] }
|
||||
futures = { version = "0.3.21", features = ["thread-pool"]}
|
||||
serde_json = "1.0.85"
|
||||
|
||||
sc-cli = { path = "../../../client/cli" }
|
||||
sp-core = { path = "../../../primitives/core" }
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
use node_template_runtime::{
|
||||
AccountId, AuraConfig, BalancesConfig, GrandpaConfig, RuntimeGenesisConfig, Signature,
|
||||
SudoConfig, SystemConfig, WASM_BINARY,
|
||||
};
|
||||
use node_template_runtime::{AccountId, RuntimeGenesisConfig, Signature, WASM_BINARY};
|
||||
use sc_service::ChainType;
|
||||
use sp_consensus_aura::sr25519::AuthorityId as AuraId;
|
||||
use sp_consensus_grandpa::AuthorityId as GrandpaId;
|
||||
@@ -37,122 +34,84 @@ pub fn authority_keys_from_seed(s: &str) -> (AuraId, GrandpaId) {
|
||||
}
|
||||
|
||||
pub fn development_config() -> Result<ChainSpec, String> {
|
||||
let wasm_binary = WASM_BINARY.ok_or_else(|| "Development wasm not available".to_string())?;
|
||||
|
||||
Ok(ChainSpec::from_genesis(
|
||||
// Name
|
||||
"Development",
|
||||
// ID
|
||||
"dev",
|
||||
ChainType::Development,
|
||||
move || {
|
||||
testnet_genesis(
|
||||
wasm_binary,
|
||||
// Initial PoA authorities
|
||||
vec![authority_keys_from_seed("Alice")],
|
||||
// Sudo account
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
// Pre-funded accounts
|
||||
vec![
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
|
||||
],
|
||||
true,
|
||||
)
|
||||
},
|
||||
// Bootnodes
|
||||
vec![],
|
||||
// Telemetry
|
||||
None,
|
||||
// Protocol ID
|
||||
None,
|
||||
None,
|
||||
// Properties
|
||||
None,
|
||||
// Extensions
|
||||
Ok(ChainSpec::builder(
|
||||
WASM_BINARY.ok_or_else(|| "Development wasm not available".to_string())?,
|
||||
None,
|
||||
)
|
||||
.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
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
// Pre-funded accounts
|
||||
vec![
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
|
||||
],
|
||||
true,
|
||||
))
|
||||
.build())
|
||||
}
|
||||
|
||||
pub fn local_testnet_config() -> Result<ChainSpec, String> {
|
||||
let wasm_binary = WASM_BINARY.ok_or_else(|| "Development wasm not available".to_string())?;
|
||||
|
||||
Ok(ChainSpec::from_genesis(
|
||||
// Name
|
||||
"Local Testnet",
|
||||
// ID
|
||||
"local_testnet",
|
||||
ChainType::Local,
|
||||
move || {
|
||||
testnet_genesis(
|
||||
wasm_binary,
|
||||
// Initial PoA authorities
|
||||
vec![authority_keys_from_seed("Alice"), authority_keys_from_seed("Bob")],
|
||||
// Sudo account
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
// Pre-funded accounts
|
||||
vec![
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),
|
||||
],
|
||||
true,
|
||||
)
|
||||
},
|
||||
// Bootnodes
|
||||
vec![],
|
||||
// Telemetry
|
||||
None,
|
||||
// Protocol ID
|
||||
None,
|
||||
// Properties
|
||||
None,
|
||||
None,
|
||||
// Extensions
|
||||
Ok(ChainSpec::builder(
|
||||
WASM_BINARY.ok_or_else(|| "Development wasm not available".to_string())?,
|
||||
None,
|
||||
)
|
||||
.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")],
|
||||
// Sudo account
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
// Pre-funded accounts
|
||||
vec![
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),
|
||||
],
|
||||
true,
|
||||
))
|
||||
.build())
|
||||
}
|
||||
|
||||
/// Configure initial storage state for FRAME modules.
|
||||
fn testnet_genesis(
|
||||
wasm_binary: &[u8],
|
||||
initial_authorities: Vec<(AuraId, GrandpaId)>,
|
||||
root_key: AccountId,
|
||||
endowed_accounts: Vec<AccountId>,
|
||||
_enable_println: bool,
|
||||
) -> RuntimeGenesisConfig {
|
||||
RuntimeGenesisConfig {
|
||||
system: SystemConfig {
|
||||
// Add Wasm runtime to storage.
|
||||
code: wasm_binary.to_vec(),
|
||||
..Default::default()
|
||||
},
|
||||
balances: BalancesConfig {
|
||||
) -> serde_json::Value {
|
||||
serde_json::json!({
|
||||
"balances": {
|
||||
// Configure endowed accounts with initial balance of 1 << 60.
|
||||
balances: endowed_accounts.iter().cloned().map(|k| (k, 1 << 60)).collect(),
|
||||
"balances": endowed_accounts.iter().cloned().map(|k| (k, 1u64 << 60)).collect::<Vec<_>>(),
|
||||
},
|
||||
aura: AuraConfig {
|
||||
authorities: initial_authorities.iter().map(|x| (x.0.clone())).collect(),
|
||||
"aura": {
|
||||
"authorities": initial_authorities.iter().map(|x| (x.0.clone())).collect::<Vec<_>>(),
|
||||
},
|
||||
grandpa: GrandpaConfig {
|
||||
authorities: initial_authorities.iter().map(|x| (x.1.clone(), 1)).collect(),
|
||||
..Default::default()
|
||||
"grandpa": {
|
||||
"authorities": initial_authorities.iter().map(|x| (x.1.clone(), 1)).collect::<Vec<_>>(),
|
||||
},
|
||||
sudo: SudoConfig {
|
||||
"sudo": {
|
||||
// Assign network admin rights.
|
||||
key: Some(root_key),
|
||||
"key": Some(root_key),
|
||||
},
|
||||
transaction_payment: Default::default(),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
||||
[dependencies]
|
||||
codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["derive"] }
|
||||
scale-info = { version = "2.10.0", default-features = false, features = ["derive"] }
|
||||
scale-info = { version = "2.10.0", default-features = false, features = ["derive", "serde"] }
|
||||
|
||||
pallet-aura = { path = "../../../frame/aura", default-features = false}
|
||||
pallet-balances = { path = "../../../frame/balances", default-features = false}
|
||||
@@ -28,17 +28,18 @@ pallet-transaction-payment = { path = "../../../frame/transaction-payment", defa
|
||||
frame-executive = { path = "../../../frame/executive", default-features = false}
|
||||
sp-api = { path = "../../../primitives/api", default-features = false}
|
||||
sp-block-builder = { path = "../../../primitives/block-builder", default-features = false}
|
||||
sp-consensus-aura = { path = "../../../primitives/consensus/aura", default-features = false}
|
||||
sp-consensus-grandpa = { path = "../../../primitives/consensus/grandpa", default-features = false}
|
||||
sp-core = { path = "../../../primitives/core", default-features = false}
|
||||
sp-consensus-aura = { path = "../../../primitives/consensus/aura", default-features = false, features = ["serde"] }
|
||||
sp-consensus-grandpa = { path = "../../../primitives/consensus/grandpa", default-features = false, features = ["serde"] }
|
||||
sp-core = { path = "../../../primitives/core", default-features = false, features = ["serde"]}
|
||||
sp-inherents = { path = "../../../primitives/inherents", default-features = false}
|
||||
sp-offchain = { path = "../../../primitives/offchain", default-features = false}
|
||||
sp-runtime = { path = "../../../primitives/runtime", default-features = false}
|
||||
sp-runtime = { path = "../../../primitives/runtime", default-features = false, features = ["serde"] }
|
||||
sp-session = { path = "../../../primitives/session", default-features = false}
|
||||
sp-std = { path = "../../../primitives/std", default-features = false}
|
||||
sp-storage = { path = "../../../primitives/storage", default-features = false}
|
||||
sp-transaction-pool = { path = "../../../primitives/transaction-pool", default-features = false}
|
||||
sp-version = { path = "../../../primitives/version", default-features = false}
|
||||
sp-version = { path = "../../../primitives/version", default-features = false, features = ["serde"] }
|
||||
serde_json = { version = "1.0.85", default-features = false, features = ["alloc"] }
|
||||
sp-genesis-builder = { default-features = false, path = "../../../primitives/genesis-builder" }
|
||||
|
||||
# Used for the node template's RPCs
|
||||
@@ -75,6 +76,7 @@ std = [
|
||||
"pallet-transaction-payment-rpc-runtime-api/std",
|
||||
"pallet-transaction-payment/std",
|
||||
"scale-info/std",
|
||||
"serde_json/std",
|
||||
"sp-api/std",
|
||||
"sp-block-builder/std",
|
||||
"sp-consensus-aura/std",
|
||||
|
||||
@@ -124,7 +124,6 @@ futures = "0.3.21"
|
||||
tempfile = "3.1.0"
|
||||
assert_cmd = "2.0.2"
|
||||
nix = { version = "0.26.1", features = ["signal"] }
|
||||
serde_json = "1.0"
|
||||
regex = "1.6.0"
|
||||
platforms = "3.0"
|
||||
soketto = "0.7.1"
|
||||
|
||||
@@ -20,10 +20,7 @@
|
||||
|
||||
use grandpa_primitives::AuthorityId as GrandpaId;
|
||||
use kitchensink_runtime::{
|
||||
constants::currency::*, wasm_binary_unwrap, BabeConfig, BalancesConfig, Block, CouncilConfig,
|
||||
DemocracyConfig, ElectionsConfig, ImOnlineConfig, IndicesConfig, MaxNominations,
|
||||
NominationPoolsConfig, SessionConfig, SessionKeys, SocietyConfig, StakerStatus, StakingConfig,
|
||||
SudoConfig, SystemConfig, TechnicalCommitteeConfig,
|
||||
constants::currency::*, wasm_binary_unwrap, Block, MaxNominations, SessionKeys, StakerStatus,
|
||||
};
|
||||
use pallet_im_online::sr25519::AuthorityId as ImOnlineId;
|
||||
use sc_chain_spec::ChainSpecExtension;
|
||||
@@ -45,6 +42,8 @@ pub use node_primitives::{AccountId, Balance, Signature};
|
||||
type AccountPublic = <Signature as Verify>::Signer;
|
||||
|
||||
const STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/";
|
||||
const ENDOWMENT: Balance = 10_000_000 * DOLLARS;
|
||||
const STASH: Balance = ENDOWMENT / 1000;
|
||||
|
||||
/// Node `ChainSpec` extensions.
|
||||
///
|
||||
@@ -78,7 +77,11 @@ fn session_keys(
|
||||
SessionKeys { grandpa, babe, im_online, authority_discovery, mixnet }
|
||||
}
|
||||
|
||||
fn staging_testnet_config_genesis() -> RuntimeGenesisConfig {
|
||||
fn configure_accounts_for_staging_testnet() -> (
|
||||
Vec<(AccountId, AccountId, GrandpaId, BabeId, ImOnlineId, AuthorityDiscoveryId, MixnetId)>,
|
||||
AccountId,
|
||||
Vec<AccountId>,
|
||||
) {
|
||||
#[rustfmt::skip]
|
||||
// stash, controller, session-key
|
||||
// generated with secret:
|
||||
@@ -190,28 +193,27 @@ fn staging_testnet_config_genesis() -> RuntimeGenesisConfig {
|
||||
);
|
||||
|
||||
let endowed_accounts: Vec<AccountId> = vec![root_key.clone()];
|
||||
(initial_authorities, root_key, endowed_accounts)
|
||||
}
|
||||
|
||||
fn staging_testnet_config_genesis() -> serde_json::Value {
|
||||
let (initial_authorities, root_key, endowed_accounts) =
|
||||
configure_accounts_for_staging_testnet();
|
||||
testnet_genesis(initial_authorities, vec![], root_key, Some(endowed_accounts))
|
||||
}
|
||||
|
||||
/// Staging testnet config.
|
||||
pub fn staging_testnet_config() -> ChainSpec {
|
||||
let boot_nodes = vec![];
|
||||
ChainSpec::from_genesis(
|
||||
"Staging Testnet",
|
||||
"staging_testnet",
|
||||
ChainType::Live,
|
||||
staging_testnet_config_genesis,
|
||||
boot_nodes,
|
||||
Some(
|
||||
ChainSpec::builder(wasm_binary_unwrap(), Default::default())
|
||||
.with_name("Staging Testnet")
|
||||
.with_id("staging_testnet")
|
||||
.with_chain_type(ChainType::Live)
|
||||
.with_genesis_config_patch(staging_testnet_config_genesis())
|
||||
.with_telemetry_endpoints(
|
||||
TelemetryEndpoints::new(vec![(STAGING_TELEMETRY_URL.to_string(), 0)])
|
||||
.expect("Staging telemetry url is valid; qed"),
|
||||
),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Default::default(),
|
||||
)
|
||||
)
|
||||
.build()
|
||||
}
|
||||
|
||||
/// Helper function to generate a crypto pair from seed.
|
||||
@@ -244,8 +246,7 @@ pub fn authority_keys_from_seed(
|
||||
)
|
||||
}
|
||||
|
||||
/// Helper function to create RuntimeGenesisConfig for testing.
|
||||
pub fn testnet_genesis(
|
||||
fn configure_accounts(
|
||||
initial_authorities: Vec<(
|
||||
AccountId,
|
||||
AccountId,
|
||||
@@ -256,9 +257,14 @@ pub fn testnet_genesis(
|
||||
MixnetId,
|
||||
)>,
|
||||
initial_nominators: Vec<AccountId>,
|
||||
root_key: AccountId,
|
||||
endowed_accounts: Option<Vec<AccountId>>,
|
||||
) -> RuntimeGenesisConfig {
|
||||
stash: Balance,
|
||||
) -> (
|
||||
Vec<(AccountId, AccountId, GrandpaId, BabeId, ImOnlineId, AuthorityDiscoveryId, MixnetId)>,
|
||||
Vec<AccountId>,
|
||||
usize,
|
||||
Vec<(AccountId, AccountId, Balance, StakerStatus<AccountId>)>,
|
||||
) {
|
||||
let mut endowed_accounts: Vec<AccountId> = endowed_accounts.unwrap_or_else(|| {
|
||||
vec![
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
@@ -290,7 +296,7 @@ pub fn testnet_genesis(
|
||||
let mut rng = rand::thread_rng();
|
||||
let stakers = initial_authorities
|
||||
.iter()
|
||||
.map(|x| (x.0.clone(), x.0.clone(), STASH, StakerStatus::Validator))
|
||||
.map(|x| (x.0.clone(), x.0.clone(), stash, StakerStatus::Validator))
|
||||
.chain(initial_nominators.iter().map(|x| {
|
||||
use rand::{seq::SliceRandom, Rng};
|
||||
let limit = (MaxNominations::get() as usize).min(initial_authorities.len());
|
||||
@@ -301,23 +307,39 @@ pub fn testnet_genesis(
|
||||
.into_iter()
|
||||
.map(|choice| choice.0.clone())
|
||||
.collect::<Vec<_>>();
|
||||
(x.clone(), x.clone(), STASH, StakerStatus::Nominator(nominations))
|
||||
(x.clone(), x.clone(), stash, StakerStatus::Nominator(nominations))
|
||||
}))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let num_endowed_accounts = endowed_accounts.len();
|
||||
|
||||
const ENDOWMENT: Balance = 10_000_000 * DOLLARS;
|
||||
const STASH: Balance = ENDOWMENT / 1000;
|
||||
(initial_authorities, endowed_accounts, num_endowed_accounts, stakers)
|
||||
}
|
||||
|
||||
RuntimeGenesisConfig {
|
||||
system: SystemConfig { code: wasm_binary_unwrap().to_vec(), ..Default::default() },
|
||||
balances: BalancesConfig {
|
||||
balances: endowed_accounts.iter().cloned().map(|x| (x, ENDOWMENT)).collect(),
|
||||
/// Helper function to create RuntimeGenesisConfig json patch for testing.
|
||||
pub fn testnet_genesis(
|
||||
initial_authorities: Vec<(
|
||||
AccountId,
|
||||
AccountId,
|
||||
GrandpaId,
|
||||
BabeId,
|
||||
ImOnlineId,
|
||||
AuthorityDiscoveryId,
|
||||
MixnetId,
|
||||
)>,
|
||||
initial_nominators: Vec<AccountId>,
|
||||
root_key: AccountId,
|
||||
endowed_accounts: Option<Vec<AccountId>>,
|
||||
) -> serde_json::Value {
|
||||
let (initial_authorities, endowed_accounts, num_endowed_accounts, stakers) =
|
||||
configure_accounts(initial_authorities, initial_nominators, endowed_accounts, STASH);
|
||||
|
||||
serde_json::json!({
|
||||
"balances": {
|
||||
"balances": endowed_accounts.iter().cloned().map(|x| (x, ENDOWMENT)).collect::<Vec<_>>(),
|
||||
},
|
||||
indices: IndicesConfig { indices: vec![] },
|
||||
session: SessionConfig {
|
||||
keys: initial_authorities
|
||||
"session": {
|
||||
"keys": initial_authorities
|
||||
.iter()
|
||||
.map(|x| {
|
||||
(
|
||||
@@ -334,67 +356,45 @@ pub fn testnet_genesis(
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
},
|
||||
staking: StakingConfig {
|
||||
validator_count: initial_authorities.len() as u32,
|
||||
minimum_validator_count: initial_authorities.len() as u32,
|
||||
invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect(),
|
||||
slash_reward_fraction: Perbill::from_percent(10),
|
||||
stakers,
|
||||
..Default::default()
|
||||
"staking": {
|
||||
"validatorCount": initial_authorities.len() as u32,
|
||||
"minimumValidatorCount": initial_authorities.len() as u32,
|
||||
"invulnerables": initial_authorities.iter().map(|x| x.0.clone()).collect::<Vec<_>>(),
|
||||
"slashRewardFraction": Perbill::from_percent(10),
|
||||
"stakers": stakers.clone(),
|
||||
},
|
||||
democracy: DemocracyConfig::default(),
|
||||
elections: ElectionsConfig {
|
||||
members: endowed_accounts
|
||||
"elections": {
|
||||
"members": endowed_accounts
|
||||
.iter()
|
||||
.take((num_endowed_accounts + 1) / 2)
|
||||
.cloned()
|
||||
.map(|member| (member, STASH))
|
||||
.collect(),
|
||||
.collect::<Vec<_>>(),
|
||||
},
|
||||
council: CouncilConfig::default(),
|
||||
technical_committee: TechnicalCommitteeConfig {
|
||||
members: endowed_accounts
|
||||
"technicalCommittee": {
|
||||
"members": endowed_accounts
|
||||
.iter()
|
||||
.take((num_endowed_accounts + 1) / 2)
|
||||
.cloned()
|
||||
.collect(),
|
||||
phantom: Default::default(),
|
||||
.collect::<Vec<_>>(),
|
||||
},
|
||||
sudo: SudoConfig { key: Some(root_key) },
|
||||
babe: BabeConfig {
|
||||
epoch_config: Some(kitchensink_runtime::BABE_GENESIS_EPOCH_CONFIG),
|
||||
..Default::default()
|
||||
"sudo": { "key": Some(root_key.clone()) },
|
||||
"babe": {
|
||||
"epochConfig": Some(kitchensink_runtime::BABE_GENESIS_EPOCH_CONFIG),
|
||||
},
|
||||
im_online: ImOnlineConfig { keys: vec![] },
|
||||
authority_discovery: Default::default(),
|
||||
grandpa: Default::default(),
|
||||
technical_membership: Default::default(),
|
||||
treasury: Default::default(),
|
||||
society: SocietyConfig { pot: 0 },
|
||||
vesting: Default::default(),
|
||||
assets: pallet_assets::GenesisConfig {
|
||||
"society": { "pot": 0 },
|
||||
"assets": {
|
||||
// This asset is used by the NIS pallet as counterpart currency.
|
||||
assets: vec![(9, get_account_id_from_seed::<sr25519::Public>("Alice"), true, 1)],
|
||||
..Default::default()
|
||||
"assets": vec![(9, get_account_id_from_seed::<sr25519::Public>("Alice"), true, 1)],
|
||||
},
|
||||
pool_assets: Default::default(),
|
||||
transaction_storage: Default::default(),
|
||||
transaction_payment: Default::default(),
|
||||
alliance: Default::default(),
|
||||
safe_mode: Default::default(),
|
||||
tx_pause: Default::default(),
|
||||
alliance_motion: Default::default(),
|
||||
nomination_pools: NominationPoolsConfig {
|
||||
min_create_bond: 10 * DOLLARS,
|
||||
min_join_bond: 1 * DOLLARS,
|
||||
..Default::default()
|
||||
"nominationPools": {
|
||||
"minCreateBond": 10 * DOLLARS,
|
||||
"minJoinBond": 1 * DOLLARS,
|
||||
},
|
||||
glutton: Default::default(),
|
||||
mixnet: Default::default(),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn development_config_genesis() -> RuntimeGenesisConfig {
|
||||
fn development_config_genesis_json() -> serde_json::Value {
|
||||
testnet_genesis(
|
||||
vec![authority_keys_from_seed("Alice")],
|
||||
vec![],
|
||||
@@ -405,21 +405,15 @@ fn development_config_genesis() -> RuntimeGenesisConfig {
|
||||
|
||||
/// Development config (single validator Alice).
|
||||
pub fn development_config() -> ChainSpec {
|
||||
ChainSpec::from_genesis(
|
||||
"Development",
|
||||
"dev",
|
||||
ChainType::Development,
|
||||
development_config_genesis,
|
||||
vec![],
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Default::default(),
|
||||
)
|
||||
ChainSpec::builder(wasm_binary_unwrap(), Default::default())
|
||||
.with_name("Development")
|
||||
.with_id("dev")
|
||||
.with_chain_type(ChainType::Development)
|
||||
.with_genesis_config_patch(development_config_genesis_json())
|
||||
.build()
|
||||
}
|
||||
|
||||
fn local_testnet_genesis() -> RuntimeGenesisConfig {
|
||||
fn local_testnet_genesis() -> serde_json::Value {
|
||||
testnet_genesis(
|
||||
vec![authority_keys_from_seed("Alice"), authority_keys_from_seed("Bob")],
|
||||
vec![],
|
||||
@@ -430,18 +424,12 @@ fn local_testnet_genesis() -> RuntimeGenesisConfig {
|
||||
|
||||
/// Local testnet config (multivalidator Alice + Bob).
|
||||
pub fn local_testnet_config() -> ChainSpec {
|
||||
ChainSpec::from_genesis(
|
||||
"Local Testnet",
|
||||
"local_testnet",
|
||||
ChainType::Local,
|
||||
local_testnet_genesis,
|
||||
vec![],
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Default::default(),
|
||||
)
|
||||
ChainSpec::builder(wasm_binary_unwrap(), Default::default())
|
||||
.with_name("Local Testnet")
|
||||
.with_id("local_testnet")
|
||||
.with_chain_type(ChainType::Local)
|
||||
.with_genesis_config_patch(local_testnet_genesis())
|
||||
.build()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -451,45 +439,29 @@ pub(crate) mod tests {
|
||||
use sc_service_test;
|
||||
use sp_runtime::BuildStorage;
|
||||
|
||||
fn local_testnet_genesis_instant_single() -> RuntimeGenesisConfig {
|
||||
testnet_genesis(
|
||||
vec![authority_keys_from_seed("Alice")],
|
||||
vec![],
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
None,
|
||||
)
|
||||
}
|
||||
|
||||
/// Local testnet config (single validator - Alice).
|
||||
pub fn integration_test_config_with_single_authority() -> ChainSpec {
|
||||
ChainSpec::from_genesis(
|
||||
"Integration Test",
|
||||
"test",
|
||||
ChainType::Development,
|
||||
local_testnet_genesis_instant_single,
|
||||
vec![],
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Default::default(),
|
||||
)
|
||||
ChainSpec::builder(wasm_binary_unwrap(), Default::default())
|
||||
.with_name("Integration Test")
|
||||
.with_id("test")
|
||||
.with_chain_type(ChainType::Development)
|
||||
.with_genesis_config_patch(testnet_genesis(
|
||||
vec![authority_keys_from_seed("Alice")],
|
||||
vec![],
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
None,
|
||||
))
|
||||
.build()
|
||||
}
|
||||
|
||||
/// Local testnet config (multivalidator Alice + Bob).
|
||||
pub fn integration_test_config_with_two_authorities() -> ChainSpec {
|
||||
ChainSpec::from_genesis(
|
||||
"Integration Test",
|
||||
"test",
|
||||
ChainType::Development,
|
||||
local_testnet_genesis,
|
||||
vec![],
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Default::default(),
|
||||
)
|
||||
ChainSpec::builder(wasm_binary_unwrap(), Default::default())
|
||||
.with_name("Integration Test")
|
||||
.with_id("test")
|
||||
.with_chain_type(ChainType::Development)
|
||||
.with_genesis_config_patch(local_testnet_genesis())
|
||||
.build()
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -14,17 +14,17 @@ targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
||||
[dependencies]
|
||||
codec = { package = "parity-scale-codec", version = "3.6.1" }
|
||||
scale-info = { version = "2.10.0", features = ["derive"] }
|
||||
scale-info = { version = "2.10.0", features = ["derive", "serde"] }
|
||||
frame-benchmarking = { path = "../../../frame/benchmarking" }
|
||||
node-primitives = { path = "../primitives" }
|
||||
kitchensink-runtime = { path = "../runtime" }
|
||||
sc-executor = { path = "../../../client/executor" }
|
||||
sp-core = { path = "../../../primitives/core" }
|
||||
sp-core = { path = "../../../primitives/core", features=["serde"] }
|
||||
sp-keystore = { path = "../../../primitives/keystore" }
|
||||
sp-state-machine = { path = "../../../primitives/state-machine" }
|
||||
sp-tracing = { path = "../../../primitives/tracing" }
|
||||
sp-trie = { path = "../../../primitives/trie" }
|
||||
sp-statement-store = { path = "../../../primitives/statement-store" }
|
||||
sp-statement-store = { path = "../../../primitives/statement-store", features=["serde"] }
|
||||
|
||||
[dev-dependencies]
|
||||
criterion = "0.4.0"
|
||||
@@ -47,6 +47,7 @@ sp-consensus-babe = { path = "../../../primitives/consensus/babe" }
|
||||
sp-externalities = { path = "../../../primitives/externalities" }
|
||||
sp-keyring = { path = "../../../primitives/keyring" }
|
||||
sp-runtime = { path = "../../../primitives/runtime" }
|
||||
serde_json = "1.0.85"
|
||||
|
||||
[features]
|
||||
stress-test = []
|
||||
|
||||
@@ -190,7 +190,7 @@ fn bench_execute_block(c: &mut Criterion) {
|
||||
|
||||
for strategy in execution_methods {
|
||||
group.bench_function(format!("{:?}", strategy), |b| {
|
||||
let genesis_config = node_testing::genesis::config(Some(compact_code_unwrap()));
|
||||
let genesis_config = node_testing::genesis::config();
|
||||
let use_native = match strategy {
|
||||
ExecutionMethod::Native => true,
|
||||
ExecutionMethod::Wasm(..) => false,
|
||||
|
||||
@@ -857,3 +857,19 @@ fn should_import_block_with_test_client() {
|
||||
|
||||
futures::executor::block_on(client.import(BlockOrigin::Own, block)).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_config_as_json_works() {
|
||||
let mut t = new_test_ext(compact_code_unwrap());
|
||||
let r = executor_call(&mut t, "GenesisBuilder_create_default_config", &vec![], false)
|
||||
.0
|
||||
.unwrap();
|
||||
let r = Vec::<u8>::decode(&mut &r[..]).unwrap();
|
||||
let json = String::from_utf8(r.into()).expect("returned value is json. qed.");
|
||||
let expected = include_str!("res/default_genesis_config.json").to_string();
|
||||
|
||||
assert_eq!(
|
||||
serde_json::from_str::<serde_json::Value>(&expected).unwrap(),
|
||||
serde_json::from_str::<serde_json::Value>(&json).unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ pub fn executor_call(
|
||||
pub fn new_test_ext(code: &[u8]) -> TestExternalities<BlakeTwo256> {
|
||||
let ext = TestExternalities::new_with_code(
|
||||
code,
|
||||
node_testing::genesis::config(Some(code)).build_storage().unwrap(),
|
||||
node_testing::genesis::config().build_storage().unwrap(),
|
||||
);
|
||||
ext
|
||||
}
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
{
|
||||
"system": {},
|
||||
"babe": {
|
||||
"authorities": [],
|
||||
"epochConfig": null
|
||||
},
|
||||
"indices": {
|
||||
"indices": []
|
||||
},
|
||||
"balances": {
|
||||
"balances": []
|
||||
},
|
||||
"transactionPayment": {
|
||||
"multiplier": "1000000000000000000"
|
||||
},
|
||||
"staking": {
|
||||
"validatorCount": 0,
|
||||
"minimumValidatorCount": 0,
|
||||
"invulnerables": [],
|
||||
"forceEra": "NotForcing",
|
||||
"slashRewardFraction": 0,
|
||||
"canceledPayout": 0,
|
||||
"stakers": [],
|
||||
"minNominatorBond": 0,
|
||||
"minValidatorBond": 0,
|
||||
"maxValidatorCount": null,
|
||||
"maxNominatorCount": null
|
||||
},
|
||||
"session": {
|
||||
"keys": []
|
||||
},
|
||||
"democracy": {},
|
||||
"council": {
|
||||
"members": []
|
||||
},
|
||||
"technicalCommittee": {
|
||||
"members": []
|
||||
},
|
||||
"elections": {
|
||||
"members": []
|
||||
},
|
||||
"technicalMembership": {
|
||||
"members": []
|
||||
},
|
||||
"grandpa": {
|
||||
"authorities": []
|
||||
},
|
||||
"treasury": {},
|
||||
"sudo": {
|
||||
"key": null
|
||||
},
|
||||
"imOnline": {
|
||||
"keys": []
|
||||
},
|
||||
"authorityDiscovery": {
|
||||
"keys": []
|
||||
},
|
||||
"society": {
|
||||
"pot": 0
|
||||
},
|
||||
"vesting": {
|
||||
"vesting": []
|
||||
},
|
||||
"glutton": {
|
||||
"compute": "0",
|
||||
"storage": "0",
|
||||
"trashDataCount": 0
|
||||
},
|
||||
"assets": {
|
||||
"assets": [],
|
||||
"metadata": [],
|
||||
"accounts": []
|
||||
},
|
||||
"poolAssets": {
|
||||
"assets": [],
|
||||
"metadata": [],
|
||||
"accounts": []
|
||||
},
|
||||
"transactionStorage": {
|
||||
"byteFee": 10,
|
||||
"entryFee": 1000,
|
||||
"storagePeriod": 100800
|
||||
},
|
||||
"allianceMotion": {
|
||||
"members": []
|
||||
},
|
||||
"alliance": {
|
||||
"fellows": [],
|
||||
"allies": []
|
||||
},
|
||||
"mixnet": {
|
||||
"mixnodes": []
|
||||
},
|
||||
"nominationPools": {
|
||||
"minJoinBond": 0,
|
||||
"minCreateBond": 0,
|
||||
"maxPools": 16,
|
||||
"maxMembersPerPool": 32,
|
||||
"maxMembers": 512,
|
||||
"globalMaxCommission": null
|
||||
},
|
||||
"txPause": {
|
||||
"paused": []
|
||||
},
|
||||
"safeMode": {
|
||||
"enteredUntil": null
|
||||
}
|
||||
}
|
||||
@@ -20,33 +20,34 @@ codec = { package = "parity-scale-codec", version = "3.6.1", default-features =
|
||||
"derive",
|
||||
"max-encoded-len",
|
||||
] }
|
||||
scale-info = { version = "2.10.0", default-features = false, features = ["derive"] }
|
||||
scale-info = { version = "2.10.0", default-features = false, features = ["derive", "serde"] }
|
||||
static_assertions = "1.1.0"
|
||||
log = { version = "0.4.17", default-features = false }
|
||||
serde_json = { version = "1.0.85", default-features = false, features = ["alloc", "arbitrary_precision"] }
|
||||
|
||||
# pallet-asset-conversion: turn on "num-traits" feature
|
||||
primitive-types = { version = "0.12.0", default-features = false, features = ["codec", "scale-info", "num-traits"] }
|
||||
|
||||
# primitives
|
||||
sp-authority-discovery = { path = "../../../primitives/authority-discovery", default-features = false}
|
||||
sp-consensus-babe = { path = "../../../primitives/consensus/babe", default-features = false}
|
||||
sp-consensus-grandpa = { path = "../../../primitives/consensus/grandpa", default-features = false}
|
||||
sp-authority-discovery = { path = "../../../primitives/authority-discovery", default-features = false, features=["serde"] }
|
||||
sp-consensus-babe = { path = "../../../primitives/consensus/babe", default-features = false, features=["serde"] }
|
||||
sp-consensus-grandpa = { path = "../../../primitives/consensus/grandpa", default-features = false, features=["serde"] }
|
||||
sp-block-builder = { path = "../../../primitives/block-builder", default-features = false}
|
||||
sp-genesis-builder = { default-features = false, path = "../../../primitives/genesis-builder" }
|
||||
sp-inherents = { path = "../../../primitives/inherents", default-features = false}
|
||||
node-primitives = { path = "../primitives", default-features = false}
|
||||
sp-mixnet = { path = "../../../primitives/mixnet", default-features = false }
|
||||
sp-offchain = { path = "../../../primitives/offchain", default-features = false}
|
||||
sp-core = { path = "../../../primitives/core", default-features = false}
|
||||
sp-core = { path = "../../../primitives/core", default-features = false, features=["serde"] }
|
||||
sp-std = { path = "../../../primitives/std", default-features = false}
|
||||
sp-api = { path = "../../../primitives/api", default-features = false}
|
||||
sp-runtime = { path = "../../../primitives/runtime", default-features = false}
|
||||
sp-staking = { path = "../../../primitives/staking", default-features = false}
|
||||
sp-runtime = { path = "../../../primitives/runtime", default-features = false, features=["serde"] }
|
||||
sp-staking = { path = "../../../primitives/staking", default-features = false, features=["serde"] }
|
||||
sp-storage = { path = "../../../primitives/storage", default-features = false}
|
||||
sp-session = { path = "../../../primitives/session", default-features = false}
|
||||
sp-transaction-pool = { path = "../../../primitives/transaction-pool", default-features = false}
|
||||
sp-statement-store = { path = "../../../primitives/statement-store", default-features = false}
|
||||
sp-version = { path = "../../../primitives/version", default-features = false}
|
||||
sp-statement-store = { path = "../../../primitives/statement-store", default-features = false, features=["serde"] }
|
||||
sp-version = { path = "../../../primitives/version", default-features = false, features=["serde"] }
|
||||
sp-io = { path = "../../../primitives/io", default-features = false}
|
||||
|
||||
# frame dependencies
|
||||
@@ -230,6 +231,7 @@ std = [
|
||||
"pallet-whitelist/std",
|
||||
"primitive-types/std",
|
||||
"scale-info/std",
|
||||
"serde_json/std",
|
||||
"sp-api/std",
|
||||
"sp-authority-discovery/std",
|
||||
"sp-block-builder/std",
|
||||
|
||||
@@ -398,7 +398,7 @@ impl BenchDb {
|
||||
|
||||
let client_config = sc_service::ClientConfig::default();
|
||||
let genesis_block_builder = sc_service::GenesisBlockBuilder::new(
|
||||
&keyring.generate_genesis(),
|
||||
keyring.as_storage_builder(),
|
||||
!client_config.no_genesis,
|
||||
backend.clone(),
|
||||
executor.clone(),
|
||||
@@ -590,12 +590,20 @@ impl BenchKeyring {
|
||||
}
|
||||
}
|
||||
|
||||
/// Generate genesis with accounts from this keyring endowed with some balance.
|
||||
pub fn generate_genesis(&self) -> kitchensink_runtime::RuntimeGenesisConfig {
|
||||
crate::genesis::config_endowed(
|
||||
Some(kitchensink_runtime::wasm_binary_unwrap()),
|
||||
self.collect_account_ids(),
|
||||
)
|
||||
/// Generate genesis with accounts from this keyring endowed with some balance and
|
||||
/// kitchensink_runtime code blob.
|
||||
pub fn as_storage_builder(&self) -> &dyn sp_runtime::BuildStorage {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl sp_runtime::BuildStorage for BenchKeyring {
|
||||
fn assimilate_storage(&self, storage: &mut sp_core::storage::Storage) -> Result<(), String> {
|
||||
storage.top.insert(
|
||||
sp_core::storage::well_known_keys::CODE.to_vec(),
|
||||
kitchensink_runtime::wasm_binary_unwrap().into(),
|
||||
);
|
||||
crate::genesis::config_endowed(self.collect_account_ids()).assimilate_storage(storage)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,12 @@ pub struct GenesisParameters;
|
||||
|
||||
impl substrate_test_client::GenesisInit for GenesisParameters {
|
||||
fn genesis_storage(&self) -> Storage {
|
||||
crate::genesis::config(None).build_storage().unwrap()
|
||||
let mut storage = crate::genesis::config().build_storage().unwrap();
|
||||
storage.top.insert(
|
||||
sp_core::storage::well_known_keys::CODE.to_vec(),
|
||||
kitchensink_runtime::wasm_binary_unwrap().into(),
|
||||
);
|
||||
storage
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,22 +20,21 @@
|
||||
|
||||
use crate::keyring::*;
|
||||
use kitchensink_runtime::{
|
||||
constants::currency::*, wasm_binary_unwrap, AccountId, AssetsConfig, BabeConfig,
|
||||
BalancesConfig, GluttonConfig, GrandpaConfig, IndicesConfig, RuntimeGenesisConfig,
|
||||
SessionConfig, SocietyConfig, StakerStatus, StakingConfig, SystemConfig,
|
||||
BABE_GENESIS_EPOCH_CONFIG,
|
||||
constants::currency::*, AccountId, AssetsConfig, BabeConfig, BalancesConfig, GluttonConfig,
|
||||
GrandpaConfig, IndicesConfig, RuntimeGenesisConfig, SessionConfig, SocietyConfig, StakerStatus,
|
||||
StakingConfig, BABE_GENESIS_EPOCH_CONFIG,
|
||||
};
|
||||
use sp_keyring::{Ed25519Keyring, Sr25519Keyring};
|
||||
use sp_runtime::Perbill;
|
||||
|
||||
/// Create genesis runtime configuration for tests.
|
||||
pub fn config(code: Option<&[u8]>) -> RuntimeGenesisConfig {
|
||||
config_endowed(code, Default::default())
|
||||
pub fn config() -> RuntimeGenesisConfig {
|
||||
config_endowed(Default::default())
|
||||
}
|
||||
|
||||
/// Create genesis runtime configuration for tests with some extra
|
||||
/// endowed accounts.
|
||||
pub fn config_endowed(code: Option<&[u8]>, extra_endowed: Vec<AccountId>) -> RuntimeGenesisConfig {
|
||||
pub fn config_endowed(extra_endowed: Vec<AccountId>) -> RuntimeGenesisConfig {
|
||||
let mut endowed = vec![
|
||||
(alice(), 111 * DOLLARS),
|
||||
(bob(), 100 * DOLLARS),
|
||||
@@ -48,10 +47,7 @@ pub fn config_endowed(code: Option<&[u8]>, extra_endowed: Vec<AccountId>) -> Run
|
||||
endowed.extend(extra_endowed.into_iter().map(|endowed| (endowed, 100 * DOLLARS)));
|
||||
|
||||
RuntimeGenesisConfig {
|
||||
system: SystemConfig {
|
||||
code: code.map(|x| x.to_vec()).unwrap_or_else(|| wasm_binary_unwrap().to_vec()),
|
||||
..Default::default()
|
||||
},
|
||||
system: Default::default(),
|
||||
indices: IndicesConfig { indices: vec![] },
|
||||
balances: BalancesConfig { balances: endowed },
|
||||
session: SessionConfig {
|
||||
|
||||
@@ -23,8 +23,12 @@ crate-type = ["rlib"]
|
||||
ansi_term = "0.12.1"
|
||||
clap = { version = "4.4.6", features = ["derive"] }
|
||||
rand = "0.8"
|
||||
kitchensink-runtime = { version = "3.0.0-dev", path = "../../node/runtime" }
|
||||
log = "0.4.17"
|
||||
node-cli = { package = "staging-node-cli", path = "../../node/cli" }
|
||||
sc-chain-spec = { path = "../../../client/chain-spec" }
|
||||
sc-keystore = { path = "../../../client/keystore" }
|
||||
serde_json = "1.0.100"
|
||||
sp-core = { path = "../../../primitives/core" }
|
||||
sp-keystore = { path = "../../../primitives/keystore" }
|
||||
sp-tracing = { version = "10.0.0", path = "../../../primitives/tracing" }
|
||||
|
||||
@@ -17,28 +17,40 @@
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use chain_spec_builder::{
|
||||
generate_authority_keys_and_store, generate_chain_spec, print_seeds, ChainSpecBuilder,
|
||||
generate_authority_keys_and_store, generate_chain_spec, generate_chain_spec_for_runtime,
|
||||
print_seeds, ChainSpecBuilder, ChainSpecBuilderCmd, EditCmd, GenerateCmd, NewCmd, VerifyCmd,
|
||||
};
|
||||
use clap::Parser;
|
||||
use node_cli::chain_spec;
|
||||
use rand::{distributions::Alphanumeric, rngs::OsRng, Rng};
|
||||
use sc_chain_spec::{update_code_in_json_chain_spec, GenericChainSpec};
|
||||
use sp_core::{crypto::Ss58Codec, sr25519};
|
||||
use staging_chain_spec_builder as chain_spec_builder;
|
||||
use std::fs;
|
||||
|
||||
fn main() -> Result<(), String> {
|
||||
#[cfg(build_type = "debug")]
|
||||
println!(
|
||||
"The chain spec builder builds a chain specification that includes a Substrate runtime \
|
||||
compiled as WASM. To ensure proper functioning of the included runtime compile (or run) \
|
||||
the chain spec builder binary in `--release` mode.\n",
|
||||
);
|
||||
sp_tracing::try_init_simple();
|
||||
|
||||
let builder = ChainSpecBuilder::parse();
|
||||
let chain_spec_path = builder.chain_spec_path().to_path_buf();
|
||||
#[cfg(build_type = "debug")]
|
||||
if matches!(builder.command, ChainSpecBuilderCmd::Generate(_) | ChainSpecBuilderCmd::New(_)) {
|
||||
println!(
|
||||
"The chain spec builder builds a chain specification that includes a Substrate runtime \
|
||||
compiled as WASM. To ensure proper functioning of the included runtime compile (or run) \
|
||||
the chain spec builder binary in `--release` mode.\n",
|
||||
);
|
||||
}
|
||||
|
||||
let (authority_seeds, nominator_accounts, endowed_accounts, sudo_account) = match builder {
|
||||
ChainSpecBuilder::Generate { authorities, nominators, endowed, keystore_path, .. } => {
|
||||
let chain_spec_path = builder.chain_spec_path.to_path_buf();
|
||||
let mut write_chain_spec = true;
|
||||
|
||||
let chain_spec_json = match builder.command {
|
||||
ChainSpecBuilderCmd::Generate(GenerateCmd {
|
||||
authorities,
|
||||
nominators,
|
||||
endowed,
|
||||
keystore_path,
|
||||
}) => {
|
||||
let authorities = authorities.max(1);
|
||||
let rand_str = || -> String {
|
||||
OsRng.sample_iter(&Alphanumeric).take(32).map(char::from).collect()
|
||||
@@ -72,19 +84,58 @@ fn main() -> Result<(), String> {
|
||||
let sudo_account =
|
||||
chain_spec::get_account_id_from_seed::<sr25519::Public>(&sudo_seed).to_ss58check();
|
||||
|
||||
(authority_seeds, nominator_accounts, endowed_accounts, sudo_account)
|
||||
generate_chain_spec(authority_seeds, nominator_accounts, endowed_accounts, sudo_account)
|
||||
},
|
||||
ChainSpecBuilder::New {
|
||||
ChainSpecBuilderCmd::New(NewCmd {
|
||||
authority_seeds,
|
||||
nominator_accounts,
|
||||
endowed_accounts,
|
||||
sudo_account,
|
||||
..
|
||||
} => (authority_seeds, nominator_accounts, endowed_accounts, sudo_account),
|
||||
};
|
||||
}) =>
|
||||
generate_chain_spec(authority_seeds, nominator_accounts, endowed_accounts, sudo_account),
|
||||
ChainSpecBuilderCmd::Runtime(cmd) => generate_chain_spec_for_runtime(&cmd),
|
||||
ChainSpecBuilderCmd::Edit(EditCmd {
|
||||
ref input_chain_spec,
|
||||
ref runtime_wasm_path,
|
||||
convert_to_raw,
|
||||
}) => {
|
||||
let chain_spec = GenericChainSpec::<()>::from_json_file(input_chain_spec.clone())?;
|
||||
|
||||
let json =
|
||||
generate_chain_spec(authority_seeds, nominator_accounts, endowed_accounts, sudo_account)?;
|
||||
let mut chain_spec_json =
|
||||
serde_json::from_str::<serde_json::Value>(&chain_spec.as_json(convert_to_raw)?)
|
||||
.map_err(|e| format!("Conversion to json failed: {e}"))?;
|
||||
if let Some(path) = runtime_wasm_path {
|
||||
update_code_in_json_chain_spec(
|
||||
&mut chain_spec_json,
|
||||
&fs::read(path.as_path())
|
||||
.map_err(|e| format!("Wasm blob file could not be read: {e}"))?[..],
|
||||
);
|
||||
}
|
||||
|
||||
fs::write(chain_spec_path, json).map_err(|err| err.to_string())
|
||||
serde_json::to_string_pretty(&chain_spec_json)
|
||||
.map_err(|e| format!("to pretty failed: {e}"))
|
||||
},
|
||||
ChainSpecBuilderCmd::Verify(VerifyCmd { ref input_chain_spec, ref runtime_wasm_path }) => {
|
||||
write_chain_spec = false;
|
||||
let chain_spec = GenericChainSpec::<()>::from_json_file(input_chain_spec.clone())?;
|
||||
let mut chain_spec_json =
|
||||
serde_json::from_str::<serde_json::Value>(&chain_spec.as_json(true)?)
|
||||
.map_err(|e| format!("Conversion to json failed: {e}"))?;
|
||||
if let Some(path) = runtime_wasm_path {
|
||||
update_code_in_json_chain_spec(
|
||||
&mut chain_spec_json,
|
||||
&fs::read(path.as_path())
|
||||
.map_err(|e| format!("Wasm blob file could not be read: {e}"))?[..],
|
||||
);
|
||||
};
|
||||
serde_json::to_string_pretty(&chain_spec_json)
|
||||
.map_err(|e| format!("to pretty failed: {e}"))
|
||||
},
|
||||
}?;
|
||||
|
||||
if write_chain_spec {
|
||||
fs::write(chain_spec_path, chain_spec_json).map_err(|err| err.to_string())
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,96 +29,169 @@
|
||||
//! [`sc-chain-spec`]: ../sc_chain_spec/index.html
|
||||
//! [`node-cli`]: ../node_cli/index.html
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::{
|
||||
fs,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use ansi_term::Style;
|
||||
use clap::Parser;
|
||||
use clap::{Parser, Subcommand};
|
||||
use sc_chain_spec::GenesisConfigBuilderRuntimeCaller;
|
||||
|
||||
use node_cli::chain_spec::{self, AccountId};
|
||||
use sc_keystore::LocalKeystore;
|
||||
use serde_json::Value;
|
||||
use sp_core::crypto::{ByteArray, Ss58Codec};
|
||||
use sp_keystore::KeystorePtr;
|
||||
|
||||
/// A utility to easily create a testnet chain spec definition with a given set
|
||||
/// of authorities and endowed accounts and/or generate random accounts.
|
||||
#[derive(Parser)]
|
||||
#[derive(Debug, Parser)]
|
||||
#[command(rename_all = "kebab-case")]
|
||||
pub enum ChainSpecBuilder {
|
||||
/// Create a new chain spec with the given authorities, endowed and sudo
|
||||
/// accounts.
|
||||
New {
|
||||
/// Authority key seed.
|
||||
#[arg(long, short, required = true)]
|
||||
authority_seeds: Vec<String>,
|
||||
/// Active nominators (SS58 format), each backing a random subset of the aforementioned
|
||||
/// authorities.
|
||||
#[arg(long, short, default_value = "0")]
|
||||
nominator_accounts: Vec<String>,
|
||||
/// Endowed account address (SS58 format).
|
||||
#[arg(long, short)]
|
||||
endowed_accounts: Vec<String>,
|
||||
/// Sudo account address (SS58 format).
|
||||
#[arg(long, short)]
|
||||
sudo_account: String,
|
||||
/// The path where the chain spec should be saved.
|
||||
#[arg(long, short, default_value = "./chain_spec.json")]
|
||||
chain_spec_path: PathBuf,
|
||||
},
|
||||
/// Create a new chain spec with the given number of authorities and endowed
|
||||
/// accounts. Random keys will be generated as required.
|
||||
Generate {
|
||||
/// The number of authorities.
|
||||
#[arg(long, short)]
|
||||
authorities: usize,
|
||||
/// The number of nominators backing the aforementioned authorities.
|
||||
///
|
||||
/// Will nominate a random subset of `authorities`.
|
||||
#[arg(long, short, default_value_t = 0)]
|
||||
nominators: usize,
|
||||
/// The number of endowed accounts.
|
||||
#[arg(long, short, default_value_t = 0)]
|
||||
endowed: usize,
|
||||
/// The path where the chain spec should be saved.
|
||||
#[arg(long, short, default_value = "./chain_spec.json")]
|
||||
chain_spec_path: PathBuf,
|
||||
/// Path to use when saving generated keystores for each authority.
|
||||
///
|
||||
/// At this path, a new folder will be created for each authority's
|
||||
/// keystore named `auth-$i` where `i` is the authority index, i.e.
|
||||
/// `auth-0`, `auth-1`, etc.
|
||||
#[arg(long, short)]
|
||||
keystore_path: Option<PathBuf>,
|
||||
},
|
||||
pub struct ChainSpecBuilder {
|
||||
#[command(subcommand)]
|
||||
pub command: ChainSpecBuilderCmd,
|
||||
/// The path where the chain spec should be saved.
|
||||
#[arg(long, short, default_value = "./chain_spec.json")]
|
||||
pub chain_spec_path: PathBuf,
|
||||
}
|
||||
|
||||
impl ChainSpecBuilder {
|
||||
/// Returns the path where the chain spec should be saved.
|
||||
pub fn chain_spec_path(&self) -> &Path {
|
||||
match self {
|
||||
ChainSpecBuilder::New { chain_spec_path, .. } => chain_spec_path.as_path(),
|
||||
ChainSpecBuilder::Generate { chain_spec_path, .. } => chain_spec_path.as_path(),
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Subcommand)]
|
||||
#[command(rename_all = "kebab-case")]
|
||||
pub enum ChainSpecBuilderCmd {
|
||||
New(NewCmd),
|
||||
Generate(GenerateCmd),
|
||||
Runtime(RuntimeCmd),
|
||||
Edit(EditCmd),
|
||||
Verify(VerifyCmd),
|
||||
}
|
||||
|
||||
fn genesis_constructor(
|
||||
authority_seeds: &[String],
|
||||
nominator_accounts: &[AccountId],
|
||||
endowed_accounts: &[AccountId],
|
||||
sudo_account: &AccountId,
|
||||
) -> chain_spec::RuntimeGenesisConfig {
|
||||
let authorities = authority_seeds
|
||||
.iter()
|
||||
.map(AsRef::as_ref)
|
||||
.map(chain_spec::authority_keys_from_seed)
|
||||
.collect::<Vec<_>>();
|
||||
/// Create a new chain spec with the given authorities, endowed and sudo
|
||||
/// accounts. Only works for kitchen-sink runtime
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(rename_all = "kebab-case")]
|
||||
pub struct NewCmd {
|
||||
/// Authority key seed.
|
||||
#[arg(long, short, required = true)]
|
||||
pub authority_seeds: Vec<String>,
|
||||
/// Active nominators (SS58 format), each backing a random subset of the aforementioned
|
||||
/// authorities.
|
||||
#[arg(long, short, default_value = "0")]
|
||||
pub nominator_accounts: Vec<String>,
|
||||
/// Endowed account address (SS58 format).
|
||||
#[arg(long, short)]
|
||||
pub endowed_accounts: Vec<String>,
|
||||
/// Sudo account address (SS58 format).
|
||||
#[arg(long, short)]
|
||||
pub sudo_account: String,
|
||||
}
|
||||
|
||||
chain_spec::testnet_genesis(
|
||||
authorities,
|
||||
nominator_accounts.to_vec(),
|
||||
sudo_account.clone(),
|
||||
Some(endowed_accounts.to_vec()),
|
||||
)
|
||||
/// Create a new chain spec with the given number of authorities and endowed
|
||||
/// accounts. Random keys will be generated as required.
|
||||
#[derive(Parser, Debug)]
|
||||
pub struct GenerateCmd {
|
||||
/// The number of authorities.
|
||||
#[arg(long, short)]
|
||||
pub authorities: usize,
|
||||
/// The number of nominators backing the aforementioned authorities.
|
||||
///
|
||||
/// Will nominate a random subset of `authorities`.
|
||||
#[arg(long, short, default_value_t = 0)]
|
||||
pub nominators: usize,
|
||||
/// The number of endowed accounts.
|
||||
#[arg(long, short, default_value_t = 0)]
|
||||
pub endowed: usize,
|
||||
/// Path to use when saving generated keystores for each authority.
|
||||
///
|
||||
/// At this path, a new folder will be created for each authority's
|
||||
/// keystore named `auth-$i` where `i` is the authority index, i.e.
|
||||
/// `auth-0`, `auth-1`, etc.
|
||||
#[arg(long, short)]
|
||||
pub keystore_path: Option<PathBuf>,
|
||||
}
|
||||
|
||||
/// Create a new chain spec by interacting with the provided runtime wasm blob.
|
||||
#[derive(Parser, Debug)]
|
||||
pub struct RuntimeCmd {
|
||||
/// The name of chain
|
||||
#[arg(long, short = 'n', default_value = "Custom")]
|
||||
chain_name: String,
|
||||
/// The chain id
|
||||
#[arg(long, short = 'i', default_value = "custom")]
|
||||
chain_id: String,
|
||||
/// The path to runtime wasm blob
|
||||
#[arg(long, short)]
|
||||
runtime_wasm_path: PathBuf,
|
||||
/// Export chainspec as raw storage
|
||||
#[arg(long, short = 's')]
|
||||
raw_storage: bool,
|
||||
/// Verify the genesis config. This silently generates the raw storage from genesis config. Any
|
||||
/// errors will be reported.
|
||||
#[arg(long, short = 'v')]
|
||||
verify: bool,
|
||||
#[command(subcommand)]
|
||||
action: GenesisBuildAction,
|
||||
}
|
||||
|
||||
#[derive(Subcommand, Debug, Clone)]
|
||||
enum GenesisBuildAction {
|
||||
Patch(PatchCmd),
|
||||
Full(FullCmd),
|
||||
Default(DefaultCmd),
|
||||
}
|
||||
|
||||
/// Patches the runtime's default genesis config with provided patch.
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
struct PatchCmd {
|
||||
/// The path to the runtime genesis config patch.
|
||||
#[arg(long, short)]
|
||||
patch_path: PathBuf,
|
||||
}
|
||||
|
||||
/// Build the genesis config for runtime using provided json file. No defaults will be used.
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
struct FullCmd {
|
||||
/// The path to the full runtime genesis config json file.
|
||||
#[arg(long, short)]
|
||||
config_path: PathBuf,
|
||||
}
|
||||
|
||||
/// Gets the default genesis config for the runtime and uses it in ChainSpec. Please note that
|
||||
/// default genesis config may not be valid. For some runtimes initial values should be added there
|
||||
/// (e.g. session keys, babe epoch).
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
struct DefaultCmd {
|
||||
/// If provided stores the default genesis config json file at given path (in addition to
|
||||
/// chain-spec).
|
||||
#[arg(long, short)]
|
||||
default_config_path: Option<PathBuf>,
|
||||
}
|
||||
|
||||
/// Edits provided input chain spec. Input can be converted into raw storage chain-spec. The code
|
||||
/// can be updated with the runtime provided in the command line.
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
pub struct EditCmd {
|
||||
/// Chain spec to be edited
|
||||
#[arg(long, short)]
|
||||
pub input_chain_spec: PathBuf,
|
||||
/// The path to new runtime wasm blob to be stored into chain-spec
|
||||
#[arg(long, short = 'r')]
|
||||
pub runtime_wasm_path: Option<PathBuf>,
|
||||
/// Convert genesis spec to raw format
|
||||
#[arg(long, short = 's')]
|
||||
pub convert_to_raw: bool,
|
||||
}
|
||||
|
||||
/// Verifies provided input chain spec. If the runtime is provided verification is performed against
|
||||
/// new runtime.
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
pub struct VerifyCmd {
|
||||
/// Chain spec to be edited
|
||||
#[arg(long, short)]
|
||||
pub input_chain_spec: PathBuf,
|
||||
/// The path to new runtime wasm blob to be stored into chain-spec
|
||||
#[arg(long, short = 'r')]
|
||||
pub runtime_wasm_path: Option<PathBuf>,
|
||||
}
|
||||
|
||||
/// Generate the chain spec using the given seeds and accounts.
|
||||
@@ -145,27 +218,24 @@ pub fn generate_chain_spec(
|
||||
|
||||
let sudo_account = parse_account(sudo_account)?;
|
||||
|
||||
let chain_spec = chain_spec::ChainSpec::from_genesis(
|
||||
"Custom",
|
||||
"custom",
|
||||
sc_chain_spec::ChainType::Live,
|
||||
move || {
|
||||
genesis_constructor(
|
||||
&authority_seeds,
|
||||
&nominator_accounts,
|
||||
&endowed_accounts,
|
||||
&sudo_account,
|
||||
)
|
||||
},
|
||||
vec![],
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Default::default(),
|
||||
);
|
||||
let authorities = authority_seeds
|
||||
.iter()
|
||||
.map(AsRef::as_ref)
|
||||
.map(chain_spec::authority_keys_from_seed)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
chain_spec.as_json(false)
|
||||
chain_spec::ChainSpec::builder(kitchensink_runtime::wasm_binary_unwrap(), Default::default())
|
||||
.with_name("Custom")
|
||||
.with_id("custom")
|
||||
.with_chain_type(sc_chain_spec::ChainType::Live)
|
||||
.with_genesis_config_patch(chain_spec::testnet_genesis(
|
||||
authorities,
|
||||
nominator_accounts,
|
||||
sudo_account,
|
||||
Some(endowed_accounts),
|
||||
))
|
||||
.build()
|
||||
.as_json(false)
|
||||
}
|
||||
|
||||
/// Generate the authority keys and store them in the given `keystore_path`.
|
||||
@@ -241,3 +311,54 @@ pub fn print_seeds(
|
||||
println!("{}", header.paint("Sudo seed"));
|
||||
println!("//{}", sudo_seed);
|
||||
}
|
||||
|
||||
/// Processes `RuntimeCmd` and returns JSON version of `ChainSpec`
|
||||
pub fn generate_chain_spec_for_runtime(cmd: &RuntimeCmd) -> Result<String, String> {
|
||||
let code = fs::read(cmd.runtime_wasm_path.as_path())
|
||||
.map_err(|e| format!("wasm blob shall be readable {e}"))?;
|
||||
|
||||
let builder = chain_spec::ChainSpec::builder(&code[..], Default::default())
|
||||
.with_name(&cmd.chain_name[..])
|
||||
.with_id(&cmd.chain_id[..])
|
||||
.with_chain_type(sc_chain_spec::ChainType::Live);
|
||||
|
||||
let builder = match cmd.action {
|
||||
GenesisBuildAction::Patch(PatchCmd { ref patch_path }) => {
|
||||
let patch = fs::read(patch_path.as_path())
|
||||
.map_err(|e| format!("patch file {patch_path:?} shall be readable: {e}"))?;
|
||||
builder.with_genesis_config_patch(serde_json::from_slice::<Value>(&patch[..]).map_err(
|
||||
|e| format!("patch file {patch_path:?} shall contain a valid json: {e}"),
|
||||
)?)
|
||||
},
|
||||
GenesisBuildAction::Full(FullCmd { ref config_path }) => {
|
||||
let config = fs::read(config_path.as_path())
|
||||
.map_err(|e| format!("config file {config_path:?} shall be readable: {e}"))?;
|
||||
builder.with_genesis_config(serde_json::from_slice::<Value>(&config[..]).map_err(
|
||||
|e| format!("config file {config_path:?} shall contain a valid json: {e}"),
|
||||
)?)
|
||||
},
|
||||
GenesisBuildAction::Default(DefaultCmd { ref default_config_path }) => {
|
||||
let caller = GenesisConfigBuilderRuntimeCaller::new(&code[..]);
|
||||
let default_config = caller
|
||||
.get_default_config()
|
||||
.map_err(|e| format!("getting default config from runtime should work: {e}"))?;
|
||||
default_config_path.clone().map(|path| {
|
||||
fs::write(path.as_path(), serde_json::to_string_pretty(&default_config).unwrap())
|
||||
.map_err(|err| err.to_string())
|
||||
});
|
||||
builder.with_genesis_config(default_config)
|
||||
},
|
||||
};
|
||||
|
||||
let chain_spec = builder.build();
|
||||
|
||||
match (cmd.verify, cmd.raw_storage) {
|
||||
(_, true) => chain_spec.as_json(true),
|
||||
(true, false) => {
|
||||
chain_spec.as_json(true)?;
|
||||
println!("Genesis config verification: OK");
|
||||
chain_spec.as_json(false)
|
||||
},
|
||||
(false, false) => chain_spec.as_json(false),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,15 +13,27 @@ readme = "README.md"
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
||||
[dependencies]
|
||||
codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["derive"] }
|
||||
memmap2 = "0.5.0"
|
||||
serde = { version = "1.0.188", features = ["derive"] }
|
||||
serde_json = "1.0.107"
|
||||
sc-client-api = { path = "../api" }
|
||||
sc-chain-spec-derive = { path = "derive" }
|
||||
sc-executor = { path = "../executor" }
|
||||
sp-io = { default-features = false, path = "../../primitives/io" }
|
||||
sc-network = { path = "../network" }
|
||||
sc-telemetry = { path = "../telemetry" }
|
||||
sp-blockchain = { path = "../../primitives/blockchain" }
|
||||
sp-core = { path = "../../primitives/core" }
|
||||
sp-genesis-builder = { path = "../../primitives/genesis-builder" }
|
||||
sp-runtime = { path = "../../primitives/runtime" }
|
||||
sp-state-machine = { path = "../../primitives/state-machine" }
|
||||
log = { version = "0.4.17", default-features = false }
|
||||
array-bytes = { version = "6.1" }
|
||||
docify = "0.2.0"
|
||||
|
||||
[dev-dependencies]
|
||||
substrate-test-runtime = { path = "../../test-utils/runtime" }
|
||||
sp-keyring = { path = "../../primitives/keyring" }
|
||||
sp-application-crypto = { default-features = false, path = "../../primitives/application-crypto", features = ["serde"] }
|
||||
sp-consensus-babe = { default-features = false, path = "../../primitives/consensus/babe", features = ["serde"] }
|
||||
|
||||
@@ -1,92 +1,6 @@
|
||||
Substrate chain configurations.
|
||||
|
||||
This crate contains structs and utilities to declare
|
||||
a runtime-specific configuration file (a.k.a chain spec).
|
||||
|
||||
Basic chain spec type containing all required parameters is
|
||||
[`ChainSpec`](https://docs.rs/sc-chain-spec/latest/sc_chain_spec/struct.GenericChainSpec.html). It can be extended with
|
||||
additional options that contain configuration specific to your chain.
|
||||
Usually the extension is going to be an amalgamate of types exposed
|
||||
by Substrate core modules. To allow the core modules to retrieve
|
||||
their configuration from your extension you should use `ChainSpecExtension`
|
||||
macro exposed by this crate.
|
||||
|
||||
```rust
|
||||
use std::collections::HashMap;
|
||||
use sc_chain_spec::{GenericChainSpec, ChainSpecExtension};
|
||||
|
||||
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, ChainSpecExtension)]
|
||||
pub struct MyExtension {
|
||||
pub known_blocks: HashMap<u64, String>,
|
||||
}
|
||||
|
||||
pub type MyChainSpec<G> = GenericChainSpec<G, MyExtension>;
|
||||
```
|
||||
|
||||
Some parameters may require different values depending on the
|
||||
current blockchain height (a.k.a. forks). You can use `ChainSpecGroup`
|
||||
macro and provided [`Forks`](https://docs.rs/sc-chain-spec/latest/sc_chain_spec/struct.Forks.html) structure to put
|
||||
such parameters to your chain spec.
|
||||
This will allow to override a single parameter starting at specific
|
||||
block number.
|
||||
|
||||
```rust
|
||||
use sc_chain_spec::{Forks, ChainSpecGroup, ChainSpecExtension, GenericChainSpec};
|
||||
|
||||
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, ChainSpecGroup)]
|
||||
pub struct ClientParams {
|
||||
max_block_size: usize,
|
||||
max_extrinsic_size: usize,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, ChainSpecGroup)]
|
||||
pub struct PoolParams {
|
||||
max_transaction_size: usize,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, ChainSpecGroup, ChainSpecExtension)]
|
||||
pub struct Extension {
|
||||
pub client: ClientParams,
|
||||
pub pool: PoolParams,
|
||||
}
|
||||
|
||||
pub type BlockNumber = u64;
|
||||
|
||||
/// A chain spec supporting forkable `ClientParams`.
|
||||
pub type MyChainSpec1<G> = GenericChainSpec<G, Forks<BlockNumber, ClientParams>>;
|
||||
|
||||
/// A chain spec supporting forkable `Extension`.
|
||||
pub type MyChainSpec2<G> = GenericChainSpec<G, Forks<BlockNumber, Extension>>;
|
||||
```
|
||||
|
||||
It's also possible to have a set of parameters that is allowed to change
|
||||
with block numbers (i.e. is forkable), and another set that is not subject to changes.
|
||||
This is also possible by declaring an extension that contains `Forks` within it.
|
||||
|
||||
|
||||
```rust
|
||||
use serde::{Serialize, Deserialize};
|
||||
use sc_chain_spec::{Forks, GenericChainSpec, ChainSpecGroup, ChainSpecExtension};
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, ChainSpecGroup)]
|
||||
pub struct ClientParams {
|
||||
max_block_size: usize,
|
||||
max_extrinsic_size: usize,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, ChainSpecGroup)]
|
||||
pub struct PoolParams {
|
||||
max_transaction_size: usize,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, ChainSpecExtension)]
|
||||
pub struct Extension {
|
||||
pub client: ClientParams,
|
||||
#[forks]
|
||||
pub pool: Forks<u64, PoolParams>,
|
||||
}
|
||||
|
||||
pub type MyChainSpec<G> = GenericChainSpec<G, Extension>;
|
||||
```
|
||||
This crate contains structs and utilities to declare a runtime-specific configuration file (a.k.a chain spec).
|
||||
Refer to crate documentation for details.
|
||||
|
||||
License: GPL-3.0-or-later WITH Classpath-exception-2.0
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "TestName",
|
||||
"id": "test_id",
|
||||
"chainType": "Local",
|
||||
"bootNodes": [],
|
||||
"telemetryEndpoints": null,
|
||||
"protocolId": null,
|
||||
"properties": null,
|
||||
"codeSubstitutes": {},
|
||||
"genesis": {
|
||||
"raw": {
|
||||
"top": {
|
||||
"0x3a636f6465": "0x010101"
|
||||
},
|
||||
"childrenDefault": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "TestName",
|
||||
"id": "test_id",
|
||||
"chainType": "Local",
|
||||
"bootNodes": [],
|
||||
"telemetryEndpoints": null,
|
||||
"protocolId": null,
|
||||
"properties": null,
|
||||
"codeSubstitutes": {},
|
||||
"genesis": {
|
||||
"raw": {
|
||||
"top": {
|
||||
"0x3a636f6465": "0x010101"
|
||||
},
|
||||
"childrenDefault": {}
|
||||
}
|
||||
},
|
||||
"code": "0x060708"
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
{
|
||||
"name": "TestName",
|
||||
"id": "test_id",
|
||||
"chainType": "Local",
|
||||
"bootNodes": [],
|
||||
"telemetryEndpoints": null,
|
||||
"protocolId": null,
|
||||
"properties": null,
|
||||
"codeSubstitutes": {},
|
||||
"genesis": {
|
||||
"runtimeGenesis": {
|
||||
"config": {
|
||||
"babe": {
|
||||
"authorities": [
|
||||
[
|
||||
"5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY",
|
||||
1
|
||||
],
|
||||
[
|
||||
"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",
|
||||
1
|
||||
],
|
||||
[
|
||||
"5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y",
|
||||
1
|
||||
]
|
||||
],
|
||||
"epochConfig": {
|
||||
"allowed_slots": "PrimaryAndSecondaryPlainSlots",
|
||||
"c": [
|
||||
3,
|
||||
10
|
||||
]
|
||||
}
|
||||
},
|
||||
"balances": {
|
||||
"balances": [
|
||||
[
|
||||
"5D34dL5prEUaGNQtPPZ3yN5Y6BnkfXunKXXz6fo7ZJbLwRRH",
|
||||
100000000000000000
|
||||
],
|
||||
[
|
||||
"5GBNeWRhZc2jXu7D55rBimKYDk8PGk8itRYFTPfC8RJLKG5o",
|
||||
100000000000000000
|
||||
],
|
||||
[
|
||||
"5Dfis6XL8J2P6JHUnUtArnFWndn62SydeP8ee8sG2ky9nfm9",
|
||||
100000000000000000
|
||||
],
|
||||
[
|
||||
"5F4H97f7nQovyrbiq4ZetaaviNwThSVcFobcA5aGab6167dK",
|
||||
100000000000000000
|
||||
],
|
||||
[
|
||||
"5DiDShBWa1fQx6gLzpf3SFBhMinCoyvHM1BWjPNsmXS8hkrW",
|
||||
100000000000000000
|
||||
],
|
||||
[
|
||||
"5EFb84yH9tpcFuiKUcsmdoF7xeeY3ajG1ZLQimxQoFt9HMKR",
|
||||
100000000000000000
|
||||
],
|
||||
[
|
||||
"5DZLHESsfGrJ5YzT3HuRPXsSNb589xQ4Unubh1mYLodzKdVY",
|
||||
100000000000000000
|
||||
],
|
||||
[
|
||||
"5GHJzqvG6tXnngCpG7B12qjUvbo5e4e9z8Xjidk3CQZHxTPZ",
|
||||
100000000000000000
|
||||
],
|
||||
[
|
||||
"5CUnSsgAyLND3bxxnfNhgWXSe9Wn676JzLpGLgyJv858qhoX",
|
||||
100000000000000000
|
||||
],
|
||||
[
|
||||
"5CVKn7HAZW1Ky4r7Vkgsr7VEW88C2sHgUNDiwHY9Ct2hjU8q",
|
||||
100000000000000000
|
||||
],
|
||||
[
|
||||
"5H673aukQ4PeDe1U2nuv1bi32xDEziimh3PZz7hDdYUB7TNz",
|
||||
100000000000000000
|
||||
],
|
||||
[
|
||||
"5HTe9L15LJryjUAt1jZXZCBPnzbbGnpvFwbjE3NwCWaAqovf",
|
||||
100000000000000000
|
||||
],
|
||||
[
|
||||
"5D7LFzGpMwHPyDBavkRbWSKWTtJhCaPPZ379wWLT23bJwXJz",
|
||||
100000000000000000
|
||||
],
|
||||
[
|
||||
"5CLepMARnEgtVR1EkUuJVUvKh97gzergpSxUU3yKGx1v6EwC",
|
||||
100000000000000000
|
||||
],
|
||||
[
|
||||
"5Chb2UhfvZpmjjEziHbFbotM4quX32ZscRV6QJBt1rUKzz51",
|
||||
100000000000000000
|
||||
],
|
||||
[
|
||||
"5HmRp3i3ZZk7xsAvbi8hyXVP6whSMnBJGebVC4FsiZVhx52e",
|
||||
100000000000000000
|
||||
],
|
||||
[
|
||||
"5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY",
|
||||
100000000000000000
|
||||
],
|
||||
[
|
||||
"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",
|
||||
100000000000000000
|
||||
],
|
||||
[
|
||||
"5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y",
|
||||
100000000000000000
|
||||
]
|
||||
]
|
||||
},
|
||||
"substrateTest": {
|
||||
"authorities": [
|
||||
"5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY",
|
||||
"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",
|
||||
"5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y"
|
||||
]
|
||||
},
|
||||
"system": {}
|
||||
},
|
||||
"code": "0x0"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"name": "TestName",
|
||||
"id": "test_id",
|
||||
"chainType": "Local",
|
||||
"bootNodes": [],
|
||||
"telemetryEndpoints": null,
|
||||
"protocolId": null,
|
||||
"properties": null,
|
||||
"codeSubstitutes": {},
|
||||
"genesis": {
|
||||
"raw": {
|
||||
"top": {
|
||||
"0x00771836bebdd29870ff246d305c578c4e7b9012096b41c4eb3aaf947f6ea429": "0x0000",
|
||||
"0x00771836bebdd29870ff246d305c578c5e0621c4869aa60c02be9adcc98a0d1d": "0x0cd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a4890b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22",
|
||||
"0x1cb6f36e027abb2091cfb5110ab5087f4e7b9012096b41c4eb3aaf947f6ea429": "0x0000",
|
||||
"0x1cb6f36e027abb2091cfb5110ab5087f5e0621c4869aa60c02be9adcc98a0d1d": "0x0cd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d01000000000000008eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48010000000000000090b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe220100000000000000",
|
||||
"0x1cb6f36e027abb2091cfb5110ab5087f66e8f035c8adbe7f1547b43c51e6f8a4": "0x00000000",
|
||||
"0x1cb6f36e027abb2091cfb5110ab5087faacf00b9b41fda7a9268821c2a2b3e4c": "0x0cd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d01000000000000008eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48010000000000000090b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe220100000000000000",
|
||||
"0x1cb6f36e027abb2091cfb5110ab5087fdc6b171b77304263c292cc3ea5ed31ef": "0x03000000000000000a0000000000000001",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef74e7b9012096b41c4eb3aaf947f6ea429": "0x0000",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef75684a022a34dd8bfa2baaf44f172b710": "0x01",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef78a42f33323cb5ced3b44dd825fda9fcc": "0x4545454545454545454545454545454545454545454545454545454545454545",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7a44704b568d21667356a5a050c118746bb1bdbcacd6ac9340000000000000000": "0x4545454545454545454545454545454545454545454545454545454545454545",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7a7fd6c28836b9a28522dc924110cf439": "0x01",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da901cae4e3edfbb32c91ed3f01ab964f4eeeab50338d8e5176d3141802d7b010a55dadcd5f23cf8aaafa724627e967e90e": "0x000000000000000000000000010000000000000000008a5d784563010000000000000000000000000000000000000000000000000000000000000080",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da91b614bd4a126f2d5d294e9a8af9da25248d7e931307afb4b68d8d565d4c66e00d856c6d65f5fed6bb82dcfb60e936c67": "0x000000000000000000000000010000000000000000008a5d784563010000000000000000000000000000000000000000000000000000000000000080",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da94b21aff9fe1e8b2fc4b0775b8cbeff28ba8e2c7594dd74730f3ca835e95455d199261897edc9735d602ea29615e2b10b": "0x000000000000000000000000010000000000000000008a5d784563010000000000000000000000000000000000000000000000000000000000000080",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da94f9aea1afa791265fae359272badc1cf8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48": "0x000000000000000000000000010000000000000000008a5d784563010000000000000000000000000000000000000000000000000000000000000080",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da95786a2916fcb81e1bd5dcd81e0d2452884617f575372edb5a36d85c04cdf2e4699f96fe33eb5f94a28c041b88e398d0c": "0x000000000000000000000000010000000000000000008a5d784563010000000000000000000000000000000000000000000000000000000000000080",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da95b8542d9672c7b7e779cc7c1e6b605691c2115d06120ea2bee32dd601d02f36367564e7ddf84ae2717ca3f097459652e": "0x000000000000000000000000010000000000000000008a5d784563010000000000000000000000000000000000000000000000000000000000000080",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da996c30bdbfab640838e6b6d3c33ab4adb4211b79e34ee8072eab506edd4b93a7b85a14c9a05e5cdd056d98e7dbca87730": "0x000000000000000000000000010000000000000000008a5d784563010000000000000000000000000000000000000000000000000000000000000080",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da99dc65b1339ec388fbf2ca0cdef51253512c6cfd663203ea16968594f24690338befd906856c4d2f4ef32dad578dba20c": "0x000000000000000000000000010000000000000000008a5d784563010000000000000000000000000000000000000000000000000000000000000080",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da99e6eb5abd62f5fd54793da91a47e6af6125d57171ff9241f07acaa1bb6a6103517965cf2cd00e643b27e7599ebccba70": "0x000000000000000000000000010000000000000000008a5d784563010000000000000000000000000000000000000000000000000000000000000080",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9b0edae20838083f2cde1c4080db8cf8090b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22": "0x000000000000000000000000010000000000000000008a5d784563010000000000000000000000000000000000000000000000000000000000000080",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9d0052993b6f3bd0544fd1f5e4125b9fbde3e789ecd53431fe5c06c12b72137153496dace35c695b5f4d7b41f7ed5763b": "0x000000000000000000000000010000000000000000008a5d784563010000000000000000000000000000000000000000000000000000000000000080",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9d6b7e9a5f12bc571053265dade10d3b4b606fc73f57f03cdb4c932d475ab426043e429cecc2ffff0d2672b0df8398c48": "0x000000000000000000000000010000000000000000008a5d784563010000000000000000000000000000000000000000000000000000000000000080",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9de1e86a9a8c739864cf3cc5ec2bea59fd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d": "0x000000000000000000000000010000000000000000008a5d784563010000000000000000000000000000000000000000000000000000000000000080",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9e1a35f56ee295d39287cbffcfc60c4b346f136b564e1fad55031404dd84e5cd3fa76bfe7cc7599b39d38fd06663bbc0a": "0x000000000000000000000000010000000000000000008a5d784563010000000000000000000000000000000000000000000000000000000000000080",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9e2c1dc507e2035edbbd8776c440d870460c57f0008067cc01c5ff9eb2e2f9b3a94299a915a91198bd1021a6c55596f57": "0x000000000000000000000000010000000000000000008a5d784563010000000000000000000000000000000000000000000000000000000000000080",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9eca0e653a94f4080f6311b4e7b6934eb2afba9278e30ccf6a6ceb3a8b6e336b70068f045c666f2e7f4f9cc5f47db8972": "0x000000000000000000000000010000000000000000008a5d784563010000000000000000000000000000000000000000000000000000000000000080",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9ee8bf7ef90fc56a8aa3b90b344c599550c29b161e27ff8ba45bf6bad4711f326fc506a8803453a4d7e3158e993495f10": "0x000000000000000000000000010000000000000000008a5d784563010000000000000000000000000000000000000000000000000000000000000080",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9f5d6f1c082fe63eec7a71fcad00f4a892e3d43b7b0d04e776e69e7be35247cecdac65504c579195731eaf64b7940966e": "0x000000000000000000000000010000000000000000008a5d784563010000000000000000000000000000000000000000000000000000000000000080",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9fbf0818841edf110e05228a6379763c4fc3c37459d9bdc61f58a5ebc01e9e2305a19d390c0543dc733861ec3cf1de01f": "0x000000000000000000000000010000000000000000008a5d784563010000000000000000000000000000000000000000000000000000000000000080",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7f9cce9c888469bb1a0dceaa129672ef8": "0x0000",
|
||||
"0x3a636f6465": "0x0",
|
||||
"0x3a65787472696e7369635f696e646578": "0x00000000",
|
||||
"0xc2261276cc9d1f8598ea4b6a74b15c2f4e7b9012096b41c4eb3aaf947f6ea429": "0x0100",
|
||||
"0xc2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80": "0x00003ef1ee275e1a"
|
||||
},
|
||||
"childrenDefault": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"name": "TestName",
|
||||
"id": "test_id",
|
||||
"chainType": "Local",
|
||||
"bootNodes": [],
|
||||
"telemetryEndpoints": null,
|
||||
"protocolId": null,
|
||||
"properties": null,
|
||||
"codeSubstitutes": {},
|
||||
"genesis": {
|
||||
"runtimeGenesis": {
|
||||
"patch": {
|
||||
"babe": {
|
||||
"epochConfig": {
|
||||
"allowed_slots": "PrimaryAndSecondaryPlainSlots",
|
||||
"c": [
|
||||
7,
|
||||
10
|
||||
]
|
||||
}
|
||||
},
|
||||
"substrateTest": {
|
||||
"authorities": [
|
||||
"5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL",
|
||||
"5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY"
|
||||
]
|
||||
}
|
||||
},
|
||||
"code": "0x0"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"name": "TestName",
|
||||
"id": "test_id",
|
||||
"chainType": "Local",
|
||||
"bootNodes": [],
|
||||
"telemetryEndpoints": null,
|
||||
"protocolId": null,
|
||||
"properties": null,
|
||||
"codeSubstitutes": {},
|
||||
"genesis": {
|
||||
"raw": {
|
||||
"top": {
|
||||
"0x00771836bebdd29870ff246d305c578c4e7b9012096b41c4eb3aaf947f6ea429": "0x0000",
|
||||
"0x00771836bebdd29870ff246d305c578c5e0621c4869aa60c02be9adcc98a0d1d": "0x081cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07cd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d",
|
||||
"0x1cb6f36e027abb2091cfb5110ab5087f4e7b9012096b41c4eb3aaf947f6ea429": "0x0000",
|
||||
"0x1cb6f36e027abb2091cfb5110ab5087f66e8f035c8adbe7f1547b43c51e6f8a4": "0x00000000",
|
||||
"0x1cb6f36e027abb2091cfb5110ab5087fdc6b171b77304263c292cc3ea5ed31ef": "0x07000000000000000a0000000000000001",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef74e7b9012096b41c4eb3aaf947f6ea429": "0x0000",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef75684a022a34dd8bfa2baaf44f172b710": "0x01",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef78a42f33323cb5ced3b44dd825fda9fcc": "0x4545454545454545454545454545454545454545454545454545454545454545",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7a44704b568d21667356a5a050c118746bb1bdbcacd6ac9340000000000000000": "0x4545454545454545454545454545454545454545454545454545454545454545",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7a7fd6c28836b9a28522dc924110cf439": "0x01",
|
||||
"0x26aa394eea5630e07c48ae0c9558cef7f9cce9c888469bb1a0dceaa129672ef8": "0x0000",
|
||||
"0x3a636f6465": "0x0",
|
||||
"0x3a65787472696e7369635f696e646578": "0x00000000",
|
||||
"0xc2261276cc9d1f8598ea4b6a74b15c2f4e7b9012096b41c4eb3aaf947f6ea429": "0x0100",
|
||||
"0xc2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80": "0x0000000000000000"
|
||||
},
|
||||
"childrenDefault": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,8 +18,10 @@
|
||||
|
||||
//! Substrate chain configurations.
|
||||
#![warn(missing_docs)]
|
||||
|
||||
use crate::{extension::GetExtension, ChainType, Properties, RuntimeGenesis};
|
||||
use crate::{
|
||||
extension::GetExtension, ChainType, GenesisConfigBuilderRuntimeCaller as RuntimeCaller,
|
||||
Properties, RuntimeGenesis,
|
||||
};
|
||||
use sc_network::config::MultiaddrWithPeerId;
|
||||
use sc_telemetry::TelemetryEndpoints;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -29,13 +31,32 @@ use sp_core::{
|
||||
Bytes,
|
||||
};
|
||||
use sp_runtime::BuildStorage;
|
||||
use std::{borrow::Cow, collections::BTreeMap, fs::File, path::PathBuf, sync::Arc};
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
collections::{BTreeMap, VecDeque},
|
||||
fs::File,
|
||||
marker::PhantomData,
|
||||
path::PathBuf,
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
enum GenesisBuildAction {
|
||||
Patch(json::Value),
|
||||
Full(json::Value),
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
enum GenesisSource<G> {
|
||||
File(PathBuf),
|
||||
Binary(Cow<'static, [u8]>),
|
||||
Factory(Arc<dyn Fn() -> G + Send + Sync>),
|
||||
/// factory function + code
|
||||
//Factory and G type parameter shall be removed togheter with `ChainSpec::from_genesis`
|
||||
Factory(Arc<dyn Fn() -> G + Send + Sync>, Vec<u8>),
|
||||
Storage(Storage),
|
||||
/// build action + code
|
||||
GenesisBuilderApi(GenesisBuildAction, Vec<u8>),
|
||||
}
|
||||
|
||||
impl<G> Clone for GenesisSource<G> {
|
||||
@@ -43,14 +64,17 @@ impl<G> Clone for GenesisSource<G> {
|
||||
match *self {
|
||||
Self::File(ref path) => Self::File(path.clone()),
|
||||
Self::Binary(ref d) => Self::Binary(d.clone()),
|
||||
Self::Factory(ref f) => Self::Factory(f.clone()),
|
||||
Self::Factory(ref f, ref c) => Self::Factory(f.clone(), c.clone()),
|
||||
Self::Storage(ref s) => Self::Storage(s.clone()),
|
||||
Self::GenesisBuilderApi(ref s, ref c) => Self::GenesisBuilderApi(s.clone(), c.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<G: RuntimeGenesis> GenesisSource<G> {
|
||||
fn resolve(&self) -> Result<Genesis<G>, String> {
|
||||
/// helper container for deserializing genesis from the JSON file (ChainSpec JSON file is
|
||||
/// also supported here)
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct GenesisContainer<G> {
|
||||
genesis: Genesis<G>,
|
||||
@@ -79,31 +103,21 @@ impl<G: RuntimeGenesis> GenesisSource<G> {
|
||||
.map_err(|e| format!("Error parsing embedded file: {}", e))?;
|
||||
Ok(genesis.genesis)
|
||||
},
|
||||
Self::Factory(f) => Ok(Genesis::Runtime(f())),
|
||||
Self::Storage(storage) => {
|
||||
let top = storage
|
||||
.top
|
||||
.iter()
|
||||
.map(|(k, v)| (StorageKey(k.clone()), StorageData(v.clone())))
|
||||
.collect();
|
||||
|
||||
let children_default = storage
|
||||
.children_default
|
||||
.iter()
|
||||
.map(|(k, child)| {
|
||||
(
|
||||
StorageKey(k.clone()),
|
||||
child
|
||||
.data
|
||||
.iter()
|
||||
.map(|(k, v)| (StorageKey(k.clone()), StorageData(v.clone())))
|
||||
.collect(),
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
|
||||
Ok(Genesis::Raw(RawGenesis { top, children_default }))
|
||||
},
|
||||
Self::Factory(f, code) => Ok(Genesis::RuntimeAndCode(RuntimeInnerWrapper {
|
||||
runtime: f(),
|
||||
code: code.clone(),
|
||||
})),
|
||||
Self::Storage(storage) => Ok(Genesis::Raw(RawGenesis::from(storage.clone()))),
|
||||
Self::GenesisBuilderApi(GenesisBuildAction::Full(config), code) =>
|
||||
Ok(Genesis::RuntimeGenesis(RuntimeGenesisInner {
|
||||
json_blob: RuntimeGenesisConfigJson::Config(config.clone()),
|
||||
code: code.clone(),
|
||||
})),
|
||||
Self::GenesisBuilderApi(GenesisBuildAction::Patch(patch), code) =>
|
||||
Ok(Genesis::RuntimeGenesis(RuntimeGenesisInner {
|
||||
json_blob: RuntimeGenesisConfigJson::Patch(patch.clone()),
|
||||
code: code.clone(),
|
||||
})),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -111,7 +125,18 @@ impl<G: RuntimeGenesis> GenesisSource<G> {
|
||||
impl<G: RuntimeGenesis, E> BuildStorage for ChainSpec<G, E> {
|
||||
fn assimilate_storage(&self, storage: &mut Storage) -> Result<(), String> {
|
||||
match self.genesis.resolve()? {
|
||||
Genesis::Runtime(gc) => gc.assimilate_storage(storage),
|
||||
#[allow(deprecated)]
|
||||
Genesis::Runtime(runtime_genesis_config) => {
|
||||
runtime_genesis_config.assimilate_storage(storage)?;
|
||||
},
|
||||
#[allow(deprecated)]
|
||||
Genesis::RuntimeAndCode(RuntimeInnerWrapper {
|
||||
runtime: runtime_genesis_config,
|
||||
code,
|
||||
}) => {
|
||||
runtime_genesis_config.assimilate_storage(storage)?;
|
||||
storage.top.insert(sp_core::storage::well_known_keys::CODE.to_vec(), code);
|
||||
},
|
||||
Genesis::Raw(RawGenesis { top: map, children_default: children_map }) => {
|
||||
storage.top.extend(map.into_iter().map(|(k, v)| (k.0, v.0)));
|
||||
children_map.into_iter().for_each(|(k, v)| {
|
||||
@@ -123,13 +148,37 @@ impl<G: RuntimeGenesis, E> BuildStorage for ChainSpec<G, E> {
|
||||
.data
|
||||
.extend(v.into_iter().map(|(k, v)| (k.0, v.0)));
|
||||
});
|
||||
Ok(())
|
||||
},
|
||||
// The `StateRootHash` variant exists as a way to keep note that other clients support
|
||||
// it, but Substrate itself isn't capable of loading chain specs with just a hash at the
|
||||
// moment.
|
||||
Genesis::StateRootHash(_) => Err("Genesis storage in hash format not supported".into()),
|
||||
}
|
||||
Genesis::StateRootHash(_) =>
|
||||
return Err("Genesis storage in hash format not supported".into()),
|
||||
Genesis::RuntimeGenesis(RuntimeGenesisInner {
|
||||
json_blob: RuntimeGenesisConfigJson::Config(config),
|
||||
code,
|
||||
}) => {
|
||||
RuntimeCaller::new(&code[..])
|
||||
.get_storage_for_config(config)?
|
||||
.assimilate_storage(storage)?;
|
||||
storage
|
||||
.top
|
||||
.insert(sp_core::storage::well_known_keys::CODE.to_vec(), code.clone());
|
||||
},
|
||||
Genesis::RuntimeGenesis(RuntimeGenesisInner {
|
||||
json_blob: RuntimeGenesisConfigJson::Patch(patch),
|
||||
code,
|
||||
}) => {
|
||||
RuntimeCaller::new(&code[..])
|
||||
.get_storage_for_patch(patch)?
|
||||
.assimilate_storage(storage)?;
|
||||
storage
|
||||
.top
|
||||
.insert(sp_core::storage::well_known_keys::CODE.to_vec(), code.clone());
|
||||
},
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,20 +193,98 @@ pub struct RawGenesis {
|
||||
pub children_default: BTreeMap<StorageKey, GenesisStorage>,
|
||||
}
|
||||
|
||||
impl From<sp_core::storage::Storage> for RawGenesis {
|
||||
fn from(value: sp_core::storage::Storage) -> Self {
|
||||
Self {
|
||||
top: value.top.into_iter().map(|(k, v)| (StorageKey(k), StorageData(v))).collect(),
|
||||
children_default: value
|
||||
.children_default
|
||||
.into_iter()
|
||||
.map(|(sk, child)| {
|
||||
(
|
||||
StorageKey(sk),
|
||||
child
|
||||
.data
|
||||
.into_iter()
|
||||
.map(|(k, v)| (StorageKey(k), StorageData(v)))
|
||||
.collect(),
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Inner representation of [`Genesis<G>::RuntimeGenesis`] format
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
struct RuntimeGenesisInner {
|
||||
/// Runtime wasm code, expected to be hex-encoded in JSON.
|
||||
/// The code shall be capable of parsing `json_blob`.
|
||||
#[serde(default, with = "sp_core::bytes")]
|
||||
code: Vec<u8>,
|
||||
/// The patch or full representation of runtime's `RuntimeGenesisConfig` struct.
|
||||
#[serde(flatten)]
|
||||
json_blob: RuntimeGenesisConfigJson,
|
||||
}
|
||||
|
||||
/// Represents two possible variants of the contained JSON blob for the
|
||||
/// [`Genesis<G>::RuntimeGenesis`] format.
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
enum RuntimeGenesisConfigJson {
|
||||
/// Represents the explicit and comprehensive runtime genesis config in JSON format.
|
||||
/// The contained object is a JSON blob that can be parsed by a compatible runtime.
|
||||
///
|
||||
/// Using a full config is useful for when someone wants to ensure that a change in the runtime
|
||||
/// makes the deserialization fail and not silently add some default values.
|
||||
Config(json::Value),
|
||||
/// Represents a patch for the default runtime genesis config in JSON format which is
|
||||
/// essentially a list of keys that are to be customized in runtime genesis config.
|
||||
/// The contained value is a JSON blob that can be parsed by a compatible runtime.
|
||||
Patch(json::Value),
|
||||
}
|
||||
|
||||
/// Inner variant wrapper for deprecated runtime.
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
struct RuntimeInnerWrapper<G> {
|
||||
/// The native `RuntimeGenesisConfig` struct.
|
||||
runtime: G,
|
||||
/// Runtime code.
|
||||
#[serde(with = "sp_core::bytes")]
|
||||
code: Vec<u8>,
|
||||
}
|
||||
|
||||
/// Represents the different formats of the genesis state within chain spec JSON blob.
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[serde(deny_unknown_fields)]
|
||||
enum Genesis<G> {
|
||||
/// (Deprecated) Contains the JSON representation of G (the native type representing the
|
||||
/// runtime's `RuntimeGenesisConfig` struct) (will be removed with `ChainSpec::from_genesis`)
|
||||
/// without the runtime code. It is required to deserialize the legacy chainspecs genereted
|
||||
/// with `ChainsSpec::from_genesis` method.
|
||||
Runtime(G),
|
||||
/// (Deprecated) Contains the JSON representation of G (the native type representing the
|
||||
/// runtime's `RuntimeGenesisConfig` struct) (will be removed with `ChainSpec::from_genesis`)
|
||||
/// and the runtime code. It is required to create and deserialize JSON chainspecs created with
|
||||
/// deprecated `ChainSpec::from_genesis` method.
|
||||
RuntimeAndCode(RuntimeInnerWrapper<G>),
|
||||
/// The genesis storage as raw data. Typically raw key-value entries in state.
|
||||
Raw(RawGenesis),
|
||||
/// State root hash of the genesis storage.
|
||||
StateRootHash(StorageData),
|
||||
/// Represents the runtime genesis config in JSON format toghether with runtime code.
|
||||
RuntimeGenesis(RuntimeGenesisInner),
|
||||
}
|
||||
|
||||
/// A configuration of a client. Does not include runtime storage initialization.
|
||||
/// Note: `genesis` field is ignored due to way how the chain specification is serialized into
|
||||
/// JSON file. Refer to [`ChainSpecJsonContainer`], which flattens [`ClientSpec`] and denies uknown
|
||||
/// fields.
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[serde(deny_unknown_fields)]
|
||||
// we cannot #[serde(deny_unknown_fields)]. Otherwise chain-spec-builder will fail on any
|
||||
// non-standard spec
|
||||
struct ClientSpec<E> {
|
||||
name: String,
|
||||
id: String,
|
||||
@@ -194,6 +321,137 @@ struct ClientSpec<E> {
|
||||
/// We use `Option` here since `()` is not flattenable by serde.
|
||||
pub type NoExtension = Option<()>;
|
||||
|
||||
/// Builder for creating [`ChainSpec`] instances.
|
||||
pub struct ChainSpecBuilder<G, E = NoExtension> {
|
||||
code: Vec<u8>,
|
||||
extensions: E,
|
||||
name: String,
|
||||
id: String,
|
||||
chain_type: ChainType,
|
||||
genesis_build_action: GenesisBuildAction,
|
||||
boot_nodes: Option<Vec<MultiaddrWithPeerId>>,
|
||||
telemetry_endpoints: Option<TelemetryEndpoints>,
|
||||
protocol_id: Option<String>,
|
||||
fork_id: Option<String>,
|
||||
properties: Option<Properties>,
|
||||
_genesis: PhantomData<G>,
|
||||
}
|
||||
|
||||
impl<G, E> ChainSpecBuilder<G, E> {
|
||||
/// Creates a new builder instance with no defaults.
|
||||
pub fn new(code: &[u8], extensions: E) -> Self {
|
||||
Self {
|
||||
code: code.into(),
|
||||
extensions,
|
||||
name: "Development".to_string(),
|
||||
id: "dev".to_string(),
|
||||
chain_type: ChainType::Local,
|
||||
genesis_build_action: GenesisBuildAction::Patch(Default::default()),
|
||||
boot_nodes: None,
|
||||
telemetry_endpoints: None,
|
||||
protocol_id: None,
|
||||
fork_id: None,
|
||||
properties: None,
|
||||
_genesis: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the spec name.
|
||||
pub fn with_name(mut self, name: &str) -> Self {
|
||||
self.name = name.into();
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the spec ID.
|
||||
pub fn with_id(mut self, id: &str) -> Self {
|
||||
self.id = id.into();
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the type of the chain.
|
||||
pub fn with_chain_type(mut self, chain_type: ChainType) -> Self {
|
||||
self.chain_type = chain_type;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets a list of bootnode addresses.
|
||||
pub fn with_boot_nodes(mut self, boot_nodes: Vec<MultiaddrWithPeerId>) -> Self {
|
||||
self.boot_nodes = Some(boot_nodes);
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets telemetry endpoints.
|
||||
pub fn with_telemetry_endpoints(mut self, telemetry_endpoints: TelemetryEndpoints) -> Self {
|
||||
self.telemetry_endpoints = Some(telemetry_endpoints);
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the network protocol ID.
|
||||
pub fn with_protocol_id(mut self, protocol_id: &str) -> Self {
|
||||
self.protocol_id = Some(protocol_id.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets an optional network fork identifier.
|
||||
pub fn with_fork_id(mut self, fork_id: &str) -> Self {
|
||||
self.fork_id = Some(fork_id.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets additional loosely-typed properties of the chain.
|
||||
pub fn with_properties(mut self, properties: Properties) -> Self {
|
||||
self.properties = Some(properties);
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets chain spec extensions.
|
||||
pub fn with_extensions(mut self, extensions: E) -> Self {
|
||||
self.extensions = extensions;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the code.
|
||||
pub fn with_code(mut self, code: &[u8]) -> Self {
|
||||
self.code = code.into();
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the JSON patch for runtime's GenesisConfig.
|
||||
pub fn with_genesis_config_patch(mut self, patch: json::Value) -> Self {
|
||||
self.genesis_build_action = GenesisBuildAction::Patch(patch);
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the full runtime's GenesisConfig JSON.
|
||||
pub fn with_genesis_config(mut self, config: json::Value) -> Self {
|
||||
self.genesis_build_action = GenesisBuildAction::Full(config);
|
||||
self
|
||||
}
|
||||
|
||||
/// Builds a [`ChainSpec`] instance using the provided settings.
|
||||
pub fn build(self) -> ChainSpec<G, E> {
|
||||
let client_spec = ClientSpec {
|
||||
name: self.name,
|
||||
id: self.id,
|
||||
chain_type: self.chain_type,
|
||||
boot_nodes: self.boot_nodes.unwrap_or_default(),
|
||||
telemetry_endpoints: self.telemetry_endpoints,
|
||||
protocol_id: self.protocol_id,
|
||||
fork_id: self.fork_id,
|
||||
properties: self.properties,
|
||||
extensions: self.extensions,
|
||||
consensus_engine: (),
|
||||
genesis: Default::default(),
|
||||
code_substitutes: BTreeMap::new(),
|
||||
};
|
||||
|
||||
ChainSpec {
|
||||
client_spec,
|
||||
genesis: GenesisSource::GenesisBuilderApi(self.genesis_build_action, self.code.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A configuration of a chain. Can be used to build a genesis block.
|
||||
pub struct ChainSpec<G, E = NoExtension> {
|
||||
client_spec: ClientSpec<E>,
|
||||
@@ -260,6 +518,10 @@ impl<G, E> ChainSpec<G, E> {
|
||||
}
|
||||
|
||||
/// Create hardcoded spec.
|
||||
#[deprecated(
|
||||
note = "`from_genesis` is planned to be removed in May 2024. Use `builder()` instead."
|
||||
)]
|
||||
// deprecated note: Genesis<G>::Runtime + GenesisSource::Factory shall also be removed
|
||||
pub fn from_genesis<F: Fn() -> G + 'static + Send + Sync>(
|
||||
name: &str,
|
||||
id: &str,
|
||||
@@ -271,6 +533,7 @@ impl<G, E> ChainSpec<G, E> {
|
||||
fork_id: Option<&str>,
|
||||
properties: Option<Properties>,
|
||||
extensions: E,
|
||||
code: &[u8],
|
||||
) -> Self {
|
||||
let client_spec = ClientSpec {
|
||||
name: name.to_owned(),
|
||||
@@ -287,21 +550,30 @@ impl<G, E> ChainSpec<G, E> {
|
||||
code_substitutes: BTreeMap::new(),
|
||||
};
|
||||
|
||||
ChainSpec { client_spec, genesis: GenesisSource::Factory(Arc::new(constructor)) }
|
||||
ChainSpec {
|
||||
client_spec,
|
||||
genesis: GenesisSource::Factory(Arc::new(constructor), code.into()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Type of the chain.
|
||||
fn chain_type(&self) -> ChainType {
|
||||
self.client_spec.chain_type.clone()
|
||||
}
|
||||
|
||||
/// Provides a `ChainSpec` builder.
|
||||
pub fn builder(code: &[u8], extensions: E) -> ChainSpecBuilder<G, E> {
|
||||
ChainSpecBuilder::new(code, extensions)
|
||||
}
|
||||
}
|
||||
|
||||
impl<G, E: serde::de::DeserializeOwned> ChainSpec<G, E> {
|
||||
impl<G: serde::de::DeserializeOwned, E: serde::de::DeserializeOwned> ChainSpec<G, E> {
|
||||
/// Parse json content into a `ChainSpec`
|
||||
pub fn from_json_bytes(json: impl Into<Cow<'static, [u8]>>) -> Result<Self, String> {
|
||||
let json = json.into();
|
||||
let client_spec = json::from_slice(json.as_ref())
|
||||
.map_err(|e| format!("Error parsing spec file: {}", e))?;
|
||||
|
||||
Ok(ChainSpec { client_spec, genesis: GenesisSource::Binary(json) })
|
||||
}
|
||||
|
||||
@@ -318,50 +590,74 @@ impl<G, E: serde::de::DeserializeOwned> ChainSpec<G, E> {
|
||||
memmap2::Mmap::map(&file)
|
||||
.map_err(|e| format!("Error mmaping spec file `{}`: {}", path.display(), e))?
|
||||
};
|
||||
|
||||
let client_spec =
|
||||
json::from_slice(&bytes).map_err(|e| format!("Error parsing spec file: {}", e))?;
|
||||
|
||||
Ok(ChainSpec { client_spec, genesis: GenesisSource::File(path) })
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper structure for serializing (and only serializing) the ChainSpec into JSON file. It
|
||||
/// represents the layout of `ChainSpec` JSON file.
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct JsonContainer<G, E> {
|
||||
// we cannot #[serde(deny_unknown_fields)]. Otherwise chain-spec-builder will fail on any
|
||||
// non-standard spec.
|
||||
struct ChainSpecJsonContainer<G, E> {
|
||||
#[serde(flatten)]
|
||||
client_spec: ClientSpec<E>,
|
||||
genesis: Genesis<G>,
|
||||
}
|
||||
|
||||
impl<G: RuntimeGenesis, E: serde::Serialize + Clone + 'static> ChainSpec<G, E> {
|
||||
fn json_container(&self, raw: bool) -> Result<JsonContainer<G, E>, String> {
|
||||
let genesis = match (raw, self.genesis.resolve()?) {
|
||||
fn json_container(&self, raw: bool) -> Result<ChainSpecJsonContainer<G, E>, String> {
|
||||
let raw_genesis = match (raw, self.genesis.resolve()?) {
|
||||
(
|
||||
true,
|
||||
Genesis::RuntimeGenesis(RuntimeGenesisInner {
|
||||
json_blob: RuntimeGenesisConfigJson::Config(config),
|
||||
code,
|
||||
}),
|
||||
) => {
|
||||
let mut storage = RuntimeCaller::new(&code[..]).get_storage_for_config(config)?;
|
||||
storage.top.insert(sp_core::storage::well_known_keys::CODE.to_vec(), code);
|
||||
RawGenesis::from(storage)
|
||||
},
|
||||
(
|
||||
true,
|
||||
Genesis::RuntimeGenesis(RuntimeGenesisInner {
|
||||
json_blob: RuntimeGenesisConfigJson::Patch(patch),
|
||||
code,
|
||||
}),
|
||||
) => {
|
||||
let mut storage = RuntimeCaller::new(&code[..]).get_storage_for_patch(patch)?;
|
||||
storage.top.insert(sp_core::storage::well_known_keys::CODE.to_vec(), code);
|
||||
RawGenesis::from(storage)
|
||||
},
|
||||
|
||||
#[allow(deprecated)]
|
||||
(true, Genesis::RuntimeAndCode(RuntimeInnerWrapper { runtime: g, code })) => {
|
||||
let mut storage = g.build_storage()?;
|
||||
storage.top.insert(sp_core::storage::well_known_keys::CODE.to_vec(), code);
|
||||
RawGenesis::from(storage)
|
||||
},
|
||||
#[allow(deprecated)]
|
||||
(true, Genesis::Runtime(g)) => {
|
||||
let storage = g.build_storage()?;
|
||||
let top =
|
||||
storage.top.into_iter().map(|(k, v)| (StorageKey(k), StorageData(v))).collect();
|
||||
let children_default = storage
|
||||
.children_default
|
||||
.into_iter()
|
||||
.map(|(sk, child)| {
|
||||
(
|
||||
StorageKey(sk),
|
||||
child
|
||||
.data
|
||||
.into_iter()
|
||||
.map(|(k, v)| (StorageKey(k), StorageData(v)))
|
||||
.collect(),
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
|
||||
Genesis::Raw(RawGenesis { top, children_default })
|
||||
RawGenesis::from(storage)
|
||||
},
|
||||
(_, genesis) => genesis,
|
||||
(true, Genesis::Raw(raw)) => raw,
|
||||
|
||||
(_, genesis) =>
|
||||
return Ok(ChainSpecJsonContainer { client_spec: self.client_spec.clone(), genesis }),
|
||||
};
|
||||
Ok(JsonContainer { client_spec: self.client_spec.clone(), genesis })
|
||||
|
||||
Ok(ChainSpecJsonContainer {
|
||||
client_spec: self.client_spec.clone(),
|
||||
genesis: Genesis::Raw(raw_genesis),
|
||||
})
|
||||
}
|
||||
|
||||
/// Dump to json string.
|
||||
/// Dump the chain specification to JSON string.
|
||||
pub fn as_json(&self, raw: bool) -> Result<String, String> {
|
||||
let container = self.json_container(raw)?;
|
||||
json::to_string_pretty(&container).map_err(|e| format!("Error generating spec json: {}", e))
|
||||
@@ -442,9 +738,87 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// The `fun` will be called with the value at `path`.
|
||||
///
|
||||
/// If exists, the value at given `path` will be passed to the `fun` and the result of `fun`
|
||||
/// call will be returned. Otherwise false is returned.
|
||||
/// `path` will be modified.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```ignore
|
||||
/// use serde_json::{from_str, json, Value};
|
||||
/// let doc = json!({"a":{"b":{"c":"5"}}});
|
||||
/// let mut path = ["a", "b", "c"].into();
|
||||
/// assert!(json_eval_value_at_key(&doc, &mut path, &|v| { assert_eq!(v,"5"); true }));
|
||||
/// ```
|
||||
fn json_eval_value_at_key(
|
||||
doc: &json::Value,
|
||||
path: &mut VecDeque<&str>,
|
||||
fun: &dyn Fn(&json::Value) -> bool,
|
||||
) -> bool {
|
||||
let Some(key) = path.pop_front() else {
|
||||
return false;
|
||||
};
|
||||
|
||||
if path.is_empty() {
|
||||
doc.as_object().map_or(false, |o| o.get(key).map_or(false, |v| fun(v)))
|
||||
} else {
|
||||
doc.as_object()
|
||||
.map_or(false, |o| o.get(key).map_or(false, |v| json_eval_value_at_key(v, path, fun)))
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! json_path {
|
||||
[ $($x:expr),+ ] => {
|
||||
VecDeque::<&str>::from([$($x),+])
|
||||
};
|
||||
}
|
||||
|
||||
fn json_contains_path(doc: &json::Value, path: &mut VecDeque<&str>) -> bool {
|
||||
json_eval_value_at_key(doc, path, &|_| true)
|
||||
}
|
||||
|
||||
/// This function updates the code in given chain spec.
|
||||
///
|
||||
/// Function support updating the runtime code in provided JSON chain spec blob. `Genesis<G>::Raw`
|
||||
/// and `Genesis<G>::RuntimeGenesis` formats are supported.
|
||||
///
|
||||
/// If update was successful `true` is returned, otherwise `false`. Chain spec JSON is modified in
|
||||
/// place.
|
||||
pub fn update_code_in_json_chain_spec(chain_spec: &mut json::Value, code: &[u8]) -> bool {
|
||||
let mut path = json_path!["genesis", "runtimeGenesis", "code"];
|
||||
let mut raw_path = json_path!["genesis", "raw", "top"];
|
||||
|
||||
if json_contains_path(&chain_spec, &mut path) {
|
||||
#[derive(Serialize)]
|
||||
struct Container<'a> {
|
||||
#[serde(with = "sp_core::bytes")]
|
||||
code: &'a [u8],
|
||||
}
|
||||
let code_patch = json::json!({"genesis":{"runtimeGenesis": Container { code }}});
|
||||
crate::json_patch::merge(chain_spec, code_patch);
|
||||
true
|
||||
} else if json_contains_path(&chain_spec, &mut raw_path) {
|
||||
#[derive(Serialize)]
|
||||
struct Container<'a> {
|
||||
#[serde(with = "sp_core::bytes", rename = "0x3a636f6465")]
|
||||
code: &'a [u8],
|
||||
}
|
||||
let code_patch = json::json!({"genesis":{"raw":{"top": Container { code }}}});
|
||||
crate::json_patch::merge(chain_spec, code_patch);
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use serde_json::{from_str, json, Value};
|
||||
use sp_application_crypto::Ss58Codec;
|
||||
use sp_core::storage::well_known_keys;
|
||||
use sp_keyring::AccountKeyring;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct Genesis(BTreeMap<String, String>);
|
||||
@@ -536,4 +910,336 @@ mod tests {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
// some tests for json path utils
|
||||
fn test_json_eval_value_at_key() {
|
||||
let doc = json!({"a":{"b1":"20","b":{"c":{"d":"10"}}}});
|
||||
|
||||
assert!(json_eval_value_at_key(&doc, &mut json_path!["a", "b1"], &|v| { *v == "20" }));
|
||||
assert!(json_eval_value_at_key(&doc, &mut json_path!["a", "b", "c", "d"], &|v| {
|
||||
*v == "10"
|
||||
}));
|
||||
assert!(!json_eval_value_at_key(&doc, &mut json_path!["a", "c", "d"], &|_| { true }));
|
||||
assert!(!json_eval_value_at_key(&doc, &mut json_path!["d"], &|_| { true }));
|
||||
|
||||
assert!(json_contains_path(&doc, &mut json_path!["a", "b1"]));
|
||||
assert!(json_contains_path(&doc, &mut json_path!["a", "b"]));
|
||||
assert!(json_contains_path(&doc, &mut json_path!["a", "b", "c"]));
|
||||
assert!(json_contains_path(&doc, &mut json_path!["a", "b", "c", "d"]));
|
||||
assert!(!json_contains_path(&doc, &mut json_path!["a", "b", "c", "d", "e"]));
|
||||
assert!(!json_contains_path(&doc, &mut json_path!["a", "b", "b1"]));
|
||||
assert!(!json_contains_path(&doc, &mut json_path!["d"]));
|
||||
}
|
||||
|
||||
fn zeroize_code_key_in_json(encoded: bool, json: &str) -> Value {
|
||||
let mut json = from_str::<Value>(json).unwrap();
|
||||
let (zeroing_patch, mut path) = if encoded {
|
||||
(
|
||||
json!({"genesis":{"raw":{"top":{"0x3a636f6465":"0x0"}}}}),
|
||||
json_path!["genesis", "raw", "top", "0x3a636f6465"],
|
||||
)
|
||||
} else {
|
||||
(
|
||||
json!({"genesis":{"runtimeGenesis":{"code":"0x0"}}}),
|
||||
json_path!["genesis", "runtimeGenesis", "code"],
|
||||
)
|
||||
};
|
||||
assert!(json_contains_path(&json, &mut path));
|
||||
crate::json_patch::merge(&mut json, zeroing_patch);
|
||||
json
|
||||
}
|
||||
|
||||
#[docify::export]
|
||||
#[test]
|
||||
fn build_chain_spec_with_patch_works() {
|
||||
let output: ChainSpec<()> = ChainSpec::builder(
|
||||
substrate_test_runtime::wasm_binary_unwrap().into(),
|
||||
Default::default(),
|
||||
)
|
||||
.with_name("TestName")
|
||||
.with_id("test_id")
|
||||
.with_chain_type(ChainType::Local)
|
||||
.with_genesis_config_patch(json!({
|
||||
"babe": {
|
||||
"epochConfig": {
|
||||
"c": [
|
||||
7,
|
||||
10
|
||||
],
|
||||
"allowed_slots": "PrimaryAndSecondaryPlainSlots"
|
||||
}
|
||||
},
|
||||
"substrateTest": {
|
||||
"authorities": [
|
||||
AccountKeyring::Ferdie.public().to_ss58check(),
|
||||
AccountKeyring::Alice.public().to_ss58check()
|
||||
],
|
||||
}
|
||||
}))
|
||||
.build();
|
||||
|
||||
let raw_chain_spec = output.as_json(true);
|
||||
assert!(raw_chain_spec.is_ok());
|
||||
}
|
||||
|
||||
#[docify::export]
|
||||
#[test]
|
||||
fn generate_chain_spec_with_patch_works() {
|
||||
let output: ChainSpec<()> = ChainSpec::builder(
|
||||
substrate_test_runtime::wasm_binary_unwrap().into(),
|
||||
Default::default(),
|
||||
)
|
||||
.with_name("TestName")
|
||||
.with_id("test_id")
|
||||
.with_chain_type(ChainType::Local)
|
||||
.with_genesis_config_patch(json!({
|
||||
"babe": {
|
||||
"epochConfig": {
|
||||
"c": [
|
||||
7,
|
||||
10
|
||||
],
|
||||
"allowed_slots": "PrimaryAndSecondaryPlainSlots"
|
||||
}
|
||||
},
|
||||
"substrateTest": {
|
||||
"authorities": [
|
||||
AccountKeyring::Ferdie.public().to_ss58check(),
|
||||
AccountKeyring::Alice.public().to_ss58check()
|
||||
],
|
||||
}
|
||||
}))
|
||||
.build();
|
||||
|
||||
let actual = output.as_json(false).unwrap();
|
||||
let actual_raw = output.as_json(true).unwrap();
|
||||
|
||||
let expected =
|
||||
from_str::<Value>(include_str!("../res/substrate_test_runtime_from_patch.json"))
|
||||
.unwrap();
|
||||
let expected_raw =
|
||||
from_str::<Value>(include_str!("../res/substrate_test_runtime_from_patch_raw.json"))
|
||||
.unwrap();
|
||||
|
||||
//wasm blob may change overtime so let's zero it. Also ensure it is there:
|
||||
let actual = zeroize_code_key_in_json(false, actual.as_str());
|
||||
let actual_raw = zeroize_code_key_in_json(true, actual_raw.as_str());
|
||||
|
||||
assert_eq!(actual, expected);
|
||||
assert_eq!(actual_raw, expected_raw);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn generate_chain_spec_with_full_config_works() {
|
||||
let j = include_str!("../../../test-utils/runtime/res/default_genesis_config.json");
|
||||
let output: ChainSpec<()> = ChainSpec::builder(
|
||||
substrate_test_runtime::wasm_binary_unwrap().into(),
|
||||
Default::default(),
|
||||
)
|
||||
.with_name("TestName")
|
||||
.with_id("test_id")
|
||||
.with_chain_type(ChainType::Local)
|
||||
.with_genesis_config(from_str(j).unwrap())
|
||||
.build();
|
||||
|
||||
let actual = output.as_json(false).unwrap();
|
||||
let actual_raw = output.as_json(true).unwrap();
|
||||
|
||||
let expected =
|
||||
from_str::<Value>(include_str!("../res/substrate_test_runtime_from_config.json"))
|
||||
.unwrap();
|
||||
let expected_raw =
|
||||
from_str::<Value>(include_str!("../res/substrate_test_runtime_from_config_raw.json"))
|
||||
.unwrap();
|
||||
|
||||
//wasm blob may change overtime so let's zero it. Also ensure it is there:
|
||||
let actual = zeroize_code_key_in_json(false, actual.as_str());
|
||||
let actual_raw = zeroize_code_key_in_json(true, actual_raw.as_str());
|
||||
|
||||
assert_eq!(actual, expected);
|
||||
assert_eq!(actual_raw, expected_raw);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn chain_spec_as_json_fails_with_invalid_config() {
|
||||
let j =
|
||||
include_str!("../../../test-utils/runtime/res/default_genesis_config_invalid_2.json");
|
||||
let output: ChainSpec<()> = ChainSpec::builder(
|
||||
substrate_test_runtime::wasm_binary_unwrap().into(),
|
||||
Default::default(),
|
||||
)
|
||||
.with_name("TestName")
|
||||
.with_id("test_id")
|
||||
.with_chain_type(ChainType::Local)
|
||||
.with_genesis_config(from_str(j).unwrap())
|
||||
.build();
|
||||
|
||||
assert_eq!(
|
||||
output.as_json(true),
|
||||
Err("Invalid JSON blob: unknown field `babex`, expected one of `system`, `babe`, `substrateTest`, `balances` at line 1 column 8".to_string())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn chain_spec_as_json_fails_with_invalid_patch() {
|
||||
let output: ChainSpec<()> = ChainSpec::builder(
|
||||
substrate_test_runtime::wasm_binary_unwrap().into(),
|
||||
Default::default(),
|
||||
)
|
||||
.with_name("TestName")
|
||||
.with_id("test_id")
|
||||
.with_chain_type(ChainType::Local)
|
||||
.with_genesis_config_patch(json!({
|
||||
"invalid_pallet": {},
|
||||
"substrateTest": {
|
||||
"authorities": [
|
||||
AccountKeyring::Ferdie.public().to_ss58check(),
|
||||
AccountKeyring::Alice.public().to_ss58check()
|
||||
],
|
||||
}
|
||||
}))
|
||||
.build();
|
||||
|
||||
assert!(output.as_json(true).unwrap_err().contains("Invalid JSON blob: unknown field `invalid_pallet`, expected one of `system`, `babe`, `substrateTest`, `balances`"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_if_code_is_valid_for_raw_without_code() {
|
||||
let spec = ChainSpec::<()>::from_json_bytes(Cow::Owned(
|
||||
include_bytes!("../res/raw_no_code.json").to_vec(),
|
||||
))
|
||||
.unwrap();
|
||||
|
||||
let j = from_str::<Value>(&spec.as_json(true).unwrap()).unwrap();
|
||||
|
||||
assert!(json_eval_value_at_key(
|
||||
&j,
|
||||
&mut json_path!["genesis", "raw", "top", "0x3a636f6465"],
|
||||
&|v| { *v == "0x010101" }
|
||||
));
|
||||
assert!(!json_contains_path(&j, &mut json_path!["code"]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_code_in_assimilated_storage_for_raw_without_code() {
|
||||
let spec = ChainSpec::<()>::from_json_bytes(Cow::Owned(
|
||||
include_bytes!("../res/raw_no_code.json").to_vec(),
|
||||
))
|
||||
.unwrap();
|
||||
|
||||
let storage = spec.build_storage().unwrap();
|
||||
assert!(storage
|
||||
.top
|
||||
.get(&well_known_keys::CODE.to_vec())
|
||||
.map(|v| *v == vec![1, 1, 1])
|
||||
.unwrap())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn update_code_works_with_runtime_genesis_config() {
|
||||
let j = include_str!("../../../test-utils/runtime/res/default_genesis_config.json");
|
||||
let chain_spec: ChainSpec<()> = ChainSpec::builder(
|
||||
substrate_test_runtime::wasm_binary_unwrap().into(),
|
||||
Default::default(),
|
||||
)
|
||||
.with_name("TestName")
|
||||
.with_id("test_id")
|
||||
.with_chain_type(ChainType::Local)
|
||||
.with_genesis_config(from_str(j).unwrap())
|
||||
.build();
|
||||
|
||||
let mut chain_spec_json = from_str::<Value>(&chain_spec.as_json(false).unwrap()).unwrap();
|
||||
assert!(update_code_in_json_chain_spec(&mut chain_spec_json, &[0, 1, 2, 4, 5, 6]));
|
||||
|
||||
assert!(json_eval_value_at_key(
|
||||
&chain_spec_json,
|
||||
&mut json_path!["genesis", "runtimeGenesis", "code"],
|
||||
&|v| { *v == "0x000102040506" }
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn update_code_works_for_raw() {
|
||||
let j = include_str!("../../../test-utils/runtime/res/default_genesis_config.json");
|
||||
let chain_spec: ChainSpec<()> = ChainSpec::builder(
|
||||
substrate_test_runtime::wasm_binary_unwrap().into(),
|
||||
Default::default(),
|
||||
)
|
||||
.with_name("TestName")
|
||||
.with_id("test_id")
|
||||
.with_chain_type(ChainType::Local)
|
||||
.with_genesis_config(from_str(j).unwrap())
|
||||
.build();
|
||||
|
||||
let mut chain_spec_json = from_str::<Value>(&chain_spec.as_json(true).unwrap()).unwrap();
|
||||
assert!(update_code_in_json_chain_spec(&mut chain_spec_json, &[0, 1, 2, 4, 5, 6]));
|
||||
|
||||
assert!(json_eval_value_at_key(
|
||||
&chain_spec_json,
|
||||
&mut json_path!["genesis", "raw", "top", "0x3a636f6465"],
|
||||
&|v| { *v == "0x000102040506" }
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn update_code_works_with_runtime_genesis_patch() {
|
||||
let chain_spec: ChainSpec<()> = ChainSpec::builder(
|
||||
substrate_test_runtime::wasm_binary_unwrap().into(),
|
||||
Default::default(),
|
||||
)
|
||||
.with_name("TestName")
|
||||
.with_id("test_id")
|
||||
.with_chain_type(ChainType::Local)
|
||||
.with_genesis_config_patch(json!({}))
|
||||
.build();
|
||||
|
||||
let mut chain_spec_json = from_str::<Value>(&chain_spec.as_json(false).unwrap()).unwrap();
|
||||
assert!(update_code_in_json_chain_spec(&mut chain_spec_json, &[0, 1, 2, 4, 5, 6]));
|
||||
|
||||
assert!(json_eval_value_at_key(
|
||||
&chain_spec_json,
|
||||
&mut json_path!["genesis", "runtimeGenesis", "code"],
|
||||
&|v| { *v == "0x000102040506" }
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn generate_from_genesis_is_still_supported() {
|
||||
#[allow(deprecated)]
|
||||
let chain_spec: ChainSpec<substrate_test_runtime::RuntimeGenesisConfig> = ChainSpec::from_genesis(
|
||||
"TestName",
|
||||
"test",
|
||||
ChainType::Local,
|
||||
move || substrate_test_runtime::RuntimeGenesisConfig {
|
||||
babe: substrate_test_runtime::BabeConfig {
|
||||
epoch_config: Some(
|
||||
substrate_test_runtime::TEST_RUNTIME_BABE_EPOCH_CONFIGURATION,
|
||||
),
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
Vec::new(),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Default::default(),
|
||||
&vec![0, 1, 2, 4, 5, 6],
|
||||
);
|
||||
|
||||
let chain_spec_json = from_str::<Value>(&chain_spec.as_json(false).unwrap()).unwrap();
|
||||
assert!(json_eval_value_at_key(
|
||||
&chain_spec_json,
|
||||
&mut json_path!["genesis", "runtimeAndCode", "code"],
|
||||
&|v| { *v == "0x000102040506" }
|
||||
));
|
||||
let chain_spec_json = from_str::<Value>(&chain_spec.as_json(true).unwrap()).unwrap();
|
||||
assert!(json_eval_value_at_key(
|
||||
&chain_spec_json,
|
||||
&mut json_path!["genesis", "raw", "top", "0x3a636f6465"],
|
||||
&|v| { *v == "0x000102040506" }
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,183 @@
|
||||
// This file is part of Substrate.
|
||||
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
//! A helper module for calling the GenesisBuilder API from arbitrary runtime wasm blobs.
|
||||
|
||||
use codec::{Decode, Encode};
|
||||
use sc_executor::{error::Result, WasmExecutor};
|
||||
use serde_json::{from_slice, Value};
|
||||
use sp_core::{
|
||||
storage::Storage,
|
||||
traits::{CallContext, CodeExecutor, Externalities, FetchRuntimeCode, RuntimeCode},
|
||||
};
|
||||
use sp_genesis_builder::Result as BuildResult;
|
||||
use sp_state_machine::BasicExternalities;
|
||||
use std::borrow::Cow;
|
||||
|
||||
/// A utility that facilitates calling the GenesisBuilder API from the runtime wasm code blob.
|
||||
pub struct GenesisConfigBuilderRuntimeCaller<'a> {
|
||||
code: Cow<'a, [u8]>,
|
||||
code_hash: Vec<u8>,
|
||||
executor: WasmExecutor<sp_io::SubstrateHostFunctions>,
|
||||
}
|
||||
|
||||
impl<'a> FetchRuntimeCode for GenesisConfigBuilderRuntimeCaller<'a> {
|
||||
fn fetch_runtime_code(&self) -> Option<Cow<[u8]>> {
|
||||
Some(self.code.as_ref().into())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> GenesisConfigBuilderRuntimeCaller<'a> {
|
||||
/// Creates new instance using the provided code blob.
|
||||
///
|
||||
/// This code is later referred to as `runtime`.
|
||||
pub fn new(code: &'a [u8]) -> Self {
|
||||
GenesisConfigBuilderRuntimeCaller {
|
||||
code: code.into(),
|
||||
code_hash: sp_core::blake2_256(code).to_vec(),
|
||||
executor: WasmExecutor::<sp_io::SubstrateHostFunctions>::builder()
|
||||
.with_allow_missing_host_functions(true)
|
||||
.build(),
|
||||
}
|
||||
}
|
||||
|
||||
fn call(&self, ext: &mut dyn Externalities, method: &str, data: &[u8]) -> Result<Vec<u8>> {
|
||||
self.executor
|
||||
.call(
|
||||
ext,
|
||||
&RuntimeCode { heap_pages: None, code_fetcher: self, hash: self.code_hash.clone() },
|
||||
method,
|
||||
data,
|
||||
false,
|
||||
CallContext::Offchain,
|
||||
)
|
||||
.0
|
||||
}
|
||||
|
||||
/// Returns the default `GenesisConfig` provided by the `runtime`.
|
||||
///
|
||||
/// Calls [`GenesisBuilder::create_default_config`](sp_genesis_builder::GenesisBuilder::create_default_config) in the `runtime`.
|
||||
pub fn get_default_config(&self) -> core::result::Result<Value, String> {
|
||||
let mut t = BasicExternalities::new_empty();
|
||||
let call_result = self
|
||||
.call(&mut t, "GenesisBuilder_create_default_config", &[])
|
||||
.map_err(|e| format!("wasm call error {e}"))?;
|
||||
let default_config = Vec::<u8>::decode(&mut &call_result[..])
|
||||
.map_err(|e| format!("scale codec error: {e}"))?;
|
||||
Ok(from_slice(&default_config[..]).expect("returned value is json. qed."))
|
||||
}
|
||||
|
||||
/// Build the given `GenesisConfig` and returns the genesis state.
|
||||
///
|
||||
/// Calls [`GenesisBuilder::build_config`](sp_genesis_builder::GenesisBuilder::build_config)
|
||||
/// provided by the `runtime`.
|
||||
pub fn get_storage_for_config(&self, config: Value) -> core::result::Result<Storage, String> {
|
||||
let mut ext = BasicExternalities::new_empty();
|
||||
|
||||
let call_result = self
|
||||
.call(&mut ext, "GenesisBuilder_build_config", &config.to_string().encode())
|
||||
.map_err(|e| format!("wasm call error {e}"))?;
|
||||
|
||||
BuildResult::decode(&mut &call_result[..])
|
||||
.map_err(|e| format!("scale codec error: {e}"))??;
|
||||
|
||||
Ok(ext.into_storages())
|
||||
}
|
||||
|
||||
/// Creates the genesis state by patching the default `GenesisConfig` and applying it.
|
||||
///
|
||||
/// This function generates the `GenesisConfig` for the runtime by applying a provided JSON
|
||||
/// patch. The patch modifies the default `GenesisConfig` allowing customization of the specific
|
||||
/// keys. The resulting `GenesisConfig` is then deserialized from the patched JSON
|
||||
/// representation and stored in the storage.
|
||||
///
|
||||
/// If the provided JSON patch is incorrect or the deserialization fails the error will be
|
||||
/// returned.
|
||||
///
|
||||
/// The patching process modifies the default `GenesisConfig` according to the following rules:
|
||||
/// 1. Existing keys in the default configuration will be overridden by the corresponding values
|
||||
/// in the patch.
|
||||
/// 2. If a key exists in the patch but not in the default configuration, it will be added to
|
||||
/// the resulting `GenesisConfig`.
|
||||
/// 3. Keys in the default configuration that have null values in the patch will be removed from
|
||||
/// the resulting `GenesisConfig`. This is helpful for changing enum variant value.
|
||||
///
|
||||
/// Please note that the patch may contain full `GenesisConfig`.
|
||||
pub fn get_storage_for_patch(&self, patch: Value) -> core::result::Result<Storage, String> {
|
||||
let mut config = self.get_default_config()?;
|
||||
crate::json_patch::merge(&mut config, patch);
|
||||
self.get_storage_for_config(config)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use serde_json::{from_str, json};
|
||||
pub use sp_consensus_babe::{AllowedSlots, BabeEpochConfiguration, Slot};
|
||||
|
||||
#[test]
|
||||
fn get_default_config_works() {
|
||||
let config =
|
||||
GenesisConfigBuilderRuntimeCaller::new(substrate_test_runtime::wasm_binary_unwrap())
|
||||
.get_default_config()
|
||||
.unwrap();
|
||||
let expected = r#"{"system":{},"babe":{"authorities":[],"epochConfig":null},"substrateTest":{"authorities":[]},"balances":{"balances":[]}}"#;
|
||||
assert_eq!(from_str::<Value>(expected).unwrap(), config);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_storage_for_patch_works() {
|
||||
let patch = json!({
|
||||
"babe": {
|
||||
"epochConfig": {
|
||||
"c": [
|
||||
69,
|
||||
696
|
||||
],
|
||||
"allowed_slots": "PrimaryAndSecondaryPlainSlots"
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
let storage =
|
||||
GenesisConfigBuilderRuntimeCaller::new(substrate_test_runtime::wasm_binary_unwrap())
|
||||
.get_storage_for_patch(patch)
|
||||
.unwrap();
|
||||
|
||||
//Babe|Authorities
|
||||
let value: Vec<u8> = storage
|
||||
.top
|
||||
.get(
|
||||
&array_bytes::hex2bytes(
|
||||
"1cb6f36e027abb2091cfb5110ab5087fdc6b171b77304263c292cc3ea5ed31ef",
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap()
|
||||
.clone();
|
||||
|
||||
assert_eq!(
|
||||
BabeEpochConfiguration::decode(&mut &value[..]).unwrap(),
|
||||
BabeEpochConfiguration {
|
||||
c: (69, 696),
|
||||
allowed_slots: AllowedSlots::PrimaryAndSecondaryPlainSlots
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
// This file is part of Substrate.
|
||||
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
//! A helper module providing json patching functions.
|
||||
|
||||
use serde_json::Value;
|
||||
|
||||
/// Recursively merges two JSON objects, `a` and `b`, into a single object.
|
||||
///
|
||||
/// If a key exists in both objects, the value from `b` will override the value from `a`.
|
||||
/// If a key exists in `b` with a `null` value, it will be removed from `a`.
|
||||
/// If a key exists only in `b` and not in `a`, it will be added to `a`.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `a` - A mutable reference to the target JSON object to merge into.
|
||||
/// * `b` - The JSON object to merge with `a`.
|
||||
pub fn merge(a: &mut Value, b: Value) {
|
||||
match (a, b) {
|
||||
(Value::Object(a), Value::Object(b)) =>
|
||||
for (k, v) in b {
|
||||
if v.is_null() {
|
||||
a.remove(&k);
|
||||
} else {
|
||||
merge(a.entry(k).or_insert(Value::Null), v);
|
||||
}
|
||||
},
|
||||
(a, b) => *a = b,
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use serde_json::json;
|
||||
|
||||
#[test]
|
||||
fn test1_simple_merge() {
|
||||
let mut j1 = json!({ "a":123 });
|
||||
merge(&mut j1, json!({ "b":256 }));
|
||||
assert_eq!(j1, json!({ "a":123, "b":256 }));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test2_patch_simple_merge_nested() {
|
||||
let mut j1 = json!({
|
||||
"a": {
|
||||
"name": "xxx",
|
||||
"value": 123
|
||||
},
|
||||
"b": { "c" : { "inner_name": "yyy" } }
|
||||
});
|
||||
|
||||
let j2 = json!({
|
||||
"a": {
|
||||
"keys": ["a", "b", "c" ]
|
||||
}
|
||||
});
|
||||
|
||||
merge(&mut j1, j2);
|
||||
assert_eq!(
|
||||
j1,
|
||||
json!({"a":{"keys":["a","b","c"],"name":"xxx","value":123}, "b": { "c" : { "inner_name": "yyy" } }})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test3_patch_overrides_existing_keys() {
|
||||
let mut j1 = json!({
|
||||
"a": {
|
||||
"name": "xxx",
|
||||
"value": 123,
|
||||
"keys": ["d"]
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
let j2 = json!({
|
||||
"a": {
|
||||
"keys": ["a", "b", "c" ]
|
||||
}
|
||||
});
|
||||
|
||||
merge(&mut j1, j2);
|
||||
assert_eq!(j1, json!({"a":{"keys":["a","b","c"],"name":"xxx","value":123}}));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test4_patch_overrides_existing_keys() {
|
||||
let mut j1 = json!({
|
||||
"a": {
|
||||
"name": "xxx",
|
||||
"value": 123,
|
||||
"b" : {
|
||||
"inner_name": "yyy"
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let j2 = json!({
|
||||
"a": {
|
||||
"name": "new_name",
|
||||
"b" : {
|
||||
"inner_name": "inner_new_name"
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
merge(&mut j1, j2);
|
||||
assert_eq!(
|
||||
j1,
|
||||
json!({ "a": {"name":"new_name", "value":123, "b" : { "inner_name": "inner_new_name" }} })
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test5_patch_overrides_existing_nested_keys() {
|
||||
let mut j1 = json!({
|
||||
"a": {
|
||||
"name": "xxx",
|
||||
"value": 123,
|
||||
"b": {
|
||||
"c": {
|
||||
"d": {
|
||||
"name": "yyy",
|
||||
"value": 256
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
let j2 = json!({
|
||||
"a": {
|
||||
"value": 456,
|
||||
"b": {
|
||||
"c": {
|
||||
"d": {
|
||||
"name": "new_name"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
merge(&mut j1, j2);
|
||||
assert_eq!(
|
||||
j1,
|
||||
json!({ "a": {"name":"xxx", "value":456, "b": { "c": { "d": { "name": "new_name", "value": 256 }}}}})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test6_patch_removes_keys_if_null() {
|
||||
let mut j1 = json!({
|
||||
"a": {
|
||||
"name": "xxx",
|
||||
"value": 123,
|
||||
"enum_variant_1": {
|
||||
"name": "yyy",
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
let j2 = json!({
|
||||
"a": {
|
||||
"value": 456,
|
||||
"enum_variant_1": null,
|
||||
"enum_variant_2": 32,
|
||||
}
|
||||
});
|
||||
|
||||
merge(&mut j1, j2);
|
||||
assert_eq!(j1, json!({ "a": {"name":"xxx", "value":456, "enum_variant_2": 32 }}));
|
||||
}
|
||||
}
|
||||
@@ -16,38 +16,253 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
//! Substrate chain configurations.
|
||||
//! This crate includes structs and utilities for defining configuration files (known as chain
|
||||
//! specification) for both runtime and node.
|
||||
//!
|
||||
//! This crate contains structs and utilities to declare
|
||||
//! a runtime-specific configuration file (a.k.a chain spec).
|
||||
//! # Intro: Chain Specification
|
||||
//!
|
||||
//! Basic chain spec type containing all required parameters is
|
||||
//! [`GenericChainSpec`]. It can be extended with
|
||||
//! additional options that contain configuration specific to your chain.
|
||||
//! Usually the extension is going to be an amalgamate of types exposed
|
||||
//! by Substrate core modules. To allow the core modules to retrieve
|
||||
//! their configuration from your extension you should use `ChainSpecExtension`
|
||||
//! macro exposed by this crate.
|
||||
//! The chain specification comprises parameters and settings that define the properties and an
|
||||
//! initial state of a chain. Users typically interact with the JSON representation of the chain
|
||||
//! spec. Internally, the chain spec is embodied by the [`GenericChainSpec`] struct, and specific
|
||||
//! properties can be accessed using the [`ChainSpec`] trait.
|
||||
//!
|
||||
//! In summary, although not restricted to, the primary role of the chain spec is to provide a list
|
||||
//! of well-known boot nodes for the blockchain network and the means for initializing the genesis
|
||||
//! storage. This initialization is necessary for creating a genesis block upon which subsequent
|
||||
//! blocks are built. When the node is launched for the first time, it reads the chain spec,
|
||||
//! initializes the genesis block, and establishes connections with the boot nodes.
|
||||
//!
|
||||
//! The JSON chain spec is divided into two main logical sections:
|
||||
//! - one section details general chain properties,
|
||||
//! - second explicitly or indirectly defines the genesis storage, which, in turn, determines the
|
||||
//! genesis hash of the chain,
|
||||
//!
|
||||
//! The chain specification consists of the following fields:
|
||||
//!
|
||||
//! <table>
|
||||
//! <thead>
|
||||
//! <tr>
|
||||
//! <th>Chain spec key</th>
|
||||
//! <th>Description</th>
|
||||
//! </tr>
|
||||
//! </thead>
|
||||
//! <tbody>
|
||||
//! <tr>
|
||||
//! <td>name</td>
|
||||
//! <td>The human readable name of the chain.</td>
|
||||
//! </tr>
|
||||
//! <tr>
|
||||
//! <td>id</td>
|
||||
//! <td>The id of the chain.</td>
|
||||
//! </tr>
|
||||
//! <tr>
|
||||
//! <td>chainType</td>
|
||||
//! <td>The chain type of this chain
|
||||
//! (refer to
|
||||
//! <a href="enum.ChainType.html" title="enum sc_chain_spec::ChainType">
|
||||
//! <code>ChainType</code>
|
||||
//! </a>).
|
||||
//! </td>
|
||||
//! </tr>
|
||||
//! <tr>
|
||||
//! <td>bootNodes</td>
|
||||
//! <td>A list of
|
||||
//! <a href="https://github.com/multiformats/multiaddr">multi addresses</a>
|
||||
//! that belong to boot nodes of the chain.</td>
|
||||
//! </tr>
|
||||
//! <tr>
|
||||
//! <td>telemetryEndpoints</td>
|
||||
//! <td>Optional list of <code>multi address, verbosity</code> of telemetry endpoints. The
|
||||
//! verbosity goes from 0 to 9. With 0 being the mode with the lowest verbosity.</td>
|
||||
//! </tr>
|
||||
//! <tr>
|
||||
//! <td>protocolId</td>
|
||||
//! <td>Optional networking protocol id that identifies the chain.</td>
|
||||
//! </tr>
|
||||
//! <tr>
|
||||
//! <td>forkId</td>
|
||||
//! <td>Optional fork id. Should most likely be left empty. Can be used to signal a fork on
|
||||
//! the network level when two chains have the same genesis hash.</td>
|
||||
//! </tr>
|
||||
//! <tr>
|
||||
//! <td>properties</td>
|
||||
//! <td>Custom properties. Shall be provided in the form of
|
||||
//! <code>key</code>-<code>value</code> json object.
|
||||
//! </td>
|
||||
//! </tr>
|
||||
//! <tr>
|
||||
//! <td>consensusEngine</td>
|
||||
//! <td>Deprecated field. Should be ignored.</td>
|
||||
//! </tr>
|
||||
//! <tr>
|
||||
//! <td>codeSubstitutes</td>
|
||||
//! <td>Optional map of <code>block_number</code> to <code>wasm_code</code>. More details in
|
||||
//! material to follow.</td>
|
||||
//! </tr>
|
||||
//! <tr>
|
||||
//! <td>genesis</td>
|
||||
//! <td>Defines the initial state of the runtime. More details in material to follow.</td>
|
||||
//! </tr>
|
||||
//! </tbody>
|
||||
//! </table>
|
||||
//!
|
||||
//! # `genesis`: Initial Runtime State
|
||||
//!
|
||||
//! All nodes in the network must build subsequent blocks upon exactly the same genesis block.
|
||||
//!
|
||||
//! The information configured in the `genesis` section of a chain specification is used to build
|
||||
//! the genesis storage, which is essential for creating the genesis block, since the block header
|
||||
//! includes the storage root hash.
|
||||
//!
|
||||
//! The `genesis` key of the chain specification definition describes the
|
||||
//! initial state of the runtime. For example, it may contain:
|
||||
//! - an initial list of funded accounts,
|
||||
//! - the administrative account that controls the sudo key,
|
||||
//! - an initial authorities set for consensus, etc.
|
||||
//!
|
||||
//! As the compiled WASM blob of the runtime code is stored in the chain's state, the initial
|
||||
//! runtime must also be provided within the chain specification.
|
||||
//!
|
||||
//! In essence, the most important formats of genesis initial state are:
|
||||
//!
|
||||
//! <table>
|
||||
//! <thead>
|
||||
//! <tr>
|
||||
//! <th>Format</th>
|
||||
//! <th>Description</th>
|
||||
//! </tr>
|
||||
//! </thead>
|
||||
//! <tbody>
|
||||
//! <tr>
|
||||
//! <td>
|
||||
//! <code>runtime / full config</code>
|
||||
//! </td>
|
||||
//! <td>A JSON object that provides an explicit and comprehensive representation of the
|
||||
//! <code>RuntimeGenesisConfig</code> struct, which is generated by <a
|
||||
//! href="../frame_support_procedural/macro.construct_runtime.html"
|
||||
//! ><code>frame::runtime::prelude::construct_runtime</code></a> macro (<a
|
||||
//! href="../substrate_test_runtime/struct.RuntimeGenesisConfig.html#"
|
||||
//! >example of generated struct</a>). Must contain all the keys of
|
||||
//! the genesis config, no defaults will be used.
|
||||
//!
|
||||
//! This format explicitly provides the code of the runtime.
|
||||
//! </td></tr>
|
||||
//! <tr>
|
||||
//! <td>
|
||||
//! <code>patch</code>
|
||||
//! </td>
|
||||
//! <td>A JSON object that offers a partial representation of the
|
||||
//! <code>RuntimeGenesisConfig</code> provided by the runtime. It contains a patch, which is
|
||||
//! essentially a list of key-value pairs to customize in the default runtime's
|
||||
//! <code>RuntimeGenesisConfig</code>.
|
||||
//! This format explicitly provides the code of the runtime.
|
||||
//! </td></tr>
|
||||
//! <tr>
|
||||
//! <td>
|
||||
//! <code>raw</code>
|
||||
//! </td>
|
||||
//! <td>A JSON object with two fields: <code>top</code> and <code>children_default</code>.
|
||||
//! Each field is a map of <code>key => value</code> pairs representing entries in a genesis storage
|
||||
//! trie. The runtime code is one of such entries.</td>
|
||||
//! </tr>
|
||||
//! </tbody>
|
||||
//! </table>
|
||||
//!
|
||||
//! For production or long-lasting blockchains, using the `raw` format in the chain specification is
|
||||
//! recommended. Only the `raw` format guarantees that storage root hash will remain unchanged when
|
||||
//! the `RuntimeGenesisConfig` format changes due to software upgrade.
|
||||
//!
|
||||
//! JSON examples in the [following section](#json-chain-specification-example) illustrate the `raw`
|
||||
//! `patch` and full genesis fields.
|
||||
//!
|
||||
//! # From Initial State to Raw Genesis.
|
||||
//!
|
||||
//! To generate a raw genesis storage from the JSON representation of the runtime genesis config,
|
||||
//! the node needs to interact with the runtime.
|
||||
//!
|
||||
//! This interaction involves passing the runtime genesis config JSON blob to the runtime using the
|
||||
//! [`sp_genesis_builder::GenesisBuilder::build_config`] function. During this operation, the
|
||||
//! runtime converts the JSON representation of the genesis config into [`sp_io::storage`] items. It
|
||||
//! is a crucial step for computing the storage root hash, which is a key component in determining
|
||||
//! the genesis hash.
|
||||
//!
|
||||
//! Consequently, the runtime must support the [`sp_genesis_builder::GenesisBuilder`] API to
|
||||
//! utilize either `patch` or `full` formats.
|
||||
//!
|
||||
//! This entire process is encapsulated within the implementation of the [`BuildStorage`] trait,
|
||||
//! which can be accessed through the [`ChainSpec::as_storage_builder`] method. There is an
|
||||
//! intermediate internal helper that facilitates this interaction,
|
||||
//! [`GenesisConfigBuilderRuntimeCaller`], which serves as a straightforward wrapper for
|
||||
//! [`sc_executor::WasmExecutor`].
|
||||
//!
|
||||
//! In case of `raw` genesis state the node does not interact with the runtime regarding the
|
||||
//! computation of initial state.
|
||||
//!
|
||||
//! The plain and `raw` chain specification JSON blobs can be found in
|
||||
//! [JSON examples](#json-chain-specification-example) section.
|
||||
//!
|
||||
//! # Optional Code Mapping
|
||||
//!
|
||||
//! Optional map of `block_number` to `wasm_code`.
|
||||
//!
|
||||
//! The given `wasm_code` will be used to substitute the on-chain wasm code starting with the
|
||||
//! given block number until the `spec_version` on-chain changes. The given `wasm_code` should
|
||||
//! be as close as possible to the on-chain wasm code. A substitute should be used to fix a bug
|
||||
//! that cannot be fixed with a runtime upgrade, if for example the runtime is constantly
|
||||
//! panicking. Introducing new runtime APIs isn't supported, because the node
|
||||
//! will read the runtime version from the on-chain wasm code.
|
||||
//!
|
||||
//! Use this functionality only when there is no other way around it, and only patch the problematic
|
||||
//! bug; the rest should be done with an on-chain runtime upgrade.
|
||||
//!
|
||||
//! # Building a Chain Specification
|
||||
//!
|
||||
//! The [`ChainSpecBuilder`] should be used to create an instance of a chain specification. Its API
|
||||
//! allows configuration of all fields of the chain spec. To generate a JSON representation of the
|
||||
//! specification, use [`ChainSpec::as_json`].
|
||||
//!
|
||||
//! The sample code to generate a chain spec is as follows:
|
||||
#![doc = docify::embed!("src/chain_spec.rs", build_chain_spec_with_patch_works)]
|
||||
//! # JSON chain specification example
|
||||
//!
|
||||
//! The following are the plain and `raw` versions of the chain specification JSON files, resulting
|
||||
//! from executing of the above [example](#building-a-chain-specification):
|
||||
//! ```ignore
|
||||
#![doc = include_str!("../res/substrate_test_runtime_from_patch.json")]
|
||||
//! ```
|
||||
//! ```ignore
|
||||
#![doc = include_str!("../res/substrate_test_runtime_from_patch_raw.json")]
|
||||
//! ```
|
||||
//! The following example shows the plain full config version of chain spec:
|
||||
//! ```ignore
|
||||
#![doc = include_str!("../res/substrate_test_runtime_from_config.json")]
|
||||
//! ```
|
||||
//! The [`ChainSpec`] trait represents the API to access values defined in the JSON chain specification.
|
||||
//!
|
||||
//!
|
||||
//! # Custom Chain Spec Extensions
|
||||
//!
|
||||
//! The basic chain spec type containing all required parameters is [`GenericChainSpec`]. It can be
|
||||
//! extended with additional options containing configuration specific to your chain. Usually, the
|
||||
//! extension will be a combination of types exposed by Substrate core modules.
|
||||
//!
|
||||
//! To allow the core modules to retrieve their configuration from your extension, you should use
|
||||
//! `ChainSpecExtension` macro exposed by this crate.
|
||||
//! ```rust
|
||||
//! use std::collections::HashMap;
|
||||
//! use sc_chain_spec::{GenericChainSpec, ChainSpecExtension};
|
||||
//!
|
||||
//! #[derive(Clone, Debug, serde::Serialize, serde::Deserialize, ChainSpecExtension)]
|
||||
//! pub struct MyExtension {
|
||||
//! pub known_blocks: HashMap<u64, String>,
|
||||
//! pub known_blocks: HashMap<u64, String>,
|
||||
//! }
|
||||
//!
|
||||
//! pub type MyChainSpec<G> = GenericChainSpec<G, MyExtension>;
|
||||
//! ```
|
||||
//!
|
||||
//! Some parameters may require different values depending on the
|
||||
//! current blockchain height (a.k.a. forks). You can use `ChainSpecGroup`
|
||||
//! macro and provided [`Forks`](./struct.Forks.html) structure to put
|
||||
//! such parameters to your chain spec.
|
||||
//! This will allow to override a single parameter starting at specific
|
||||
//! block number.
|
||||
//!
|
||||
//! Some parameters may require different values depending on the current blockchain height (a.k.a.
|
||||
//! forks). You can use the [`ChainSpecGroup`](macro@ChainSpecGroup) macro and the provided [`Forks`]
|
||||
//! structure to add such parameters to your chain spec. This will allow overriding a single
|
||||
//! parameter starting at a specific block number.
|
||||
//! ```rust
|
||||
//! use sc_chain_spec::{Forks, ChainSpecGroup, ChainSpecExtension, GenericChainSpec};
|
||||
//!
|
||||
@@ -76,12 +291,9 @@
|
||||
//! /// A chain spec supporting forkable `Extension`.
|
||||
//! pub type MyChainSpec2<G> = GenericChainSpec<G, Forks<BlockNumber, Extension>>;
|
||||
//! ```
|
||||
//!
|
||||
//! It's also possible to have a set of parameters that is allowed to change
|
||||
//! with block numbers (i.e. is forkable), and another set that is not subject to changes.
|
||||
//! This is also possible by declaring an extension that contains `Forks` within it.
|
||||
//!
|
||||
//!
|
||||
//! It's also possible to have a set of parameters that are allowed to change with block numbers
|
||||
//! (i.e., they are forkable), and another set that is not subject to changes. This can also be
|
||||
//! achieved by declaring an extension that contains [`Forks`] within it.
|
||||
//! ```rust
|
||||
//! use serde::{Serialize, Deserialize};
|
||||
//! use sc_chain_spec::{Forks, GenericChainSpec, ChainSpecGroup, ChainSpecExtension};
|
||||
@@ -106,98 +318,26 @@
|
||||
//!
|
||||
//! pub type MyChainSpec<G> = GenericChainSpec<G, Extension>;
|
||||
//! ```
|
||||
//!
|
||||
//! # Substrate chain specification format
|
||||
//!
|
||||
//! The Substrate chain specification is a `json` file that describes the basics of a chain. Most
|
||||
//! importantly it lays out the genesis storage which leads to the genesis hash. The default
|
||||
//! Substrate chain specification format is the following:
|
||||
//!
|
||||
//! ```json
|
||||
//! // The human readable name of the chain.
|
||||
//! "name": "Flaming Fir",
|
||||
//!
|
||||
//! // The id of the chain.
|
||||
//! "id": "flamingfir9",
|
||||
//!
|
||||
//! // The chain type of this chain.
|
||||
//! // Possible values are `Live`, `Development`, `Local`.
|
||||
//! "chainType": "Live",
|
||||
//!
|
||||
//! // A list of multi addresses that belong to boot nodes of the chain.
|
||||
//! "bootNodes": [
|
||||
//! "/dns/0.flamingfir.paritytech.net/tcp/30333/p2p/12D3KooWLK2gMLhWsYJzjW3q35zAs9FDDVqfqVfVuskiGZGRSMvR",
|
||||
//! ],
|
||||
//!
|
||||
//! // Optional list of "multi address, verbosity" of telemetry endpoints.
|
||||
//! // The verbosity goes from `0` to `9`. With `0` being the mode with the lowest verbosity.
|
||||
//! "telemetryEndpoints": [
|
||||
//! [
|
||||
//! "/dns/telemetry.polkadot.io/tcp/443/x-parity-wss/%2Fsubmit%2F",
|
||||
//! 0
|
||||
//! ]
|
||||
//! ],
|
||||
//!
|
||||
//! // Optional networking protocol id that identifies the chain.
|
||||
//! "protocolId": "fir9",
|
||||
//!
|
||||
//! // Optional fork id. Should most likely be left empty.
|
||||
//! // Can be used to signal a fork on the network level when two chains have the
|
||||
//! // same genesis hash.
|
||||
//! "forkId": "random_fork",
|
||||
//!
|
||||
//! // Custom properties.
|
||||
//! "properties": {
|
||||
//! "tokenDecimals": 15,
|
||||
//! "tokenSymbol": "FIR"
|
||||
//! },
|
||||
//!
|
||||
//! // Deprecated field. Should be ignored.
|
||||
//! "consensusEngine": null,
|
||||
//!
|
||||
//! // The genesis declaration of the chain.
|
||||
//! //
|
||||
//! // `runtime`, `raw`, `stateRootHash` denote the type of the genesis declaration.
|
||||
//! //
|
||||
//! // These declarations are in the following formats:
|
||||
//! // - `runtime` is a `json` object that can be parsed by a compatible `GenesisConfig`. This
|
||||
//! // `GenesisConfig` is declared by a runtime and opaque to the node.
|
||||
//! // - `raw` is a `json` object with two fields `top` and `children_default`. Each of these
|
||||
//! // fields is a map of `key => value`. These key/value pairs represent the genesis storage.
|
||||
//! // - `stateRootHash` is a single hex encoded hash that represents the genesis hash. The hash
|
||||
//! // type depends on the hash used by the chain.
|
||||
//! //
|
||||
//! "genesis": { "runtime": {} },
|
||||
//!
|
||||
//! /// Optional map of `block_number` to `wasm_code`.
|
||||
//! ///
|
||||
//! /// The given `wasm_code` will be used to substitute the on-chain wasm code starting with the
|
||||
//! /// given block number until the `spec_version` on-chain changes. The given `wasm_code` should
|
||||
//! /// be as close as possible to the on-chain wasm code. A substitute should be used to fix a bug
|
||||
//! /// that can not be fixed with a runtime upgrade, if for example the runtime is constantly
|
||||
//! /// panicking. Introducing new runtime apis isn't supported, because the node
|
||||
//! /// will read the runtime version from the on-chain wasm code. Use this functionality only when
|
||||
//! /// there is no other way around it and only patch the problematic bug, the rest should be done
|
||||
//! /// with a on-chain runtime upgrade.
|
||||
//! "codeSubstitutes": [],
|
||||
//! ```
|
||||
//!
|
||||
//! See [`ChainSpec`] for a trait representation of the above.
|
||||
//!
|
||||
//! The chain spec can be extended with other fields that are opaque to the default chain spec.
|
||||
//! Specific node implementations will need to be able to deserialize these extensions.
|
||||
|
||||
mod chain_spec;
|
||||
mod extension;
|
||||
mod genesis;
|
||||
mod genesis_block;
|
||||
mod genesis_config_builder;
|
||||
mod json_patch;
|
||||
|
||||
pub use self::{
|
||||
chain_spec::{ChainSpec as GenericChainSpec, NoExtension},
|
||||
chain_spec::{
|
||||
update_code_in_json_chain_spec, ChainSpec as GenericChainSpec, ChainSpecBuilder,
|
||||
NoExtension,
|
||||
},
|
||||
extension::{get_extension, get_extension_mut, Extension, Fork, Forks, GetExtension, Group},
|
||||
genesis::{
|
||||
genesis_block::{
|
||||
construct_genesis_block, resolve_state_version_from_wasm, BuildGenesisBlock,
|
||||
GenesisBlockBuilder,
|
||||
},
|
||||
genesis_config_builder::GenesisConfigBuilderRuntimeCaller,
|
||||
};
|
||||
pub use sc_chain_spec_derive::{ChainSpecExtension, ChainSpecGroup};
|
||||
|
||||
|
||||
@@ -126,18 +126,14 @@ mod tests {
|
||||
}
|
||||
|
||||
fn load_spec(&self, _: &str) -> std::result::Result<Box<dyn ChainSpec>, String> {
|
||||
Ok(Box::new(GenericChainSpec::from_genesis(
|
||||
"test",
|
||||
"test_id",
|
||||
ChainType::Development,
|
||||
|| unimplemented!("Not required in tests"),
|
||||
Vec::new(),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
NoExtension::None,
|
||||
)))
|
||||
Ok(Box::new(
|
||||
GenericChainSpec::<()>::builder(Default::default(), NoExtension::None)
|
||||
.with_name("test")
|
||||
.with_id("test_id")
|
||||
.with_chain_type(ChainType::Development)
|
||||
.with_genesis_config_patch(Default::default())
|
||||
.build(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -251,18 +251,14 @@ mod tests {
|
||||
trie_cache_maximum_size: None,
|
||||
state_pruning: None,
|
||||
blocks_pruning: sc_client_db::BlocksPruning::KeepAll,
|
||||
chain_spec: Box::new(GenericChainSpec::from_genesis(
|
||||
"test",
|
||||
"test_id",
|
||||
ChainType::Development,
|
||||
|| unimplemented!("Not required in tests"),
|
||||
Vec::new(),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
NoExtension::None,
|
||||
)),
|
||||
chain_spec: Box::new(
|
||||
GenericChainSpec::<()>::builder(Default::default(), NoExtension::None)
|
||||
.with_name("test")
|
||||
.with_id("test_id")
|
||||
.with_chain_type(ChainType::Development)
|
||||
.with_genesis_config_patch(Default::default())
|
||||
.build(),
|
||||
),
|
||||
wasm_method: Default::default(),
|
||||
wasm_runtime_overrides: None,
|
||||
rpc_addr: None,
|
||||
|
||||
@@ -724,8 +724,6 @@ pub mod pallet {
|
||||
#[derive(frame_support::DefaultNoBound)]
|
||||
#[pallet::genesis_config]
|
||||
pub struct GenesisConfig<T: Config> {
|
||||
#[serde(with = "sp_core::bytes")]
|
||||
pub code: Vec<u8>,
|
||||
#[serde(skip)]
|
||||
pub _config: sp_std::marker::PhantomData<T>,
|
||||
}
|
||||
@@ -739,7 +737,6 @@ pub mod pallet {
|
||||
<UpgradedToU32RefCount<T>>::put(true);
|
||||
<UpgradedToTripleRefCount<T>>::put(true);
|
||||
|
||||
sp_io::storage::set(well_known_keys::CODE, &self.code);
|
||||
sp_io::storage::set(well_known_keys::EXTRINSIC_INDEX, &0u32.encode());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,8 +141,9 @@
|
||||
//! side features. The corresponding runtime, called [`kitchensink_runtime`] contains all of the
|
||||
//! modules that are provided with `FRAME`. This node and runtime is only used for testing and
|
||||
//! demonstration.
|
||||
//! * [`chain-spec-builder`]: Utility to build more detailed chain-specs for the aforementioned
|
||||
//! node. Other projects typically contain a `build-spec` subcommand that does the same.
|
||||
//! * [`chain-spec-builder`]: Utility to build more detailed [chain-spec][`sc-chain-spec`] for the
|
||||
//! aforementioned node. Other projects typically contain a `build-spec` subcommand that does the
|
||||
//! same.
|
||||
//! * [`node-template`]: a template node that contains a minimal set of features and can act as a
|
||||
//! starting point of a project.
|
||||
//! * [`subkey`]: Substrate's key management utility.
|
||||
@@ -177,6 +178,8 @@
|
||||
//!
|
||||
//! Additional noteworthy crates within substrate:
|
||||
//!
|
||||
//! - Chain specification of a Substrate node:
|
||||
//! - [`sc-chain-spec`]
|
||||
//! - RPC APIs of a Substrate node: [`sc-rpc-api`]/[`sc-rpc`]
|
||||
//! - CLI Options of a Substrate node: [`sc-cli`]
|
||||
//! - All of the consensus related crates provided by Substrate:
|
||||
@@ -217,6 +220,7 @@
|
||||
//! [`sp-api`]: ../sp_api/index.html
|
||||
//! [`sp-api`]: ../sp_api/index.html
|
||||
//! [`sc-client-db`]: ../sc_client_db/index.html
|
||||
//! [`sc-chain-spec`]: ../sc_chain_spec/index.html
|
||||
//! [`sc-network`]: ../sc_network/index.html
|
||||
//! [`sc-rpc-api`]: ../sc_rpc_api/index.html
|
||||
//! [`sc-rpc`]: ../sc_rpc/index.html
|
||||
|
||||
@@ -48,8 +48,6 @@ sp-externalities = { path = "../../primitives/externalities", default-features =
|
||||
# 3rd party
|
||||
array-bytes = { version = "6.1", optional = true }
|
||||
log = { version = "0.4.17", default-features = false }
|
||||
serde = { version = "1.0.188", features = ["alloc", "derive"], default-features = false }
|
||||
serde_json = { version = "1.0.107", default-features = false, features = ["alloc"] }
|
||||
|
||||
[dev-dependencies]
|
||||
futures = "0.3.21"
|
||||
@@ -60,6 +58,8 @@ sp-consensus = { path = "../../primitives/consensus/common" }
|
||||
substrate-test-runtime-client = { path = "client" }
|
||||
sp-tracing = { path = "../../primitives/tracing" }
|
||||
json-patch = { version = "1.0.0", default-features = false }
|
||||
serde = { version = "1.0.188", features = ["alloc", "derive"], default-features = false }
|
||||
serde_json = { version = "1.0.107", default-features = false, features = ["alloc"] }
|
||||
|
||||
[build-dependencies]
|
||||
substrate-wasm-builder = { path = "../../utils/wasm-builder", optional = true }
|
||||
|
||||
+1
-3
@@ -1,7 +1,5 @@
|
||||
{
|
||||
"system": {
|
||||
"code": "0x52"
|
||||
},
|
||||
"system": {},
|
||||
"babe": {
|
||||
"authorities": [
|
||||
[
|
||||
+1
-3
@@ -1,7 +1,5 @@
|
||||
{
|
||||
"system": {
|
||||
"code": "0x52"
|
||||
},
|
||||
"system": {},
|
||||
"babe": {
|
||||
"epochConfig": {
|
||||
"c": [
|
||||
+1
-3
@@ -1,7 +1,5 @@
|
||||
{
|
||||
"system": {
|
||||
"code": "0x52"
|
||||
},
|
||||
"system": {},
|
||||
"babe": {
|
||||
"renamed_authorities": [
|
||||
[
|
||||
@@ -0,0 +1,113 @@
|
||||
{
|
||||
"system": {},
|
||||
"babex": {
|
||||
"authorities": [
|
||||
[
|
||||
"5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY",
|
||||
1
|
||||
],
|
||||
[
|
||||
"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",
|
||||
1
|
||||
],
|
||||
[
|
||||
"5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y",
|
||||
1
|
||||
]
|
||||
],
|
||||
"epochConfig": {
|
||||
"c": [
|
||||
3,
|
||||
10
|
||||
],
|
||||
"allowed_slots": "PrimaryAndSecondaryPlainSlots"
|
||||
}
|
||||
},
|
||||
"substrateTest": {
|
||||
"authorities": [
|
||||
"5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY",
|
||||
"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",
|
||||
"5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y"
|
||||
]
|
||||
},
|
||||
"balances": {
|
||||
"balances": [
|
||||
[
|
||||
"5D34dL5prEUaGNQtPPZ3yN5Y6BnkfXunKXXz6fo7ZJbLwRRH",
|
||||
100000000000000000
|
||||
],
|
||||
[
|
||||
"5GBNeWRhZc2jXu7D55rBimKYDk8PGk8itRYFTPfC8RJLKG5o",
|
||||
100000000000000000
|
||||
],
|
||||
[
|
||||
"5Dfis6XL8J2P6JHUnUtArnFWndn62SydeP8ee8sG2ky9nfm9",
|
||||
100000000000000000
|
||||
],
|
||||
[
|
||||
"5F4H97f7nQovyrbiq4ZetaaviNwThSVcFobcA5aGab6167dK",
|
||||
100000000000000000
|
||||
],
|
||||
[
|
||||
"5DiDShBWa1fQx6gLzpf3SFBhMinCoyvHM1BWjPNsmXS8hkrW",
|
||||
100000000000000000
|
||||
],
|
||||
[
|
||||
"5EFb84yH9tpcFuiKUcsmdoF7xeeY3ajG1ZLQimxQoFt9HMKR",
|
||||
100000000000000000
|
||||
],
|
||||
[
|
||||
"5DZLHESsfGrJ5YzT3HuRPXsSNb589xQ4Unubh1mYLodzKdVY",
|
||||
100000000000000000
|
||||
],
|
||||
[
|
||||
"5GHJzqvG6tXnngCpG7B12qjUvbo5e4e9z8Xjidk3CQZHxTPZ",
|
||||
100000000000000000
|
||||
],
|
||||
[
|
||||
"5CUnSsgAyLND3bxxnfNhgWXSe9Wn676JzLpGLgyJv858qhoX",
|
||||
100000000000000000
|
||||
],
|
||||
[
|
||||
"5CVKn7HAZW1Ky4r7Vkgsr7VEW88C2sHgUNDiwHY9Ct2hjU8q",
|
||||
100000000000000000
|
||||
],
|
||||
[
|
||||
"5H673aukQ4PeDe1U2nuv1bi32xDEziimh3PZz7hDdYUB7TNz",
|
||||
100000000000000000
|
||||
],
|
||||
[
|
||||
"5HTe9L15LJryjUAt1jZXZCBPnzbbGnpvFwbjE3NwCWaAqovf",
|
||||
100000000000000000
|
||||
],
|
||||
[
|
||||
"5D7LFzGpMwHPyDBavkRbWSKWTtJhCaPPZ379wWLT23bJwXJz",
|
||||
100000000000000000
|
||||
],
|
||||
[
|
||||
"5CLepMARnEgtVR1EkUuJVUvKh97gzergpSxUU3yKGx1v6EwC",
|
||||
100000000000000000
|
||||
],
|
||||
[
|
||||
"5Chb2UhfvZpmjjEziHbFbotM4quX32ZscRV6QJBt1rUKzz51",
|
||||
100000000000000000
|
||||
],
|
||||
[
|
||||
"5HmRp3i3ZZk7xsAvbi8hyXVP6whSMnBJGebVC4FsiZVhx52e",
|
||||
100000000000000000
|
||||
],
|
||||
[
|
||||
"5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY",
|
||||
100000000000000000
|
||||
],
|
||||
[
|
||||
"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",
|
||||
100000000000000000
|
||||
],
|
||||
[
|
||||
"5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y",
|
||||
100000000000000000
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -117,10 +117,7 @@ impl GenesisStorageBuilder {
|
||||
.collect();
|
||||
|
||||
RuntimeGenesisConfig {
|
||||
system: frame_system::GenesisConfig {
|
||||
code: self.wasm_code.clone().unwrap_or(wasm_binary_unwrap().to_vec()),
|
||||
..Default::default()
|
||||
},
|
||||
system: Default::default(),
|
||||
babe: pallet_babe::GenesisConfig {
|
||||
authorities: authorities_sr25519
|
||||
.clone()
|
||||
@@ -149,6 +146,11 @@ impl GenesisStorageBuilder {
|
||||
storage.top.insert(well_known_keys::HEAP_PAGES.into(), heap_pages.encode());
|
||||
}
|
||||
|
||||
storage.top.insert(
|
||||
well_known_keys::CODE.into(),
|
||||
self.wasm_code.clone().unwrap_or(wasm_binary_unwrap().to_vec()),
|
||||
);
|
||||
|
||||
storage.top.extend(self.extra_storage.top.clone());
|
||||
storage.children_default.extend(self.extra_storage.children_default.clone());
|
||||
|
||||
|
||||
@@ -464,11 +464,10 @@ impl_opaque_keys! {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) const TEST_RUNTIME_BABE_EPOCH_CONFIGURATION: BabeEpochConfiguration =
|
||||
BabeEpochConfiguration {
|
||||
c: (3, 10),
|
||||
allowed_slots: AllowedSlots::PrimaryAndSecondaryPlainSlots,
|
||||
};
|
||||
pub const TEST_RUNTIME_BABE_EPOCH_CONFIGURATION: BabeEpochConfiguration = BabeEpochConfiguration {
|
||||
c: (3, 10),
|
||||
allowed_slots: AllowedSlots::PrimaryAndSecondaryPlainSlots,
|
||||
};
|
||||
|
||||
impl_runtime_apis! {
|
||||
impl sp_api::Core<Block> for Runtime {
|
||||
@@ -1237,7 +1236,7 @@ mod tests {
|
||||
#[test]
|
||||
fn build_minimal_genesis_config_works() {
|
||||
sp_tracing::try_init_simple();
|
||||
let default_minimal_json = r#"{"system":{"code":"0x"},"babe":{"authorities":[],"epochConfig":{"c": [ 3, 10 ],"allowed_slots":"PrimaryAndSecondaryPlainSlots"}},"substrateTest":{"authorities":[]},"balances":{"balances":[]}}"#;
|
||||
let default_minimal_json = r#"{"system":{},"babe":{"authorities":[],"epochConfig":{"c": [ 3, 10 ],"allowed_slots":"PrimaryAndSecondaryPlainSlots"}},"substrateTest":{"authorities":[]},"balances":{"balances":[]}}"#;
|
||||
let mut t = BasicExternalities::new_empty();
|
||||
|
||||
executor_call(&mut t, "GenesisBuilder_build_config", &default_minimal_json.encode())
|
||||
@@ -1264,8 +1263,6 @@ mod tests {
|
||||
|
||||
// System|LastRuntimeUpgrade
|
||||
"26aa394eea5630e07c48ae0c9558cef7f9cce9c888469bb1a0dceaa129672ef8",
|
||||
// :code
|
||||
"3a636f6465",
|
||||
// :extrinsic_index
|
||||
"3a65787472696e7369635f696e646578",
|
||||
// Balances|TotalIssuance
|
||||
@@ -1294,35 +1291,55 @@ mod tests {
|
||||
let r = Vec::<u8>::decode(&mut &r[..]).unwrap();
|
||||
let json = String::from_utf8(r.into()).expect("returned value is json. qed.");
|
||||
|
||||
let expected = r#"{"system":{"code":"0x"},"babe":{"authorities":[],"epochConfig":null},"substrateTest":{"authorities":[]},"balances":{"balances":[]}}"#;
|
||||
let expected = r#"{"system":{},"babe":{"authorities":[],"epochConfig":null},"substrateTest":{"authorities":[]},"balances":{"balances":[]}}"#;
|
||||
assert_eq!(expected.to_string(), json);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn build_config_from_json_works() {
|
||||
sp_tracing::try_init_simple();
|
||||
let j = include_str!("test_json/default_genesis_config.json");
|
||||
let j = include_str!("../res/default_genesis_config.json");
|
||||
|
||||
let mut t = BasicExternalities::new_empty();
|
||||
let r = executor_call(&mut t, "GenesisBuilder_build_config", &j.encode()).unwrap();
|
||||
let r = BuildResult::decode(&mut &r[..]);
|
||||
assert!(r.is_ok());
|
||||
|
||||
let keys = t.into_storages().top.keys().cloned().map(hex).collect::<Vec<String>>();
|
||||
let mut keys = t.into_storages().top.keys().cloned().map(hex).collect::<Vec<String>>();
|
||||
|
||||
// following keys are not placed during `<RuntimeGenesisConfig as GenesisBuild>::build`
|
||||
// process, add them `keys` to assert against known keys.
|
||||
keys.push(hex(b":code"));
|
||||
keys.sort();
|
||||
|
||||
assert_eq!(keys, storage_key_generator::get_expected_storage_hashed_keys(false));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn build_config_from_invalid_json_fails() {
|
||||
sp_tracing::try_init_simple();
|
||||
let j = include_str!("test_json/default_genesis_config_invalid.json");
|
||||
let j = include_str!("../res/default_genesis_config_invalid.json");
|
||||
let mut t = BasicExternalities::new_empty();
|
||||
let r = executor_call(&mut t, "GenesisBuilder_build_config", &j.encode()).unwrap();
|
||||
let r = BuildResult::decode(&mut &r[..]).unwrap();
|
||||
log::info!("result: {:#?}", r);
|
||||
assert_eq!(r, Err(
|
||||
sp_runtime::RuntimeString::Owned(
|
||||
"Invalid JSON blob: unknown field `renamed_authorities`, expected `authorities` or `epochConfig` at line 6 column 25".to_string(),
|
||||
"Invalid JSON blob: unknown field `renamed_authorities`, expected `authorities` or `epochConfig` at line 4 column 25".to_string(),
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn build_config_from_invalid_json_fails_2() {
|
||||
sp_tracing::try_init_simple();
|
||||
let j = include_str!("../res/default_genesis_config_invalid_2.json");
|
||||
let mut t = BasicExternalities::new_empty();
|
||||
let r = executor_call(&mut t, "GenesisBuilder_build_config", &j.encode()).unwrap();
|
||||
let r = BuildResult::decode(&mut &r[..]).unwrap();
|
||||
assert_eq!(r, Err(
|
||||
sp_runtime::RuntimeString::Owned(
|
||||
"Invalid JSON blob: unknown field `babex`, expected one of `system`, `babe`, `substrateTest`, `balances` at line 3 column 9".to_string(),
|
||||
))
|
||||
);
|
||||
}
|
||||
@@ -1330,7 +1347,7 @@ mod tests {
|
||||
#[test]
|
||||
fn build_config_from_incomplete_json_fails() {
|
||||
sp_tracing::try_init_simple();
|
||||
let j = include_str!("test_json/default_genesis_config_incomplete.json");
|
||||
let j = include_str!("../res/default_genesis_config_incomplete.json");
|
||||
|
||||
let mut t = BasicExternalities::new_empty();
|
||||
let r = executor_call(&mut t, "GenesisBuilder_build_config", &j.encode()).unwrap();
|
||||
@@ -1339,7 +1356,7 @@ mod tests {
|
||||
assert_eq!(
|
||||
r,
|
||||
Err(sp_runtime::RuntimeString::Owned(
|
||||
"Invalid JSON blob: missing field `authorities` at line 13 column 3"
|
||||
"Invalid JSON blob: missing field `authorities` at line 11 column 3"
|
||||
.to_string()
|
||||
))
|
||||
);
|
||||
@@ -1438,10 +1455,6 @@ mod tests {
|
||||
);
|
||||
assert_eq!(u64::decode(&mut &value[..]).unwrap(), 0);
|
||||
|
||||
// :code
|
||||
let value: Vec<u8> = get_from_storage("3a636f6465");
|
||||
assert!(Vec::<u8>::decode(&mut &value[..]).is_err());
|
||||
|
||||
//System|ParentHash
|
||||
let value: Vec<u8> = get_from_storage(
|
||||
"26aa394eea5630e07c48ae0c9558cef78a42f33323cb5ced3b44dd825fda9fcc",
|
||||
|
||||
Reference in New Issue
Block a user