|
@@ -415,247 +415,250 @@ pub fn new_light(config: Configuration) -> Result<impl AbstractService, ServiceE
|
|
|
Ok(service)
|
|
|
}
|
|
|
|
|
|
-#[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()],
|
|
|
- )
|
|
|
- }
|
|
|
-}
|
|
|
+// 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()],
|
|
|
+// )
|
|
|
+// }
|
|
|
+// }
|