diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock index 332b0a286a..dbdaae9709 100644 --- a/substrate/Cargo.lock +++ b/substrate/Cargo.lock @@ -1706,6 +1706,7 @@ dependencies = [ "rhododendron 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 0.1.0", + "sr-primitives 0.1.0", "substrate-bft 0.1.0", "substrate-client 0.1.0", "substrate-keyring 0.1.0", diff --git a/substrate/core/network/src/protocol.rs b/substrate/core/network/src/protocol.rs index 6c0e887b66..a828c386c3 100644 --- a/substrate/core/network/src/protocol.rs +++ b/substrate/core/network/src/protocol.rs @@ -472,6 +472,8 @@ impl, H: ExHashT> Protocol { for t in extrinsics { if let Some(hash) = self.transaction_pool.import(&t) { peer.known_extrinsics.insert(hash); + } else { + trace!(target: "sync", "Extrinsic rejected"); } } } diff --git a/substrate/core/service/src/lib.rs b/substrate/core/service/src/lib.rs index 4df7e0b884..4f65e5b263 100644 --- a/substrate/core/service/src/lib.rs +++ b/substrate/core/service/src/lib.rs @@ -158,7 +158,7 @@ impl Service Components::build_transaction_pool(config.transaction_pool, client.clone())? ); let transaction_pool_adapter = TransactionPoolAdapter:: { - imports_external_transactions: !config.roles == Roles::LIGHT, + imports_external_transactions: !(config.roles == Roles::LIGHT), pool: transaction_pool.clone(), client: client.clone(), }; @@ -404,6 +404,7 @@ impl network::TransactionPool, ComponentBlock< fn import(&self, transaction: &ComponentExtrinsic) -> Option> { if !self.imports_external_transactions { + debug!("Transaction rejected"); return None; } diff --git a/substrate/core/service/test/src/lib.rs b/substrate/core/service/test/src/lib.rs index 6ec3720deb..929ca480dc 100644 --- a/substrate/core/service/test/src/lib.rs +++ b/substrate/core/service/test/src/lib.rs @@ -49,6 +49,7 @@ use service::{ use network::{NetworkConfiguration, NonReservedPeerMode, Protocol, SyncProvider, ManageNetwork}; use client::{BlockOrigin, JustifiedHeader}; use sr_primitives::traits::As; +use sr_primitives::generic::BlockId; struct TestNet { runtime: Runtime, @@ -212,10 +213,11 @@ pub fn connectivity(spec: FactoryChainSpec) { } } -pub fn sync(spec: FactoryChainSpec, block_factory: B) +pub fn sync(spec: FactoryChainSpec, block_factory: B, extrinsic_factory: E) where F: ServiceFactory, B: Fn(&F::FullService) -> (JustifiedHeader, Option>>), + E: Fn(&F::FullService) -> FactoryExtrinsic, { const NUM_NODES: u32 = 10; const NUM_BLOCKS: usize = 512; @@ -237,9 +239,16 @@ where for (_, service) in network.full_nodes.iter().skip(1) { service.network().add_reserved_peer(first_address.clone()).expect("Error adding reserved peer"); } - network.run_until_all_full(|_index, service| { + network.run_until_all_full(|_index, service| service.client().info().unwrap().chain.best_number == As::sa(NUM_BLOCKS as u64) - }); + ); + info!("Checking extrinsic propagation"); + let first_service = network.full_nodes[0].1.clone(); + let best_block = BlockId::number(first_service.client().info().unwrap().chain.best_number); + first_service.transaction_pool().submit_one(&best_block, extrinsic_factory(&first_service)).unwrap(); + network.run_until_all_full(|_index, service| + service.transaction_pool().all().len() == 1 + ); } pub fn consensus(spec: FactoryChainSpec, authorities: Vec) diff --git a/substrate/node/runtime/src/lib.rs b/substrate/node/runtime/src/lib.rs index 75204d46eb..a59321b880 100644 --- a/substrate/node/runtime/src/lib.rs +++ b/substrate/node/runtime/src/lib.rs @@ -72,6 +72,7 @@ use version::NativeVersion; pub use runtime_primitives::BuildStorage; pub use consensus::Call as ConsensusCall; pub use timestamp::Call as TimestampCall; +pub use balances::Call as BalancesCall; pub use runtime_primitives::{Permill, Perbill}; pub use timestamp::BlockPeriod; pub use srml_support::StorageValue; diff --git a/substrate/node/service/Cargo.toml b/substrate/node/service/Cargo.toml index bbb3ab66c9..a9c58ebb47 100644 --- a/substrate/node/service/Cargo.toml +++ b/substrate/node/service/Cargo.toml @@ -19,6 +19,7 @@ node-consensus = { path = "../consensus" } node-network = { path = "../network" } node-transaction-pool = { path = "../transaction-pool" } sr-io = { path = "../../core/sr-io" } +sr-primitives = { path = "../../core/sr-primitives" } substrate-primitives = { path = "../../core/primitives" } substrate-network = { path = "../../core/network" } substrate-client = { path = "../../core/client" } diff --git a/substrate/node/service/src/lib.rs b/substrate/node/service/src/lib.rs index 27382621ce..d20c099c10 100644 --- a/substrate/node/service/src/lib.rs +++ b/substrate/node/service/src/lib.rs @@ -45,7 +45,8 @@ extern crate substrate_bft as bft; extern crate substrate_test_client; #[cfg(test)] extern crate substrate_keyring as keyring; - +#[cfg(test)] +extern crate sr_primitives as runtime_primitives; pub mod chain_spec; use std::sync::Arc; @@ -213,12 +214,18 @@ mod tests { use {service, service_test, Factory, chain_spec}; use consensus::{self, OfflineTracker}; use primitives::ed25519; + use runtime_primitives::traits::BlockNumberToHash; + use runtime_primitives::generic::Era; use node_primitives::Block; use bft::{Proposer, Environment}; use node_network::consensus::ConsensusNetwork; use substrate_test_client::fake_justify; use node_primitives::BlockId; use keyring::Keyring; + use node_runtime::{UncheckedExtrinsic, Call, BalancesCall}; + use node_primitives::UncheckedExtrinsic as OpaqueExtrinsic; + use codec::{Decode, Encode}; + use node_runtime::RawAddress; #[test] fn test_connectivity() { @@ -251,7 +258,18 @@ mod tests { let justification = service.client().check_justification(block.header, justification).unwrap(); (justification, Some(block.extrinsics)) }; - service_test::sync::(chain_spec::integration_test_config(), block_factory); + let extrinsic_factory = |service: &::FullService| { + let payload = (0, Call::Balances(BalancesCall::transfer(RawAddress::Id(bob.public().0.into()), 69)), Era::immortal(), service.client().genesis_hash()); + let signature = alice.sign(&payload.encode()).into(); + let id = alice.public().0.into(); + let xt = UncheckedExtrinsic { + signature: Some((RawAddress::Id(id), signature, payload.0, Era::immortal())), + function: payload.1, + }.encode(); + let v: Vec = Decode::decode(&mut xt.as_slice()).unwrap(); + OpaqueExtrinsic(v) + }; + service_test::sync::(chain_spec::integration_test_config(), block_factory, extrinsic_factory); } #[test]