|
@@ -415,250 +415,247 @@ pub fn new_light(config: Configuration) -> Result<impl AbstractService, ServiceE
|
|
|
Ok(service)
|
|
|
}
|
|
|
|
|
|
-// Tests are commented out until we find a solution to why
|
|
|
-// building dependencies for the tests are taking so long on Travis CI
|
|
|
-
|
|
|
-// #[cfg(test)]
|
|
|
-// mod tests {
|
|
|
-// use crate::node_executor;
|
|
|
-// use crate::node_rpc;
|
|
|
-// use crate::service::{new_full, new_light};
|
|
|
-// use codec::{Decode, Encode};
|
|
|
-// use node_runtime::RuntimeApi;
|
|
|
-// use node_runtime::{currency::CENTS, SLOT_DURATION};
|
|
|
-// use node_runtime::{opaque::Block, AccountId, DigestItem, Signature};
|
|
|
-// use node_runtime::{BalancesCall, Call, UncheckedExtrinsic};
|
|
|
-// use sc_consensus_babe::{BabeIntermediate, CompatibleDigestItem, INTERMEDIATE_KEY};
|
|
|
-// use sc_consensus_epochs::descendent_query;
|
|
|
-// use sc_finality_grandpa::{self as grandpa};
|
|
|
-// use sc_service::AbstractService;
|
|
|
-// use sp_consensus::{
|
|
|
-// BlockImport, BlockImportParams, BlockOrigin, Environment, ForkChoiceStrategy, Proposer,
|
|
|
-// RecordProof,
|
|
|
-// };
|
|
|
-// use sp_core::{crypto::Pair as CryptoPair, H256};
|
|
|
-// use sp_finality_tracker;
|
|
|
-// use sp_keyring::AccountKeyring;
|
|
|
-// use sp_runtime::traits::IdentifyAccount;
|
|
|
-// use sp_runtime::{
|
|
|
-// generic::{BlockId, Digest, Era, SignedPayload},
|
|
|
-// traits::Verify,
|
|
|
-// traits::{Block as BlockT, Header as HeaderT},
|
|
|
-// OpaqueExtrinsic,
|
|
|
-// };
|
|
|
-// use sp_timestamp;
|
|
|
-// use sp_transaction_pool::{ChainEvent, MaintainedTransactionPool};
|
|
|
-// use std::{any::Any, borrow::Cow, sync::Arc};
|
|
|
-
|
|
|
-// type AccountPublic = <Signature as Verify>::Signer;
|
|
|
-
|
|
|
-// // Long running test. Run it locally only after the node changes.
|
|
|
-// #[test]
|
|
|
-// // It is "ignored", but the node-cli ignored tests are running on the CI.
|
|
|
-// // This can be run locally with `cargo test --release -p node-cli test_sync -- --ignored`.
|
|
|
-// #[ignore]
|
|
|
-// fn test_sync() {
|
|
|
-// let keystore_path = tempfile::tempdir().expect("Creates keystore path");
|
|
|
-// let keystore =
|
|
|
-// sc_keystore::Store::open(keystore_path.path(), None).expect("Creates keystore");
|
|
|
-// let alice = keystore
|
|
|
-// .write()
|
|
|
-// .insert_ephemeral_from_seed::<sc_consensus_babe::AuthorityPair>("//Alice")
|
|
|
-// .expect("Creates authority pair");
|
|
|
-
|
|
|
-// let chain_spec = crate::chain_spec::tests::integration_test_config_with_single_authority();
|
|
|
-
|
|
|
-// // For the block factory
|
|
|
-// let mut slot_num = 1u64;
|
|
|
-
|
|
|
-// // For the extrinsics factory
|
|
|
-// let bob = Arc::new(AccountKeyring::Bob.pair());
|
|
|
-// let charlie = Arc::new(AccountKeyring::Charlie.pair());
|
|
|
-// let mut index = 0;
|
|
|
-
|
|
|
-// sc_service_test::sync(
|
|
|
-// chain_spec,
|
|
|
-// |config| {
|
|
|
-// let mut setup_handles = None;
|
|
|
-// new_full!(
|
|
|
-// config,
|
|
|
-// |block_import: &sc_consensus_babe::BabeBlockImport<Block, _, _>,
|
|
|
-// babe_link: &sc_consensus_babe::BabeLink<Block>| {
|
|
|
-// setup_handles = Some((block_import.clone(), babe_link.clone()));
|
|
|
-// }
|
|
|
-// )
|
|
|
-// .map(move |(node, x)| (node, (x, setup_handles.unwrap())))
|
|
|
-// },
|
|
|
-// |config| new_light(config),
|
|
|
-// |service, &mut (ref inherent_data_providers, (ref mut block_import, ref babe_link))| {
|
|
|
-// let mut inherent_data = inherent_data_providers
|
|
|
-// .create_inherent_data()
|
|
|
-// .expect("Creates inherent data.");
|
|
|
-// inherent_data.replace_data(sp_finality_tracker::INHERENT_IDENTIFIER, &1u64);
|
|
|
-
|
|
|
-// let parent_id = BlockId::number(service.client().chain_info().best_number);
|
|
|
-// let parent_header = service.client().header(&parent_id).unwrap().unwrap();
|
|
|
-// let parent_hash = parent_header.hash();
|
|
|
-// let parent_number = *parent_header.number();
|
|
|
-
|
|
|
-// futures::executor::block_on(service.transaction_pool().maintain(
|
|
|
-// ChainEvent::NewBlock {
|
|
|
-// is_new_best: true,
|
|
|
-// hash: parent_header.hash(),
|
|
|
-// tree_route: None,
|
|
|
-// header: parent_header.clone(),
|
|
|
-// },
|
|
|
-// ));
|
|
|
-
|
|
|
-// let mut proposer_factory = sc_basic_authorship::ProposerFactory::new(
|
|
|
-// service.client(),
|
|
|
-// service.transaction_pool(),
|
|
|
-// None,
|
|
|
-// );
|
|
|
-
|
|
|
-// let epoch_descriptor = babe_link
|
|
|
-// .epoch_changes()
|
|
|
-// .lock()
|
|
|
-// .epoch_descriptor_for_child_of(
|
|
|
-// descendent_query(&*service.client()),
|
|
|
-// &parent_hash,
|
|
|
-// parent_number,
|
|
|
-// slot_num,
|
|
|
-// )
|
|
|
-// .unwrap()
|
|
|
-// .unwrap();
|
|
|
-
|
|
|
-// let mut digest = Digest::<H256>::default();
|
|
|
-
|
|
|
-// // even though there's only one authority some slots might be empty,
|
|
|
-// // so we must keep trying the next slots until we can claim one.
|
|
|
-// let babe_pre_digest = loop {
|
|
|
-// inherent_data.replace_data(
|
|
|
-// sp_timestamp::INHERENT_IDENTIFIER,
|
|
|
-// &(slot_num * SLOT_DURATION),
|
|
|
-// );
|
|
|
-// if let Some(babe_pre_digest) = sc_consensus_babe::test_helpers::claim_slot(
|
|
|
-// slot_num,
|
|
|
-// &parent_header,
|
|
|
-// &*service.client(),
|
|
|
-// &keystore,
|
|
|
-// &babe_link,
|
|
|
-// ) {
|
|
|
-// break babe_pre_digest;
|
|
|
-// }
|
|
|
-
|
|
|
-// slot_num += 1;
|
|
|
-// };
|
|
|
-
|
|
|
-// digest.push(<DigestItem as CompatibleDigestItem>::babe_pre_digest(
|
|
|
-// babe_pre_digest,
|
|
|
-// ));
|
|
|
-
|
|
|
-// let new_block = futures::executor::block_on(async move {
|
|
|
-// let proposer = proposer_factory.init(&parent_header).await;
|
|
|
-// proposer
|
|
|
-// .unwrap()
|
|
|
-// .propose(
|
|
|
-// inherent_data,
|
|
|
-// digest,
|
|
|
-// std::time::Duration::from_secs(1),
|
|
|
-// RecordProof::Yes,
|
|
|
-// )
|
|
|
-// .await
|
|
|
-// })
|
|
|
-// .expect("Error making test block")
|
|
|
-// .block;
|
|
|
-
|
|
|
-// let (new_header, new_body) = new_block.deconstruct();
|
|
|
-// let pre_hash = new_header.hash();
|
|
|
-// // sign the pre-sealed hash of the block and then
|
|
|
-// // add it to a digest item.
|
|
|
-// let to_sign = pre_hash.encode();
|
|
|
-// let signature = alice.sign(&to_sign[..]);
|
|
|
-// let item = <DigestItem as CompatibleDigestItem>::babe_seal(signature.into());
|
|
|
-// slot_num += 1;
|
|
|
-
|
|
|
-// let mut params = BlockImportParams::new(BlockOrigin::File, new_header);
|
|
|
-// params.post_digests.push(item);
|
|
|
-// params.body = Some(new_body);
|
|
|
-// params.intermediates.insert(
|
|
|
-// Cow::from(INTERMEDIATE_KEY),
|
|
|
-// Box::new(BabeIntermediate::<Block> { epoch_descriptor }) as Box<dyn Any>,
|
|
|
-// );
|
|
|
-// params.fork_choice = Some(ForkChoiceStrategy::LongestChain);
|
|
|
-
|
|
|
-// block_import
|
|
|
-// .import_block(params, Default::default())
|
|
|
-// .expect("error importing test block");
|
|
|
-// },
|
|
|
-// |service, _| {
|
|
|
-// let amount = 5 * CENTS;
|
|
|
-// let to: AccountId = AccountPublic::from(bob.public()).into_account().into();
|
|
|
-// let from: AccountId = AccountPublic::from(charlie.public()).into_account().into();
|
|
|
-// let genesis_hash = service.client().block_hash(0).unwrap().unwrap();
|
|
|
-// let best_block_id = BlockId::number(service.client().chain_info().best_number);
|
|
|
-// let (spec_version, transaction_version) = {
|
|
|
-// let version = service.client().runtime_version_at(&best_block_id).unwrap();
|
|
|
-// (version.spec_version, version.transaction_version)
|
|
|
-// };
|
|
|
-// let signer = charlie.clone();
|
|
|
-
|
|
|
-// let function = Call::Balances(BalancesCall::transfer(to.into(), amount));
|
|
|
-
|
|
|
-// let check_spec_version = frame_system::CheckSpecVersion::new();
|
|
|
-// let check_tx_version = frame_system::CheckTxVersion::new();
|
|
|
-// let check_genesis = frame_system::CheckGenesis::new();
|
|
|
-// let check_era = frame_system::CheckEra::from(Era::Immortal);
|
|
|
-// let check_nonce = frame_system::CheckNonce::from(index);
|
|
|
-// let check_weight = frame_system::CheckWeight::new();
|
|
|
-// let payment = pallet_transaction_payment::ChargeTransactionPayment::from(0);
|
|
|
-// let validate_grandpa_equivocation =
|
|
|
-// pallet_grandpa::ValidateEquivocationReport::new();
|
|
|
-// let extra = (
|
|
|
-// check_spec_version,
|
|
|
-// check_tx_version,
|
|
|
-// check_genesis,
|
|
|
-// check_era,
|
|
|
-// check_nonce,
|
|
|
-// check_weight,
|
|
|
-// payment,
|
|
|
-// validate_grandpa_equivocation,
|
|
|
-// );
|
|
|
-// let raw_payload = SignedPayload::from_raw(
|
|
|
-// function,
|
|
|
-// extra,
|
|
|
-// (
|
|
|
-// spec_version,
|
|
|
-// transaction_version,
|
|
|
-// genesis_hash,
|
|
|
-// genesis_hash,
|
|
|
-// (),
|
|
|
-// (),
|
|
|
-// (),
|
|
|
-// (),
|
|
|
-// ),
|
|
|
-// );
|
|
|
-// let signature = raw_payload.using_encoded(|payload| signer.sign(payload));
|
|
|
-// let (function, extra, _) = raw_payload.deconstruct();
|
|
|
-// let xt =
|
|
|
-// UncheckedExtrinsic::new_signed(function, from.into(), signature.into(), extra)
|
|
|
-// .encode();
|
|
|
-// let v: Vec<u8> = Decode::decode(&mut xt.as_slice()).unwrap();
|
|
|
-
|
|
|
-// index += 1;
|
|
|
-// OpaqueExtrinsic(v)
|
|
|
-// },
|
|
|
-// );
|
|
|
-// }
|
|
|
-
|
|
|
-// #[test]
|
|
|
-// #[ignore]
|
|
|
-// fn test_consensus() {
|
|
|
-// sc_service_test::consensus(
|
|
|
-// crate::chain_spec::tests::integration_test_config_with_two_authorities(),
|
|
|
-// |config| new_full(config),
|
|
|
-// |config| new_light(config),
|
|
|
-// vec!["//Alice".into(), "//Bob".into()],
|
|
|
-// )
|
|
|
-// }
|
|
|
-// }
|
|
|
+#[cfg(test)]
|
|
|
+mod tests {
|
|
|
+ use crate::node_executor;
|
|
|
+ use crate::node_rpc;
|
|
|
+ use crate::service::{new_full, new_light};
|
|
|
+ use codec::{Decode, Encode};
|
|
|
+ use node_runtime::RuntimeApi;
|
|
|
+ use node_runtime::{currency::CENTS, SLOT_DURATION};
|
|
|
+ use node_runtime::{opaque::Block, AccountId, DigestItem, Signature};
|
|
|
+ use node_runtime::{BalancesCall, Call, UncheckedExtrinsic};
|
|
|
+ use sc_consensus_babe::{BabeIntermediate, CompatibleDigestItem, INTERMEDIATE_KEY};
|
|
|
+ use sc_consensus_epochs::descendent_query;
|
|
|
+ use sc_finality_grandpa::{self as grandpa};
|
|
|
+ use sc_service::AbstractService;
|
|
|
+ use sp_consensus::{
|
|
|
+ BlockImport, BlockImportParams, BlockOrigin, Environment, ForkChoiceStrategy, Proposer,
|
|
|
+ RecordProof,
|
|
|
+ };
|
|
|
+ use sp_core::{crypto::Pair as CryptoPair, H256};
|
|
|
+ use sp_finality_tracker;
|
|
|
+ use sp_keyring::AccountKeyring;
|
|
|
+ use sp_runtime::traits::IdentifyAccount;
|
|
|
+ use sp_runtime::{
|
|
|
+ generic::{BlockId, Digest, Era, SignedPayload},
|
|
|
+ traits::Verify,
|
|
|
+ traits::{Block as BlockT, Header as HeaderT},
|
|
|
+ OpaqueExtrinsic,
|
|
|
+ };
|
|
|
+ use sp_timestamp;
|
|
|
+ use sp_transaction_pool::{ChainEvent, MaintainedTransactionPool};
|
|
|
+ use std::{any::Any, borrow::Cow, sync::Arc};
|
|
|
+
|
|
|
+ type AccountPublic = <Signature as Verify>::Signer;
|
|
|
+
|
|
|
+ // Long running test. Run it locally only after the node changes.
|
|
|
+ #[test]
|
|
|
+ // It is "ignored", but the node-cli ignored tests are running on the CI.
|
|
|
+ // This can be run locally with `cargo test --release -p node-cli test_sync -- --ignored`.
|
|
|
+ #[ignore]
|
|
|
+ fn test_sync() {
|
|
|
+ let keystore_path = tempfile::tempdir().expect("Creates keystore path");
|
|
|
+ let keystore =
|
|
|
+ sc_keystore::Store::open(keystore_path.path(), None).expect("Creates keystore");
|
|
|
+ let alice = keystore
|
|
|
+ .write()
|
|
|
+ .insert_ephemeral_from_seed::<sc_consensus_babe::AuthorityPair>("//Alice")
|
|
|
+ .expect("Creates authority pair");
|
|
|
+
|
|
|
+ let chain_spec = crate::chain_spec::tests::integration_test_config_with_single_authority();
|
|
|
+
|
|
|
+ // For the block factory
|
|
|
+ let mut slot_num = 1u64;
|
|
|
+
|
|
|
+ // For the extrinsics factory
|
|
|
+ let bob = Arc::new(AccountKeyring::Bob.pair());
|
|
|
+ let charlie = Arc::new(AccountKeyring::Charlie.pair());
|
|
|
+ let mut index = 0;
|
|
|
+
|
|
|
+ sc_service_test::sync(
|
|
|
+ chain_spec,
|
|
|
+ |config| {
|
|
|
+ let mut setup_handles = None;
|
|
|
+ new_full!(
|
|
|
+ config,
|
|
|
+ |block_import: &sc_consensus_babe::BabeBlockImport<Block, _, _>,
|
|
|
+ babe_link: &sc_consensus_babe::BabeLink<Block>| {
|
|
|
+ setup_handles = Some((block_import.clone(), babe_link.clone()));
|
|
|
+ }
|
|
|
+ )
|
|
|
+ .map(move |(node, x)| (node, (x, setup_handles.unwrap())))
|
|
|
+ },
|
|
|
+ |config| new_light(config),
|
|
|
+ |service, &mut (ref inherent_data_providers, (ref mut block_import, ref babe_link))| {
|
|
|
+ let mut inherent_data = inherent_data_providers
|
|
|
+ .create_inherent_data()
|
|
|
+ .expect("Creates inherent data.");
|
|
|
+ inherent_data.replace_data(sp_finality_tracker::INHERENT_IDENTIFIER, &1u64);
|
|
|
+
|
|
|
+ let parent_id = BlockId::number(service.client().chain_info().best_number);
|
|
|
+ let parent_header = service.client().header(&parent_id).unwrap().unwrap();
|
|
|
+ let parent_hash = parent_header.hash();
|
|
|
+ let parent_number = *parent_header.number();
|
|
|
+
|
|
|
+ futures::executor::block_on(service.transaction_pool().maintain(
|
|
|
+ ChainEvent::NewBlock {
|
|
|
+ is_new_best: true,
|
|
|
+ hash: parent_header.hash(),
|
|
|
+ tree_route: None,
|
|
|
+ header: parent_header.clone(),
|
|
|
+ },
|
|
|
+ ));
|
|
|
+
|
|
|
+ let mut proposer_factory = sc_basic_authorship::ProposerFactory::new(
|
|
|
+ service.client(),
|
|
|
+ service.transaction_pool(),
|
|
|
+ None,
|
|
|
+ );
|
|
|
+
|
|
|
+ let epoch_descriptor = babe_link
|
|
|
+ .epoch_changes()
|
|
|
+ .lock()
|
|
|
+ .epoch_descriptor_for_child_of(
|
|
|
+ descendent_query(&*service.client()),
|
|
|
+ &parent_hash,
|
|
|
+ parent_number,
|
|
|
+ slot_num,
|
|
|
+ )
|
|
|
+ .unwrap()
|
|
|
+ .unwrap();
|
|
|
+
|
|
|
+ let mut digest = Digest::<H256>::default();
|
|
|
+
|
|
|
+ // even though there's only one authority some slots might be empty,
|
|
|
+ // so we must keep trying the next slots until we can claim one.
|
|
|
+ let babe_pre_digest = loop {
|
|
|
+ inherent_data.replace_data(
|
|
|
+ sp_timestamp::INHERENT_IDENTIFIER,
|
|
|
+ &(slot_num * SLOT_DURATION),
|
|
|
+ );
|
|
|
+ if let Some(babe_pre_digest) = sc_consensus_babe::test_helpers::claim_slot(
|
|
|
+ slot_num,
|
|
|
+ &parent_header,
|
|
|
+ &*service.client(),
|
|
|
+ &keystore,
|
|
|
+ &babe_link,
|
|
|
+ ) {
|
|
|
+ break babe_pre_digest;
|
|
|
+ }
|
|
|
+
|
|
|
+ slot_num += 1;
|
|
|
+ };
|
|
|
+
|
|
|
+ digest.push(<DigestItem as CompatibleDigestItem>::babe_pre_digest(
|
|
|
+ babe_pre_digest,
|
|
|
+ ));
|
|
|
+
|
|
|
+ let new_block = futures::executor::block_on(async move {
|
|
|
+ let proposer = proposer_factory.init(&parent_header).await;
|
|
|
+ proposer
|
|
|
+ .unwrap()
|
|
|
+ .propose(
|
|
|
+ inherent_data,
|
|
|
+ digest,
|
|
|
+ std::time::Duration::from_secs(1),
|
|
|
+ RecordProof::Yes,
|
|
|
+ )
|
|
|
+ .await
|
|
|
+ })
|
|
|
+ .expect("Error making test block")
|
|
|
+ .block;
|
|
|
+
|
|
|
+ let (new_header, new_body) = new_block.deconstruct();
|
|
|
+ let pre_hash = new_header.hash();
|
|
|
+ // sign the pre-sealed hash of the block and then
|
|
|
+ // add it to a digest item.
|
|
|
+ let to_sign = pre_hash.encode();
|
|
|
+ let signature = alice.sign(&to_sign[..]);
|
|
|
+ let item = <DigestItem as CompatibleDigestItem>::babe_seal(signature.into());
|
|
|
+ slot_num += 1;
|
|
|
+
|
|
|
+ let mut params = BlockImportParams::new(BlockOrigin::File, new_header);
|
|
|
+ params.post_digests.push(item);
|
|
|
+ params.body = Some(new_body);
|
|
|
+ params.intermediates.insert(
|
|
|
+ Cow::from(INTERMEDIATE_KEY),
|
|
|
+ Box::new(BabeIntermediate::<Block> { epoch_descriptor }) as Box<dyn Any>,
|
|
|
+ );
|
|
|
+ params.fork_choice = Some(ForkChoiceStrategy::LongestChain);
|
|
|
+
|
|
|
+ block_import
|
|
|
+ .import_block(params, Default::default())
|
|
|
+ .expect("error importing test block");
|
|
|
+ },
|
|
|
+ |service, _| {
|
|
|
+ let amount = 5 * CENTS;
|
|
|
+ let to: AccountId = AccountPublic::from(bob.public()).into_account().into();
|
|
|
+ let from: AccountId = AccountPublic::from(charlie.public()).into_account().into();
|
|
|
+ let genesis_hash = service.client().block_hash(0).unwrap().unwrap();
|
|
|
+ let best_block_id = BlockId::number(service.client().chain_info().best_number);
|
|
|
+ let (spec_version, transaction_version) = {
|
|
|
+ let version = service.client().runtime_version_at(&best_block_id).unwrap();
|
|
|
+ (version.spec_version, version.transaction_version)
|
|
|
+ };
|
|
|
+ let signer = charlie.clone();
|
|
|
+
|
|
|
+ let function = Call::Balances(BalancesCall::transfer(to.into(), amount));
|
|
|
+
|
|
|
+ let check_spec_version = frame_system::CheckSpecVersion::new();
|
|
|
+ let check_tx_version = frame_system::CheckTxVersion::new();
|
|
|
+ let check_genesis = frame_system::CheckGenesis::new();
|
|
|
+ let check_era = frame_system::CheckEra::from(Era::Immortal);
|
|
|
+ let check_nonce = frame_system::CheckNonce::from(index);
|
|
|
+ let check_weight = frame_system::CheckWeight::new();
|
|
|
+ let payment = pallet_transaction_payment::ChargeTransactionPayment::from(0);
|
|
|
+ let validate_grandpa_equivocation =
|
|
|
+ pallet_grandpa::ValidateEquivocationReport::new();
|
|
|
+ let extra = (
|
|
|
+ check_spec_version,
|
|
|
+ check_tx_version,
|
|
|
+ check_genesis,
|
|
|
+ check_era,
|
|
|
+ check_nonce,
|
|
|
+ check_weight,
|
|
|
+ payment,
|
|
|
+ validate_grandpa_equivocation,
|
|
|
+ );
|
|
|
+ let raw_payload = SignedPayload::from_raw(
|
|
|
+ function,
|
|
|
+ extra,
|
|
|
+ (
|
|
|
+ spec_version,
|
|
|
+ transaction_version,
|
|
|
+ genesis_hash,
|
|
|
+ genesis_hash,
|
|
|
+ (),
|
|
|
+ (),
|
|
|
+ (),
|
|
|
+ (),
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ let signature = raw_payload.using_encoded(|payload| signer.sign(payload));
|
|
|
+ let (function, extra, _) = raw_payload.deconstruct();
|
|
|
+ let xt =
|
|
|
+ UncheckedExtrinsic::new_signed(function, from.into(), signature.into(), extra)
|
|
|
+ .encode();
|
|
|
+ let v: Vec<u8> = Decode::decode(&mut xt.as_slice()).unwrap();
|
|
|
+
|
|
|
+ index += 1;
|
|
|
+ OpaqueExtrinsic(v)
|
|
|
+ },
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ #[ignore]
|
|
|
+ fn test_consensus() {
|
|
|
+ sc_service_test::consensus(
|
|
|
+ crate::chain_spec::tests::integration_test_config_with_two_authorities(),
|
|
|
+ |config| new_full(config),
|
|
|
+ |config| new_light(config),
|
|
|
+ vec!["//Alice".into(), "//Bob".into()],
|
|
|
+ )
|
|
|
+ }
|
|
|
+}
|