From c36998aeaf72f240ebe0089caa1aeddbb12cc765 Mon Sep 17 00:00:00 2001
From: Andrew Jones <ascjones@gmail.com>
Date: Sat, 1 Dec 2018 08:47:40 +0000
Subject: [PATCH] Default boot_nodes to local node in build-spec (#1181)

* Default to local bootnode with build-spec

* Rexport libp2p stuff via network crate

* Remove unused imports and fix where formatting

* Remove spurious blank lines

* Remove unnecessary else clause
---
 substrate/core/cli/src/lib.rs               | 43 ++++++++++++++++++---
 substrate/core/network-libp2p/src/lib.rs    |  3 +-
 substrate/core/network-libp2p/src/secret.rs |  2 +-
 substrate/core/network/src/lib.rs           |  5 ++-
 substrate/core/service/src/chain_spec.rs    |  5 +++
 substrate/node/cli/src/lib.rs               |  2 +-
 6 files changed, 51 insertions(+), 9 deletions(-)

diff --git a/substrate/core/cli/src/lib.rs b/substrate/core/cli/src/lib.rs
index 6220ceda875..e65d90d3524 100644
--- a/substrate/core/cli/src/lib.rs
+++ b/substrate/core/cli/src/lib.rs
@@ -63,7 +63,10 @@ use service::{
 	ServiceFactory, FactoryFullConfiguration, RuntimeGenesis,
 	FactoryGenesis, PruningMode, ChainSpec,
 };
-use network::{Protocol, config::NonReservedPeerMode};
+use network::{
+	Protocol, config::{NetworkConfiguration, NonReservedPeerMode},
+	multiaddr,
+};
 use primitives::H256;
 
 use std::io::{Write, Read, stdin, stdout};
@@ -325,7 +328,8 @@ where
 pub fn execute_default<'a, F, E>(
 	spec: ChainSpec<FactoryGenesis<F>>,
 	exit: E,
-	matches: &clap::ArgMatches<'a>
+	matches: &clap::ArgMatches<'a>,
+	config: &FactoryFullConfiguration<F>
 ) -> error::Result<Action<E>>
 where
 	E: IntoExit,
@@ -339,7 +343,7 @@ where
 	fdlimit::raise_fd_limit();
 
 	if let Some(matches) = matches.subcommand_matches("build-spec") {
-		build_spec::<F>(matches, spec)?;
+		build_spec::<F>(matches, spec, config)?;
 		return Ok(Action::ExecutedInternally);
 	}
 
@@ -366,11 +370,40 @@ where
 	Ok(Action::RunService(exit))
 }
 
-fn build_spec<F>(matches: &clap::ArgMatches, spec: ChainSpec<FactoryGenesis<F>>) -> error::Result<()>
-	where F: ServiceFactory,
+fn with_default_boot_node<F>(
+	spec: &ChainSpec<FactoryGenesis<F>>,
+	config: &NetworkConfiguration
+) -> error::Result<ChainSpec<FactoryGenesis<F>>>
+where
+	F: ServiceFactory
+{
+	let mut spec = spec.clone();
+	if spec.boot_nodes().is_empty() {
+		let network_keys =
+			network::obtain_private_key(config)
+				.map_err(|err| format!("Error obtaining network key: {}", err))?;
+		let peer_id = network_keys.to_peer_id();
+		let addr = multiaddr![
+			Ip4([127, 0, 0, 1]),
+			Tcp(30333u16),
+			P2p(peer_id)
+		];
+		spec.add_boot_node(addr)
+	}
+	Ok(spec)
+}
+
+fn build_spec<F>(
+	matches: &clap::ArgMatches,
+	spec: ChainSpec<FactoryGenesis<F>>,
+	config: &FactoryFullConfiguration<F>
+) -> error::Result<()>
+where
+	F: ServiceFactory
 {
 	info!("Building chain spec");
 	let raw = matches.is_present("raw");
+	let spec = with_default_boot_node::<F>(&spec, &config.network)?;
 	let json = service::chain_ops::build_spec::<FactoryGenesis<F>>(spec, raw)?;
 	print!("{}", json);
 	Ok(())
diff --git a/substrate/core/network-libp2p/src/lib.rs b/substrate/core/network-libp2p/src/lib.rs
index 2bf6a0d4907..8c5df15c495 100644
--- a/substrate/core/network-libp2p/src/lib.rs
+++ b/substrate/core/network-libp2p/src/lib.rs
@@ -53,7 +53,8 @@ mod transport;
 
 pub use custom_proto::RegisteredProtocol;
 pub use error::{Error, ErrorKind, DisconnectReason};
-pub use libp2p::{Multiaddr, multiaddr::Protocol, PeerId};
+pub use libp2p::{Multiaddr, multiaddr::{Protocol}, multiaddr, PeerId};
+pub use secret::obtain_private_key;
 pub use service_task::{start_service, Service, ServiceEvent};
 pub use traits::{NetworkConfiguration, NodeIndex, NodeId, NonReservedPeerMode};
 pub use traits::{ProtocolId, Secret, Severity};
diff --git a/substrate/core/network-libp2p/src/secret.rs b/substrate/core/network-libp2p/src/secret.rs
index 26d800bdf91..1eec994ea1b 100644
--- a/substrate/core/network-libp2p/src/secret.rs
+++ b/substrate/core/network-libp2p/src/secret.rs
@@ -25,7 +25,7 @@ use NetworkConfiguration;
 const SECRET_FILE: &str = "secret";
 
 /// Obtains or generates the local private key using the configuration.
-pub(crate) fn obtain_private_key(
+pub fn obtain_private_key(
 	config: &NetworkConfiguration
 ) -> Result<secio::SecioKeyPair, IoError> {
 	if let Some(ref secret) = config.use_secret {
diff --git a/substrate/core/network/src/lib.rs b/substrate/core/network/src/lib.rs
index de3a30402e4..b6ba3f78836 100644
--- a/substrate/core/network/src/lib.rs
+++ b/substrate/core/network/src/lib.rs
@@ -68,7 +68,10 @@ pub use chain::Client as ClientHandle;
 pub use service::{Service, FetchFuture, TransactionPool, ManageNetwork, SyncProvider, ExHashT};
 pub use protocol::{ProtocolStatus, PeerInfo, Context};
 pub use sync::{Status as SyncStatus, SyncState};
-pub use network_libp2p::{NodeIndex, ProtocolId, Severity, Protocol};
+pub use network_libp2p::{
+    NodeIndex, ProtocolId, Severity, Protocol, Multiaddr,
+    obtain_private_key, multiaddr,
+};
 pub use message::{generic as generic_message, RequestId, Status as StatusMessage};
 pub use error::Error;
 pub use on_demand::{OnDemand, OnDemandService, RemoteResponse};
diff --git a/substrate/core/service/src/chain_spec.rs b/substrate/core/service/src/chain_spec.rs
index bc3ebf63cb4..dafae1501c6 100644
--- a/substrate/core/service/src/chain_spec.rs
+++ b/substrate/core/service/src/chain_spec.rs
@@ -23,6 +23,7 @@ use primitives::storage::{StorageKey, StorageData};
 use runtime_primitives::{BuildStorage, StorageMap, ChildrenStorageMap};
 use serde_json as json;
 use components::RuntimeGenesis;
+use network::Multiaddr;
 
 enum GenesisSource<G> {
 	File(PathBuf),
@@ -139,6 +140,10 @@ impl<G: RuntimeGenesis> ChainSpec<G> {
 		self.spec.properties.as_ref().unwrap_or(&json::map::Map::new()).clone()
 	}
 
+	pub fn add_boot_node(&mut self, addr: Multiaddr) {
+		self.spec.boot_nodes.push(addr.to_string())
+	}
+
 	/// Parse json content into a `ChainSpec`
 	pub fn from_embedded(json: &'static [u8]) -> Result<Self, String> {
 		let spec = json::from_slice(json).map_err(|e| format!("Error parsing spec file: {}", e))?;
diff --git a/substrate/node/cli/src/lib.rs b/substrate/node/cli/src/lib.rs
index 8d240face3c..3a8b951b277 100644
--- a/substrate/node/cli/src/lib.rs
+++ b/substrate/node/cli/src/lib.rs
@@ -135,7 +135,7 @@ pub fn run<I, T, E>(args: I, exit: E, version: cli::VersionInfo) -> error::Resul
 		config.roles = ServiceRoles::AUTHORITY;
 	}
 
-	match cli::execute_default::<service::Factory, _>(spec, exit, &matches)? {
+	match cli::execute_default::<service::Factory, _>(spec, exit, &matches, &config)? {
 		cli::Action::ExecutedInternally => (),
 		cli::Action::RunService(exit) => {
 			info!("Substrate Node");
-- 
GitLab