mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-23 22:31:06 +00:00
Generated
+205
-137
File diff suppressed because it is too large
Load Diff
@@ -52,6 +52,7 @@ members = [
|
|||||||
"node/service",
|
"node/service",
|
||||||
"node/subsystem",
|
"node/subsystem",
|
||||||
"node/test-helpers/subsystem",
|
"node/test-helpers/subsystem",
|
||||||
|
"node/test-service",
|
||||||
|
|
||||||
"parachain/test-parachains",
|
"parachain/test-parachains",
|
||||||
"parachain/test-parachains/adder",
|
"parachain/test-parachains/adder",
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ fn prepare_good_block() -> (TestClient, Hash, u64, PeerId, IncomingBlock<Block>)
|
|||||||
let mut client = polkadot_test_runtime_client::new();
|
let mut client = polkadot_test_runtime_client::new();
|
||||||
let mut builder = client.new_block(Default::default()).unwrap();
|
let mut builder = client.new_block(Default::default()).unwrap();
|
||||||
|
|
||||||
let extrinsics = polkadot_test_runtime_client::needed_extrinsics(vec![]);
|
let extrinsics = polkadot_test_runtime_client::needed_extrinsics(vec![], 0);
|
||||||
|
|
||||||
for extrinsic in &extrinsics {
|
for extrinsic in &extrinsics {
|
||||||
builder.push(extrinsic.clone()).unwrap();
|
builder.push(extrinsic.clone()).unwrap();
|
||||||
|
|||||||
@@ -250,17 +250,21 @@ mod tests {
|
|||||||
|
|
||||||
let mut push_blocks = {
|
let mut push_blocks = {
|
||||||
let mut client = client.clone();
|
let mut client = client.clone();
|
||||||
|
let mut base = 0;
|
||||||
|
|
||||||
move |n| {
|
move |n| {
|
||||||
for _ in 0..n {
|
for i in 0..n {
|
||||||
let mut builder = client.new_block(Default::default()).unwrap();
|
let mut builder = client.new_block(Default::default()).unwrap();
|
||||||
|
|
||||||
for extrinsic in polkadot_test_runtime_client::needed_extrinsics(vec![]) {
|
for extrinsic in polkadot_test_runtime_client::needed_extrinsics(vec![], base + i) {
|
||||||
builder.push(extrinsic).unwrap()
|
builder.push(extrinsic).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
let block = builder.build().unwrap().block;
|
let block = builder.build().unwrap().block;
|
||||||
client.import(BlockOrigin::Own, block).unwrap();
|
client.import(BlockOrigin::Own, block).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
base += n;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
[package]
|
||||||
|
name = "polkadot-test-service"
|
||||||
|
version = "0.8.2"
|
||||||
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
futures = "0.3.4"
|
||||||
|
futures01 = { package = "futures", version = "0.1.29" }
|
||||||
|
hex = "0.4"
|
||||||
|
log = "0.4.8"
|
||||||
|
rand = "0.7.3"
|
||||||
|
tempfile = "3.1.0"
|
||||||
|
|
||||||
|
# Polkadot dependencies
|
||||||
|
av_store = { package = "polkadot-availability-store", path = "../../availability-store" }
|
||||||
|
consensus = { package = "polkadot-validation", path = "../../validation" }
|
||||||
|
polkadot-network = { path = "../../network" }
|
||||||
|
polkadot-primitives = { path = "../../primitives" }
|
||||||
|
polkadot-rpc = { path = "../../rpc" }
|
||||||
|
polkadot-runtime-common = { path = "../../runtime/common" }
|
||||||
|
polkadot-service = { path = "../../service" }
|
||||||
|
polkadot-test-runtime = { path = "../../runtime/test-runtime" }
|
||||||
|
|
||||||
|
# Substrate dependencies
|
||||||
|
authority-discovery = { package = "sc-authority-discovery", git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
babe = { package = "sc-consensus-babe", git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
babe-primitives = { package = "sp-consensus-babe", git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
consensus_common = { package = "sp-consensus", git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
frame-system = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
grandpa = { package = "sc-finality-grandpa", git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
grandpa_primitives = { package = "sp-finality-grandpa", git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
inherents = { package = "sp-inherents", git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
pallet-staking = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
sc-chain-spec = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
sc-consensus = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
sc-executor = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
sc-informant = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
sc-network = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
sc-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
service = { package = "sc-service", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||||
|
sp-arithmetic = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
sp-state-machine = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
substrate-test-client = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||||
|
serde_json = "1.0"
|
||||||
|
tokio = { version = "0.2", features = ["macros"] }
|
||||||
@@ -0,0 +1,184 @@
|
|||||||
|
// Copyright 2020 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Polkadot.
|
||||||
|
|
||||||
|
// Polkadot 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.
|
||||||
|
|
||||||
|
// Polkadot 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 Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
use babe_primitives::AuthorityId as BabeId;
|
||||||
|
use grandpa::AuthorityId as GrandpaId;
|
||||||
|
use pallet_staking::Forcing;
|
||||||
|
use polkadot_primitives::{parachain::ValidatorId, AccountId};
|
||||||
|
use polkadot_service::chain_spec::{get_account_id_from_seed, get_from_seed, Extensions};
|
||||||
|
use polkadot_test_runtime::constants::currency::DOTS;
|
||||||
|
use sc_chain_spec::{ChainSpec, ChainType};
|
||||||
|
use sp_core::{sr25519, ChangesTrieConfiguration};
|
||||||
|
use sp_runtime::Perbill;
|
||||||
|
|
||||||
|
const DEFAULT_PROTOCOL_ID: &str = "dot";
|
||||||
|
|
||||||
|
/// The `ChainSpec parametrised for polkadot runtime`.
|
||||||
|
pub type PolkadotChainSpec =
|
||||||
|
service::GenericChainSpec<polkadot_test_runtime::GenesisConfig, Extensions>;
|
||||||
|
|
||||||
|
/// Polkadot 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(None),
|
||||||
|
vec![],
|
||||||
|
None,
|
||||||
|
Some(DEFAULT_PROTOCOL_ID),
|
||||||
|
None,
|
||||||
|
Default::default(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Polkadot local testnet genesis config (multivalidator Alice + Bob)
|
||||||
|
pub fn polkadot_local_testnet_genesis(
|
||||||
|
changes_trie_config: Option<ChangesTrieConfiguration>,
|
||||||
|
) -> polkadot_test_runtime::GenesisConfig {
|
||||||
|
polkadot_testnet_genesis(
|
||||||
|
vec![
|
||||||
|
get_authority_keys_from_seed("Alice"),
|
||||||
|
get_authority_keys_from_seed("Bob"),
|
||||||
|
get_authority_keys_from_seed("Charlie"),
|
||||||
|
],
|
||||||
|
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||||
|
None,
|
||||||
|
changes_trie_config,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Helper function to generate stash, controller and session key from seed
|
||||||
|
fn get_authority_keys_from_seed(
|
||||||
|
seed: &str,
|
||||||
|
) -> (AccountId, AccountId, BabeId, GrandpaId, ValidatorId) {
|
||||||
|
(
|
||||||
|
get_account_id_from_seed::<sr25519::Public>(&format!("{}//stash", seed)),
|
||||||
|
get_account_id_from_seed::<sr25519::Public>(seed),
|
||||||
|
get_from_seed::<BabeId>(seed),
|
||||||
|
get_from_seed::<GrandpaId>(seed),
|
||||||
|
get_from_seed::<ValidatorId>(seed),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn testnet_accounts() -> Vec<AccountId> {
|
||||||
|
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"),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Helper function to create polkadot GenesisConfig for testing
|
||||||
|
fn polkadot_testnet_genesis(
|
||||||
|
initial_authorities: Vec<(AccountId, AccountId, BabeId, GrandpaId, ValidatorId)>,
|
||||||
|
root_key: AccountId,
|
||||||
|
endowed_accounts: Option<Vec<AccountId>>,
|
||||||
|
changes_trie_config: Option<ChangesTrieConfiguration>,
|
||||||
|
) -> polkadot_test_runtime::GenesisConfig {
|
||||||
|
use polkadot_test_runtime as polkadot;
|
||||||
|
|
||||||
|
let endowed_accounts: Vec<AccountId> = endowed_accounts.unwrap_or_else(testnet_accounts);
|
||||||
|
|
||||||
|
const ENDOWMENT: u128 = 1_000_000 * DOTS;
|
||||||
|
const STASH: u128 = 100 * DOTS;
|
||||||
|
|
||||||
|
polkadot::GenesisConfig {
|
||||||
|
system: Some(polkadot::SystemConfig {
|
||||||
|
code: polkadot::WASM_BINARY.to_vec(),
|
||||||
|
changes_trie_config,
|
||||||
|
}),
|
||||||
|
indices: Some(polkadot::IndicesConfig { indices: vec![] }),
|
||||||
|
balances: Some(polkadot::BalancesConfig {
|
||||||
|
balances: endowed_accounts
|
||||||
|
.iter()
|
||||||
|
.map(|k| (k.clone(), ENDOWMENT))
|
||||||
|
.collect(),
|
||||||
|
}),
|
||||||
|
session: Some(polkadot::SessionConfig {
|
||||||
|
keys: initial_authorities
|
||||||
|
.iter()
|
||||||
|
.map(|x| {
|
||||||
|
(
|
||||||
|
x.0.clone(),
|
||||||
|
x.0.clone(),
|
||||||
|
polkadot_test_runtime::SessionKeys {
|
||||||
|
babe: x.2.clone(),
|
||||||
|
grandpa: x.3.clone(),
|
||||||
|
parachain_validator: x.4.clone(),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
}),
|
||||||
|
staking: Some(polkadot::StakingConfig {
|
||||||
|
minimum_validator_count: 1,
|
||||||
|
validator_count: 2,
|
||||||
|
stakers: initial_authorities
|
||||||
|
.iter()
|
||||||
|
.map(|x| {
|
||||||
|
(
|
||||||
|
x.0.clone(),
|
||||||
|
x.1.clone(),
|
||||||
|
STASH,
|
||||||
|
polkadot::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()
|
||||||
|
}),
|
||||||
|
babe: Some(Default::default()),
|
||||||
|
grandpa: Some(Default::default()),
|
||||||
|
authority_discovery: Some(polkadot::AuthorityDiscoveryConfig { keys: vec![] }),
|
||||||
|
parachains: Some(polkadot::ParachainsConfig {
|
||||||
|
authorities: vec![],
|
||||||
|
}),
|
||||||
|
registrar: Some(polkadot::RegistrarConfig {
|
||||||
|
parachains: vec![],
|
||||||
|
_phdata: Default::default(),
|
||||||
|
}),
|
||||||
|
claims: Some(polkadot::ClaimsConfig {
|
||||||
|
claims: vec![],
|
||||||
|
vesting: vec![],
|
||||||
|
}),
|
||||||
|
vesting: Some(polkadot::VestingConfig { vesting: vec![] }),
|
||||||
|
sudo: Some(polkadot::SudoConfig { key: root_key }),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Can be called for a `Configuration` to check if it is a configuration for the `Test` network.
|
||||||
|
pub trait IdentifyVariant {
|
||||||
|
/// Returns if this is a configuration for the `Test` network.
|
||||||
|
fn is_test(&self) -> bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IdentifyVariant for Box<dyn ChainSpec> {
|
||||||
|
fn is_test(&self) -> bool {
|
||||||
|
self.id().starts_with("test")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,307 @@
|
|||||||
|
// Copyright 2020 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Polkadot.
|
||||||
|
|
||||||
|
// Polkadot 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.
|
||||||
|
|
||||||
|
// Polkadot 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 Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! Polkadot test service only.
|
||||||
|
|
||||||
|
#![warn(missing_docs)]
|
||||||
|
|
||||||
|
mod chain_spec;
|
||||||
|
|
||||||
|
pub use chain_spec::*;
|
||||||
|
use consensus_common::{block_validation::Chain, SelectChain};
|
||||||
|
use futures::future::Future;
|
||||||
|
use grandpa::FinalityProofProvider as GrandpaFinalityProofProvider;
|
||||||
|
use log::info;
|
||||||
|
use polkadot_network::{legacy::gossip::Known, protocol as network_protocol};
|
||||||
|
use polkadot_primitives::{
|
||||||
|
parachain::{self, CollatorId},
|
||||||
|
Block, BlockId, Hash,
|
||||||
|
};
|
||||||
|
use polkadot_runtime_common::{parachains, registrar, BlockHashCount};
|
||||||
|
use polkadot_service::{
|
||||||
|
new_full, new_full_start, FullNodeHandles, PolkadotClient, ServiceComponents,
|
||||||
|
};
|
||||||
|
use polkadot_test_runtime::{RestrictFunctionality, Runtime, SignedExtra, SignedPayload, VERSION};
|
||||||
|
use sc_chain_spec::ChainSpec;
|
||||||
|
use sc_client_api::{execution_extensions::ExecutionStrategies, BlockchainEvents};
|
||||||
|
use sc_executor::native_executor_instance;
|
||||||
|
use sc_informant::OutputFormat;
|
||||||
|
use sc_network::{
|
||||||
|
config::{NetworkConfiguration, TransportConfig},
|
||||||
|
multiaddr, NetworkService,
|
||||||
|
};
|
||||||
|
use service::{
|
||||||
|
config::{DatabaseConfig, KeystoreConfig, MultiaddrWithPeerId, WasmExecutionMethod},
|
||||||
|
error::Error as ServiceError,
|
||||||
|
RpcHandlers, TaskExecutor, TaskManager,
|
||||||
|
};
|
||||||
|
use service::{BasePath, Configuration, Role, TFullBackend};
|
||||||
|
use sp_arithmetic::traits::SaturatedConversion;
|
||||||
|
use sp_blockchain::HeaderBackend;
|
||||||
|
use sp_keyring::Sr25519Keyring;
|
||||||
|
use sp_runtime::{codec::Encode, generic};
|
||||||
|
use sp_state_machine::BasicExternalities;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use std::time::Duration;
|
||||||
|
use substrate_test_client::{BlockchainEventsExt, RpcHandlersExt, RpcTransactionOutput, RpcTransactionError};
|
||||||
|
|
||||||
|
native_executor_instance!(
|
||||||
|
pub PolkadotTestExecutor,
|
||||||
|
polkadot_test_runtime::api::dispatch,
|
||||||
|
polkadot_test_runtime::native_version,
|
||||||
|
frame_benchmarking::benchmarking::HostFunctions,
|
||||||
|
);
|
||||||
|
|
||||||
|
/// Create a new Polkadot test service for a full node.
|
||||||
|
pub fn polkadot_test_new_full(
|
||||||
|
config: Configuration,
|
||||||
|
collating_for: Option<(CollatorId, parachain::Id)>,
|
||||||
|
max_block_data_size: Option<u64>,
|
||||||
|
authority_discovery_enabled: bool,
|
||||||
|
slot_duration: u64,
|
||||||
|
) -> Result<
|
||||||
|
(
|
||||||
|
TaskManager,
|
||||||
|
Arc<impl PolkadotClient<Block, TFullBackend<Block>, polkadot_test_runtime::RuntimeApi>>,
|
||||||
|
FullNodeHandles,
|
||||||
|
Arc<NetworkService<Block, Hash>>,
|
||||||
|
Arc<RpcHandlers>,
|
||||||
|
),
|
||||||
|
ServiceError,
|
||||||
|
> {
|
||||||
|
let (task_manager, client, handles, network, rpc_handlers) = new_full!(test
|
||||||
|
config,
|
||||||
|
collating_for,
|
||||||
|
max_block_data_size,
|
||||||
|
authority_discovery_enabled,
|
||||||
|
slot_duration,
|
||||||
|
polkadot_test_runtime::RuntimeApi,
|
||||||
|
PolkadotTestExecutor,
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok((task_manager, client, handles, network, rpc_handlers))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a Polkadot `Configuration`. By default an in-memory socket will be used, therefore you need to provide boot
|
||||||
|
/// nodes if you want the future node to be connected to other nodes. The `storage_update_func` can be used to make
|
||||||
|
/// adjustements to the runtime before the node starts.
|
||||||
|
pub fn node_config(
|
||||||
|
storage_update_func: impl Fn(),
|
||||||
|
task_executor: TaskExecutor,
|
||||||
|
key: Sr25519Keyring,
|
||||||
|
boot_nodes: Vec<MultiaddrWithPeerId>,
|
||||||
|
) -> Configuration {
|
||||||
|
let base_path = BasePath::new_temp_dir().expect("could not create temporary directory");
|
||||||
|
let root = base_path.path();
|
||||||
|
let role = Role::Authority {
|
||||||
|
sentry_nodes: Vec::new(),
|
||||||
|
};
|
||||||
|
let key_seed = key.to_seed();
|
||||||
|
let mut spec = polkadot_local_testnet_config();
|
||||||
|
let mut storage = spec
|
||||||
|
.as_storage_builder()
|
||||||
|
.build_storage()
|
||||||
|
.expect("could not build storage");
|
||||||
|
|
||||||
|
BasicExternalities::execute_with_storage(&mut storage, storage_update_func);
|
||||||
|
spec.set_storage(storage);
|
||||||
|
|
||||||
|
let mut network_config = NetworkConfiguration::new(
|
||||||
|
format!("Polkadot Test Node for: {}", key_seed),
|
||||||
|
"network/test/0.1",
|
||||||
|
Default::default(),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
let informant_output_format = OutputFormat {
|
||||||
|
enable_color: false,
|
||||||
|
prefix: format!("[{}] ", key_seed),
|
||||||
|
};
|
||||||
|
|
||||||
|
network_config.boot_nodes = boot_nodes;
|
||||||
|
|
||||||
|
network_config.allow_non_globals_in_dht = true;
|
||||||
|
|
||||||
|
network_config
|
||||||
|
.listen_addresses
|
||||||
|
.push(multiaddr::Protocol::Memory(rand::random()).into());
|
||||||
|
|
||||||
|
network_config.transport = TransportConfig::MemoryOnly;
|
||||||
|
|
||||||
|
Configuration {
|
||||||
|
impl_name: "polkadot-test-node".to_string(),
|
||||||
|
impl_version: "0.1".to_string(),
|
||||||
|
role,
|
||||||
|
task_executor,
|
||||||
|
transaction_pool: Default::default(),
|
||||||
|
network: network_config,
|
||||||
|
keystore: KeystoreConfig::Path {
|
||||||
|
path: root.join("key"),
|
||||||
|
password: None,
|
||||||
|
},
|
||||||
|
database: DatabaseConfig::RocksDb {
|
||||||
|
path: root.join("db"),
|
||||||
|
cache_size: 128,
|
||||||
|
},
|
||||||
|
state_cache_size: 16777216,
|
||||||
|
state_cache_child_ratio: None,
|
||||||
|
pruning: Default::default(),
|
||||||
|
chain_spec: Box::new(spec),
|
||||||
|
wasm_method: WasmExecutionMethod::Interpreted,
|
||||||
|
// NOTE: we enforce the use of the native runtime to make the errors more debuggable
|
||||||
|
execution_strategies: ExecutionStrategies {
|
||||||
|
syncing: sc_client_api::ExecutionStrategy::NativeWhenPossible,
|
||||||
|
importing: sc_client_api::ExecutionStrategy::NativeWhenPossible,
|
||||||
|
block_construction: sc_client_api::ExecutionStrategy::NativeWhenPossible,
|
||||||
|
offchain_worker: sc_client_api::ExecutionStrategy::NativeWhenPossible,
|
||||||
|
other: sc_client_api::ExecutionStrategy::NativeWhenPossible,
|
||||||
|
},
|
||||||
|
rpc_http: None,
|
||||||
|
rpc_ws: None,
|
||||||
|
rpc_ipc: None,
|
||||||
|
rpc_ws_max_connections: None,
|
||||||
|
rpc_cors: None,
|
||||||
|
rpc_methods: Default::default(),
|
||||||
|
prometheus_config: None,
|
||||||
|
telemetry_endpoints: None,
|
||||||
|
telemetry_external_transport: None,
|
||||||
|
default_heap_pages: None,
|
||||||
|
offchain_worker: Default::default(),
|
||||||
|
force_authoring: false,
|
||||||
|
disable_grandpa: false,
|
||||||
|
dev_key_seed: Some(key_seed),
|
||||||
|
tracing_targets: None,
|
||||||
|
tracing_receiver: Default::default(),
|
||||||
|
max_runtime_instances: 8,
|
||||||
|
announce_block: true,
|
||||||
|
base_path: Some(base_path),
|
||||||
|
informant_output_format,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Run a Polkadot test node using the Polkadot test runtime. The node will be using an in-memory socket, therefore you
|
||||||
|
/// need to provide boot nodes if you want it to be connected to other nodes. The `storage_update_func` can be used to
|
||||||
|
/// make adjustements to the runtime before the node starts.
|
||||||
|
pub fn run_test_node(
|
||||||
|
task_executor: TaskExecutor,
|
||||||
|
key: Sr25519Keyring,
|
||||||
|
storage_update_func: impl Fn(),
|
||||||
|
boot_nodes: Vec<MultiaddrWithPeerId>,
|
||||||
|
) -> PolkadotTestNode<
|
||||||
|
TaskManager,
|
||||||
|
impl PolkadotClient<Block, TFullBackend<Block>, polkadot_test_runtime::RuntimeApi>,
|
||||||
|
> {
|
||||||
|
let config = node_config(storage_update_func, task_executor, key, boot_nodes);
|
||||||
|
let multiaddr = config.network.listen_addresses[0].clone();
|
||||||
|
let authority_discovery_enabled = false;
|
||||||
|
let (task_manager, client, handles, network, rpc_handlers) =
|
||||||
|
polkadot_test_new_full(config, None, None, authority_discovery_enabled, 6000)
|
||||||
|
.expect("could not create Polkadot test service");
|
||||||
|
|
||||||
|
let peer_id = network.local_peer_id().clone();
|
||||||
|
let addr = MultiaddrWithPeerId { multiaddr, peer_id };
|
||||||
|
|
||||||
|
PolkadotTestNode {
|
||||||
|
task_manager,
|
||||||
|
client,
|
||||||
|
handles,
|
||||||
|
addr,
|
||||||
|
rpc_handlers,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A Polkadot test node instance used for testing.
|
||||||
|
pub struct PolkadotTestNode<S, C> {
|
||||||
|
/// TaskManager's instance.
|
||||||
|
pub task_manager: S,
|
||||||
|
/// Client's instance.
|
||||||
|
pub client: Arc<C>,
|
||||||
|
/// Node's handles.
|
||||||
|
pub handles: FullNodeHandles,
|
||||||
|
/// The `MultiaddrWithPeerId` to this node. This is useful if you want to pass it as "boot node" to other nodes.
|
||||||
|
pub addr: MultiaddrWithPeerId,
|
||||||
|
/// RPCHandlers to make RPC queries.
|
||||||
|
pub rpc_handlers: Arc<RpcHandlers>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S, C> PolkadotTestNode<S, C>
|
||||||
|
where
|
||||||
|
C: HeaderBackend<Block>,
|
||||||
|
{
|
||||||
|
/// Send a transaction through RPCHandlers to call a function.
|
||||||
|
pub async fn call_function(
|
||||||
|
&self,
|
||||||
|
function: polkadot_test_runtime::Call,
|
||||||
|
caller: Sr25519Keyring,
|
||||||
|
) -> Result<RpcTransactionOutput, RpcTransactionError> {
|
||||||
|
let current_block_hash = self.client.info().best_hash;
|
||||||
|
let current_block = self.client.info().best_number.saturated_into();
|
||||||
|
let genesis_block = self.client.hash(0).unwrap().unwrap();
|
||||||
|
let nonce = 0;
|
||||||
|
let period = BlockHashCount::get()
|
||||||
|
.checked_next_power_of_two()
|
||||||
|
.map(|c| c / 2)
|
||||||
|
.unwrap_or(2) as u64;
|
||||||
|
let tip = 0;
|
||||||
|
let extra: SignedExtra = (
|
||||||
|
RestrictFunctionality,
|
||||||
|
frame_system::CheckSpecVersion::<Runtime>::new(),
|
||||||
|
frame_system::CheckTxVersion::<Runtime>::new(),
|
||||||
|
frame_system::CheckGenesis::<Runtime>::new(),
|
||||||
|
frame_system::CheckEra::<Runtime>::from(generic::Era::mortal(period, current_block)),
|
||||||
|
frame_system::CheckNonce::<Runtime>::from(nonce),
|
||||||
|
frame_system::CheckWeight::<Runtime>::new(),
|
||||||
|
pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(tip),
|
||||||
|
registrar::LimitParathreadCommits::<Runtime>::new(),
|
||||||
|
parachains::ValidateDoubleVoteReports::<Runtime>::new(),
|
||||||
|
);
|
||||||
|
let raw_payload = SignedPayload::from_raw(
|
||||||
|
function.clone(),
|
||||||
|
extra.clone(),
|
||||||
|
(
|
||||||
|
(),
|
||||||
|
VERSION.spec_version,
|
||||||
|
VERSION.transaction_version,
|
||||||
|
genesis_block,
|
||||||
|
current_block_hash,
|
||||||
|
(),
|
||||||
|
(),
|
||||||
|
(),
|
||||||
|
(),
|
||||||
|
(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
let signature = raw_payload.using_encoded(|e| caller.sign(e));
|
||||||
|
let extrinsic = polkadot_test_runtime::UncheckedExtrinsic::new_signed(
|
||||||
|
function.clone(),
|
||||||
|
polkadot_test_runtime::Address::Id(caller.public().into()),
|
||||||
|
polkadot_primitives::Signature::Sr25519(signature.clone()),
|
||||||
|
extra.clone(),
|
||||||
|
);
|
||||||
|
|
||||||
|
self.rpc_handlers.send_transaction(extrinsic.into()).await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S, C> PolkadotTestNode<S, C>
|
||||||
|
where
|
||||||
|
C: BlockchainEvents<Block>,
|
||||||
|
{
|
||||||
|
/// Wait for `count` blocks to be imported in the node and then exit. This function will not return if no blocks
|
||||||
|
/// are ever created, thus you should restrict the maximum amount of time of the test execution.
|
||||||
|
pub fn wait_for_blocks(&self, count: usize) -> impl Future<Output = ()> {
|
||||||
|
self.client.wait_for_blocks(count)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
// Copyright 2020 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Polkadot.
|
||||||
|
|
||||||
|
// Polkadot 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.
|
||||||
|
|
||||||
|
// Polkadot 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 Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
use tokio::{time::delay_for as sleep, task::spawn};
|
||||||
|
use futures::{future, pin_mut, select, FutureExt as _};
|
||||||
|
use polkadot_test_service::*;
|
||||||
|
use service::TaskExecutor;
|
||||||
|
use sp_keyring::Sr25519Keyring;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
static INTEGRATION_TEST_ALLOWED_TIME: Option<&str> = option_env!("INTEGRATION_TEST_ALLOWED_TIME");
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn ensure_test_service_build_blocks() {
|
||||||
|
let task_executor: TaskExecutor = (move |fut, _| {
|
||||||
|
spawn(fut);
|
||||||
|
})
|
||||||
|
.into();
|
||||||
|
let mut alice = run_test_node(
|
||||||
|
task_executor.clone(),
|
||||||
|
Sr25519Keyring::Alice,
|
||||||
|
|| {},
|
||||||
|
Vec::new(),
|
||||||
|
);
|
||||||
|
let mut bob = run_test_node(
|
||||||
|
task_executor.clone(),
|
||||||
|
Sr25519Keyring::Bob,
|
||||||
|
|| {},
|
||||||
|
vec![alice.addr.clone()],
|
||||||
|
);
|
||||||
|
let t1 = sleep(Duration::from_secs(
|
||||||
|
INTEGRATION_TEST_ALLOWED_TIME
|
||||||
|
.and_then(|x| x.parse().ok())
|
||||||
|
.unwrap_or(600),
|
||||||
|
))
|
||||||
|
.fuse();
|
||||||
|
let t2 = async {
|
||||||
|
{
|
||||||
|
let t1 = future::join(alice.wait_for_blocks(3), bob.wait_for_blocks(3)).fuse();
|
||||||
|
let t2 = alice.task_manager.future().fuse();
|
||||||
|
let t3 = bob.task_manager.future().fuse();
|
||||||
|
|
||||||
|
pin_mut!(t1, t2, t3);
|
||||||
|
|
||||||
|
select! {
|
||||||
|
_ = t1 => {},
|
||||||
|
_ = t2 => panic!("service Alice failed"),
|
||||||
|
_ = t3 => panic!("service Bob failed"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
alice.task_manager.terminate();
|
||||||
|
bob.task_manager.terminate();
|
||||||
|
}
|
||||||
|
.fuse();
|
||||||
|
|
||||||
|
pin_mut!(t1, t2);
|
||||||
|
|
||||||
|
select! {
|
||||||
|
_ = t1 => {
|
||||||
|
panic!("the test took too long, maybe no blocks have been produced");
|
||||||
|
},
|
||||||
|
_ = t2 => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
// Copyright 2020 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Polkadot.
|
||||||
|
|
||||||
|
// Polkadot 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.
|
||||||
|
|
||||||
|
// Polkadot 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 Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
use tokio::{time::delay_for as sleep, task::spawn};
|
||||||
|
use futures::{pin_mut, select, FutureExt as _};
|
||||||
|
use polkadot_test_service::*;
|
||||||
|
use sp_keyring::Sr25519Keyring::{Alice, Bob};
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
static INTEGRATION_TEST_ALLOWED_TIME: Option<&str> = option_env!("INTEGRATION_TEST_ALLOWED_TIME");
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn call_function_actually_work() {
|
||||||
|
let mut alice = run_test_node(
|
||||||
|
(move |fut, _| {
|
||||||
|
spawn(fut);
|
||||||
|
})
|
||||||
|
.into(),
|
||||||
|
Alice,
|
||||||
|
|| {},
|
||||||
|
Vec::new(),
|
||||||
|
);
|
||||||
|
let t1 = sleep(Duration::from_secs(
|
||||||
|
INTEGRATION_TEST_ALLOWED_TIME
|
||||||
|
.and_then(|x| x.parse().ok())
|
||||||
|
.unwrap_or(600),
|
||||||
|
))
|
||||||
|
.fuse();
|
||||||
|
let t2 = async {
|
||||||
|
let function = polkadot_test_runtime::Call::Balances(pallet_balances::Call::transfer(
|
||||||
|
Default::default(),
|
||||||
|
1,
|
||||||
|
));
|
||||||
|
let output = alice.call_function(function, Bob).await.unwrap();
|
||||||
|
|
||||||
|
let res = output.result.expect("return value expected");
|
||||||
|
let json = serde_json::from_str::<serde_json::Value>(res.as_str()).expect("valid JSON");
|
||||||
|
let object = json.as_object().expect("JSON is an object");
|
||||||
|
assert!(object.contains_key("jsonrpc"), "key jsonrpc exists");
|
||||||
|
let result = object.get("result");
|
||||||
|
let result = result.expect("key result exists");
|
||||||
|
assert_eq!(
|
||||||
|
result.as_str().map(|x| x.starts_with("0x")),
|
||||||
|
Some(true),
|
||||||
|
"result starts with 0x"
|
||||||
|
);
|
||||||
|
|
||||||
|
alice.task_manager.terminate();
|
||||||
|
}
|
||||||
|
.fuse();
|
||||||
|
|
||||||
|
pin_mut!(t1, t2);
|
||||||
|
|
||||||
|
select! {
|
||||||
|
_ = t1 => {
|
||||||
|
panic!("the test took too long, maybe no blocks have been produced");
|
||||||
|
},
|
||||||
|
_ = t2 => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,9 +14,11 @@ serde = { version = "1.0.102", default-features = false }
|
|||||||
serde_derive = { version = "1.0.102", optional = true }
|
serde_derive = { version = "1.0.102", optional = true }
|
||||||
smallvec = "1.4.1"
|
smallvec = "1.4.1"
|
||||||
|
|
||||||
|
authority-discovery-primitives = { package = "sp-authority-discovery", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||||
babe-primitives = { package = "sp-consensus-babe", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
babe-primitives = { package = "sp-consensus-babe", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||||
sp-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
sp-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||||
inherents = { package = "sp-inherents", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
inherents = { package = "sp-inherents", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||||
|
offchain-primitives = { package = "sp-offchain", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||||
rstd = { package = "sp-std", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
rstd = { package = "sp-std", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||||
sp-io = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
sp-io = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||||
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||||
@@ -27,6 +29,7 @@ version = { package = "sp-version", git = "https://github.com/paritytech/substra
|
|||||||
tx-pool-api = { package = "sp-transaction-pool", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
tx-pool-api = { package = "sp-transaction-pool", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||||
block-builder-api = { package = "sp-block-builder", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
block-builder-api = { package = "sp-block-builder", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||||
|
|
||||||
|
authority-discovery = { package = "pallet-authority-discovery", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||||
authorship = { package = "pallet-authorship", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
authorship = { package = "pallet-authorship", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||||
babe = { package = "pallet-babe", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
babe = { package = "pallet-babe", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||||
balances = { package = "pallet-balances", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
balances = { package = "pallet-balances", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||||
@@ -46,6 +49,7 @@ pallet-staking-reward-curve = { git = "https://github.com/paritytech/substrate",
|
|||||||
system = { package = "frame-system", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
system = { package = "frame-system", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||||
system_rpc_runtime_api = { package = "frame-system-rpc-runtime-api", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
system_rpc_runtime_api = { package = "frame-system-rpc-runtime-api", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||||
timestamp = { package = "pallet-timestamp", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
timestamp = { package = "pallet-timestamp", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||||
|
sudo = { package = "pallet-sudo", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||||
vesting = { package = "pallet-vesting", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
vesting = { package = "pallet-vesting", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||||
|
|
||||||
runtime-common = { package = "polkadot-runtime-common", path = "../common", default-features = false }
|
runtime-common = { package = "polkadot-runtime-common", path = "../common", default-features = false }
|
||||||
@@ -68,6 +72,8 @@ default = ["std"]
|
|||||||
no_std = []
|
no_std = []
|
||||||
only-staking = []
|
only-staking = []
|
||||||
std = [
|
std = [
|
||||||
|
"authority-discovery-primitives/std",
|
||||||
|
"authority-discovery/std",
|
||||||
"bitvec/std",
|
"bitvec/std",
|
||||||
"primitives/std",
|
"primitives/std",
|
||||||
"rustc-hex/std",
|
"rustc-hex/std",
|
||||||
@@ -78,6 +84,7 @@ std = [
|
|||||||
"sp-api/std",
|
"sp-api/std",
|
||||||
"tx-pool-api/std",
|
"tx-pool-api/std",
|
||||||
"block-builder-api/std",
|
"block-builder-api/std",
|
||||||
|
"offchain-primitives/std",
|
||||||
"rstd/std",
|
"rstd/std",
|
||||||
"sp-io/std",
|
"sp-io/std",
|
||||||
"frame-support/std",
|
"frame-support/std",
|
||||||
|
|||||||
@@ -6,19 +6,24 @@ edition = "2018"
|
|||||||
license = "GPL-3.0"
|
license = "GPL-3.0"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
futures = "0.3.1"
|
||||||
|
codec = { package = "parity-scale-codec", version = "1.0.0" }
|
||||||
|
|
||||||
|
# Polkadot dependencies
|
||||||
|
polkadot-primitives = { path = "../../../primitives" }
|
||||||
|
polkadot-runtime-common = { path = "../../common" }
|
||||||
|
polkadot-test-runtime = { path = ".." }
|
||||||
|
polkadot-test-service = { path = "../../../node/test-service" }
|
||||||
|
|
||||||
|
# Substrate dependencies
|
||||||
|
pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sc-block-builder = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sc-block-builder = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sc-consensus = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sc-consensus = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sc-light = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sc-light = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sc-service = { git = "https://github.com/paritytech/substrate", branch = "master", features = ["test-helpers"], default-features = false }
|
sc-service = { git = "https://github.com/paritytech/substrate", branch = "master", features = ["test-helpers"], default-features = false }
|
||||||
substrate-test-client = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
|
||||||
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
|
||||||
polkadot-test-runtime = { path = ".." }
|
|
||||||
polkadot-runtime-common = { path = "../../common" }
|
|
||||||
polkadot-primitives = { path = "../../../primitives" }
|
|
||||||
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
|
||||||
sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
codec = { package = "parity-scale-codec", version = "1.0.0" }
|
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
substrate-test-client = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
futures = "0.3.1"
|
|
||||||
|
|||||||
@@ -20,13 +20,18 @@
|
|||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
use std::convert::TryFrom;
|
||||||
pub use substrate_test_client::*;
|
pub use substrate_test_client::*;
|
||||||
pub use polkadot_test_runtime as runtime;
|
pub use polkadot_test_runtime as runtime;
|
||||||
|
|
||||||
use sp_core::{sr25519, ChangesTrieConfiguration, map, twox_128};
|
use sp_core::{ChangesTrieConfiguration, map, twox_128};
|
||||||
use sp_core::storage::{ChildInfo, Storage, StorageChild};
|
use sp_core::storage::{ChildInfo, Storage, StorageChild};
|
||||||
use polkadot_test_runtime::genesismap::GenesisConfig;
|
use polkadot_test_runtime::GenesisConfig;
|
||||||
use sp_runtime::traits::{Block as BlockT, Header as HeaderT, Hash as HashT, HashFor};
|
use polkadot_test_service::polkadot_local_testnet_genesis;
|
||||||
|
use sp_runtime::{
|
||||||
|
traits::{Block as BlockT, Header as HeaderT, Hash as HashT, HashFor},
|
||||||
|
BuildStorage,
|
||||||
|
};
|
||||||
use sc_consensus::LongestChain;
|
use sc_consensus::LongestChain;
|
||||||
use sc_client_api::light::{RemoteCallRequest, RemoteBodyRequest};
|
use sc_client_api::light::{RemoteCallRequest, RemoteBodyRequest};
|
||||||
use sc_service::client::{
|
use sc_service::client::{
|
||||||
@@ -89,16 +94,10 @@ pub struct GenesisParameters {
|
|||||||
|
|
||||||
impl GenesisParameters {
|
impl GenesisParameters {
|
||||||
fn genesis_config(&self) -> GenesisConfig {
|
fn genesis_config(&self) -> GenesisConfig {
|
||||||
GenesisConfig::new(
|
let config = polkadot_local_testnet_genesis(self.changes_trie_config.clone());
|
||||||
self.changes_trie_config.clone(),
|
config.assimilate_storage(&mut self.extra_storage.clone()).expect("Adding `system::GensisConfig` to the genesis");
|
||||||
vec![
|
|
||||||
sr25519::Public::from(Sr25519Keyring::Alice).into(),
|
config
|
||||||
sr25519::Public::from(Sr25519Keyring::Bob).into(),
|
|
||||||
sr25519::Public::from(Sr25519Keyring::Charlie).into(),
|
|
||||||
],
|
|
||||||
1000,
|
|
||||||
self.extra_storage.clone(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,7 +111,7 @@ impl substrate_test_client::GenesisInit for GenesisParameters {
|
|||||||
fn genesis_storage(&self) -> Storage {
|
fn genesis_storage(&self) -> Storage {
|
||||||
use codec::Encode;
|
use codec::Encode;
|
||||||
|
|
||||||
let mut storage = self.genesis_config().genesis_map();
|
let mut storage = self.genesis_config().build_storage().unwrap();
|
||||||
|
|
||||||
let child_roots = storage.children_default.iter().map(|(sk, child_content)| {
|
let child_roots = storage.children_default.iter().map(|(sk, child_content)| {
|
||||||
let state_root = <<<runtime::Block as BlockT>::Header as HeaderT>::Hashing as HashT>::trie_root(
|
let state_root = <<<runtime::Block as BlockT>::Header as HeaderT>::Hashing as HashT>::trie_root(
|
||||||
@@ -323,20 +322,28 @@ pub fn new_native_executor() -> sc_executor::NativeExecutor<LocalExecutor> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Extrinsics that must be included in each block.
|
/// Extrinsics that must be included in each block.
|
||||||
pub fn needed_extrinsics(heads: Vec<polkadot_primitives::parachain::AttestedCandidate>) -> Vec<polkadot_test_runtime::UncheckedExtrinsic> {
|
///
|
||||||
|
/// The index of the block must be provided to calculate a valid timestamp for the block. The value starts at 0 and
|
||||||
|
/// should be incremented by one for every block produced.
|
||||||
|
pub fn needed_extrinsics(
|
||||||
|
heads: Vec<polkadot_primitives::parachain::AttestedCandidate>,
|
||||||
|
i: u64,
|
||||||
|
) -> Vec<polkadot_test_runtime::UncheckedExtrinsic> {
|
||||||
use polkadot_runtime_common::parachains;
|
use polkadot_runtime_common::parachains;
|
||||||
|
|
||||||
|
let timestamp = std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH)
|
||||||
|
.expect("now always later than unix epoch; qed")
|
||||||
|
.as_millis() + (i * polkadot_test_runtime::constants::time::SLOT_DURATION / 2) as u128;
|
||||||
|
|
||||||
vec![
|
vec![
|
||||||
polkadot_test_runtime::UncheckedExtrinsic {
|
polkadot_test_runtime::UncheckedExtrinsic {
|
||||||
function: polkadot_test_runtime::Call::Parachains(parachains::Call::set_heads(heads)),
|
function: polkadot_test_runtime::Call::Parachains(parachains::Call::set_heads(heads)),
|
||||||
signature: None,
|
signature: None,
|
||||||
},
|
},
|
||||||
polkadot_test_runtime::UncheckedExtrinsic {
|
polkadot_test_runtime::UncheckedExtrinsic {
|
||||||
function: polkadot_test_runtime::Call::Timestamp(pallet_timestamp::Call::set({
|
function: polkadot_test_runtime::Call::Timestamp(pallet_timestamp::Call::set(
|
||||||
std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH)
|
u64::try_from(timestamp).expect("unexpected big timestamp"),
|
||||||
.expect("now always later than unix epoch; qed")
|
)),
|
||||||
.as_millis() as u64
|
|
||||||
})),
|
|
||||||
signature: None,
|
signature: None,
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,75 +0,0 @@
|
|||||||
// Copyright 2020 Parity Technologies (UK) Ltd.
|
|
||||||
// This file is part of Substrate.
|
|
||||||
|
|
||||||
// Substrate 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.
|
|
||||||
|
|
||||||
// Substrate 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 Substrate. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
//! Tool for creating the genesis block.
|
|
||||||
|
|
||||||
use std::collections::BTreeMap;
|
|
||||||
use super::{AccountId, WASM_BINARY, constants::currency};
|
|
||||||
use sp_core::ChangesTrieConfiguration;
|
|
||||||
use sp_core::storage::Storage;
|
|
||||||
use sp_runtime::BuildStorage;
|
|
||||||
|
|
||||||
/// Configuration of a general Substrate test genesis block.
|
|
||||||
pub struct GenesisConfig {
|
|
||||||
changes_trie_config: Option<ChangesTrieConfiguration>,
|
|
||||||
balances: Vec<(AccountId, u128)>,
|
|
||||||
/// Additional storage key pairs that will be added to the genesis map.
|
|
||||||
extra_storage: Storage,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GenesisConfig {
|
|
||||||
pub fn new(
|
|
||||||
changes_trie_config: Option<ChangesTrieConfiguration>,
|
|
||||||
endowed_accounts: Vec<AccountId>,
|
|
||||||
balance: u128,
|
|
||||||
extra_storage: Storage,
|
|
||||||
) -> Self {
|
|
||||||
GenesisConfig {
|
|
||||||
changes_trie_config,
|
|
||||||
balances: endowed_accounts.into_iter().map(|a| (a, balance * currency::DOLLARS)).collect(),
|
|
||||||
extra_storage,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn genesis_map(&self) -> Storage {
|
|
||||||
// Assimilate the system genesis config.
|
|
||||||
let mut storage = Storage {
|
|
||||||
top: BTreeMap::new(),
|
|
||||||
children_default: self.extra_storage.children_default.clone(),
|
|
||||||
};
|
|
||||||
let config = crate::GenesisConfig {
|
|
||||||
system: Some(system::GenesisConfig {
|
|
||||||
changes_trie_config: self.changes_trie_config.clone(),
|
|
||||||
code: WASM_BINARY.to_vec(),
|
|
||||||
}),
|
|
||||||
babe: None,
|
|
||||||
indices: None,
|
|
||||||
balances: Some(balances::GenesisConfig {
|
|
||||||
balances: self.balances.clone()
|
|
||||||
}),
|
|
||||||
staking: None,
|
|
||||||
session: None,
|
|
||||||
grandpa: None,
|
|
||||||
claims: None,
|
|
||||||
parachains: None,
|
|
||||||
registrar: None,
|
|
||||||
vesting: None,
|
|
||||||
};
|
|
||||||
config.assimilate_storage(&mut storage).expect("Adding `system::GensisConfig` to the genesis");
|
|
||||||
|
|
||||||
storage
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -55,6 +55,7 @@ use frame_support::{
|
|||||||
traits::{KeyOwnerProofSystem, Randomness},
|
traits::{KeyOwnerProofSystem, Randomness},
|
||||||
weights::Weight,
|
weights::Weight,
|
||||||
};
|
};
|
||||||
|
use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId;
|
||||||
use pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo;
|
use pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo;
|
||||||
use session::historical as session_historical;
|
use session::historical as session_historical;
|
||||||
|
|
||||||
@@ -69,8 +70,6 @@ pub use parachains::Call as ParachainsCall;
|
|||||||
|
|
||||||
/// Constant values used within the runtime.
|
/// Constant values used within the runtime.
|
||||||
pub mod constants;
|
pub mod constants;
|
||||||
#[cfg(feature = "std")]
|
|
||||||
pub mod genesismap;
|
|
||||||
use constants::{time::*, currency::*, fee::*};
|
use constants::{time::*, currency::*, fee::*};
|
||||||
|
|
||||||
// Make the WASM binary available.
|
// Make the WASM binary available.
|
||||||
@@ -166,8 +165,8 @@ impl<C> system::offchain::SendTransactionTypes<C> for Runtime where
|
|||||||
}
|
}
|
||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
pub const EpochDuration: u64 = EPOCH_DURATION_IN_BLOCKS as u64;
|
pub storage EpochDuration: u64 = EPOCH_DURATION_IN_BLOCKS as u64;
|
||||||
pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK;
|
pub storage ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl babe::Trait for Runtime {
|
impl babe::Trait for Runtime {
|
||||||
@@ -193,7 +192,7 @@ impl babe::Trait for Runtime {
|
|||||||
}
|
}
|
||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
pub const IndexDeposit: Balance = 1 * DOLLARS;
|
pub storage IndexDeposit: Balance = 1 * DOLLARS;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl indices::Trait for Runtime {
|
impl indices::Trait for Runtime {
|
||||||
@@ -205,7 +204,7 @@ impl indices::Trait for Runtime {
|
|||||||
}
|
}
|
||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
pub const ExistentialDeposit: Balance = 1 * CENTS;
|
pub storage ExistentialDeposit: Balance = 1 * CENTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl balances::Trait for Runtime {
|
impl balances::Trait for Runtime {
|
||||||
@@ -218,7 +217,7 @@ impl balances::Trait for Runtime {
|
|||||||
}
|
}
|
||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
pub const TransactionByteFee: Balance = 10 * MILLICENTS;
|
pub storage TransactionByteFee: Balance = 10 * MILLICENTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl transaction_payment::Trait for Runtime {
|
impl transaction_payment::Trait for Runtime {
|
||||||
@@ -230,7 +229,8 @@ impl transaction_payment::Trait for Runtime {
|
|||||||
}
|
}
|
||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
pub const MinimumPeriod: u64 = 0;
|
pub storage SlotDuration: u64 = SLOT_DURATION;
|
||||||
|
pub storage MinimumPeriod: u64 = SlotDuration::get() / 2;
|
||||||
}
|
}
|
||||||
impl timestamp::Trait for Runtime {
|
impl timestamp::Trait for Runtime {
|
||||||
type Moment = u64;
|
type Moment = u64;
|
||||||
@@ -240,7 +240,7 @@ impl timestamp::Trait for Runtime {
|
|||||||
}
|
}
|
||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
pub const UncleGenerations: u32 = 0;
|
pub storage UncleGenerations: u32 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: substrate#2986 implement this properly
|
// TODO: substrate#2986 implement this properly
|
||||||
@@ -252,8 +252,8 @@ impl authorship::Trait for Runtime {
|
|||||||
}
|
}
|
||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
pub const Period: BlockNumber = 10 * MINUTES;
|
pub storage Period: BlockNumber = 10 * MINUTES;
|
||||||
pub const Offset: BlockNumber = 0;
|
pub storage Offset: BlockNumber = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_opaque_keys! {
|
impl_opaque_keys! {
|
||||||
@@ -265,7 +265,7 @@ impl_opaque_keys! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(17);
|
pub storage DisabledValidatorsThreshold: Perbill = Perbill::from_percent(17);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl session::Trait for Runtime {
|
impl session::Trait for Runtime {
|
||||||
@@ -299,16 +299,16 @@ pallet_staking_reward_curve::build! {
|
|||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
// Six sessions in an era (6 hours).
|
// Six sessions in an era (6 hours).
|
||||||
pub const SessionsPerEra: SessionIndex = 6;
|
pub storage SessionsPerEra: SessionIndex = 6;
|
||||||
// 28 eras for unbonding (7 days).
|
// 28 eras for unbonding (7 days).
|
||||||
pub const BondingDuration: staking::EraIndex = 28;
|
pub storage BondingDuration: staking::EraIndex = 28;
|
||||||
// 28 eras in which slashes can be cancelled (7 days).
|
// 28 eras in which slashes can be cancelled (7 days).
|
||||||
pub const SlashDeferDuration: staking::EraIndex = 28;
|
pub storage SlashDeferDuration: staking::EraIndex = 28;
|
||||||
pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE;
|
pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE;
|
||||||
pub const MaxNominatorRewardedPerValidator: u32 = 64;
|
pub storage MaxNominatorRewardedPerValidator: u32 = 64;
|
||||||
pub const ElectionLookahead: BlockNumber = 0;
|
pub storage ElectionLookahead: BlockNumber = 0;
|
||||||
pub const StakingUnsignedPriority: TransactionPriority = TransactionPriority::max_value() / 2;
|
pub storage StakingUnsignedPriority: TransactionPriority = TransactionPriority::max_value() / 2;
|
||||||
pub const MaxIterations: u32 = 10;
|
pub storage MaxIterations: u32 = 10;
|
||||||
pub MinSolutionScoreBump: Perbill = Perbill::from_rational_approximation(5u32, 10_000);
|
pub MinSolutionScoreBump: Perbill = Perbill::from_rational_approximation(5u32, 10_000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -366,12 +366,12 @@ impl attestations::Trait for Runtime {
|
|||||||
}
|
}
|
||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
pub const MaxCodeSize: u32 = 10 * 1024 * 1024; // 10 MB
|
pub storage MaxCodeSize: u32 = 10 * 1024 * 1024; // 10 MB
|
||||||
pub const MaxHeadDataSize: u32 = 20 * 1024; // 20 KB
|
pub storage MaxHeadDataSize: u32 = 20 * 1024; // 20 KB
|
||||||
|
|
||||||
pub const ValidationUpgradeFrequency: BlockNumber = 2;
|
pub storage ValidationUpgradeFrequency: BlockNumber = 2;
|
||||||
pub const ValidationUpgradeDelay: BlockNumber = 1;
|
pub storage ValidationUpgradeDelay: BlockNumber = 1;
|
||||||
pub const SlashPeriod: BlockNumber = 1 * MINUTES;
|
pub storage SlashPeriod: BlockNumber = 1 * MINUTES;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl parachains::Trait for Runtime {
|
impl parachains::Trait for Runtime {
|
||||||
@@ -447,7 +447,7 @@ impl system::offchain::SigningTypes for Runtime {
|
|||||||
}
|
}
|
||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
pub OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) * MaximumBlockWeight::get();
|
pub storage OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) * MaximumBlockWeight::get();
|
||||||
}
|
}
|
||||||
|
|
||||||
impl offences::Trait for Runtime {
|
impl offences::Trait for Runtime {
|
||||||
@@ -458,10 +458,12 @@ impl offences::Trait for Runtime {
|
|||||||
type WeightInfo = ();
|
type WeightInfo = ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl authority_discovery::Trait for Runtime {}
|
||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
pub const ParathreadDeposit: Balance = 5 * DOLLARS;
|
pub storage ParathreadDeposit: Balance = 5 * DOLLARS;
|
||||||
pub const QueueSize: usize = 2;
|
pub const QueueSize: usize = 2;
|
||||||
pub const MaxRetries: u32 = 3;
|
pub storage MaxRetries: u32 = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl registrar::Trait for Runtime {
|
impl registrar::Trait for Runtime {
|
||||||
@@ -475,8 +477,8 @@ impl registrar::Trait for Runtime {
|
|||||||
}
|
}
|
||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
pub const LeasePeriod: BlockNumber = 100_000;
|
pub storage LeasePeriod: BlockNumber = 100_000;
|
||||||
pub const EndingPeriod: BlockNumber = 1000;
|
pub storage EndingPeriod: BlockNumber = 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl slots::Trait for Runtime {
|
impl slots::Trait for Runtime {
|
||||||
@@ -500,7 +502,7 @@ impl claims::Trait for Runtime {
|
|||||||
}
|
}
|
||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
pub const MinVestedTransfer: Balance = 100 * DOLLARS;
|
pub storage MinVestedTransfer: Balance = 100 * DOLLARS;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl vesting::Trait for Runtime {
|
impl vesting::Trait for Runtime {
|
||||||
@@ -511,6 +513,11 @@ impl vesting::Trait for Runtime {
|
|||||||
type WeightInfo = ();
|
type WeightInfo = ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl sudo::Trait for Runtime {
|
||||||
|
type Event = Event;
|
||||||
|
type Call = Call;
|
||||||
|
}
|
||||||
|
|
||||||
construct_runtime! {
|
construct_runtime! {
|
||||||
pub enum Runtime where
|
pub enum Runtime where
|
||||||
Block = Block,
|
Block = Block,
|
||||||
@@ -536,6 +543,7 @@ construct_runtime! {
|
|||||||
Historical: session_historical::{Module},
|
Historical: session_historical::{Module},
|
||||||
Session: session::{Module, Call, Storage, Event, Config<T>},
|
Session: session::{Module, Call, Storage, Event, Config<T>},
|
||||||
Grandpa: grandpa::{Module, Call, Storage, Config, Event},
|
Grandpa: grandpa::{Module, Call, Storage, Config, Event},
|
||||||
|
AuthorityDiscovery: authority_discovery::{Module, Call, Config},
|
||||||
|
|
||||||
// Claims. Usable initially.
|
// Claims. Usable initially.
|
||||||
Claims: claims::{Module, Call, Storage, Event<T>, Config<T>, ValidateUnsigned},
|
Claims: claims::{Module, Call, Storage, Event<T>, Config<T>, ValidateUnsigned},
|
||||||
@@ -549,6 +557,9 @@ construct_runtime! {
|
|||||||
|
|
||||||
// Vesting. Usable initially, but removed once all vesting is finished.
|
// Vesting. Usable initially, but removed once all vesting is finished.
|
||||||
Vesting: vesting::{Module, Call, Storage, Event<T>, Config<T>},
|
Vesting: vesting::{Module, Call, Storage, Event<T>, Config<T>},
|
||||||
|
|
||||||
|
// Sudo. Last module.
|
||||||
|
Sudo: sudo::{Module, Call, Storage, Config<T>, Event<T>},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -642,6 +653,18 @@ sp_api::impl_runtime_apis! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl offchain_primitives::OffchainWorkerApi<Block> for Runtime {
|
||||||
|
fn offchain_worker(header: &<Block as BlockT>::Header) {
|
||||||
|
Executive::offchain_worker(header)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl authority_discovery_primitives::AuthorityDiscoveryApi<Block> for Runtime {
|
||||||
|
fn authorities() -> Vec<AuthorityDiscoveryId> {
|
||||||
|
Vec::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl parachain::ParachainHost<Block> for Runtime {
|
impl parachain::ParachainHost<Block> for Runtime {
|
||||||
fn validators() -> Vec<parachain::ValidatorId> {
|
fn validators() -> Vec<parachain::ValidatorId> {
|
||||||
Parachains::authorities()
|
Parachains::authorities()
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ use sp_runtime::traits::{Block as BlockT, NumberFor};
|
|||||||
/// same last finalized block) after a given block at height `N` has been
|
/// same last finalized block) after a given block at height `N` has been
|
||||||
/// finalized and for a delay of `M` blocks, i.e. until the best block reaches
|
/// finalized and for a delay of `M` blocks, i.e. until the best block reaches
|
||||||
/// `N` + `M`, the voter will keep voting for block `N`.
|
/// `N` + `M`, the voter will keep voting for block `N`.
|
||||||
pub(crate) struct PauseAfterBlockFor<N>(pub(crate) N, pub(crate) N);
|
pub struct PauseAfterBlockFor<N>(pub N, pub N);
|
||||||
|
|
||||||
impl<Block, B> grandpa::VotingRule<Block, B> for PauseAfterBlockFor<NumberFor<Block>> where
|
impl<Block, B> grandpa::VotingRule<Block, B> for PauseAfterBlockFor<NumberFor<Block>> where
|
||||||
Block: BlockT,
|
Block: BlockT,
|
||||||
@@ -250,17 +250,21 @@ mod tests {
|
|||||||
|
|
||||||
let mut push_blocks = {
|
let mut push_blocks = {
|
||||||
let mut client = client.clone();
|
let mut client = client.clone();
|
||||||
|
let mut base = 0;
|
||||||
|
|
||||||
move |n| {
|
move |n| {
|
||||||
for _ in 0..n {
|
for i in 0..n {
|
||||||
let mut builder = client.new_block(Default::default()).unwrap();
|
let mut builder = client.new_block(Default::default()).unwrap();
|
||||||
|
|
||||||
for extrinsic in polkadot_test_runtime_client::needed_extrinsics(vec![]) {
|
for extrinsic in polkadot_test_runtime_client::needed_extrinsics(vec![], base + i) {
|
||||||
builder.push(extrinsic).unwrap()
|
builder.push(extrinsic).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
let block = builder.build().unwrap().block;
|
let block = builder.build().unwrap().block;
|
||||||
client.import(BlockOrigin::Own, block).unwrap();
|
client.import(BlockOrigin::Own, block).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
base += n;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+141
-79
@@ -17,7 +17,7 @@
|
|||||||
//! Polkadot service. Specialized wrapper over substrate service.
|
//! Polkadot service. Specialized wrapper over substrate service.
|
||||||
|
|
||||||
pub mod chain_spec;
|
pub mod chain_spec;
|
||||||
mod grandpa_support;
|
pub mod grandpa_support;
|
||||||
mod client;
|
mod client;
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@@ -136,27 +136,20 @@ impl IdentifyVariant for Box<dyn ChainSpec> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're using prometheus, use a registry with a prefix of `polkadot`.
|
|
||||||
fn set_prometheus_registry(config: &mut Configuration) -> Result<(), ServiceError> {
|
|
||||||
if let Some(PrometheusConfig { registry, .. }) = config.prometheus_config.as_mut() {
|
|
||||||
*registry = Registry::new_custom(Some("polkadot".into()), None)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Starts a `ServiceBuilder` for a full service.
|
/// Starts a `ServiceBuilder` for a full service.
|
||||||
///
|
///
|
||||||
/// Use this macro if you don't actually need the full service, but just the builder in order to
|
/// Use this macro if you don't actually need the full service, but just the builder in order to
|
||||||
/// be able to perform chain operations.
|
/// be able to perform chain operations.
|
||||||
|
#[macro_export]
|
||||||
macro_rules! new_full_start {
|
macro_rules! new_full_start {
|
||||||
($config:expr, $runtime:ty, $executor:ty) => {{
|
(prometheus_setup $config:expr) => {{
|
||||||
set_prometheus_registry(&mut $config)?;
|
// If we're using prometheus, use a registry with a prefix of `polkadot`.
|
||||||
|
if let Some(PrometheusConfig { registry, .. }) = $config.prometheus_config.as_mut() {
|
||||||
let mut import_setup = None;
|
*registry = Registry::new_custom(Some("polkadot".into()), None)?;
|
||||||
let mut rpc_setup = None;
|
}
|
||||||
let inherent_data_providers = inherents::InherentDataProviders::new();
|
}};
|
||||||
let builder = service::ServiceBuilder::new_full::<
|
(start_builder $config:expr, $runtime:ty, $executor:ty $(,)?) => {{
|
||||||
|
service::ServiceBuilder::new_full::<
|
||||||
Block, $runtime, $executor
|
Block, $runtime, $executor
|
||||||
>($config)?
|
>($config)?
|
||||||
.with_select_chain(|_, backend| {
|
.with_select_chain(|_, backend| {
|
||||||
@@ -174,56 +167,58 @@ macro_rules! new_full_start {
|
|||||||
);
|
);
|
||||||
Ok(pool)
|
Ok(pool)
|
||||||
})?
|
})?
|
||||||
.with_import_queue(|
|
}};
|
||||||
config,
|
(import_queue_setup
|
||||||
|
$builder:expr, $inherent_data_providers:expr, $import_setup:expr, $grandpa_hard_forks:expr, $(,)?
|
||||||
|
) => {{
|
||||||
|
$builder.with_import_queue(|
|
||||||
|
_config,
|
||||||
|
client,
|
||||||
|
mut select_chain,
|
||||||
|
_,
|
||||||
|
spawn_task_handle,
|
||||||
|
registry,
|
||||||
|
| {
|
||||||
|
let select_chain = select_chain.take()
|
||||||
|
.ok_or_else(|| service::Error::SelectChainRequired)?;
|
||||||
|
|
||||||
|
let (grandpa_block_import, grandpa_link) =
|
||||||
|
grandpa::block_import_with_authority_set_hard_forks(
|
||||||
|
client.clone(),
|
||||||
|
&(client.clone() as Arc<_>),
|
||||||
|
select_chain.clone(),
|
||||||
|
$grandpa_hard_forks,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let justification_import = grandpa_block_import.clone();
|
||||||
|
|
||||||
|
let (block_import, babe_link) = babe::block_import(
|
||||||
|
babe::Config::get_or_compute(&*client)?,
|
||||||
|
grandpa_block_import,
|
||||||
|
client.clone(),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let import_queue = babe::import_queue(
|
||||||
|
babe_link.clone(),
|
||||||
|
block_import.clone(),
|
||||||
|
Some(Box::new(justification_import)),
|
||||||
|
None,
|
||||||
client,
|
client,
|
||||||
mut select_chain,
|
select_chain,
|
||||||
_,
|
$inherent_data_providers.clone(),
|
||||||
spawn_task_handle,
|
spawn_task_handle,
|
||||||
registry,
|
registry,
|
||||||
| {
|
)?;
|
||||||
let select_chain = select_chain.take()
|
|
||||||
.ok_or_else(|| service::Error::SelectChainRequired)?;
|
|
||||||
|
|
||||||
let grandpa_hard_forks = if config.chain_spec.is_kusama() {
|
$import_setup = Some((block_import, grandpa_link, babe_link));
|
||||||
grandpa_support::kusama_hard_forks()
|
Ok(import_queue)
|
||||||
} else {
|
})?
|
||||||
Vec::new()
|
}};
|
||||||
};
|
(finish_builder_setup $builder:expr, $inherent_data_providers:expr, $import_setup:expr) => {{
|
||||||
|
let mut rpc_setup = None;
|
||||||
|
|
||||||
let (grandpa_block_import, grandpa_link) =
|
let builder = $builder.with_rpc_extensions_builder(|builder| {
|
||||||
grandpa::block_import_with_authority_set_hard_forks(
|
let grandpa_link = $import_setup.as_ref().map(|s| &s.1)
|
||||||
client.clone(),
|
|
||||||
&(client.clone() as Arc<_>),
|
|
||||||
select_chain.clone(),
|
|
||||||
grandpa_hard_forks,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let justification_import = grandpa_block_import.clone();
|
|
||||||
|
|
||||||
let (block_import, babe_link) = babe::block_import(
|
|
||||||
babe::Config::get_or_compute(&*client)?,
|
|
||||||
grandpa_block_import,
|
|
||||||
client.clone(),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let import_queue = babe::import_queue(
|
|
||||||
babe_link.clone(),
|
|
||||||
block_import.clone(),
|
|
||||||
Some(Box::new(justification_import)),
|
|
||||||
None,
|
|
||||||
client,
|
|
||||||
select_chain,
|
|
||||||
inherent_data_providers.clone(),
|
|
||||||
spawn_task_handle,
|
|
||||||
registry,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
import_setup = Some((block_import, grandpa_link, babe_link));
|
|
||||||
Ok(import_queue)
|
|
||||||
})?
|
|
||||||
.with_rpc_extensions_builder(|builder| {
|
|
||||||
let grandpa_link = import_setup.as_ref().map(|s| &s.1)
|
|
||||||
.expect("GRANDPA LinkHalf is present for full services or set up failed; qed.");
|
.expect("GRANDPA LinkHalf is present for full services or set up failed; qed.");
|
||||||
|
|
||||||
let shared_authority_set = grandpa_link.shared_authority_set().clone();
|
let shared_authority_set = grandpa_link.shared_authority_set().clone();
|
||||||
@@ -231,7 +226,7 @@ macro_rules! new_full_start {
|
|||||||
|
|
||||||
rpc_setup = Some((shared_voter_state.clone()));
|
rpc_setup = Some((shared_voter_state.clone()));
|
||||||
|
|
||||||
let babe_link = import_setup.as_ref().map(|s| &s.2)
|
let babe_link = $import_setup.as_ref().map(|s| &s.2)
|
||||||
.expect("BabeLink is present for full services or set up faile; qed.");
|
.expect("BabeLink is present for full services or set up faile; qed.");
|
||||||
|
|
||||||
let babe_config = babe_link.config().clone();
|
let babe_config = babe_link.config().clone();
|
||||||
@@ -264,22 +259,47 @@ macro_rules! new_full_start {
|
|||||||
})
|
})
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
(builder, import_setup, inherent_data_providers, rpc_setup)
|
(builder, $import_setup, $inherent_data_providers, rpc_setup)
|
||||||
}}
|
}};
|
||||||
|
($config:expr, $runtime:ty, $executor:ty $(,)?) => {{
|
||||||
|
let inherent_data_providers = inherents::InherentDataProviders::new();
|
||||||
|
let mut import_setup = None;
|
||||||
|
new_full_start!(prometheus_setup $config);
|
||||||
|
let grandpa_hard_forks = if $config.chain_spec.is_kusama() {
|
||||||
|
$crate::grandpa_support::kusama_hard_forks()
|
||||||
|
} else {
|
||||||
|
Vec::new()
|
||||||
|
};
|
||||||
|
let builder = new_full_start!(start_builder $config, $runtime, $executor);
|
||||||
|
let builder = new_full_start!(import_queue_setup
|
||||||
|
builder, inherent_data_providers, import_setup, grandpa_hard_forks,
|
||||||
|
);
|
||||||
|
new_full_start!(finish_builder_setup builder, inherent_data_providers, import_setup)
|
||||||
|
}};
|
||||||
|
(test $config:expr, $runtime:ty, $executor:ty $(,)?) => {{
|
||||||
|
let inherent_data_providers = inherents::InherentDataProviders::new();
|
||||||
|
let mut import_setup = None;
|
||||||
|
let grandpa_hard_forks = Vec::new();
|
||||||
|
let builder = new_full_start!(start_builder $config, $runtime, $executor);
|
||||||
|
let builder = new_full_start!(import_queue_setup
|
||||||
|
builder, inherent_data_providers, import_setup, grandpa_hard_forks,
|
||||||
|
);
|
||||||
|
new_full_start!(finish_builder_setup builder, inherent_data_providers, import_setup)
|
||||||
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builds a new service for a full client.
|
/// Builds a new service for a full client.
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! new_full {
|
macro_rules! new_full {
|
||||||
(
|
(
|
||||||
|
with_full_start
|
||||||
$config:expr,
|
$config:expr,
|
||||||
$collating_for:expr,
|
$collating_for:expr,
|
||||||
$max_block_data_size:expr,
|
$max_block_data_size:expr,
|
||||||
$authority_discovery_enabled:expr,
|
$authority_discovery_enabled:expr,
|
||||||
$slot_duration:expr,
|
$slot_duration:expr,
|
||||||
$grandpa_pause:expr,
|
$grandpa_pause:expr,
|
||||||
$runtime:ty,
|
$new_full_start:expr $(,)?
|
||||||
$dispatch:ty,
|
|
||||||
) => {{
|
) => {{
|
||||||
use sc_network::Event;
|
use sc_network::Event;
|
||||||
use sc_client_api::ExecutorProvider;
|
use sc_client_api::ExecutorProvider;
|
||||||
@@ -290,22 +310,21 @@ macro_rules! new_full {
|
|||||||
let role = $config.role.clone();
|
let role = $config.role.clone();
|
||||||
let is_authority = role.is_authority() && !is_collator;
|
let is_authority = role.is_authority() && !is_collator;
|
||||||
let force_authoring = $config.force_authoring;
|
let force_authoring = $config.force_authoring;
|
||||||
let max_block_data_size = $max_block_data_size;
|
|
||||||
let db_path = match $config.database.path() {
|
let db_path = match $config.database.path() {
|
||||||
Some(path) => std::path::PathBuf::from(path),
|
Some(path) => std::path::PathBuf::from(path),
|
||||||
None => return Err("Starting a Polkadot service with a custom database isn't supported".to_string().into()),
|
None => return Err("Starting a Polkadot service with a custom database isn't supported".to_string().into()),
|
||||||
};
|
};
|
||||||
|
let max_block_data_size = $max_block_data_size;
|
||||||
let disable_grandpa = $config.disable_grandpa;
|
let disable_grandpa = $config.disable_grandpa;
|
||||||
let name = $config.network.node_name.clone();
|
let name = $config.network.node_name.clone();
|
||||||
let authority_discovery_enabled = $authority_discovery_enabled;
|
let authority_discovery_enabled = $authority_discovery_enabled;
|
||||||
let slot_duration = $slot_duration;
|
let slot_duration = $slot_duration;
|
||||||
|
|
||||||
let (builder, mut import_setup, inherent_data_providers, mut rpc_setup) =
|
let (builder, mut import_setup, inherent_data_providers, mut rpc_setup) = $new_full_start;
|
||||||
new_full_start!($config, $runtime, $dispatch);
|
|
||||||
|
|
||||||
let ServiceComponents {
|
let ServiceComponents {
|
||||||
client, network, select_chain, keystore, transaction_pool, prometheus_registry,
|
client, network, select_chain, keystore, transaction_pool, prometheus_registry,
|
||||||
task_manager, telemetry_on_connect_sinks, ..
|
task_manager, telemetry_on_connect_sinks, rpc_handlers, ..
|
||||||
} = builder
|
} = builder
|
||||||
.with_finality_proof_provider(|client, backend| {
|
.with_finality_proof_provider(|client, backend| {
|
||||||
let provider = client as Arc<dyn grandpa::StorageAndProofProvider<_, _>>;
|
let provider = client as Arc<dyn grandpa::StorageAndProofProvider<_, _>>;
|
||||||
@@ -510,7 +529,7 @@ macro_rules! new_full {
|
|||||||
);
|
);
|
||||||
|
|
||||||
grandpa::VotingRulesBuilder::default()
|
grandpa::VotingRulesBuilder::default()
|
||||||
.add(grandpa_support::PauseAfterBlockFor(block, delay))
|
.add($crate::grandpa_support::PauseAfterBlockFor(block, delay))
|
||||||
.build()
|
.build()
|
||||||
},
|
},
|
||||||
None =>
|
None =>
|
||||||
@@ -542,15 +561,58 @@ macro_rules! new_full {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handles.polkadot_network = Some(polkadot_network_service);
|
handles.polkadot_network = Some(polkadot_network_service);
|
||||||
(task_manager, client, handles)
|
(task_manager, client, handles, network, rpc_handlers)
|
||||||
}}
|
}};
|
||||||
|
(
|
||||||
|
$config:expr,
|
||||||
|
$collating_for:expr,
|
||||||
|
$max_block_data_size:expr,
|
||||||
|
$authority_discovery_enabled:expr,
|
||||||
|
$slot_duration:expr,
|
||||||
|
$grandpa_pause:expr,
|
||||||
|
$runtime:ty,
|
||||||
|
$dispatch:ty,
|
||||||
|
) => {{
|
||||||
|
new_full!(with_full_start
|
||||||
|
$config,
|
||||||
|
$collating_for,
|
||||||
|
$max_block_data_size,
|
||||||
|
$authority_discovery_enabled,
|
||||||
|
$slot_duration,
|
||||||
|
$grandpa_pause,
|
||||||
|
new_full_start!($config, $runtime, $dispatch),
|
||||||
|
)
|
||||||
|
}};
|
||||||
|
(
|
||||||
|
test
|
||||||
|
$config:expr,
|
||||||
|
$collating_for:expr,
|
||||||
|
$max_block_data_size:expr,
|
||||||
|
$authority_discovery_enabled:expr,
|
||||||
|
$slot_duration:expr,
|
||||||
|
$runtime:ty,
|
||||||
|
$dispatch:ty,
|
||||||
|
) => {{
|
||||||
|
new_full!(with_full_start
|
||||||
|
$config,
|
||||||
|
$collating_for,
|
||||||
|
$max_block_data_size,
|
||||||
|
$authority_discovery_enabled,
|
||||||
|
$slot_duration,
|
||||||
|
None,
|
||||||
|
new_full_start!(test $config, $runtime, $dispatch),
|
||||||
|
)
|
||||||
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builds a new service for a light client.
|
/// Builds a new service for a light client.
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! new_light {
|
macro_rules! new_light {
|
||||||
($config:expr, $runtime:ty, $dispatch:ty) => {{
|
($config:expr, $runtime:ty, $dispatch:ty) => {{
|
||||||
crate::set_prometheus_registry(&mut $config)?;
|
// If we're using prometheus, use a registry with a prefix of `polkadot`.
|
||||||
|
if let Some(PrometheusConfig { registry, .. }) = $config.prometheus_config.as_mut() {
|
||||||
|
*registry = Registry::new_custom(Some("polkadot".into()), None)?;
|
||||||
|
}
|
||||||
let inherent_data_providers = inherents::InherentDataProviders::new();
|
let inherent_data_providers = inherents::InherentDataProviders::new();
|
||||||
|
|
||||||
ServiceBuilder::new_light::<Block, $runtime, $dispatch>($config)?
|
ServiceBuilder::new_light::<Block, $runtime, $dispatch>($config)?
|
||||||
@@ -646,7 +708,7 @@ macro_rules! new_light {
|
|||||||
/// Builds a new object suitable for chain operations.
|
/// Builds a new object suitable for chain operations.
|
||||||
pub fn new_chain_ops<Runtime, Dispatch, Extrinsic>(mut config: Configuration) -> Result<
|
pub fn new_chain_ops<Runtime, Dispatch, Extrinsic>(mut config: Configuration) -> Result<
|
||||||
(
|
(
|
||||||
Arc<service::TFullClient<Block, Runtime, Dispatch>>,
|
Arc<service::TFullClient<Block, Runtime, Dispatch>>,
|
||||||
Arc<TFullBackend<Block>>,
|
Arc<TFullBackend<Block>>,
|
||||||
consensus_common::import_queue::BasicQueue<Block, PrefixedMemoryDB<BlakeTwo256>>,
|
consensus_common::import_queue::BasicQueue<Block, PrefixedMemoryDB<BlakeTwo256>>,
|
||||||
TaskManager,
|
TaskManager,
|
||||||
@@ -685,7 +747,7 @@ pub fn polkadot_new_full(
|
|||||||
FullNodeHandles,
|
FullNodeHandles,
|
||||||
), ServiceError>
|
), ServiceError>
|
||||||
{
|
{
|
||||||
let (service, client, handles) = new_full!(
|
let (service, client, handles, _, _) = new_full!(
|
||||||
config,
|
config,
|
||||||
collating_for,
|
collating_for,
|
||||||
max_block_data_size,
|
max_block_data_size,
|
||||||
@@ -719,7 +781,7 @@ pub fn kusama_new_full(
|
|||||||
FullNodeHandles
|
FullNodeHandles
|
||||||
), ServiceError>
|
), ServiceError>
|
||||||
{
|
{
|
||||||
let (service, client, handles) = new_full!(
|
let (service, client, handles, _, _) = new_full!(
|
||||||
config,
|
config,
|
||||||
collating_for,
|
collating_for,
|
||||||
max_block_data_size,
|
max_block_data_size,
|
||||||
@@ -753,7 +815,7 @@ pub fn westend_new_full(
|
|||||||
FullNodeHandles,
|
FullNodeHandles,
|
||||||
), ServiceError>
|
), ServiceError>
|
||||||
{
|
{
|
||||||
let (service, client, handles) = new_full!(
|
let (service, client, handles, _, _) = new_full!(
|
||||||
config,
|
config,
|
||||||
collating_for,
|
collating_for,
|
||||||
max_block_data_size,
|
max_block_data_size,
|
||||||
|
|||||||
Reference in New Issue
Block a user