Add configuration system.
This commit is contained in:
parent
7da347fc86
commit
adce8eb288
12
Cargo.lock
generated
12
Cargo.lock
generated
@ -609,9 +609,15 @@ dependencies = [
|
||||
"libp2p 0.3.0",
|
||||
"multibase 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"multihash 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-multiaddr 0.1.0",
|
||||
"parity-multihash 0.1.0",
|
||||
"protobuf 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.86 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.86 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"xdg 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2136,6 +2142,11 @@ dependencies = [
|
||||
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xdg"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "yamux"
|
||||
version = "0.1.6"
|
||||
@ -2360,4 +2371,5 @@ dependencies = [
|
||||
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
|
||||
"checksum xdg 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57"
|
||||
"checksum yamux 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e25561b512df3c287cf52404cab0b07ea43d095cb96230e9e2cb635db72d75f0"
|
||||
|
@ -10,6 +10,12 @@ futures = "*"
|
||||
libp2p = { version = "*", path = "../rust-libp2p" }
|
||||
multibase = "*"
|
||||
multihash = "*"
|
||||
parity-multiaddr = { version = "*", path = "../rust-libp2p/misc/multiaddr" }
|
||||
parity-multihash = { version = "*", path = "../rust-libp2p/misc/multihash" }
|
||||
protobuf = "2.0.2"
|
||||
rand = "0.6"
|
||||
serde = "1.0"
|
||||
serde_derive = "1.0"
|
||||
serde_json = "1.0"
|
||||
tokio = "*"
|
||||
xdg = "*"
|
94
src/config.rs
Normal file
94
src/config.rs
Normal file
@ -0,0 +1,94 @@
|
||||
use libp2p::{Multiaddr, PeerId};
|
||||
use libp2p::multiaddr::Protocol;
|
||||
use libp2p::secio::SecioKeyPair;
|
||||
use rand::{Rng, rngs::EntropyRng};
|
||||
use serde_derive::{Serialize, Deserialize};
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
const APP_NAME: &'static str = "rust-ipfs";
|
||||
const CONFIG_FILE: &'static str = "config.json";
|
||||
|
||||
const BOOTSTRAP_NODES: &[&'static str] = &[
|
||||
"/ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ",
|
||||
"/ip4/104.236.179.241/tcp/4001/p2p/QmSoLPppuBtQSGwKDZT2M73ULpjvfd3aZ6ha4oFGL1KrGM",
|
||||
"/ip4/104.236.76.40/tcp/4001/p2p/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64",
|
||||
"/ip4/128.199.219.111/tcp/4001/p2p/QmSoLSafTMBsPKadTEgaXctDQVcqN88CNLHXMkTNwMKPnu",
|
||||
"/ip4/178.62.158.247/tcp/4001/p2p/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd",
|
||||
"/ip6/2400:6180:0:d0::151:6001/tcp/4001/p2p/QmSoLSafTMBsPKadTEgaXctDQVcqN88CNLHXMkTNwMKPnu",
|
||||
"/ip6/2604:a880:1:20::203:d001/tcp/4001/p2p/QmSoLPppuBtQSGwKDZT2M73ULpjvfd3aZ6ha4oFGL1KrGM",
|
||||
"/ip6/2604:a880:800:10::4a:5001/tcp/4001/p2p/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64",
|
||||
"/ip6/2a03:b0c0:0:1010::23:1001/tcp/4001/p2p/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd",
|
||||
];
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Configuration {
|
||||
raw_key: [u8; 32],
|
||||
bootstrap: Vec<Multiaddr>,
|
||||
}
|
||||
|
||||
impl Configuration {
|
||||
pub fn new() -> Self {
|
||||
let xdg_dirs = xdg::BaseDirectories::with_prefix(APP_NAME).unwrap();
|
||||
let path = xdg_dirs.place_config_file(CONFIG_FILE).unwrap();
|
||||
Configuration::from_file(path)
|
||||
}
|
||||
|
||||
pub fn secio_key_pair(&self) -> SecioKeyPair {
|
||||
SecioKeyPair::ed25519_raw_key(&self.raw_key).unwrap()
|
||||
}
|
||||
|
||||
pub fn bootstrap(&self) -> Vec<(Multiaddr, PeerId)> {
|
||||
let mut bootstrap = Vec::new();
|
||||
for addr in &self.bootstrap {
|
||||
let mut addr = addr.to_owned();
|
||||
let peer_id = match addr.pop() {
|
||||
Some(Protocol::P2p(hash)) => PeerId::from_multihash(hash).unwrap(),
|
||||
_ => panic!("No peer id for addr"),
|
||||
};
|
||||
bootstrap.push((addr, peer_id));
|
||||
}
|
||||
bootstrap
|
||||
}
|
||||
|
||||
pub fn generate() -> Self {
|
||||
let raw_key: [u8; 32] = EntropyRng::new().gen();
|
||||
let bootstrap = BOOTSTRAP_NODES.iter().map(|node| {
|
||||
node.parse().unwrap()
|
||||
}).collect();
|
||||
Configuration {
|
||||
raw_key,
|
||||
bootstrap,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_file<P: AsRef<Path>>(path: P) -> Self {
|
||||
fs::read_to_string(&path).map(|content| {
|
||||
serde_json::from_str(&content).unwrap()
|
||||
}).unwrap_or_else(|_| {
|
||||
let config = Configuration::generate();
|
||||
let string = serde_json::to_string(&config).unwrap();
|
||||
fs::write(path, string).unwrap();
|
||||
config
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub struct NetworkConfig {
|
||||
pub key_pair: SecioKeyPair,
|
||||
pub peer_id: PeerId,
|
||||
pub bootstrap: Vec<(Multiaddr, PeerId)>,
|
||||
}
|
||||
|
||||
impl From<&Configuration> for NetworkConfig {
|
||||
fn from(config: &Configuration) -> Self {
|
||||
let key_pair = config.secio_key_pair();
|
||||
let peer_id = key_pair.to_peer_id();
|
||||
let bootstrap = config.bootstrap();
|
||||
NetworkConfig {
|
||||
key_pair,
|
||||
peer_id,
|
||||
bootstrap,
|
||||
}
|
||||
}
|
||||
}
|
@ -4,16 +4,17 @@
|
||||
#![feature(drain_filter)]
|
||||
use futures::prelude::*;
|
||||
use futures::try_ready;
|
||||
use libp2p::secio::SecioKeyPair;
|
||||
|
||||
mod bitswap;
|
||||
pub mod block;
|
||||
mod config;
|
||||
mod future;
|
||||
mod p2p;
|
||||
mod repo;
|
||||
|
||||
use self::bitswap::{strategy::AltruisticStrategy, Strategy};
|
||||
pub use self::block::{Block, Cid};
|
||||
use self::config::{Configuration, NetworkConfig};
|
||||
use self::future::BlockFuture;
|
||||
use self::p2p::{create_swarm, Swarm};
|
||||
use self::repo::Repo;
|
||||
@ -30,10 +31,10 @@ pub struct Ipfs {
|
||||
impl Ipfs {
|
||||
/// Creates a new ipfs node.
|
||||
pub fn new() -> Self {
|
||||
let config = Configuration::new();
|
||||
let repo = Repo::new();
|
||||
let local_key = SecioKeyPair::ed25519_generated().unwrap();
|
||||
let strategy = AltruisticStrategy::new(repo.clone());
|
||||
let swarm = create_swarm(local_key);
|
||||
let swarm = create_swarm(NetworkConfig::from(&config));
|
||||
|
||||
Ipfs {
|
||||
repo,
|
||||
|
@ -1,5 +1,6 @@
|
||||
use crate::bitswap::{Bitswap, BitswapEvent};
|
||||
use crate::block::{Block, Cid};
|
||||
use crate::config::NetworkConfig;
|
||||
use libp2p::{NetworkBehaviour, PeerId};
|
||||
use libp2p::core::swarm::NetworkBehaviourEventProcess;
|
||||
use libp2p::core::muxing::{StreamMuxerBox, SubstreamRef};
|
||||
@ -8,46 +9,6 @@ use parity_multihash::Multihash;
|
||||
use std::sync::Arc;
|
||||
use tokio::prelude::*;
|
||||
|
||||
/// IPFS bootstrap nodes.
|
||||
const BOOTSTRAP_NODES: &[(&'static str, &'static str)] = &[
|
||||
(
|
||||
"QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ",
|
||||
"/ip4/104.131.131.82/tcp/4001",
|
||||
),
|
||||
(
|
||||
"QmSoLPppuBtQSGwKDZT2M73ULpjvfd3aZ6ha4oFGL1KrGM",
|
||||
"/ip4/104.236.179.241/tcp/4001",
|
||||
),
|
||||
(
|
||||
"QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64",
|
||||
"/ip4/104.236.76.40/tcp/4001",
|
||||
),
|
||||
(
|
||||
"QmSoLSafTMBsPKadTEgaXctDQVcqN88CNLHXMkTNwMKPnu",
|
||||
"/ip4/128.199.219.111/tcp/4001",
|
||||
),
|
||||
(
|
||||
"QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd",
|
||||
"/ip4/178.62.158.247/tcp/4001",
|
||||
),
|
||||
/*(
|
||||
"QmSoLSafTMBsPKadTEgaXctDQVcqN88CNLHXMkTNwMKPnu",
|
||||
"/ip6/2400:6180:0:d0::151:6001/tcp/4001",
|
||||
),
|
||||
(
|
||||
"QmSoLPppuBtQSGwKDZT2M73ULpjvfd3aZ6ha4oFGL1KrGM",
|
||||
"/ip6/2604:a880:1:20::203:d001/tcp/4001",
|
||||
),
|
||||
(
|
||||
"QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64",
|
||||
"/ip6/2604:a880:800:10::4a:5001/tcp/4001",
|
||||
),
|
||||
(
|
||||
"QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd",
|
||||
"/ip6/2a03:b0c0:0:1010::23:1001/tcp/4001",
|
||||
),*/
|
||||
];
|
||||
|
||||
/// Behaviour type.
|
||||
#[derive(NetworkBehaviour)]
|
||||
pub struct Behaviour<TSubstream: AsyncRead + AsyncWrite> {
|
||||
@ -103,21 +64,13 @@ impl<TSubstream: AsyncRead + AsyncWrite>
|
||||
impl<TSubstream: AsyncRead + AsyncWrite> Behaviour<TSubstream>
|
||||
{
|
||||
/// Create a Kademlia behaviour with the IPFS bootstrap nodes.
|
||||
pub fn new(local_peer_id: PeerId) -> Self {
|
||||
println!("Local peer id: {}", &local_peer_id.to_base58());
|
||||
pub fn new(config: &NetworkConfig) -> Self {
|
||||
println!("Local peer id: {}", config.peer_id.to_base58());
|
||||
|
||||
// Note that normally the Kademlia process starts by performing lots of
|
||||
// request in order to insert our local node in the DHT. However here we use
|
||||
// `without_init` because this example is very ephemeral and we don't want
|
||||
// to pollute the DHT. In a real world application, you want to use `new`
|
||||
// instead.
|
||||
let mut kademlia = Kademlia::without_init(local_peer_id);
|
||||
let mut kademlia = Kademlia::new(config.peer_id.to_owned());
|
||||
|
||||
for (identity, location) in BOOTSTRAP_NODES {
|
||||
kademlia.add_address(
|
||||
&identity.parse().unwrap(),
|
||||
location.parse().unwrap(),
|
||||
);
|
||||
for (addr, peer_id) in &config.bootstrap {
|
||||
kademlia.add_address(peer_id, addr.to_owned());
|
||||
}
|
||||
|
||||
let bitswap = Bitswap::new();
|
||||
@ -153,6 +106,6 @@ impl<TSubstream: AsyncRead + AsyncWrite> Behaviour<TSubstream>
|
||||
pub type TBehaviour = Behaviour<SubstreamRef<Arc<StreamMuxerBox>>>;
|
||||
|
||||
/// Create a IPFS behaviour with the IPFS bootstrap nodes.
|
||||
pub fn build_behaviour(local_peer_id: PeerId) -> TBehaviour {
|
||||
Behaviour::new(local_peer_id)
|
||||
pub fn build_behaviour(config: &NetworkConfig) -> TBehaviour {
|
||||
Behaviour::new(config)
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
//! P2P handling for IPFS nodes.
|
||||
pub use libp2p::secio::SecioKeyPair;
|
||||
use crate::config::NetworkConfig;
|
||||
|
||||
mod behaviour;
|
||||
mod transport;
|
||||
@ -7,15 +7,13 @@ mod transport;
|
||||
pub type Swarm = libp2p::core::Swarm<transport::TTransport, behaviour::TBehaviour>;
|
||||
|
||||
/// Creates a new IPFS swarm.
|
||||
pub fn create_swarm(local_private_key: SecioKeyPair) -> Swarm {
|
||||
let local_peer_id = local_private_key.to_peer_id();
|
||||
|
||||
pub fn create_swarm(config: NetworkConfig) -> Swarm {
|
||||
// Set up an encrypted TCP transport over the Mplex protocol.
|
||||
let transport = transport::build_transport(local_private_key);
|
||||
let transport = transport::build_transport(&config);
|
||||
|
||||
// Create a Kademlia behaviour
|
||||
let behaviour = behaviour::build_behaviour(local_peer_id.clone());
|
||||
let behaviour = behaviour::build_behaviour(&config);
|
||||
|
||||
// Create a Swarm
|
||||
libp2p::core::Swarm::new(transport, behaviour, local_peer_id)
|
||||
libp2p::core::Swarm::new(transport, behaviour, config.peer_id)
|
||||
}
|
||||
|
@ -1,10 +1,11 @@
|
||||
use crate::config::NetworkConfig;
|
||||
use futures::future::Future;
|
||||
use libp2p::{PeerId, Transport};
|
||||
use libp2p::core::muxing::StreamMuxerBox;
|
||||
use libp2p::core::transport::boxed::Boxed;
|
||||
use libp2p::core::upgrade::{self, InboundUpgradeExt, OutboundUpgradeExt};
|
||||
use libp2p::mplex::MplexConfig;
|
||||
use libp2p::secio::{SecioConfig, SecioKeyPair};
|
||||
use libp2p::secio::SecioConfig;
|
||||
use libp2p::tcp::TcpConfig;
|
||||
use std::io::{Error, ErrorKind};
|
||||
use std::time::Duration;
|
||||
@ -15,9 +16,9 @@ pub type TTransport = Boxed<(PeerId, StreamMuxerBox), Error>;
|
||||
/// Builds the transport that serves as a common ground for all connections.
|
||||
///
|
||||
/// Set up an encrypted TCP transport over the Mplex protocol.
|
||||
pub fn build_transport(local_private_key: SecioKeyPair) -> TTransport {
|
||||
pub fn build_transport(config: &NetworkConfig) -> TTransport {
|
||||
let transport = TcpConfig::new();
|
||||
let secio_config = SecioConfig::new(local_private_key);
|
||||
let secio_config = SecioConfig::new(config.key_pair.to_owned());
|
||||
let mplex_config = MplexConfig::new();
|
||||
|
||||
transport
|
||||
|
Loading…
x
Reference in New Issue
Block a user