diff --git a/.gitlab/pipeline/test.yml b/.gitlab/pipeline/test.yml
index 79ef9070dba9..9c3fa7701c8f 100644
--- a/.gitlab/pipeline/test.yml
+++ b/.gitlab/pipeline/test.yml
@@ -522,4 +522,4 @@ test-syscalls:
- if [[ "$CI_JOB_STATUS" == "failed" ]]; then
printf "The x86_64 syscalls used by the worker binaries have changed. Please review if this is expected and update polkadot/scripts/list-syscalls/*-worker-syscalls as needed.\n";
fi
- allow_failure: true # TODO: remove this once we have an idea how often the syscall lists will change
+ allow_failure: false # this rarely triggers in practice
diff --git a/Cargo.lock b/Cargo.lock
index 3fbede968bc6..8a3f8e05fbcf 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -10795,6 +10795,7 @@ dependencies = [
name = "pallet-safe-mode"
version = "4.0.0-dev"
dependencies = [
+ "docify",
"frame-benchmarking",
"frame-support",
"frame-system",
@@ -11198,6 +11199,7 @@ dependencies = [
name = "pallet-tx-pause"
version = "4.0.0-dev"
dependencies = [
+ "docify",
"frame-benchmarking",
"frame-support",
"frame-system",
diff --git a/cumulus/polkadot-parachain/src/chain_spec/asset_hubs.rs b/cumulus/polkadot-parachain/src/chain_spec/asset_hubs.rs
index a8d3d2975ada..2988d6af0d13 100644
--- a/cumulus/polkadot-parachain/src/chain_spec/asset_hubs.rs
+++ b/cumulus/polkadot-parachain/src/chain_spec/asset_hubs.rs
@@ -15,7 +15,8 @@
// along with Cumulus. If not, see .
use crate::chain_spec::{
- get_account_id_from_seed, get_collator_keys_from_seed, Extensions, SAFE_XCM_VERSION,
+ get_account_id_from_seed, get_collator_keys_from_seed, Extensions, GenericChainSpec,
+ SAFE_XCM_VERSION,
};
use cumulus_primitives_core::ParaId;
use hex_literal::hex;
@@ -23,16 +24,6 @@ use parachains_common::{AccountId, AssetHubPolkadotAuraId, AuraId, Balance as As
use sc_service::ChainType;
use sp_core::{crypto::UncheckedInto, sr25519};
-/// Specialized `ChainSpec` for the normal parachain runtime.
-pub type AssetHubPolkadotChainSpec =
- sc_service::GenericChainSpec;
-pub type AssetHubKusamaChainSpec =
- sc_service::GenericChainSpec;
-pub type AssetHubWestendChainSpec =
- sc_service::GenericChainSpec;
-pub type AssetHubRococoChainSpec =
- sc_service::GenericChainSpec;
-
const ASSET_HUB_POLKADOT_ED: AssetHubBalance =
parachains_common::polkadot::currency::EXISTENTIAL_DEPOSIT;
const ASSET_HUB_KUSAMA_ED: AssetHubBalance =
@@ -72,13 +63,13 @@ pub fn asset_hub_westend_session_keys(keys: AuraId) -> asset_hub_westend_runtime
asset_hub_westend_runtime::SessionKeys { aura: keys }
}
-pub fn asset_hub_polkadot_development_config() -> AssetHubPolkadotChainSpec {
+pub fn asset_hub_polkadot_development_config() -> GenericChainSpec {
let mut properties = sc_chain_spec::Properties::new();
properties.insert("ss58Format".into(), 0.into());
properties.insert("tokenSymbol".into(), "DOT".into());
properties.insert("tokenDecimals".into(), 10.into());
- AssetHubPolkadotChainSpec::builder(
+ GenericChainSpec::builder(
asset_hub_polkadot_runtime::WASM_BINARY
.expect("WASM binary was not built, please build it!"),
Extensions { relay_chain: "polkadot-dev".into(), para_id: 1000 },
@@ -104,13 +95,13 @@ pub fn asset_hub_polkadot_development_config() -> AssetHubPolkadotChainSpec {
.build()
}
-pub fn asset_hub_polkadot_local_config() -> AssetHubPolkadotChainSpec {
+pub fn asset_hub_polkadot_local_config() -> GenericChainSpec {
let mut properties = sc_chain_spec::Properties::new();
properties.insert("ss58Format".into(), 0.into());
properties.insert("tokenSymbol".into(), "DOT".into());
properties.insert("tokenDecimals".into(), 10.into());
- AssetHubPolkadotChainSpec::builder(
+ GenericChainSpec::builder(
asset_hub_polkadot_runtime::WASM_BINARY
.expect("WASM binary was not built, please build it!"),
Extensions { relay_chain: "polkadot-local".into(), para_id: 1000 },
@@ -152,13 +143,13 @@ pub fn asset_hub_polkadot_local_config() -> AssetHubPolkadotChainSpec {
}
// Not used for syncing, but just to determine the genesis values set for the upgrade from shell.
-pub fn asset_hub_polkadot_config() -> AssetHubPolkadotChainSpec {
+pub fn asset_hub_polkadot_config() -> GenericChainSpec {
let mut properties = sc_chain_spec::Properties::new();
properties.insert("ss58Format".into(), 0.into());
properties.insert("tokenSymbol".into(), "DOT".into());
properties.insert("tokenDecimals".into(), 10.into());
- AssetHubPolkadotChainSpec::builder(
+ GenericChainSpec::builder(
asset_hub_polkadot_runtime::WASM_BINARY
.expect("WASM binary was not built, please build it!"),
Extensions { relay_chain: "polkadot".into(), para_id: 1000 },
@@ -249,13 +240,13 @@ fn asset_hub_polkadot_genesis(
})
}
-pub fn asset_hub_kusama_development_config() -> AssetHubKusamaChainSpec {
+pub fn asset_hub_kusama_development_config() -> GenericChainSpec {
let mut properties = sc_chain_spec::Properties::new();
properties.insert("ss58Format".into(), 2.into());
properties.insert("tokenSymbol".into(), "KSM".into());
properties.insert("tokenDecimals".into(), 12.into());
- AssetHubKusamaChainSpec::builder(
+ GenericChainSpec::builder(
asset_hub_kusama_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"),
Extensions { relay_chain: "kusama-dev".into(), para_id: 1000 },
)
@@ -280,13 +271,13 @@ pub fn asset_hub_kusama_development_config() -> AssetHubKusamaChainSpec {
.build()
}
-pub fn asset_hub_kusama_local_config() -> AssetHubKusamaChainSpec {
+pub fn asset_hub_kusama_local_config() -> GenericChainSpec {
let mut properties = sc_chain_spec::Properties::new();
properties.insert("ss58Format".into(), 2.into());
properties.insert("tokenSymbol".into(), "KSM".into());
properties.insert("tokenDecimals".into(), 12.into());
- AssetHubKusamaChainSpec::builder(
+ GenericChainSpec::builder(
asset_hub_kusama_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"),
Extensions { relay_chain: "kusama-local".into(), para_id: 1000 },
)
@@ -325,13 +316,13 @@ pub fn asset_hub_kusama_local_config() -> AssetHubKusamaChainSpec {
.build()
}
-pub fn asset_hub_kusama_config() -> AssetHubKusamaChainSpec {
+pub fn asset_hub_kusama_config() -> GenericChainSpec {
let mut properties = sc_chain_spec::Properties::new();
properties.insert("ss58Format".into(), 2.into());
properties.insert("tokenSymbol".into(), "KSM".into());
properties.insert("tokenDecimals".into(), 12.into());
- AssetHubKusamaChainSpec::builder(
+ GenericChainSpec::builder(
asset_hub_kusama_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"),
Extensions { relay_chain: "kusama".into(), para_id: 1000 },
)
@@ -407,12 +398,12 @@ fn asset_hub_kusama_genesis(
})
}
-pub fn asset_hub_westend_development_config() -> AssetHubWestendChainSpec {
+pub fn asset_hub_westend_development_config() -> GenericChainSpec {
let mut properties = sc_chain_spec::Properties::new();
properties.insert("tokenSymbol".into(), "WND".into());
properties.insert("tokenDecimals".into(), 12.into());
- AssetHubWestendChainSpec::builder(
+ GenericChainSpec::builder(
asset_hub_westend_runtime::WASM_BINARY
.expect("WASM binary was not built, please build it!"),
Extensions { relay_chain: "westend".into(), para_id: 1000 },
@@ -439,12 +430,12 @@ pub fn asset_hub_westend_development_config() -> AssetHubWestendChainSpec {
.build()
}
-pub fn asset_hub_westend_local_config() -> AssetHubWestendChainSpec {
+pub fn asset_hub_westend_local_config() -> GenericChainSpec {
let mut properties = sc_chain_spec::Properties::new();
properties.insert("tokenSymbol".into(), "WND".into());
properties.insert("tokenDecimals".into(), 12.into());
- AssetHubWestendChainSpec::builder(
+ GenericChainSpec::builder(
asset_hub_westend_runtime::WASM_BINARY
.expect("WASM binary was not built, please build it!"),
Extensions { relay_chain: "westend-local".into(), para_id: 1000 },
@@ -485,12 +476,12 @@ pub fn asset_hub_westend_local_config() -> AssetHubWestendChainSpec {
.build()
}
-pub fn asset_hub_westend_config() -> AssetHubWestendChainSpec {
+pub fn asset_hub_westend_config() -> GenericChainSpec {
let mut properties = sc_chain_spec::Properties::new();
properties.insert("tokenSymbol".into(), "WND".into());
properties.insert("tokenDecimals".into(), 12.into());
- AssetHubWestendChainSpec::builder(
+ GenericChainSpec::builder(
asset_hub_westend_runtime::WASM_BINARY
.expect("WASM binary was not built, please build it!"),
Extensions { relay_chain: "westend".into(), para_id: 1000 },
@@ -569,7 +560,7 @@ fn asset_hub_westend_genesis(
})
}
-pub fn asset_hub_rococo_development_config() -> AssetHubRococoChainSpec {
+pub fn asset_hub_rococo_development_config() -> GenericChainSpec {
let mut properties = sc_chain_spec::Properties::new();
properties.insert("ss58Format".into(), 42.into());
properties.insert("tokenSymbol".into(), "ROC".into());
@@ -587,8 +578,8 @@ fn asset_hub_rococo_like_development_config(
name: &str,
chain_id: &str,
para_id: u32,
-) -> AssetHubRococoChainSpec {
- AssetHubRococoChainSpec::builder(
+) -> GenericChainSpec {
+ GenericChainSpec::builder(
asset_hub_rococo_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"),
Extensions { relay_chain: "rococo-dev".into(), para_id },
)
@@ -614,7 +605,7 @@ fn asset_hub_rococo_like_development_config(
.build()
}
-pub fn asset_hub_rococo_local_config() -> AssetHubRococoChainSpec {
+pub fn asset_hub_rococo_local_config() -> GenericChainSpec {
let mut properties = sc_chain_spec::Properties::new();
properties.insert("ss58Format".into(), 42.into());
properties.insert("tokenSymbol".into(), "ROC".into());
@@ -632,8 +623,8 @@ fn asset_hub_rococo_like_local_config(
name: &str,
chain_id: &str,
para_id: u32,
-) -> AssetHubRococoChainSpec {
- AssetHubRococoChainSpec::builder(
+) -> GenericChainSpec {
+ GenericChainSpec::builder(
asset_hub_rococo_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"),
Extensions { relay_chain: "rococo-local".into(), para_id },
)
@@ -673,12 +664,12 @@ fn asset_hub_rococo_like_local_config(
.build()
}
-pub fn asset_hub_rococo_genesis_config() -> AssetHubRococoChainSpec {
+pub fn asset_hub_rococo_genesis_config() -> GenericChainSpec {
let mut properties = sc_chain_spec::Properties::new();
properties.insert("tokenSymbol".into(), "ROC".into());
properties.insert("tokenDecimals".into(), 12.into());
let para_id = 1000;
- AssetHubRococoChainSpec::builder(
+ GenericChainSpec::builder(
asset_hub_rococo_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"),
Extensions { relay_chain: "rococo".into(), para_id },
)
diff --git a/cumulus/polkadot-parachain/src/chain_spec/bridge_hubs.rs b/cumulus/polkadot-parachain/src/chain_spec/bridge_hubs.rs
index eb253908f5fc..377ceb20e1e0 100644
--- a/cumulus/polkadot-parachain/src/chain_spec/bridge_hubs.rs
+++ b/cumulus/polkadot-parachain/src/chain_spec/bridge_hubs.rs
@@ -14,12 +14,12 @@
// You should have received a copy of the GNU General Public License
// along with Cumulus. If not, see .
-use crate::chain_spec::{get_account_id_from_seed, get_collator_keys_from_seed};
+use crate::chain_spec::{get_account_id_from_seed, get_collator_keys_from_seed, GenericChainSpec};
use cumulus_primitives_core::ParaId;
use parachains_common::Balance as BridgeHubBalance;
use sc_chain_spec::ChainSpec;
use sp_core::sr25519;
-use std::{path::PathBuf, str::FromStr};
+use std::str::FromStr;
/// Collects all supported BridgeHub configurations
#[derive(Debug, PartialEq)]
@@ -71,33 +71,11 @@ impl FromStr for BridgeHubRuntimeType {
impl BridgeHubRuntimeType {
pub const ID_PREFIX: &'static str = "bridge-hub";
- pub fn chain_spec_from_json_file(&self, path: PathBuf) -> Result, String> {
- match self {
- BridgeHubRuntimeType::Polkadot |
- BridgeHubRuntimeType::PolkadotLocal |
- BridgeHubRuntimeType::PolkadotDevelopment =>
- Ok(Box::new(polkadot::BridgeHubChainSpec::from_json_file(path)?)),
- BridgeHubRuntimeType::Kusama |
- BridgeHubRuntimeType::KusamaLocal |
- BridgeHubRuntimeType::KusamaDevelopment =>
- Ok(Box::new(kusama::BridgeHubChainSpec::from_json_file(path)?)),
- BridgeHubRuntimeType::Westend |
- BridgeHubRuntimeType::WestendLocal |
- BridgeHubRuntimeType::WestendDevelopment =>
- Ok(Box::new(westend::BridgeHubChainSpec::from_json_file(path)?)),
- BridgeHubRuntimeType::Rococo |
- BridgeHubRuntimeType::RococoLocal |
- BridgeHubRuntimeType::RococoDevelopment =>
- Ok(Box::new(rococo::BridgeHubChainSpec::from_json_file(path)?)),
- }
- }
-
pub fn load_config(&self) -> Result, String> {
match self {
- BridgeHubRuntimeType::Polkadot =>
- Ok(Box::new(polkadot::BridgeHubChainSpec::from_json_bytes(
- &include_bytes!("../../chain-specs/bridge-hub-polkadot.json")[..],
- )?)),
+ BridgeHubRuntimeType::Polkadot => Ok(Box::new(GenericChainSpec::from_json_bytes(
+ &include_bytes!("../../chain-specs/bridge-hub-polkadot.json")[..],
+ )?)),
BridgeHubRuntimeType::PolkadotLocal => Ok(Box::new(polkadot::local_config(
polkadot::BRIDGE_HUB_POLKADOT_LOCAL,
"Polkadot BridgeHub Local",
@@ -110,10 +88,9 @@ impl BridgeHubRuntimeType {
"polkadot-dev",
ParaId::new(1002),
))),
- BridgeHubRuntimeType::Kusama =>
- Ok(Box::new(kusama::BridgeHubChainSpec::from_json_bytes(
- &include_bytes!("../../chain-specs/bridge-hub-kusama.json")[..],
- )?)),
+ BridgeHubRuntimeType::Kusama => Ok(Box::new(GenericChainSpec::from_json_bytes(
+ &include_bytes!("../../chain-specs/bridge-hub-kusama.json")[..],
+ )?)),
BridgeHubRuntimeType::KusamaLocal => Ok(Box::new(kusama::local_config(
kusama::BRIDGE_HUB_KUSAMA_LOCAL,
"Kusama BridgeHub Local",
@@ -126,10 +103,9 @@ impl BridgeHubRuntimeType {
"kusama-dev",
ParaId::new(1003),
))),
- BridgeHubRuntimeType::Westend =>
- Ok(Box::new(westend::BridgeHubChainSpec::from_json_bytes(
- &include_bytes!("../../chain-specs/bridge-hub-westend.json")[..],
- )?)),
+ BridgeHubRuntimeType::Westend => Ok(Box::new(GenericChainSpec::from_json_bytes(
+ &include_bytes!("../../chain-specs/bridge-hub-westend.json")[..],
+ )?)),
BridgeHubRuntimeType::WestendLocal => Ok(Box::new(westend::local_config(
westend::BRIDGE_HUB_WESTEND_LOCAL,
"Westend BridgeHub Local",
@@ -144,10 +120,9 @@ impl BridgeHubRuntimeType {
ParaId::new(1002),
Some("Bob".to_string()),
))),
- BridgeHubRuntimeType::Rococo =>
- Ok(Box::new(rococo::BridgeHubChainSpec::from_json_bytes(
- &include_bytes!("../../chain-specs/bridge-hub-rococo.json")[..],
- )?)),
+ BridgeHubRuntimeType::Rococo => Ok(Box::new(GenericChainSpec::from_json_bytes(
+ &include_bytes!("../../chain-specs/bridge-hub-rococo.json")[..],
+ )?)),
BridgeHubRuntimeType::RococoLocal => Ok(Box::new(rococo::local_config(
rococo::BRIDGE_HUB_ROCOCO_LOCAL,
"Rococo BridgeHub Local",
@@ -184,7 +159,7 @@ fn ensure_id(id: &str) -> Result<&str, String> {
/// Sub-module for Rococo setup
pub mod rococo {
use super::{get_account_id_from_seed, get_collator_keys_from_seed, sr25519, ParaId};
- use crate::chain_spec::{Extensions, SAFE_XCM_VERSION};
+ use crate::chain_spec::{Extensions, GenericChainSpec, SAFE_XCM_VERSION};
use parachains_common::{AccountId, AuraId};
use sc_chain_spec::ChainType;
@@ -196,9 +171,6 @@ pub mod rococo {
const BRIDGE_HUB_ROCOCO_ED: BridgeHubBalance =
parachains_common::rococo::currency::EXISTENTIAL_DEPOSIT;
- /// Specialized `ChainSpec` for the normal parachain runtime.
- pub type BridgeHubChainSpec = sc_service::GenericChainSpec<(), Extensions>;
-
pub fn local_config(
id: &str,
chain_name: &str,
@@ -206,7 +178,7 @@ pub mod rococo {
para_id: ParaId,
bridges_pallet_owner_seed: Option,
modify_props: ModifyProperties,
- ) -> BridgeHubChainSpec {
+ ) -> GenericChainSpec {
// Rococo defaults
let mut properties = sc_chain_spec::Properties::new();
properties.insert("ss58Format".into(), 42.into());
@@ -214,7 +186,7 @@ pub mod rococo {
properties.insert("tokenDecimals".into(), 12.into());
modify_props(&mut properties);
- BridgeHubChainSpec::builder(
+ GenericChainSpec::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() },
@@ -303,7 +275,8 @@ pub mod rococo {
pub mod kusama {
use super::{BridgeHubBalance, ParaId};
use crate::chain_spec::{
- get_account_id_from_seed, get_collator_keys_from_seed, Extensions, SAFE_XCM_VERSION,
+ get_account_id_from_seed, get_collator_keys_from_seed, Extensions, GenericChainSpec,
+ SAFE_XCM_VERSION,
};
use parachains_common::{AccountId, AuraId};
use sc_chain_spec::ChainType;
@@ -315,21 +288,18 @@ pub mod kusama {
const BRIDGE_HUB_KUSAMA_ED: BridgeHubBalance =
parachains_common::kusama::currency::EXISTENTIAL_DEPOSIT;
- /// Specialized `ChainSpec` for the normal parachain runtime.
- pub type BridgeHubChainSpec = sc_service::GenericChainSpec<(), Extensions>;
-
pub fn local_config(
id: &str,
chain_name: &str,
relay_chain: &str,
para_id: ParaId,
- ) -> BridgeHubChainSpec {
+ ) -> GenericChainSpec {
let mut properties = sc_chain_spec::Properties::new();
properties.insert("ss58Format".into(), 2.into());
properties.insert("tokenSymbol".into(), "KSM".into());
properties.insert("tokenDecimals".into(), 12.into());
- BridgeHubChainSpec::builder(
+ GenericChainSpec::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() },
@@ -411,7 +381,7 @@ pub mod kusama {
/// Sub-module for Westend setup.
pub mod westend {
use super::{get_account_id_from_seed, get_collator_keys_from_seed, sr25519, ParaId};
- use crate::chain_spec::{Extensions, SAFE_XCM_VERSION};
+ use crate::chain_spec::{Extensions, GenericChainSpec, SAFE_XCM_VERSION};
use parachains_common::{AccountId, AuraId};
use sc_chain_spec::ChainType;
@@ -423,22 +393,18 @@ pub mod westend {
const BRIDGE_HUB_WESTEND_ED: BridgeHubBalance =
parachains_common::westend::currency::EXISTENTIAL_DEPOSIT;
- /// Specialized `ChainSpec` for the normal parachain runtime.
- pub type BridgeHubChainSpec =
- sc_service::GenericChainSpec;
-
pub fn local_config(
id: &str,
chain_name: &str,
relay_chain: &str,
para_id: ParaId,
bridges_pallet_owner_seed: Option,
- ) -> BridgeHubChainSpec {
+ ) -> GenericChainSpec {
let mut properties = sc_chain_spec::Properties::new();
properties.insert("tokenSymbol".into(), "WND".into());
properties.insert("tokenDecimals".into(), 12.into());
- BridgeHubChainSpec::builder(
+ GenericChainSpec::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() },
@@ -527,7 +493,8 @@ pub mod westend {
pub mod polkadot {
use super::{BridgeHubBalance, ParaId};
use crate::chain_spec::{
- get_account_id_from_seed, get_collator_keys_from_seed, Extensions, SAFE_XCM_VERSION,
+ get_account_id_from_seed, get_collator_keys_from_seed, Extensions, GenericChainSpec,
+ SAFE_XCM_VERSION,
};
use parachains_common::{AccountId, AuraId};
use sc_chain_spec::ChainType;
@@ -539,21 +506,18 @@ pub mod polkadot {
const BRIDGE_HUB_POLKADOT_ED: BridgeHubBalance =
parachains_common::polkadot::currency::EXISTENTIAL_DEPOSIT;
- /// Specialized `ChainSpec` for the normal parachain runtime.
- pub type BridgeHubChainSpec = sc_service::GenericChainSpec<(), Extensions>;
-
pub fn local_config(
id: &str,
chain_name: &str,
relay_chain: &str,
para_id: ParaId,
- ) -> BridgeHubChainSpec {
+ ) -> GenericChainSpec {
let mut properties = sc_chain_spec::Properties::new();
properties.insert("ss58Format".into(), 0.into());
properties.insert("tokenSymbol".into(), "DOT".into());
properties.insert("tokenDecimals".into(), 10.into());
- BridgeHubChainSpec::builder(
+ GenericChainSpec::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() },
diff --git a/cumulus/polkadot-parachain/src/chain_spec/collectives.rs b/cumulus/polkadot-parachain/src/chain_spec/collectives.rs
index 07bd742fa8e3..ac75a40ebdec 100644
--- a/cumulus/polkadot-parachain/src/chain_spec/collectives.rs
+++ b/cumulus/polkadot-parachain/src/chain_spec/collectives.rs
@@ -15,16 +15,14 @@
// along with Cumulus. If not, see .
use crate::chain_spec::{
- get_account_id_from_seed, get_collator_keys_from_seed, Extensions, SAFE_XCM_VERSION,
+ get_account_id_from_seed, get_collator_keys_from_seed, Extensions, GenericChainSpec,
+ SAFE_XCM_VERSION,
};
use cumulus_primitives_core::ParaId;
use parachains_common::{AccountId, AuraId, Balance as CollectivesBalance};
use sc_service::ChainType;
use sp_core::sr25519;
-pub type CollectivesPolkadotChainSpec = sc_service::GenericChainSpec<(), Extensions>;
-pub type CollectivesWestendChainSpec = sc_service::GenericChainSpec<(), Extensions>;
-
const COLLECTIVES_POLKADOT_ED: CollectivesBalance =
parachains_common::polkadot::currency::EXISTENTIAL_DEPOSIT;
const COLLECTIVES_WESTEND_ED: CollectivesBalance =
@@ -39,13 +37,13 @@ pub fn collectives_polkadot_session_keys(
collectives_polkadot_runtime::SessionKeys { aura: keys }
}
-pub fn collectives_polkadot_development_config() -> CollectivesPolkadotChainSpec {
+pub fn collectives_polkadot_development_config() -> GenericChainSpec {
let mut properties = sc_chain_spec::Properties::new();
properties.insert("ss58Format".into(), 0.into());
properties.insert("tokenSymbol".into(), "DOT".into());
properties.insert("tokenDecimals".into(), 10.into());
- CollectivesPolkadotChainSpec::builder(
+ GenericChainSpec::builder(
collectives_polkadot_runtime::WASM_BINARY
.expect("WASM binary was not built, please build it!"),
Extensions { relay_chain: "polkadot-dev".into(), para_id: 1002 },
@@ -75,13 +73,13 @@ pub fn collectives_polkadot_development_config() -> CollectivesPolkadotChainSpec
}
/// Collectives Polkadot Local Config.
-pub fn collectives_polkadot_local_config() -> CollectivesPolkadotChainSpec {
+pub fn collectives_polkadot_local_config() -> GenericChainSpec {
let mut properties = sc_chain_spec::Properties::new();
properties.insert("ss58Format".into(), 0.into());
properties.insert("tokenSymbol".into(), "DOT".into());
properties.insert("tokenDecimals".into(), 10.into());
- CollectivesPolkadotChainSpec::builder(
+ GenericChainSpec::builder(
collectives_polkadot_runtime::WASM_BINARY
.expect("WASM binary was not built, please build it!"),
Extensions { relay_chain: "polkadot-local".into(), para_id: 1002 },
@@ -169,13 +167,13 @@ pub fn collectives_westend_session_keys(keys: AuraId) -> collectives_westend_run
collectives_westend_runtime::SessionKeys { aura: keys }
}
-pub fn collectives_westend_development_config() -> CollectivesWestendChainSpec {
+pub fn collectives_westend_development_config() -> GenericChainSpec {
let mut properties = sc_chain_spec::Properties::new();
properties.insert("ss58Format".into(), 42.into());
properties.insert("tokenSymbol".into(), "WND".into());
properties.insert("tokenDecimals".into(), 12.into());
- CollectivesWestendChainSpec::builder(
+ GenericChainSpec::builder(
collectives_westend_runtime::WASM_BINARY
.expect("WASM binary was not built, please build it!"),
Extensions { relay_chain: "westend-dev".into(), para_id: 1002 },
@@ -205,13 +203,13 @@ pub fn collectives_westend_development_config() -> CollectivesWestendChainSpec {
}
/// Collectives Westend Local Config.
-pub fn collectives_westend_local_config() -> CollectivesWestendChainSpec {
+pub fn collectives_westend_local_config() -> GenericChainSpec {
let mut properties = sc_chain_spec::Properties::new();
properties.insert("ss58Format".into(), 42.into());
properties.insert("tokenSymbol".into(), "WND".into());
properties.insert("tokenDecimals".into(), 12.into());
- CollectivesWestendChainSpec::builder(
+ GenericChainSpec::builder(
collectives_westend_runtime::WASM_BINARY
.expect("WASM binary was not built, please build it!"),
Extensions { relay_chain: "westend-local".into(), para_id: 1002 },
diff --git a/cumulus/polkadot-parachain/src/chain_spec/contracts.rs b/cumulus/polkadot-parachain/src/chain_spec/contracts.rs
index 7ca66354fbfd..87ac1ed2fa18 100644
--- a/cumulus/polkadot-parachain/src/chain_spec/contracts.rs
+++ b/cumulus/polkadot-parachain/src/chain_spec/contracts.rs
@@ -15,7 +15,8 @@
// along with Cumulus. If not, see .
use crate::chain_spec::{
- get_account_id_from_seed, get_collator_keys_from_seed, Extensions, SAFE_XCM_VERSION,
+ get_account_id_from_seed, get_collator_keys_from_seed, Extensions, GenericChainSpec,
+ SAFE_XCM_VERSION,
};
use cumulus_primitives_core::ParaId;
use hex_literal::hex;
@@ -23,8 +24,6 @@ use parachains_common::{AccountId, AuraId};
use sc_service::ChainType;
use sp_core::{crypto::UncheckedInto, sr25519};
-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;
@@ -32,12 +31,12 @@ const CONTRACTS_PARACHAIN_ID: u32 = 1002;
const CONTRACTS_ROCOCO_ED: contracts_rococo_runtime::Balance =
parachains_common::rococo::currency::EXISTENTIAL_DEPOSIT;
-pub fn contracts_rococo_development_config() -> ContractsRococoChainSpec {
+pub fn contracts_rococo_development_config() -> GenericChainSpec {
let mut properties = sc_chain_spec::Properties::new();
properties.insert("tokenSymbol".into(), "ROC".into());
properties.insert("tokenDecimals".into(), 12.into());
- ContractsRococoChainSpec::builder(
+ GenericChainSpec::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!
@@ -79,12 +78,12 @@ pub fn contracts_rococo_development_config() -> ContractsRococoChainSpec {
.build()
}
-pub fn contracts_rococo_local_config() -> ContractsRococoChainSpec {
+pub fn contracts_rococo_local_config() -> GenericChainSpec {
let mut properties = sc_chain_spec::Properties::new();
properties.insert("tokenSymbol".into(), "ROC".into());
properties.insert("tokenDecimals".into(), 12.into());
- ContractsRococoChainSpec::builder(
+ GenericChainSpec::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!
@@ -126,13 +125,13 @@ pub fn contracts_rococo_local_config() -> ContractsRococoChainSpec {
.build()
}
-pub fn contracts_rococo_config() -> ContractsRococoChainSpec {
+pub fn contracts_rococo_config() -> GenericChainSpec {
// Give your base currency a unit name and decimal places
let mut properties = sc_chain_spec::Properties::new();
properties.insert("tokenSymbol".into(), "ROC".into());
properties.insert("tokenDecimals".into(), 12.into());
- ContractsRococoChainSpec::builder(
+ GenericChainSpec::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 }
)
diff --git a/cumulus/polkadot-parachain/src/chain_spec/glutton.rs b/cumulus/polkadot-parachain/src/chain_spec/glutton.rs
index aff1358d1aec..8eced8d8f816 100644
--- a/cumulus/polkadot-parachain/src/chain_spec/glutton.rs
+++ b/cumulus/polkadot-parachain/src/chain_spec/glutton.rs
@@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Cumulus. If not, see .
-use crate::chain_spec::{get_account_id_from_seed, Extensions};
+use crate::chain_spec::{get_account_id_from_seed, Extensions, GenericChainSpec};
use cumulus_primitives_core::ParaId;
use parachains_common::AuraId;
use sc_service::ChainType;
@@ -22,12 +22,8 @@ use sp_core::sr25519;
use super::get_collator_keys_from_seed;
-/// Specialized `ChainSpec` for the Glutton parachain runtime.
-pub type GluttonChainSpec = sc_service::GenericChainSpec<(), Extensions>;
-pub type GluttonWestendChainSpec = sc_service::GenericChainSpec<(), Extensions>;
-
-pub fn glutton_development_config(para_id: ParaId) -> GluttonChainSpec {
- GluttonChainSpec::builder(
+pub fn glutton_development_config(para_id: ParaId) -> GenericChainSpec {
+ GenericChainSpec::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() },
)
@@ -41,8 +37,8 @@ pub fn glutton_development_config(para_id: ParaId) -> GluttonChainSpec {
.build()
}
-pub fn glutton_local_config(para_id: ParaId) -> GluttonChainSpec {
- GluttonChainSpec::builder(
+pub fn glutton_local_config(para_id: ParaId) -> GenericChainSpec {
+ GenericChainSpec::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() },
)
@@ -59,11 +55,11 @@ pub fn glutton_local_config(para_id: ParaId) -> GluttonChainSpec {
.build()
}
-pub fn glutton_config(para_id: ParaId) -> GluttonChainSpec {
+pub fn glutton_config(para_id: ParaId) -> GenericChainSpec {
let mut properties = sc_chain_spec::Properties::new();
properties.insert("ss58Format".into(), 2.into());
- GluttonChainSpec::builder(
+ GenericChainSpec::builder(
glutton_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"),
Extensions { relay_chain: "kusama".into(), para_id: para_id.into() },
)
@@ -94,8 +90,8 @@ fn glutton_genesis(parachain_id: ParaId, collators: Vec) -> serde_json::
})
}
-pub fn glutton_westend_development_config(para_id: ParaId) -> GluttonWestendChainSpec {
- GluttonWestendChainSpec::builder(
+pub fn glutton_westend_development_config(para_id: ParaId) -> GenericChainSpec {
+ GenericChainSpec::builder(
glutton_westend_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"),
Extensions { relay_chain: "westend-dev".into(), para_id: para_id.into() },
)
@@ -109,8 +105,8 @@ pub fn glutton_westend_development_config(para_id: ParaId) -> GluttonWestendChai
.build()
}
-pub fn glutton_westend_local_config(para_id: ParaId) -> GluttonWestendChainSpec {
- GluttonWestendChainSpec::builder(
+pub fn glutton_westend_local_config(para_id: ParaId) -> GenericChainSpec {
+ GenericChainSpec::builder(
glutton_westend_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"),
Extensions { relay_chain: "westend-local".into(), para_id: para_id.into() },
)
@@ -127,11 +123,11 @@ pub fn glutton_westend_local_config(para_id: ParaId) -> GluttonWestendChainSpec
.build()
}
-pub fn glutton_westend_config(para_id: ParaId) -> GluttonWestendChainSpec {
+pub fn glutton_westend_config(para_id: ParaId) -> GenericChainSpec {
let mut properties = sc_chain_spec::Properties::new();
properties.insert("ss58Format".into(), 42.into());
- GluttonChainSpec::builder(
+ GenericChainSpec::builder(
glutton_westend_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"),
Extensions { relay_chain: "westend".into(), para_id: para_id.into() },
)
diff --git a/cumulus/polkadot-parachain/src/chain_spec/mod.rs b/cumulus/polkadot-parachain/src/chain_spec/mod.rs
index 9cd0a37ad633..e8ed8a74ed79 100644
--- a/cumulus/polkadot-parachain/src/chain_spec/mod.rs
+++ b/cumulus/polkadot-parachain/src/chain_spec/mod.rs
@@ -50,6 +50,9 @@ impl Extensions {
}
}
+/// Generic chain spec for all polkadot-parachain runtimes
+pub type GenericChainSpec = sc_service::GenericChainSpec<(), Extensions>;
+
/// Helper function to generate a crypto pair from seed
pub fn get_from_seed(seed: &str) -> ::Public {
TPublic::Pair::from_string(&format!("//{}", seed), None)
diff --git a/cumulus/polkadot-parachain/src/chain_spec/penpal.rs b/cumulus/polkadot-parachain/src/chain_spec/penpal.rs
index 2e35ee231dff..cb1cb632d638 100644
--- a/cumulus/polkadot-parachain/src/chain_spec/penpal.rs
+++ b/cumulus/polkadot-parachain/src/chain_spec/penpal.rs
@@ -15,23 +15,22 @@
// along with Cumulus. If not, see .
use crate::chain_spec::{
- get_account_id_from_seed, get_collator_keys_from_seed, Extensions, SAFE_XCM_VERSION,
+ get_account_id_from_seed, get_collator_keys_from_seed, Extensions, GenericChainSpec,
+ SAFE_XCM_VERSION,
};
use cumulus_primitives_core::ParaId;
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<(), Extensions>;
-pub fn get_penpal_chain_spec(id: ParaId, relay_chain: &str) -> PenpalChainSpec {
+pub fn get_penpal_chain_spec(id: ParaId, relay_chain: &str) -> GenericChainSpec {
// Give your base currency a unit name and decimal places
let mut properties = sc_chain_spec::Properties::new();
properties.insert("tokenSymbol".into(), "UNIT".into());
properties.insert("tokenDecimals".into(), 12u32.into());
properties.insert("ss58Format".into(), 42u32.into());
- PenpalChainSpec::builder(
+ GenericChainSpec::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!
diff --git a/cumulus/polkadot-parachain/src/chain_spec/rococo_parachain.rs b/cumulus/polkadot-parachain/src/chain_spec/rococo_parachain.rs
index c2ba44314568..0434e5f7be8f 100644
--- a/cumulus/polkadot-parachain/src/chain_spec/rococo_parachain.rs
+++ b/cumulus/polkadot-parachain/src/chain_spec/rococo_parachain.rs
@@ -16,7 +16,7 @@
//! ChainSpecs dedicated to Rococo parachain setups (for testing and example purposes)
-use crate::chain_spec::{get_from_seed, Extensions, SAFE_XCM_VERSION};
+use crate::chain_spec::{get_from_seed, Extensions, GenericChainSpec, SAFE_XCM_VERSION};
use cumulus_primitives_core::ParaId;
use hex_literal::hex;
use parachains_common::AccountId;
@@ -25,10 +25,8 @@ use rococo_parachain_runtime::AuraId;
use sc_chain_spec::ChainType;
use sp_core::{crypto::UncheckedInto, sr25519};
-pub type RococoParachainChainSpec = sc_service::GenericChainSpec<(), Extensions>;
-
-pub fn rococo_parachain_local_config() -> RococoParachainChainSpec {
- RococoParachainChainSpec::builder(
+pub fn rococo_parachain_local_config() -> GenericChainSpec {
+ GenericChainSpec::builder(
rococo_parachain_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"),
Extensions { relay_chain: "rococo-local".into(), para_id: 1000 },
)
@@ -57,9 +55,9 @@ pub fn rococo_parachain_local_config() -> RococoParachainChainSpec {
.build()
}
-pub fn staging_rococo_parachain_local_config() -> RococoParachainChainSpec {
+pub fn staging_rococo_parachain_local_config() -> GenericChainSpec {
#[allow(deprecated)]
- RococoParachainChainSpec::builder(
+ GenericChainSpec::builder(
rococo_parachain_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"),
Extensions { relay_chain: "rococo-local".into(), para_id: 1000 },
)
diff --git a/cumulus/polkadot-parachain/src/chain_spec/seedling.rs b/cumulus/polkadot-parachain/src/chain_spec/seedling.rs
index b034588e14c0..32d516220545 100644
--- a/cumulus/polkadot-parachain/src/chain_spec/seedling.rs
+++ b/cumulus/polkadot-parachain/src/chain_spec/seedling.rs
@@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Cumulus. If not, see .
-use crate::chain_spec::{get_account_id_from_seed, Extensions};
+use crate::chain_spec::{get_account_id_from_seed, Extensions, GenericChainSpec};
use cumulus_primitives_core::ParaId;
use parachains_common::{AccountId, AuraId};
use sc_service::ChainType;
@@ -22,11 +22,8 @@ use sp_core::sr25519;
use super::get_collator_keys_from_seed;
-/// Specialized `ChainSpec` for the seedling parachain runtime.
-pub type SeedlingChainSpec = sc_service::GenericChainSpec<(), Extensions>;
-
-pub fn get_seedling_chain_spec() -> SeedlingChainSpec {
- SeedlingChainSpec::builder(
+pub fn get_seedling_chain_spec() -> GenericChainSpec {
+ GenericChainSpec::builder(
seedling_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"),
Extensions { relay_chain: "westend".into(), para_id: 2000 },
)
diff --git a/cumulus/polkadot-parachain/src/chain_spec/shell.rs b/cumulus/polkadot-parachain/src/chain_spec/shell.rs
index 02c65e809a6c..e0a9875fb96f 100644
--- a/cumulus/polkadot-parachain/src/chain_spec/shell.rs
+++ b/cumulus/polkadot-parachain/src/chain_spec/shell.rs
@@ -14,18 +14,15 @@
// You should have received a copy of the GNU General Public License
// along with Cumulus. If not, see .
-use crate::chain_spec::Extensions;
+use crate::chain_spec::{Extensions, GenericChainSpec};
use cumulus_primitives_core::ParaId;
use parachains_common::AuraId;
use sc_service::ChainType;
use super::get_collator_keys_from_seed;
-/// Specialized `ChainSpec` for the shell parachain runtime.
-pub type ShellChainSpec = sc_service::GenericChainSpec<(), Extensions>;
-
-pub fn get_shell_chain_spec() -> ShellChainSpec {
- ShellChainSpec::builder(
+pub fn get_shell_chain_spec() -> GenericChainSpec {
+ GenericChainSpec::builder(
shell_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"),
Extensions { relay_chain: "westend".into(), para_id: 1000 },
)
diff --git a/cumulus/polkadot-parachain/src/command.rs b/cumulus/polkadot-parachain/src/command.rs
index ea19ad12ba05..f966a5db8f31 100644
--- a/cumulus/polkadot-parachain/src/command.rs
+++ b/cumulus/polkadot-parachain/src/command.rs
@@ -16,6 +16,7 @@
use crate::{
chain_spec,
+ chain_spec::GenericChainSpec,
cli::{Cli, RelayChainCli, Subcommand},
fake_runtime_api::{
asset_hub_polkadot_aura::RuntimeApi as AssetHubPolkadotRuntimeApi, aura::RuntimeApi,
@@ -128,18 +129,15 @@ fn load_spec(id: &str) -> std::result::Result, String> {
// - Defaul-like
"staging" =>
Box::new(chain_spec::rococo_parachain::staging_rococo_parachain_local_config()),
- "tick" =>
- Box::new(chain_spec::rococo_parachain::RococoParachainChainSpec::from_json_bytes(
- &include_bytes!("../chain-specs/tick.json")[..],
- )?),
- "trick" =>
- Box::new(chain_spec::rococo_parachain::RococoParachainChainSpec::from_json_bytes(
- &include_bytes!("../chain-specs/trick.json")[..],
- )?),
- "track" =>
- Box::new(chain_spec::rococo_parachain::RococoParachainChainSpec::from_json_bytes(
- &include_bytes!("../chain-specs/track.json")[..],
- )?),
+ "tick" => Box::new(GenericChainSpec::from_json_bytes(
+ &include_bytes!("../chain-specs/tick.json")[..],
+ )?),
+ "trick" => Box::new(GenericChainSpec::from_json_bytes(
+ &include_bytes!("../chain-specs/trick.json")[..],
+ )?),
+ "track" => Box::new(GenericChainSpec::from_json_bytes(
+ &include_bytes!("../chain-specs/track.json")[..],
+ )?),
// -- Starters
"shell" => Box::new(chain_spec::shell::get_shell_chain_spec()),
@@ -154,10 +152,9 @@ fn load_spec(id: &str) -> std::result::Result, String> {
"asset-hub-polkadot-genesis" | "statemint-genesis" =>
Box::new(chain_spec::asset_hubs::asset_hub_polkadot_config()),
// the shell-based chain spec as used for syncing
- "asset-hub-polkadot" | "statemint" =>
- Box::new(chain_spec::asset_hubs::AssetHubPolkadotChainSpec::from_json_bytes(
- &include_bytes!("../chain-specs/asset-hub-polkadot.json")[..],
- )?),
+ "asset-hub-polkadot" | "statemint" => Box::new(GenericChainSpec::from_json_bytes(
+ &include_bytes!("../chain-specs/asset-hub-polkadot.json")[..],
+ )?),
// -- Asset Hub Kusama
"asset-hub-kusama-dev" | "statemine-dev" =>
@@ -168,10 +165,9 @@ fn load_spec(id: &str) -> std::result::Result, String> {
"asset-hub-kusama-genesis" | "statemine-genesis" =>
Box::new(chain_spec::asset_hubs::asset_hub_kusama_config()),
// the shell-based chain spec as used for syncing
- "asset-hub-kusama" | "statemine" =>
- Box::new(chain_spec::asset_hubs::AssetHubKusamaChainSpec::from_json_bytes(
- &include_bytes!("../chain-specs/asset-hub-kusama.json")[..],
- )?),
+ "asset-hub-kusama" | "statemine" => Box::new(GenericChainSpec::from_json_bytes(
+ &include_bytes!("../chain-specs/asset-hub-kusama.json")[..],
+ )?),
// -- Asset Hub Rococo
"asset-hub-rococo-dev" =>
@@ -181,10 +177,9 @@ fn load_spec(id: &str) -> std::result::Result, String> {
// the chain spec as used for generating the upgrade genesis values
"asset-hub-rococo-genesis" =>
Box::new(chain_spec::asset_hubs::asset_hub_rococo_genesis_config()),
- "asset-hub-rococo" =>
- Box::new(chain_spec::asset_hubs::AssetHubRococoChainSpec::from_json_bytes(
- &include_bytes!("../chain-specs/asset-hub-rococo.json")[..],
- )?),
+ "asset-hub-rococo" => Box::new(GenericChainSpec::from_json_bytes(
+ &include_bytes!("../chain-specs/asset-hub-rococo.json")[..],
+ )?),
// -- Asset Hub Westend
"asset-hub-westend-dev" | "westmint-dev" =>
@@ -195,28 +190,25 @@ fn load_spec(id: &str) -> std::result::Result, String> {
"asset-hub-westend-genesis" | "westmint-genesis" =>
Box::new(chain_spec::asset_hubs::asset_hub_westend_config()),
// the shell-based chain spec as used for syncing
- "asset-hub-westend" | "westmint" =>
- Box::new(chain_spec::asset_hubs::AssetHubWestendChainSpec::from_json_bytes(
- &include_bytes!("../chain-specs/asset-hub-westend.json")[..],
- )?),
+ "asset-hub-westend" | "westmint" => Box::new(GenericChainSpec::from_json_bytes(
+ &include_bytes!("../chain-specs/asset-hub-westend.json")[..],
+ )?),
// -- Polkadot Collectives
"collectives-polkadot-dev" =>
Box::new(chain_spec::collectives::collectives_polkadot_development_config()),
"collectives-polkadot-local" =>
Box::new(chain_spec::collectives::collectives_polkadot_local_config()),
- "collectives-polkadot" =>
- Box::new(chain_spec::collectives::CollectivesPolkadotChainSpec::from_json_bytes(
- &include_bytes!("../chain-specs/collectives-polkadot.json")[..],
- )?),
+ "collectives-polkadot" => Box::new(GenericChainSpec::from_json_bytes(
+ &include_bytes!("../chain-specs/collectives-polkadot.json")[..],
+ )?),
"collectives-westend-dev" =>
Box::new(chain_spec::collectives::collectives_westend_development_config()),
"collectives-westend-local" =>
Box::new(chain_spec::collectives::collectives_westend_local_config()),
- "collectives-westend" =>
- Box::new(chain_spec::collectives::CollectivesWestendChainSpec::from_json_bytes(
- &include_bytes!("../chain-specs/collectives-westend.json")[..],
- )?),
+ "collectives-westend" => Box::new(GenericChainSpec::from_json_bytes(
+ &include_bytes!("../chain-specs/collectives-westend.json")[..],
+ )?),
// -- Contracts on Rococo
"contracts-rococo-dev" =>
@@ -224,10 +216,9 @@ fn load_spec(id: &str) -> std::result::Result, String> {
"contracts-rococo-local" =>
Box::new(chain_spec::contracts::contracts_rococo_local_config()),
"contracts-rococo-genesis" => Box::new(chain_spec::contracts::contracts_rococo_config()),
- "contracts-rococo" =>
- Box::new(chain_spec::contracts::ContractsRococoChainSpec::from_json_bytes(
- &include_bytes!("../chain-specs/contracts-rococo.json")[..],
- )?),
+ "contracts-rococo" => Box::new(GenericChainSpec::from_json_bytes(
+ &include_bytes!("../chain-specs/contracts-rococo.json")[..],
+ )?),
// -- BridgeHub
bridge_like_id
@@ -279,44 +270,7 @@ fn load_spec(id: &str) -> std::result::Result, String> {
},
// -- Loading a specific spec from disk
- path => {
- let path: PathBuf = path.into();
- match path.runtime() {
- Runtime::AssetHubPolkadot => Box::new(
- chain_spec::asset_hubs::AssetHubPolkadotChainSpec::from_json_file(path)?,
- ),
- Runtime::AssetHubKusama =>
- Box::new(chain_spec::asset_hubs::AssetHubKusamaChainSpec::from_json_file(path)?),
- Runtime::AssetHubRococo =>
- Box::new(chain_spec::asset_hubs::AssetHubRococoChainSpec::from_json_file(path)?),
- Runtime::AssetHubWestend => Box::new(
- chain_spec::asset_hubs::AssetHubWestendChainSpec::from_json_file(path)?,
- ),
- Runtime::CollectivesPolkadot => Box::new(
- chain_spec::collectives::CollectivesPolkadotChainSpec::from_json_file(path)?,
- ),
- Runtime::CollectivesWestend => Box::new(
- chain_spec::collectives::CollectivesWestendChainSpec::from_json_file(path)?,
- ),
- Runtime::Shell =>
- Box::new(chain_spec::shell::ShellChainSpec::from_json_file(path)?),
- Runtime::Seedling =>
- Box::new(chain_spec::seedling::SeedlingChainSpec::from_json_file(path)?),
- Runtime::ContractsRococo =>
- Box::new(chain_spec::contracts::ContractsRococoChainSpec::from_json_file(path)?),
- Runtime::BridgeHub(bridge_hub_runtime_type) =>
- bridge_hub_runtime_type.chain_spec_from_json_file(path)?,
- Runtime::Penpal(_para_id) =>
- Box::new(chain_spec::penpal::PenpalChainSpec::from_json_file(path)?),
- Runtime::GluttonWestend =>
- Box::new(chain_spec::glutton::GluttonChainSpec::from_json_file(path)?),
- Runtime::Glutton =>
- Box::new(chain_spec::glutton::GluttonChainSpec::from_json_file(path)?),
- Runtime::Default => Box::new(
- chain_spec::rococo_parachain::RococoParachainChainSpec::from_json_file(path)?,
- ),
- }
- },
+ path => Box::new(GenericChainSpec::from_json_file(path.into())?),
})
}
diff --git a/polkadot/node/core/pvf/src/execute/worker_intf.rs b/polkadot/node/core/pvf/src/execute/worker_intf.rs
index fc6cd8fc7256..16a7c290b528 100644
--- a/polkadot/node/core/pvf/src/execute/worker_intf.rs
+++ b/polkadot/node/core/pvf/src/execute/worker_intf.rs
@@ -18,7 +18,6 @@
use crate::{
artifacts::ArtifactPathId,
- security,
worker_intf::{
clear_worker_dir_path, framed_recv, framed_send, spawn_with_program_path, IdleWorker,
SpawnErr, WorkerDir, WorkerHandle, JOB_TIMEOUT_WALL_CLOCK_FACTOR,
@@ -33,7 +32,7 @@ use polkadot_node_core_pvf_common::{
execute::{Handshake, WorkerResponse},
worker_dir, SecurityStatus,
};
-use polkadot_parachain_primitives::primitives::{ValidationCodeHash, ValidationResult};
+use polkadot_parachain_primitives::primitives::ValidationResult;
use polkadot_primitives::ExecutorParams;
use std::{path::Path, time::Duration};
use tokio::{io, net::UnixStream};
@@ -132,10 +131,7 @@ pub async fn start_work(
artifact.path.display(),
);
- let artifact_path = artifact.path.clone();
with_worker_dir_setup(worker_dir, pid, &artifact.path, |worker_dir| async move {
- let audit_log_file = security::AuditLogFile::try_open_and_seek_to_end().await;
-
if let Err(error) = send_request(&mut stream, &validation_params, execution_timeout).await {
gum::warn!(
target: LOG_TARGET,
@@ -160,10 +156,7 @@ pub async fn start_work(
handle_response(
response,
pid,
- &artifact.id.code_hash,
- &artifact_path,
execution_timeout,
- audit_log_file
)
.await,
Err(error) => {
@@ -217,10 +210,7 @@ pub async fn start_work(
async fn handle_response(
response: WorkerResponse,
worker_pid: u32,
- validation_code_hash: &ValidationCodeHash,
- artifact_path: &Path,
execution_timeout: Duration,
- audit_log_file: Option,
) -> WorkerResponse {
if let WorkerResponse::Ok { duration, .. } = response {
if duration > execution_timeout {
@@ -238,25 +228,6 @@ async fn handle_response(
}
}
- if let WorkerResponse::JobDied { err: _, job_pid } = response {
- // The job died. Check if it was due to a seccomp violation.
- //
- // NOTE: Log, but don't change the outcome. Not all validators may have
- // auditing enabled, so we don't want attackers to abuse a non-deterministic
- // outcome.
- for syscall in security::check_seccomp_violations_for_job(audit_log_file, job_pid).await {
- gum::error!(
- target: LOG_TARGET,
- %worker_pid,
- %job_pid,
- %syscall,
- ?validation_code_hash,
- ?artifact_path,
- "A forbidden syscall was attempted! This is a violation of our seccomp security policy. Report an issue ASAP!"
- );
- }
- }
-
response
}
diff --git a/polkadot/node/core/pvf/src/prepare/worker_intf.rs b/polkadot/node/core/pvf/src/prepare/worker_intf.rs
index f978005068c8..a393e9baa9e5 100644
--- a/polkadot/node/core/pvf/src/prepare/worker_intf.rs
+++ b/polkadot/node/core/pvf/src/prepare/worker_intf.rs
@@ -19,7 +19,6 @@
use crate::{
artifacts::ArtifactId,
metrics::Metrics,
- security,
worker_intf::{
clear_worker_dir_path, framed_recv, framed_send, spawn_with_program_path, IdleWorker,
SpawnErr, WorkerDir, WorkerHandle, JOB_TIMEOUT_WALL_CLOCK_FACTOR,
@@ -134,7 +133,6 @@ pub async fn start_work(
pid,
|tmp_artifact_file, mut stream, worker_dir| async move {
let preparation_timeout = pvf.prep_timeout();
- let audit_log_file = security::AuditLogFile::try_open_and_seek_to_end().await;
if let Err(err) = send_request(&mut stream, &pvf).await {
gum::warn!(
@@ -170,7 +168,6 @@ pub async fn start_work(
&pvf,
&cache_path,
preparation_timeout,
- audit_log_file,
)
.await,
Ok(Err(err)) => {
@@ -211,34 +208,13 @@ async fn handle_response(
pvf: &PvfPrepData,
cache_path: &Path,
preparation_timeout: Duration,
- audit_log_file: Option,
) -> Outcome {
let PrepareWorkerSuccess { checksum, stats: PrepareStats { cpu_time_elapsed, memory_stats } } =
match result.clone() {
Ok(result) => result,
// Timed out on the child. This should already be logged by the child.
Err(PrepareError::TimedOut) => return Outcome::TimedOut,
- Err(PrepareError::JobDied { err, job_pid }) => {
- // The job died. Check if it was due to a seccomp violation.
- //
- // NOTE: Log, but don't change the outcome. Not all validators may have
- // auditing enabled, so we don't want attackers to abuse a non-deterministic
- // outcome.
- for syscall in
- security::check_seccomp_violations_for_job(audit_log_file, job_pid).await
- {
- gum::error!(
- target: LOG_TARGET,
- %worker_pid,
- %job_pid,
- %syscall,
- ?pvf,
- "A forbidden syscall was attempted! This is a violation of our seccomp security policy. Report an issue ASAP!"
- );
- }
-
- return Outcome::JobDied { err, job_pid }
- },
+ Err(PrepareError::JobDied { err, job_pid }) => return Outcome::JobDied { err, job_pid },
Err(PrepareError::OutOfMemory) => return Outcome::OutOfMemory,
Err(err) => return Outcome::Concluded { worker, result: Err(err) },
};
diff --git a/polkadot/node/core/pvf/src/security.rs b/polkadot/node/core/pvf/src/security.rs
index ef8714f58c81..2fd3b53e96b4 100644
--- a/polkadot/node/core/pvf/src/security.rs
+++ b/polkadot/node/core/pvf/src/security.rs
@@ -17,10 +17,6 @@
use crate::{Config, SecurityStatus, LOG_TARGET};
use futures::join;
use std::{fmt, path::Path};
-use tokio::{
- fs::{File, OpenOptions},
- io::{AsyncReadExt, AsyncSeekExt, SeekFrom},
-};
const SECURE_MODE_ANNOUNCEMENT: &'static str =
"In the next release this will be a hard error by default.
@@ -35,7 +31,6 @@ const SECURE_MODE_ANNOUNCEMENT: &'static str =
pub async fn check_security_status(config: &Config) -> SecurityStatus {
let Config { prepare_worker_program_path, cache_path, .. } = config;
- // TODO: add check that syslog is available and that seccomp violations are logged?
let (landlock, seccomp, change_root) = join!(
check_landlock(prepare_worker_program_path),
check_seccomp(prepare_worker_program_path),
@@ -303,147 +298,3 @@ async fn check_seccomp(
}
}
}
-
-const AUDIT_LOG_PATH: &'static str = "/var/log/audit/audit.log";
-const SYSLOG_PATH: &'static str = "/var/log/syslog";
-
-/// System audit log.
-pub struct AuditLogFile {
- file: File,
- path: &'static str,
-}
-
-impl AuditLogFile {
- /// Looks for an audit log file on the system and opens it, seeking to the end to skip any
- /// events from before this was called.
- ///
- /// A bit of a verbose name, but it should clue future refactorers not to move calls closer to
- /// where the `AuditLogFile` is used.
- pub async fn try_open_and_seek_to_end() -> Option {
- let mut path = AUDIT_LOG_PATH;
- let mut file = match OpenOptions::new().read(true).open(AUDIT_LOG_PATH).await {
- Ok(file) => Ok(file),
- Err(_) => {
- path = SYSLOG_PATH;
- OpenOptions::new().read(true).open(SYSLOG_PATH).await
- },
- }
- .ok()?;
-
- let _pos = file.seek(SeekFrom::End(0)).await;
-
- Some(Self { file, path })
- }
-
- async fn read_new_since_open(mut self) -> String {
- let mut buf = String::new();
- let _len = self.file.read_to_string(&mut buf).await;
- buf
- }
-}
-
-/// Check if a seccomp violation occurred for the given job process. As the syslog may be in a
-/// different location, or seccomp auditing may be disabled, this function provides a best-effort
-/// attempt only.
-///
-/// The `audit_log_file` must have been obtained before the job started. It only allows reading
-/// entries that were written since it was obtained, so that we do not consider events from previous
-/// processes with the same pid. This can still be racy, but it's unlikely and fine for a
-/// best-effort attempt.
-pub async fn check_seccomp_violations_for_job(
- audit_log_file: Option,
- job_pid: i32,
-) -> Vec {
- let audit_event_pid_field = format!("pid={job_pid}");
-
- let audit_log_file = match audit_log_file {
- Some(file) => {
- gum::trace!(
- target: LOG_TARGET,
- %job_pid,
- audit_log_path = ?file.path,
- "checking audit log for seccomp violations",
- );
- file
- },
- None => {
- gum::warn!(
- target: LOG_TARGET,
- %job_pid,
- "could not open either {AUDIT_LOG_PATH} or {SYSLOG_PATH} for reading audit logs"
- );
- return vec![]
- },
- };
- let events = audit_log_file.read_new_since_open().await;
-
- let mut violations = vec![];
- for event in events.lines() {
- if let Some(syscall) = parse_audit_log_for_seccomp_event(event, &audit_event_pid_field) {
- violations.push(syscall);
- }
- }
-
- violations
-}
-
-fn parse_audit_log_for_seccomp_event(event: &str, audit_event_pid_field: &str) -> Option {
- const SECCOMP_AUDIT_EVENT_TYPE: &'static str = "type=1326";
-
- // Do a series of simple .contains instead of a regex, because I'm not sure if the fields are
- // guaranteed to always be in the same order.
- if !event.contains(SECCOMP_AUDIT_EVENT_TYPE) || !event.contains(&audit_event_pid_field) {
- return None
- }
-
- // Get the syscall. Let's avoid a dependency on regex just for this.
- for field in event.split(" ") {
- if let Some(syscall) = field.strip_prefix("syscall=") {
- return syscall.parse::().ok()
- }
- }
-
- None
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn test_parse_audit_log_for_seccomp_event() {
- let audit_event_pid_field = "pid=2559058";
-
- assert_eq!(
- parse_audit_log_for_seccomp_event(
- r#"Oct 24 13:15:24 build kernel: [5883980.283910] audit: type=1326 audit(1698153324.786:23): auid=0 uid=0 gid=0 ses=2162 subj=unconfined pid=2559058 comm="polkadot-prepar" exe="/root/paritytech/polkadot-sdk-2/target/debug/polkadot-prepare-worker" sig=31 arch=c000003e syscall=53 compat=0 ip=0x7f7542c80d5e code=0x80000000"#,
- audit_event_pid_field
- ),
- Some(53)
- );
- // pid is wrong
- assert_eq!(
- parse_audit_log_for_seccomp_event(
- r#"Oct 24 13:15:24 build kernel: [5883980.283910] audit: type=1326 audit(1698153324.786:23): auid=0 uid=0 gid=0 ses=2162 subj=unconfined pid=2559057 comm="polkadot-prepar" exe="/root/paritytech/polkadot-sdk-2/target/debug/polkadot-prepare-worker" sig=31 arch=c000003e syscall=53 compat=0 ip=0x7f7542c80d5e code=0x80000000"#,
- audit_event_pid_field
- ),
- None
- );
- // type is wrong
- assert_eq!(
- parse_audit_log_for_seccomp_event(
- r#"Oct 24 13:15:24 build kernel: [5883980.283910] audit: type=1327 audit(1698153324.786:23): auid=0 uid=0 gid=0 ses=2162 subj=unconfined pid=2559057 comm="polkadot-prepar" exe="/root/paritytech/polkadot-sdk-2/target/debug/polkadot-prepare-worker" sig=31 arch=c000003e syscall=53 compat=0 ip=0x7f7542c80d5e code=0x80000000"#,
- audit_event_pid_field
- ),
- None
- );
- // no syscall field
- assert_eq!(
- parse_audit_log_for_seccomp_event(
- r#"Oct 24 13:15:24 build kernel: [5883980.283910] audit: type=1327 audit(1698153324.786:23): auid=0 uid=0 gid=0 ses=2162 subj=unconfined pid=2559057 comm="polkadot-prepar" exe="/root/paritytech/polkadot-sdk-2/target/debug/polkadot-prepare-worker" sig=31 arch=c000003e compat=0 ip=0x7f7542c80d5e code=0x80000000"#,
- audit_event_pid_field
- ),
- None
- );
- }
-}
diff --git a/substrate/frame/safe-mode/Cargo.toml b/substrate/frame/safe-mode/Cargo.toml
index ac469bb385c9..f7b4ea4dd8c9 100644
--- a/substrate/frame/safe-mode/Cargo.toml
+++ b/substrate/frame/safe-mode/Cargo.toml
@@ -13,6 +13,7 @@ targets = ["x86_64-unknown-linux-gnu"]
[dependencies]
codec = { package = "parity-scale-codec", version = "3.2.2", default-features = false, features = ["derive"] }
+docify = "0.2.6"
frame-benchmarking = { path = "../benchmarking", default-features = false, optional = true}
frame-support = { path = "../support", default-features = false}
frame-system = { path = "../system", default-features = false}
diff --git a/substrate/frame/safe-mode/src/lib.rs b/substrate/frame/safe-mode/src/lib.rs
index b8e8378fa9e7..554f509db63e 100644
--- a/substrate/frame/safe-mode/src/lib.rs
+++ b/substrate/frame/safe-mode/src/lib.rs
@@ -15,6 +15,62 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+//! # Safe Mode
+//!
+//! Trigger for stopping all extrinsics outside of a specific whitelist.
+//!
+//! ## WARNING
+//!
+//! NOT YET AUDITED. DO NOT USE IN PRODUCTION.
+//!
+//! ## Pallet API
+//!
+//! See the [`pallet`] module for more information about the interfaces this pallet exposes,
+//! including its configuration trait, dispatchables, storage items, events, and errors.
+//!
+//! ## Overview
+//!
+//! Safe mode is entered via two paths (deposit or forced) until a set block number.
+//! The mode is exited when the block number is reached or a call to one of the exit extrinsics is
+//! made. A `WhitelistedCalls` configuration item contains all calls that can be executed while in
+//! safe mode.
+//!
+//! ### Primary Features
+//!
+//! - Entering safe mode can be via privileged origin or anyone who places a deposit.
+//! - Origin configuration items are separated for privileged entering and exiting safe mode.
+//! - A configurable duration sets the number of blocks after which the system will exit safe mode.
+//! - Safe mode may be extended beyond the configured exit by additional calls.
+//!
+//! ### Example
+//!
+//! Configuration of call filters:
+//!
+//! ```ignore
+//! impl frame_system::Config for Runtime {
+//! // …
+//! type BaseCallFilter = InsideBoth;
+//! // …
+//! }
+//! ```
+//!
+//! Entering safe mode with deposit:
+#![doc = docify::embed!("src/tests.rs", can_activate)]
+//!
+//! Entering safe mode via privileged origin:
+#![doc = docify::embed!("src/tests.rs", can_force_activate_with_config_origin)]
+//!
+//! Exiting safe mode via privileged origin:
+#![doc = docify::embed!("src/tests.rs", can_force_deactivate_with_config_origin)]
+//!
+//! ## Low Level / Implementation Details
+//!
+//! ### Use Cost
+//!
+//! A storage value (`EnteredUntil`) is used to store the block safe mode will be exited on.
+//! Using the call filter will require a db read of that storage on the first extrinsic.
+//! The storage will be added to the overlay and incur low cost for all additional calls.
+
#![cfg_attr(not(feature = "std"), no_std)]
#![deny(rustdoc::broken_intra_doc_links)]
diff --git a/substrate/frame/safe-mode/src/tests.rs b/substrate/frame/safe-mode/src/tests.rs
index b92c5b87a530..c0a2f45a3e7a 100644
--- a/substrate/frame/safe-mode/src/tests.rs
+++ b/substrate/frame/safe-mode/src/tests.rs
@@ -189,6 +189,7 @@ fn can_filter_balance_in_proxy_when_activated() {
});
}
+#[docify::export]
#[test]
fn can_activate() {
new_test_ext().execute_with(|| {
@@ -271,6 +272,7 @@ fn fails_force_deactivate_if_not_activated() {
});
}
+#[docify::export]
#[test]
fn can_force_activate_with_config_origin() {
new_test_ext().execute_with(|| {
@@ -288,6 +290,7 @@ fn can_force_activate_with_config_origin() {
});
}
+#[docify::export]
#[test]
fn can_force_deactivate_with_config_origin() {
new_test_ext().execute_with(|| {
diff --git a/substrate/frame/tx-pause/Cargo.toml b/substrate/frame/tx-pause/Cargo.toml
index 9af424f541cd..bf0641f5b6d5 100644
--- a/substrate/frame/tx-pause/Cargo.toml
+++ b/substrate/frame/tx-pause/Cargo.toml
@@ -13,6 +13,7 @@ targets = ["x86_64-unknown-linux-gnu"]
[dependencies]
codec = { package = "parity-scale-codec", version = "3.2.2", default-features = false, features = ["derive"] }
+docify = "0.2.6"
frame-benchmarking = { path = "../benchmarking", default-features = false, optional = true}
frame-support = { path = "../support", default-features = false}
frame-system = { path = "../system", default-features = false}
diff --git a/substrate/frame/tx-pause/src/lib.rs b/substrate/frame/tx-pause/src/lib.rs
index a3be0f501727..31be575fba7c 100644
--- a/substrate/frame/tx-pause/src/lib.rs
+++ b/substrate/frame/tx-pause/src/lib.rs
@@ -15,6 +15,62 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+//! # Transaction Pause
+//!
+//! Allows dynamic, chain-state-based pausing and unpausing of specific extrinsics via call filters.
+//!
+//! ## WARNING
+//!
+//! NOT YET AUDITED. DO NOT USE IN PRODUCTION.
+//!
+//! ## Pallet API
+//!
+//! See the [`pallet`] module for more information about the interfaces this pallet exposes,
+//! including its configuration trait, dispatchables, storage items, events, and errors.
+//!
+//! ## Overview
+//!
+//! A dynamic call filter that can be controlled with extrinsics.
+//!
+//! Pausing an extrinsic means that the extrinsic CANNOT be called again until it is unpaused.
+//! The exception is calls that use `dispatch_bypass_filter`, typically only with the root origin.
+//!
+//! ### Primary Features
+//!
+//! - Calls that should never be paused can be added to a whitelist.
+//! - Separate origins are configurable for pausing and pausing.
+//! - Pausing is triggered using the string representation of the call.
+//! - Pauses can target a single extrinsic or an entire pallet.
+//! - Pauses can target future extrinsics or pallets.
+//!
+//! ### Example
+//!
+//! Configuration of call filters:
+//!
+//! ```ignore
+//! impl frame_system::Config for Runtime {
+//! // …
+//! type BaseCallFilter = InsideBoth;
+//! // …
+//! }
+//! ```
+//!
+//! Pause specific all:
+#![doc = docify::embed!("src/tests.rs", can_pause_specific_call)]
+//!
+//! Unpause specific all:
+#![doc = docify::embed!("src/tests.rs", can_unpause_specific_call)]
+//!
+//! Pause all calls in a pallet:
+#![doc = docify::embed!("src/tests.rs", can_pause_all_calls_in_pallet_except_on_whitelist)]
+//!
+//! ## Low Level / Implementation Details
+//!
+//! ### Use Cost
+//!
+//! A storage map (`PausedCalls`) is used to store currently paused calls.
+//! Using the call filter will require a db read of that storage on each extrinsic.
+
#![cfg_attr(not(feature = "std"), no_std)]
#![deny(rustdoc::broken_intra_doc_links)]
diff --git a/substrate/frame/tx-pause/src/tests.rs b/substrate/frame/tx-pause/src/tests.rs
index a71ff3439d90..823abf9d9c43 100644
--- a/substrate/frame/tx-pause/src/tests.rs
+++ b/substrate/frame/tx-pause/src/tests.rs
@@ -25,6 +25,7 @@ use sp_runtime::DispatchError;
// GENERAL SUCCESS/POSITIVE TESTS ---------------------
+#[docify::export]
#[test]
fn can_pause_specific_call() {
new_test_ext().execute_with(|| {
@@ -43,6 +44,7 @@ fn can_pause_specific_call() {
});
}
+#[docify::export]
#[test]
fn can_pause_all_calls_in_pallet_except_on_whitelist() {
new_test_ext().execute_with(|| {
@@ -64,6 +66,7 @@ fn can_pause_all_calls_in_pallet_except_on_whitelist() {
});
}
+#[docify::export]
#[test]
fn can_unpause_specific_call() {
new_test_ext().execute_with(|| {