mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-23 20:11:06 +00:00
Adds integration test based on adder collator (#1928)
* Adds integration test based on adder collator This adds an integration test for parachains that uses the adder collator. The test will start two relay chain nodes and one collator and waits until 4 blocks are build and enacted by the parachain. * Make sure the integration test is run in CI * Fix wasm compilation * Update parachain/test-parachains/adder/collator/src/lib.rs Co-authored-by: Sergei Shulepov <sergei@parity.io> * Update cli/src/command.rs Co-authored-by: Sergei Shulepov <sergei@parity.io>
This commit is contained in:
@@ -16,10 +16,11 @@
|
||||
|
||||
//! Chain specifications for the test runtime.
|
||||
|
||||
use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId;
|
||||
use babe_primitives::AuthorityId as BabeId;
|
||||
use grandpa::AuthorityId as GrandpaId;
|
||||
use pallet_staking::Forcing;
|
||||
use polkadot_primitives::v0::{ValidatorId, AccountId};
|
||||
use polkadot_primitives::v1::{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};
|
||||
@@ -53,7 +54,6 @@ pub fn polkadot_local_testnet_genesis() -> polkadot_test_runtime::GenesisConfig
|
||||
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,
|
||||
@@ -63,13 +63,14 @@ pub fn polkadot_local_testnet_genesis() -> polkadot_test_runtime::GenesisConfig
|
||||
/// Helper function to generate stash, controller and session key from seed
|
||||
fn get_authority_keys_from_seed(
|
||||
seed: &str,
|
||||
) -> (AccountId, AccountId, BabeId, GrandpaId, ValidatorId) {
|
||||
) -> (AccountId, AccountId, BabeId, GrandpaId, ValidatorId, AuthorityDiscoveryId) {
|
||||
(
|
||||
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),
|
||||
get_from_seed::<AuthorityDiscoveryId>(seed),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -92,46 +93,47 @@ fn testnet_accounts() -> Vec<AccountId> {
|
||||
|
||||
/// Helper function to create polkadot GenesisConfig for testing
|
||||
fn polkadot_testnet_genesis(
|
||||
initial_authorities: Vec<(AccountId, AccountId, BabeId, GrandpaId, ValidatorId)>,
|
||||
initial_authorities: Vec<(AccountId, AccountId, BabeId, GrandpaId, ValidatorId, AuthorityDiscoveryId)>,
|
||||
root_key: AccountId,
|
||||
endowed_accounts: Option<Vec<AccountId>>,
|
||||
) -> polkadot_test_runtime::GenesisConfig {
|
||||
use polkadot_test_runtime as polkadot;
|
||||
use polkadot_test_runtime as runtime;
|
||||
|
||||
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 {
|
||||
frame_system: Some(polkadot::SystemConfig {
|
||||
code: polkadot::WASM_BINARY.expect("Wasm binary must be built for testing").to_vec(),
|
||||
runtime::GenesisConfig {
|
||||
frame_system: Some(runtime::SystemConfig {
|
||||
code: runtime::WASM_BINARY.expect("Wasm binary must be built for testing").to_vec(),
|
||||
..Default::default()
|
||||
}),
|
||||
pallet_indices: Some(polkadot::IndicesConfig { indices: vec![] }),
|
||||
pallet_balances: Some(polkadot::BalancesConfig {
|
||||
pallet_indices: Some(runtime::IndicesConfig { indices: vec![] }),
|
||||
pallet_balances: Some(runtime::BalancesConfig {
|
||||
balances: endowed_accounts
|
||||
.iter()
|
||||
.map(|k| (k.clone(), ENDOWMENT))
|
||||
.collect(),
|
||||
}),
|
||||
pallet_session: Some(polkadot::SessionConfig {
|
||||
pallet_session: Some(runtime::SessionConfig {
|
||||
keys: initial_authorities
|
||||
.iter()
|
||||
.map(|x| {
|
||||
(
|
||||
x.0.clone(),
|
||||
x.0.clone(),
|
||||
polkadot_test_runtime::SessionKeys {
|
||||
runtime::SessionKeys {
|
||||
babe: x.2.clone(),
|
||||
grandpa: x.3.clone(),
|
||||
parachain_validator: x.4.clone(),
|
||||
authority_discovery: x.5.clone(),
|
||||
},
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
}),
|
||||
pallet_staking: Some(polkadot::StakingConfig {
|
||||
pallet_staking: Some(runtime::StakingConfig {
|
||||
minimum_validator_count: 1,
|
||||
validator_count: 2,
|
||||
stakers: initial_authorities
|
||||
@@ -141,7 +143,7 @@ fn polkadot_testnet_genesis(
|
||||
x.0.clone(),
|
||||
x.1.clone(),
|
||||
STASH,
|
||||
polkadot::StakerStatus::Validator,
|
||||
runtime::StakerStatus::Validator,
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
@@ -152,13 +154,24 @@ fn polkadot_testnet_genesis(
|
||||
}),
|
||||
pallet_babe: Some(Default::default()),
|
||||
pallet_grandpa: Some(Default::default()),
|
||||
pallet_authority_discovery: Some(polkadot::AuthorityDiscoveryConfig { keys: vec![] }),
|
||||
claims: Some(polkadot::ClaimsConfig {
|
||||
pallet_authority_discovery: Some(runtime::AuthorityDiscoveryConfig { keys: vec![] }),
|
||||
claims: Some(runtime::ClaimsConfig {
|
||||
claims: vec![],
|
||||
vesting: vec![],
|
||||
}),
|
||||
pallet_vesting: Some(polkadot::VestingConfig { vesting: vec![] }),
|
||||
pallet_sudo: Some(polkadot::SudoConfig { key: root_key }),
|
||||
pallet_vesting: Some(runtime::VestingConfig { vesting: vec![] }),
|
||||
pallet_sudo: Some(runtime::SudoConfig { key: root_key }),
|
||||
parachains_configuration: Some(runtime::ParachainsConfigurationConfig {
|
||||
config: polkadot_runtime_parachains::configuration::HostConfiguration {
|
||||
validation_upgrade_frequency: 10u32,
|
||||
validation_upgrade_delay: 5,
|
||||
acceptance_period: 1200,
|
||||
max_code_size: 5 * 1024 * 1024,
|
||||
max_head_data_size: 32 * 1024,
|
||||
group_rotation_frequency: 10,
|
||||
..Default::default()
|
||||
},
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,17 +23,22 @@ pub mod chain_spec;
|
||||
pub use chain_spec::*;
|
||||
use futures::future::Future;
|
||||
use polkadot_overseer::OverseerHandler;
|
||||
use polkadot_primitives::v1::{Id as ParaId, HeadData, ValidationCode, Balance};
|
||||
use polkadot_primitives::v1::{
|
||||
Id as ParaId, HeadData, ValidationCode, Balance, CollatorPair, CollatorId, ValidationData, Hash,
|
||||
};
|
||||
use polkadot_runtime_common::BlockHashCount;
|
||||
use polkadot_service::{
|
||||
new_full, NewFull, FullClient, ClientHandle, ExecuteWithClient, IsCollator,
|
||||
NewFull, FullClient, ClientHandle, ExecuteWithClient, IsCollator,
|
||||
};
|
||||
use polkadot_test_runtime::{Runtime, SignedExtra, SignedPayload, VERSION, ParasSudoWrapperCall, UncheckedExtrinsic};
|
||||
use polkadot_node_subsystem::messages::{CollatorProtocolMessage, CollationGenerationMessage};
|
||||
use polkadot_test_runtime::{
|
||||
Runtime, SignedExtra, SignedPayload, VERSION, ParasSudoWrapperCall, SudoCall, UncheckedExtrinsic,
|
||||
};
|
||||
use polkadot_node_primitives::{Collation, CollationGenerationConfig};
|
||||
use polkadot_runtime_parachains::paras::ParaGenesisArgs;
|
||||
use sc_chain_spec::ChainSpec;
|
||||
use sc_client_api::execution_extensions::ExecutionStrategies;
|
||||
use sc_executor::native_executor_instance;
|
||||
use sc_informant::OutputFormat;
|
||||
use sc_network::{
|
||||
config::{NetworkConfiguration, TransportConfig},
|
||||
multiaddr,
|
||||
@@ -49,7 +54,7 @@ use sp_blockchain::HeaderBackend;
|
||||
use sp_keyring::Sr25519Keyring;
|
||||
use sp_runtime::{codec::Encode, generic, traits::IdentifyAccount, MultiSigner};
|
||||
use sp_state_machine::BasicExternalities;
|
||||
use std::{sync::Arc, time::Duration};
|
||||
use std::{sync::Arc, time::Duration, pin::Pin};
|
||||
use substrate_test_client::{BlockchainEventsExt, RpcHandlersExt, RpcTransactionOutput, RpcTransactionError};
|
||||
|
||||
native_executor_instance!(
|
||||
@@ -64,23 +69,25 @@ pub type Client = FullClient<polkadot_test_runtime::RuntimeApi, PolkadotTestExec
|
||||
|
||||
pub use polkadot_service::FullBackend;
|
||||
|
||||
/// Create a new Polkadot test service for a full node.
|
||||
/// Create a new full node.
|
||||
#[sc_cli::prefix_logs_with(config.network.node_name.as_str())]
|
||||
pub fn polkadot_test_new_full(
|
||||
pub fn new_full(
|
||||
config: Configuration,
|
||||
is_collator: IsCollator,
|
||||
) -> Result<
|
||||
NewFull<Arc<Client>>,
|
||||
ServiceError,
|
||||
> {
|
||||
new_full::<polkadot_test_runtime::RuntimeApi, PolkadotTestExecutor>(
|
||||
polkadot_service::new_full::<polkadot_test_runtime::RuntimeApi, PolkadotTestExecutor>(
|
||||
config,
|
||||
IsCollator::No,
|
||||
is_collator,
|
||||
None,
|
||||
Some(sc_authority_discovery::WorkerConfig {
|
||||
query_interval: Duration::from_secs(1),
|
||||
query_start_delay: Duration::from_secs(0),
|
||||
..Default::default()
|
||||
}),
|
||||
polkadot_parachain::wasm_executor::ExecutionMode::InProcess,
|
||||
).map_err(Into::into)
|
||||
}
|
||||
|
||||
@@ -105,11 +112,14 @@ pub fn node_config(
|
||||
task_executor: TaskExecutor,
|
||||
key: Sr25519Keyring,
|
||||
boot_nodes: Vec<MultiaddrWithPeerId>,
|
||||
is_validator: bool,
|
||||
) -> 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 role = if is_validator {
|
||||
Role::Authority { sentry_nodes: Vec::new() }
|
||||
} else {
|
||||
Role::Full
|
||||
};
|
||||
let key_seed = key.to_seed();
|
||||
let mut spec = polkadot_local_testnet_config();
|
||||
@@ -127,17 +137,19 @@ pub fn node_config(
|
||||
Default::default(),
|
||||
None,
|
||||
);
|
||||
let informant_output_format = OutputFormat {
|
||||
enable_color: false,
|
||||
};
|
||||
|
||||
network_config.boot_nodes = boot_nodes;
|
||||
|
||||
network_config.allow_non_globals_in_dht = true;
|
||||
|
||||
let addr: multiaddr::Multiaddr = multiaddr::Protocol::Memory(rand::random()).into();
|
||||
network_config
|
||||
.listen_addresses
|
||||
.push(multiaddr::Protocol::Memory(rand::random()).into());
|
||||
.push(addr.clone());
|
||||
|
||||
network_config
|
||||
.public_addresses
|
||||
.push(addr);
|
||||
|
||||
network_config.transport = TransportConfig::MemoryOnly;
|
||||
|
||||
@@ -148,10 +160,7 @@ pub fn node_config(
|
||||
task_executor,
|
||||
transaction_pool: Default::default(),
|
||||
network: network_config,
|
||||
keystore: KeystoreConfig::Path {
|
||||
path: root.join("key"),
|
||||
password: None,
|
||||
},
|
||||
keystore: KeystoreConfig::InMemory,
|
||||
database: DatabaseConfig::RocksDb {
|
||||
path: root.join("db"),
|
||||
cache_size: 128,
|
||||
@@ -189,28 +198,64 @@ pub fn node_config(
|
||||
max_runtime_instances: 8,
|
||||
announce_block: true,
|
||||
base_path: Some(base_path),
|
||||
informant_output_format,
|
||||
informant_output_format: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Run a Polkadot test node using the Polkadot test runtime.
|
||||
/// Run a test validator node that uses the 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` function will be executed in an externalities provided environment
|
||||
/// and can be used to make adjustements to the runtime genesis storage.
|
||||
pub fn run_test_node(
|
||||
pub fn run_validator_node(
|
||||
task_executor: TaskExecutor,
|
||||
key: Sr25519Keyring,
|
||||
storage_update_func: impl Fn(),
|
||||
boot_nodes: Vec<MultiaddrWithPeerId>,
|
||||
) -> PolkadotTestNode {
|
||||
let config = node_config(storage_update_func, task_executor, key, boot_nodes);
|
||||
let config = node_config(storage_update_func, task_executor, key, boot_nodes, true);
|
||||
let multiaddr = config.network.listen_addresses[0].clone();
|
||||
let NewFull {task_manager, client, network, rpc_handlers, overseer_handler, ..} =
|
||||
polkadot_test_new_full(config)
|
||||
.expect("could not create Polkadot test service");
|
||||
let NewFull { task_manager, client, network, rpc_handlers, overseer_handler, .. } =
|
||||
new_full(config, IsCollator::No).expect("could not create Polkadot test service");
|
||||
|
||||
let overseer_handler = overseer_handler.expect("test node must have an overseer handler");
|
||||
let peer_id = network.local_peer_id().clone();
|
||||
let addr = MultiaddrWithPeerId { multiaddr, peer_id };
|
||||
|
||||
PolkadotTestNode {
|
||||
task_manager,
|
||||
client,
|
||||
overseer_handler,
|
||||
addr,
|
||||
rpc_handlers,
|
||||
}
|
||||
}
|
||||
|
||||
/// Run a test collator node that uses the 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` function will be executed in an externalities provided environment
|
||||
/// and can be used to make adjustements to the runtime genesis storage.
|
||||
///
|
||||
/// # Note
|
||||
///
|
||||
/// The collator functionionality still needs to be registered at the node! This can be done using
|
||||
/// [`PolkadotTestNode::register_collator`].
|
||||
pub fn run_collator_node(
|
||||
task_executor: TaskExecutor,
|
||||
key: Sr25519Keyring,
|
||||
storage_update_func: impl Fn(),
|
||||
boot_nodes: Vec<MultiaddrWithPeerId>,
|
||||
collator_id: CollatorId,
|
||||
) -> PolkadotTestNode {
|
||||
let config = node_config(storage_update_func, task_executor, key, boot_nodes, false);
|
||||
let multiaddr = config.network.listen_addresses[0].clone();
|
||||
let NewFull { task_manager, client, network, rpc_handlers, overseer_handler, .. } =
|
||||
new_full(config, IsCollator::Yes(collator_id)).expect("could not create Polkadot test service");
|
||||
|
||||
let overseer_handler = overseer_handler.expect("test node must have an overseer handler");
|
||||
let peer_id = network.local_peer_id().clone();
|
||||
@@ -255,19 +300,19 @@ impl PolkadotTestNode {
|
||||
pub async fn register_parachain(
|
||||
&self,
|
||||
id: ParaId,
|
||||
validation_code: ValidationCode,
|
||||
genesis_head: HeadData,
|
||||
validation_code: impl Into<ValidationCode>,
|
||||
genesis_head: impl Into<HeadData>,
|
||||
) -> Result<(), RpcTransactionError> {
|
||||
let call = ParasSudoWrapperCall::sudo_schedule_para_initialize(
|
||||
id,
|
||||
ParaGenesisArgs {
|
||||
genesis_head,
|
||||
validation_code,
|
||||
genesis_head: genesis_head.into(),
|
||||
validation_code: validation_code.into(),
|
||||
parachain: true,
|
||||
},
|
||||
);
|
||||
|
||||
self.send_extrinsic(call, Sr25519Keyring::Alice).await.map(drop)
|
||||
self.send_extrinsic(SudoCall::sudo(Box::new(call.into())), Sr25519Keyring::Alice).await.map(drop)
|
||||
}
|
||||
|
||||
/// Wait for `count` blocks to be imported in the node and then exit. This function will not return if no blocks
|
||||
@@ -275,6 +320,29 @@ impl PolkadotTestNode {
|
||||
pub fn wait_for_blocks(&self, count: usize) -> impl Future<Output = ()> {
|
||||
self.client.wait_for_blocks(count)
|
||||
}
|
||||
|
||||
/// Register the collator functionality in the overseer of this node.
|
||||
pub async fn register_collator(
|
||||
&mut self,
|
||||
collator_key: CollatorPair,
|
||||
para_id: ParaId,
|
||||
collator: Box<dyn Fn(Hash, &ValidationData) -> Pin<Box<dyn Future<Output = Option<Collation>> + Send>> + Send + Sync>,
|
||||
) {
|
||||
let config = CollationGenerationConfig {
|
||||
key: collator_key,
|
||||
collator,
|
||||
para_id
|
||||
};
|
||||
|
||||
self.overseer_handler.send_msg(
|
||||
CollationGenerationMessage::Initialize(config),
|
||||
).await.expect("Registers the collator");
|
||||
|
||||
self.overseer_handler
|
||||
.send_msg(CollatorProtocolMessage::CollateOn(para_id))
|
||||
.await
|
||||
.expect("Sends CollateOn");
|
||||
}
|
||||
}
|
||||
|
||||
/// Construct an extrinsic that can be applied to the test runtime.
|
||||
|
||||
Reference in New Issue
Block a user