Fix integration test (#124)

This commit is contained in:
Cecile Tonglet
2020-07-23 16:12:11 +02:00
committed by GitHub
parent 537a311587
commit 96d5bdac96
10 changed files with 554 additions and 770 deletions
+10 -13
View File
@@ -49,10 +49,11 @@ cumulus-primitives = { path = "../../primitives" }
# Polkadot dependencies
polkadot-primitives = { git = "https://github.com/paritytech/polkadot", branch = "cumulus-branch" }
polkadot-parachain = { git = "https://github.com/paritytech/polkadot", branch = "cumulus-branch" }
polkadot-collator = { git = "https://github.com/paritytech/polkadot", branch = "cumulus-branch" }
polkadot-service = { git = "https://github.com/paritytech/polkadot", branch = "cumulus-branch" }
polkadot-cli = { git = "https://github.com/paritytech/polkadot", branch = "cumulus-branch" }
polkadot-test-service = { git = "https://github.com/paritytech/polkadot", branch = "cumulus-branch" }
polkadot-parachain = { git = "https://github.com/paritytech/polkadot", branch = "cumulus-branch" }
[build-dependencies]
substrate-build-script-utils = { git = "https://github.com/paritytech/substrate", branch = "cumulus-branch" }
@@ -60,21 +61,17 @@ substrate-build-script-utils = { git = "https://github.com/paritytech/substrate"
[dev-dependencies]
assert_cmd = "0.12"
nix = "0.17"
tempfile = "3.1"
jsonrpsee = "0.1"
async-std = { version = "1.2.0", features = [ "attributes" ] }
hex = "0.4"
serde_json = "1.0"
rand = "0.7.3"
tokio = { version = "0.2.13", features = ["macros"] }
# Polkadot dependencies
polkadot-runtime-common = { git = "https://github.com/paritytech/polkadot", branch = "cumulus-branch" }
polkadot-runtime = { git = "https://github.com/paritytech/polkadot", branch = "cumulus-branch" }
polkadot-test-runtime = { git = "https://github.com/paritytech/polkadot", branch = "cumulus-branch" }
polkadot-test-runtime-client = { git = "https://github.com/paritytech/polkadot", branch = "cumulus-branch" }
polkadot-test-service = { git = "https://github.com/paritytech/polkadot", branch = "cumulus-branch" }
# Substrate dependencies
substrate-test-runtime-client = { git = "https://github.com/paritytech/substrate", branch = "cumulus-branch" }
frame-system = { git = "https://github.com/paritytech/substrate", branch = "cumulus-branch" }
pallet-grandpa = { git = "https://github.com/paritytech/substrate", branch = "cumulus-branch" }
pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "cumulus-branch" }
sp-arithmetic = { git = "https://github.com/paritytech/substrate", branch = "cumulus-branch" }
sp-version = { git = "https://github.com/paritytech/substrate", branch = "cumulus-branch" }
pallet-sudo = { git = "https://github.com/paritytech/substrate", branch = "cumulus-branch" }
sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "cumulus-branch" }
substrate-test-client = { git = "https://github.com/paritytech/substrate", branch = "cumulus-branch" }
substrate-test-runtime-client = { git = "https://github.com/paritytech/substrate", branch = "cumulus-branch" }
-6
View File
@@ -28,12 +28,6 @@ pub enum Subcommand {
/// Export the genesis state of the parachain.
#[structopt(name = "export-genesis-state")]
ExportGenesisState(ExportGenesisStateCommand),
/// Run Polkadot for testing purpose
Polkadot(polkadot_cli::Cli),
#[structopt(name = "validation-worker", setting = structopt::clap::AppSettings::Hidden)]
PolkadotValidationWorker(polkadot_cli::ValidationWorkerCommand),
}
/// Command for exporting the genesis state of the parachain
+4 -33
View File
@@ -115,7 +115,8 @@ impl SubstrateCli for PolkadotCli {
}
}
fn generate_genesis_state(para_id: ParaId) -> Result<Block> {
/// Generate the genesis block
pub fn generate_genesis_state(para_id: ParaId) -> Result<Block> {
let storage = (&chain_spec::get_chain_spec(para_id)).build_storage()?;
let child_roots = storage.children_default.iter().map(|(sk, child_content)| {
@@ -156,7 +157,7 @@ pub fn run() -> Result<()> {
})
}
Some(Subcommand::ExportGenesisState(params)) => {
sc_cli::init_logger("", &<sc_cli::LogRotationOpt as structopt::StructOpt>::from_args())?;
sc_cli::init_logger("");
let block = generate_genesis_state(params.parachain_id.into())?;
let header_hex = format!("0x{:?}", HexDisplay::from(&block.header().encode()));
@@ -169,37 +170,6 @@ pub fn run() -> Result<()> {
Ok(())
}
Some(Subcommand::Polkadot(polkadot_cli)) => {
let runner = polkadot_cli.create_runner(&polkadot_cli.run.base)?;
let authority_discovery_enabled = polkadot_cli.run.authority_discovery_enabled;
let grandpa_pause = if polkadot_cli.run.grandpa_pause.is_empty() {
None
} else {
Some((
polkadot_cli.run.grandpa_pause[0],
polkadot_cli.run.grandpa_pause[1],
))
};
runner.run_node_until_exit(|config| match config.role {
Role::Light => polkadot_service::polkadot_new_light(config).map(|r| r.0),
_ => polkadot_service::polkadot_new_full(
config,
None,
None,
authority_discovery_enabled,
6000,
grandpa_pause,
)
.map(|(s, _, _)| s),
})
}
Some(Subcommand::PolkadotValidationWorker(cmd)) => {
sc_cli::init_logger("", &<sc_cli::LogRotationOpt as structopt::StructOpt>::from_args())?;
polkadot_service::run_validation_worker(&cmd.mem_id)?;
Ok(())
}
None => {
let runner = cli.create_runner(&*cli.run)?;
@@ -238,6 +208,7 @@ pub fn run() -> Result<()> {
info!("Parachain genesis state: {}", genesis_state);
crate::service::run_collator(config, key, polkadot_config, id)
.map(|x| x.task_manager)
})
}
}
@@ -0,0 +1,211 @@
// 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/>.
use codec::Encode;
use futures::{
future::{self, FutureExt},
pin_mut, select,
};
use polkadot_primitives::parachain::{Id as ParaId, Info, Scheduling};
use polkadot_runtime_common::registrar;
use polkadot_test_runtime_client::Sr25519Keyring;
use sc_client_api::execution_extensions::ExecutionStrategies;
use sc_informant::OutputFormat;
use sc_network::{config::TransportConfig, multiaddr};
use sc_service::{
config::{
DatabaseConfig, KeystoreConfig, MultiaddrWithPeerId, NetworkConfiguration,
WasmExecutionMethod,
},
BasePath, Configuration, Error as ServiceError, Role, TaskExecutor,
};
use std::{sync::Arc, time::Duration};
use substrate_test_client::BlockchainEventsExt;
use substrate_test_runtime_client::AccountKeyring::*;
use tokio::{spawn, time::delay_for as sleep};
static INTEGRATION_TEST_ALLOWED_TIME: Option<&str> = option_env!("INTEGRATION_TEST_ALLOWED_TIME");
#[tokio::test]
#[ignore]
async fn integration_test() {
let task_executor: TaskExecutor = (|fut, _| {
spawn(fut);
})
.into();
// start alice
let mut alice =
polkadot_test_service::run_test_node(task_executor.clone(), Alice, || {}, vec![]);
// start bob
let mut bob = polkadot_test_service::run_test_node(
task_executor.clone(),
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 para_id = ParaId::from(100);
future::join(alice.wait_for_blocks(2), bob.wait_for_blocks(2)).await;
// export genesis state
let genesis_state = crate::command::generate_genesis_state(para_id)
.unwrap()
.encode();
// create and sign transaction
let function = polkadot_test_runtime::Call::Sudo(pallet_sudo::Call::sudo(Box::new(
polkadot_test_runtime::Call::Registrar(registrar::Call::register_para(
para_id,
Info {
scheduling: Scheduling::Always,
},
parachain_runtime::WASM_BINARY.to_vec().into(),
genesis_state.into(),
)),
)));
// register parachain
let _ = alice.call_function(function, Alice).await.unwrap();
// run cumulus charlie
let key = Arc::new(sp_core::Pair::from_seed(&[10; 32]));
let mut polkadot_config = polkadot_test_service::node_config(
|| {},
task_executor.clone(),
Charlie,
vec![alice.addr.clone(), bob.addr.clone()],
);
use std::net::{Ipv4Addr, SocketAddr};
polkadot_config.rpc_http = Some(SocketAddr::new(Ipv4Addr::LOCALHOST.into(), 27016));
polkadot_config.rpc_methods = sc_service::config::RpcMethods::Unsafe;
let parachain_config =
parachain_config(task_executor.clone(), Charlie, vec![], para_id).unwrap();
let service =
crate::service::run_collator(parachain_config, key, polkadot_config, para_id).unwrap();
sleep(Duration::from_secs(3)).await;
service.client.wait_for_blocks(4).await;
alice.task_manager.terminate();
bob.task_manager.terminate();
}
.fuse();
pin_mut!(t1, t2);
select! {
_ = t1 => {
panic!("the test took too long, maybe no parachain blocks have been produced");
},
_ = t2 => {},
}
}
pub fn parachain_config(
task_executor: TaskExecutor,
key: Sr25519Keyring,
boot_nodes: Vec<MultiaddrWithPeerId>,
para_id: ParaId,
) -> Result<Configuration, ServiceError> {
let base_path = BasePath::new_temp_dir()?;
let root = base_path.path().to_path_buf();
let role = Role::Authority {
sentry_nodes: Vec::new(),
};
let key_seed = key.to_seed();
let spec = crate::chain_spec::get_chain_spec(para_id);
let mut network_config = NetworkConfiguration::new(
format!("Cumulus 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;
Ok(Configuration {
impl_name: "cumulus-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,
})
}
+2
View File
@@ -24,6 +24,8 @@ mod chain_spec;
mod service;
mod cli;
mod command;
#[cfg(test)]
mod integration_test;
fn main() -> sc_cli::Result<()> {
command::run()
+18 -4
View File
@@ -25,7 +25,7 @@ use sc_finality_grandpa::{
FinalityProofProvider as GrandpaFinalityProofProvider, StorageAndProofProvider,
};
use sc_informant::OutputFormat;
use sc_service::{Configuration, TaskManager};
use sc_service::{Configuration, ServiceComponents, TFullBackend, TFullClient};
use std::sync::Arc;
// Our native executor instance.
@@ -55,10 +55,12 @@ macro_rules! new_full_start {
client.clone(),
builder.prometheus_registry(),
));
let pool = sc_transaction_pool::BasicPool::new(
let pool = sc_transaction_pool::BasicPool::new_full(
builder.config().transaction_pool.clone(),
pool_api,
builder.prometheus_registry(),
builder.spawn_handle(),
client.clone(),
);
Ok(pool)
})?
@@ -86,7 +88,19 @@ pub fn run_collator(
key: Arc<CollatorPair>,
mut polkadot_config: polkadot_collator::Configuration,
id: polkadot_primitives::parachain::Id,
) -> sc_service::error::Result<TaskManager> {
) -> sc_service::error::Result<ServiceComponents<
parachain_runtime::opaque::Block,
TFullBackend<parachain_runtime::opaque::Block>,
sc_consensus::LongestChain<TFullBackend<parachain_runtime::opaque::Block>, parachain_runtime::opaque::Block>,
sc_transaction_pool::BasicPool<
sc_transaction_pool::FullChainApi<
TFullClient<parachain_runtime::opaque::Block, parachain_runtime::RuntimeApi, crate::service::Executor>,
parachain_runtime::opaque::Block,
>,
parachain_runtime::opaque::Block,
>,
TFullClient<parachain_runtime::opaque::Block, parachain_runtime::RuntimeApi, crate::service::Executor>,
>> {
let mut parachain_config = prepare_collator_config(parachain_config);
parachain_config.informant_output_format = OutputFormat {
@@ -152,5 +166,5 @@ pub fn run_collator(
.spawn_essential_handle()
.spawn("polkadot", polkadot_future);
Ok(service.task_manager)
Ok(service)
}
@@ -1,382 +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/>.
// TODO: this is necessary for the jsonrpsee macro used
#![allow(unused_variables, dead_code)]
use assert_cmd::cargo::cargo_bin;
use async_std::{net, task::sleep};
use codec::Encode;
use futures::{future::FutureExt, join, pin_mut, select};
use jsonrpsee::{raw::RawClient, transport::http::HttpTransportClient};
use polkadot_primitives::parachain::{Info, Scheduling};
use polkadot_primitives::Hash as PHash;
use polkadot_runtime::{Header, Runtime, SignedExtra, SignedPayload};
use polkadot_runtime_common::{parachains, registrar, BlockHashCount, claims};
use serde_json::Value;
use sp_arithmetic::traits::SaturatedConversion;
use sp_runtime::generic;
use sp_version::RuntimeVersion;
use std::{
collections::HashSet,
env, fs,
io::Read,
path::PathBuf,
process::{Child, Command, Stdio},
time::Duration,
};
use substrate_test_runtime_client::AccountKeyring::Alice;
use tempfile::tempdir;
static POLKADOT_ARGS: &[&str] = &["polkadot", "--chain=res/polkadot_chainspec.json"];
static INTEGRATION_TEST_ALLOWED_TIME: Option<&str> = option_env!("INTEGRATION_TEST_ALLOWED_TIME");
jsonrpsee::rpc_api! {
Author {
#[rpc(method = "author_submitExtrinsic", positional_params)]
fn submit_extrinsic(extrinsic: String) -> PHash;
}
Chain {
#[rpc(method = "chain_getFinalizedHead")]
fn current_block_hash() -> PHash;
#[rpc(method = "chain_getHeader", positional_params)]
fn header(hash: PHash) -> Option<Header>;
#[rpc(method = "chain_getBlockHash", positional_params)]
fn block_hash(hash: Option<u64>) -> Option<PHash>;
}
State {
#[rpc(method = "state_getRuntimeVersion")]
fn runtime_version() -> RuntimeVersion;
}
System {
#[rpc(method = "system_networkState")]
fn network_state() -> Value;
}
}
// Adapted from
// https://github.com/rust-lang/cargo/blob/485670b3983b52289a2f353d589c57fae2f60f82/tests/testsuite/support/mod.rs#L507
fn target_dir() -> PathBuf {
env::current_exe()
.ok()
.map(|mut path| {
path.pop();
if path.ends_with("deps") {
path.pop();
}
path
})
.unwrap()
}
struct ChildHelper<'a> {
name: String,
child: &'a mut Child,
}
impl<'a> Drop for ChildHelper<'a> {
fn drop(&mut self) {
let name = self.name.clone();
self.terminate();
let mut stdout = String::new();
if let Some(reader) = self.child.stdout.as_mut() {
let _ = reader.read_to_string(&mut stdout);
}
eprintln!("process '{}' stdout:\n{}\n", name, stdout,);
let mut stderr = String::new();
if let Some(reader) = self.child.stderr.as_mut() {
let _ = reader.read_to_string(&mut stderr);
}
eprintln!("process '{}' stderr:\n{}\n", name, stderr,);
}
}
impl<'a> ChildHelper<'a> {
fn new(name: &str, child: &'a mut Child) -> ChildHelper<'a> {
ChildHelper {
name: name.to_string(),
child,
}
}
fn terminate(&mut self) {
match self.child.try_wait() {
Ok(Some(_)) => return,
Ok(None) => {}
Err(err) => {
eprintln!("could not wait for child process to finish: {}", err);
let _ = self.child.kill();
let _ = self.child.wait();
return;
}
}
let _ = self.child.kill();
let _ = self.child.wait();
}
}
async fn wait_for_tcp<A: net::ToSocketAddrs + std::fmt::Display>(address: A) {
while let Err(err) = net::TcpStream::connect(&address).await {
eprintln!("Waiting for {} to be up ({})...", address, err);
sleep(Duration::from_secs(2)).await;
}
}
/// wait for parachain blocks to be produced
async fn wait_for_blocks(number_of_blocks: usize, mut client: &mut RawClient<HttpTransportClient>) {
let mut previous_blocks = HashSet::with_capacity(number_of_blocks);
loop {
let current_block_hash = Chain::block_hash(&mut client, None).await.unwrap().unwrap();
if previous_blocks.insert(current_block_hash) {
eprintln!("new parachain block: {}", current_block_hash);
if previous_blocks.len() == number_of_blocks {
break;
}
}
sleep(Duration::from_secs(2)).await;
}
}
#[async_std::test]
#[ignore]
#[cfg(feature = "disabled")]
async fn integration_test() {
assert!(
!net::TcpStream::connect("127.0.0.1:27015").await.is_ok(),
"tcp port is already open 127.0.0.1:27015, this test cannot be run",
);
assert!(
!net::TcpStream::connect("127.0.0.1:27016").await.is_ok(),
"tcp port is already open 127.0.0.1:27016, this test cannot be run",
);
let t1 = sleep(Duration::from_secs(
INTEGRATION_TEST_ALLOWED_TIME
.and_then(|x| x.parse().ok())
.unwrap_or(600),
))
.fuse();
let t2 = async {
// start alice
let polkadot_alice_dir = tempdir().unwrap();
let mut polkadot_alice = Command::new(cargo_bin("cumulus-test-parachain-collator"))
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.args(POLKADOT_ARGS)
.arg("--base-path")
.arg(polkadot_alice_dir.path())
.arg("--alice")
.arg("--rpc-methods=unsafe")
.arg("--rpc-port=27015")
.arg("--port=27115")
.spawn()
.unwrap();
let polkadot_alice_helper = ChildHelper::new("alice", &mut polkadot_alice);
// start bob
let polkadot_bob_dir = tempdir().unwrap();
let mut polkadot_bob = Command::new(cargo_bin("cumulus-test-parachain-collator"))
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.args(POLKADOT_ARGS)
.arg("--base-path")
.arg(polkadot_bob_dir.path())
.arg("--bob")
.arg("--rpc-methods=unsafe")
.arg("--rpc-port=27016")
.arg("--port=27116")
.spawn()
.unwrap();
let polkadot_bob_helper = ChildHelper::new("bob", &mut polkadot_bob);
// wait for both nodes to be up and running
join!(
wait_for_tcp("127.0.0.1:27015"),
wait_for_tcp("127.0.0.1:27016")
);
// export genesis state
let cmd = Command::new(cargo_bin("cumulus-test-parachain-collator"))
.arg("export-genesis-state")
.output()
.unwrap();
assert!(cmd.status.success());
let output = &cmd.stdout;
let genesis_state = hex::decode(&output[2..output.len() - 1]).unwrap();
// connect RPC clients
let transport_client_alice =
jsonrpsee::transport::http::HttpTransportClient::new("http://127.0.0.1:27015");
let mut client_alice = jsonrpsee::raw::RawClient::new(transport_client_alice);
let transport_client_bob =
jsonrpsee::transport::http::HttpTransportClient::new("http://127.0.0.1:27016");
let mut client_bob = jsonrpsee::raw::RawClient::new(transport_client_bob);
// retrieve nodes network id
let polkadot_alice_id = System::network_state(&mut client_alice).await.unwrap()["peerId"]
.as_str()
.unwrap()
.to_string();
let polkadot_bob_id = System::network_state(&mut client_bob).await.unwrap()["peerId"]
.as_str()
.unwrap()
.to_string();
// retrieve runtime version
let runtime_version = State::runtime_version(&mut client_alice).await.unwrap();
// get the current block
let current_block_hash = Chain::block_hash(&mut client_alice, None)
.await
.unwrap()
.unwrap();
let current_block = Chain::header(&mut client_alice, current_block_hash)
.await
.unwrap()
.unwrap()
.number
.saturated_into::<u64>();
let genesis_block = Chain::block_hash(&mut client_alice, 0)
.await
.unwrap()
.unwrap();
// create and sign transaction
let wasm = fs::read(target_dir().join(
"wbuild/cumulus-test-parachain-runtime/cumulus_test_parachain_runtime.compact.wasm",
))
.unwrap();
let call = pallet_sudo::Call::sudo(Box::new(
registrar::Call::<Runtime>::register_para(
100.into(),
Info {
scheduling: Scheduling::Always,
},
wasm.into(),
genesis_state.into(),
)
.into(),
));
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 = (
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(),
pallet_grandpa::ValidateEquivocationReport::<Runtime>::new(),
claims::PrevalidateAttests::<Runtime>::new(),
);
let raw_payload = SignedPayload::from_raw(
call.clone().into(),
extra.clone(),
(
(),
runtime_version.spec_version,
runtime_version.transaction_version,
genesis_block,
current_block_hash,
(),
(),
(),
(),
(),
(),
(),
),
);
let signature = raw_payload.using_encoded(|e| Alice.sign(e));
// register parachain
let ex = polkadot_runtime::UncheckedExtrinsic::new_signed(
call.into(),
Alice.into(),
sp_runtime::MultiSignature::Sr25519(signature),
extra,
);
let _register_block_hash =
Author::submit_extrinsic(&mut client_alice, format!("0x{}", hex::encode(ex.encode())))
.await
.unwrap();
// run cumulus charlie
let cumulus_charlie_dir = tempdir().unwrap();
let mut cumulus_charlie = Command::new(cargo_bin("cumulus-test-parachain-collator"))
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.arg("--base-path")
.arg(cumulus_charlie_dir.path())
.arg("--rpc-methods=unsafe")
.arg("--rpc-port=27017")
.arg("--port=27117")
.arg("--")
.arg(format!(
"--bootnodes=/ip4/127.0.0.1/tcp/27115/p2p/{}",
polkadot_alice_id
))
.arg(format!(
"--bootnodes=/ip4/127.0.0.1/tcp/27116/p2p/{}",
polkadot_bob_id
))
.arg("--charlie")
.spawn()
.unwrap();
let cumulus_charlie_helper = ChildHelper::new("cumulus-charlie", &mut cumulus_charlie);
wait_for_tcp("127.0.0.1:27017").await;
// connect rpc client to cumulus
let transport_client_cumulus_charlie =
jsonrpsee::transport::http::HttpTransportClient::new("http://127.0.0.1:27017");
let mut client_cumulus_charlie =
jsonrpsee::raw::RawClient::new(transport_client_cumulus_charlie);
wait_for_blocks(4, &mut client_cumulus_charlie).await;
}
.fuse();
pin_mut!(t1, t2);
select! {
_ = t1 => {
panic!("the test took too long, maybe no parachain blocks have been produced");
},
_ = t2 => {},
}
}