Introduce NetworkConfig and NetworkState
This commit is contained in:
parent
c1d93d073d
commit
ba38cef25e
@ -13,7 +13,6 @@ clap = "2.32.0"
|
|||||||
eth-secp256k1 = { git = "https://github.com/paritytech/rust-secp256k1" }
|
eth-secp256k1 = { git = "https://github.com/paritytech/rust-secp256k1" }
|
||||||
ethereum-types = ""
|
ethereum-types = ""
|
||||||
futures = "0.1.23"
|
futures = "0.1.23"
|
||||||
hex = "0.3.2"
|
|
||||||
libp2p-peerstore = { git = "https://github.com/tomaka/libp2p-rs", branch ="zksummit" }
|
libp2p-peerstore = { git = "https://github.com/tomaka/libp2p-rs", branch ="zksummit" }
|
||||||
libp2p-core = { git = "https://github.com/tomaka/libp2p-rs", branch ="zksummit" }
|
libp2p-core = { git = "https://github.com/tomaka/libp2p-rs", branch ="zksummit" }
|
||||||
libp2p-mplex = { git = "https://github.com/tomaka/libp2p-rs", branch ="zksummit" }
|
libp2p-mplex = { git = "https://github.com/tomaka/libp2p-rs", branch ="zksummit" }
|
||||||
@ -21,6 +20,8 @@ libp2p-tcp-transport = { git = "https://github.com/tomaka/libp2p-rs", branch ="z
|
|||||||
libp2p-floodsub = { git = "https://github.com/tomaka/libp2p-rs", branch ="zksummit" }
|
libp2p-floodsub = { git = "https://github.com/tomaka/libp2p-rs", branch ="zksummit" }
|
||||||
libp2p-identify = { git = "https://github.com/tomaka/libp2p-rs", branch ="zksummit" }
|
libp2p-identify = { git = "https://github.com/tomaka/libp2p-rs", branch ="zksummit" }
|
||||||
libp2p-kad = { git = "https://github.com/tomaka/libp2p-rs", branch ="zksummit" }
|
libp2p-kad = { git = "https://github.com/tomaka/libp2p-rs", branch ="zksummit" }
|
||||||
|
# TODO: Bring pem module internal; too risky to have as external dep.
|
||||||
|
pem = "0.5.0"
|
||||||
rand = "0.3"
|
rand = "0.3"
|
||||||
rlp = { git = "https://github.com/paritytech/parity-common" }
|
rlp = { git = "https://github.com/paritytech/parity-common" }
|
||||||
slog = "^2.2.3"
|
slog = "^2.2.3"
|
||||||
|
17
src/main.rs
17
src/main.rs
@ -10,8 +10,10 @@ pub mod pubkeystore;
|
|||||||
pub mod state;
|
pub mod state;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
|
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use slog::Drain;
|
use slog::Drain;
|
||||||
use clap::{ App, SubCommand};
|
use clap::{ Arg, App, SubCommand};
|
||||||
use p2p::config::NetworkConfig;
|
use p2p::config::NetworkConfig;
|
||||||
use p2p::floodsub;
|
use p2p::floodsub;
|
||||||
use p2p::state::NetworkState;
|
use p2p::state::NetworkState;
|
||||||
@ -24,17 +26,24 @@ fn main() {
|
|||||||
|
|
||||||
let matches = App::new("Lighthouse")
|
let matches = App::new("Lighthouse")
|
||||||
.version("0.0.1")
|
.version("0.0.1")
|
||||||
.author("Paul H. <paul@sigmaprime.io>")
|
.author("Sigma Prime <paul@sigmaprime.io>")
|
||||||
.about("Eth 2.0 Client")
|
.about("Eth 2.0 Client")
|
||||||
|
.arg(Arg::with_name("datadir")
|
||||||
|
.value_name("DIR")
|
||||||
|
.help("Data directory for keys and databases."))
|
||||||
.subcommand(SubCommand::with_name("generate-keys"))
|
.subcommand(SubCommand::with_name("generate-keys"))
|
||||||
.about("Generates a new set of random keys for p2p dev.")
|
.about("Generates a new set of random keys for p2p dev.")
|
||||||
.get_matches();
|
.get_matches();
|
||||||
|
|
||||||
let config = NetworkConfig::default();
|
let mut config = NetworkConfig::default();
|
||||||
|
if let Some(dir) = matches.value_of("datadir") {
|
||||||
|
config.data_dir = PathBuf::from(dir.to_string());
|
||||||
|
}
|
||||||
|
info!(log, ""; "data_dir" => &config.data_dir.to_str());
|
||||||
if let Some(_) = matches.subcommand_matches("generate-keys") {
|
if let Some(_) = matches.subcommand_matches("generate-keys") {
|
||||||
// keys::generate_keys(&log).expect("Failed to generate keys");
|
// keys::generate_keys(&log).expect("Failed to generate keys");
|
||||||
} else {
|
} else {
|
||||||
let state = NetworkState::new(&config).expect("setup failed");
|
let state = NetworkState::new(config, &log).expect("setup failed");
|
||||||
floodsub::listen(state, &log);
|
floodsub::listen(state, &log);
|
||||||
}
|
}
|
||||||
info!(log, "Exiting.");
|
info!(log, "Exiting.");
|
||||||
|
@ -1,14 +1,25 @@
|
|||||||
|
use std::env;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use super::libp2p_core::Multiaddr;
|
use super::libp2p_core::Multiaddr;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct NetworkConfig {
|
pub struct NetworkConfig {
|
||||||
pub config_dir: String,
|
pub data_dir: PathBuf,
|
||||||
pub listen_multiaddr: Multiaddr,
|
pub listen_multiaddr: Multiaddr,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DEFAULT_LIGHTHOUSE_DIR: &str = ".lighthouse";
|
||||||
|
|
||||||
impl NetworkConfig {
|
impl NetworkConfig {
|
||||||
pub fn default() -> Self{
|
pub fn default() -> Self{
|
||||||
|
let data_dir = {
|
||||||
|
let home = env::home_dir()
|
||||||
|
.expect("Unable to determine home dir.");
|
||||||
|
home.join(DEFAULT_LIGHTHOUSE_DIR)
|
||||||
|
};
|
||||||
Self {
|
Self {
|
||||||
config_dir: ".lighthouse".to_string(),
|
data_dir,
|
||||||
listen_multiaddr: "/ip4/0.0.0.0/tcp/0"
|
listen_multiaddr: "/ip4/0.0.0.0/tcp/0"
|
||||||
.parse::<Multiaddr>().unwrap()
|
.parse::<Multiaddr>().unwrap()
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
extern crate bigint;
|
extern crate bigint;
|
||||||
extern crate bytes;
|
extern crate bytes;
|
||||||
extern crate futures;
|
extern crate futures;
|
||||||
extern crate hex;
|
|
||||||
extern crate libp2p_peerstore;
|
extern crate libp2p_peerstore;
|
||||||
extern crate libp2p_identify;
|
extern crate libp2p_identify;
|
||||||
extern crate libp2p_core;
|
extern crate libp2p_core;
|
||||||
|
@ -18,26 +18,22 @@ const LOCAL_PK_FILE: &str = "local.pk";
|
|||||||
const LOCAL_SK_FILE: &str = "local.sk";
|
const LOCAL_SK_FILE: &str = "local.sk";
|
||||||
const BOOTSTRAP_PK_FILE: &str = "bootstrap.pk";
|
const BOOTSTRAP_PK_FILE: &str = "bootstrap.pk";
|
||||||
|
|
||||||
fn get_curve() -> secp256k1::Secp256k1 { secp256k1::Secp256k1::new() }
|
|
||||||
|
|
||||||
/// Generates a new public and secret key pair and writes them to
|
/// Generates a new public and secret key pair and writes them to
|
||||||
/// individual files.
|
/// individual files.
|
||||||
|
///
|
||||||
|
/// This function should only be present during
|
||||||
|
/// early development states and should be removed.
|
||||||
pub fn generate_keys(config: NetworkConfig, log: &Logger)
|
pub fn generate_keys(config: NetworkConfig, log: &Logger)
|
||||||
-> Result<(), IoError>
|
-> Result<(), IoError>
|
||||||
{
|
{
|
||||||
|
// TODO: remove this method and import pem files instead
|
||||||
info!(log, "Generating keys...");
|
info!(log, "Generating keys...");
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
let curve = get_curve();
|
let curve = secp256k1::Secp256k1::new();
|
||||||
let s = SecretKey::new(&curve, &mut rng);
|
let s = SecretKey::new(&curve, &mut rng);
|
||||||
let p = PublicKey::from_secret_key(&curve, &s).unwrap();
|
|
||||||
let p_vec = p.serialize_vec(&curve, false);
|
|
||||||
let s_vec = &s[..];
|
let s_vec = &s[..];
|
||||||
let p_string = hex::encode(p_vec);
|
|
||||||
let s_string = hex::encode(s_vec);
|
let s_string = hex::encode(s_vec);
|
||||||
let mut p_file = File::create(LOCAL_PK_FILE)?;
|
|
||||||
let mut s_file = File::create(LOCAL_SK_FILE)?;
|
let mut s_file = File::create(LOCAL_SK_FILE)?;
|
||||||
info!(log, "Writing public key...");
|
|
||||||
p_file.write(p_string.as_bytes())?;
|
|
||||||
info!(log, "Writing secret key...");
|
info!(log, "Writing secret key...");
|
||||||
s_file.write(s_string.as_bytes())?;
|
s_file.write(s_string.as_bytes())?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
extern crate hex;
|
|
||||||
extern crate libp2p_core;
|
extern crate libp2p_core;
|
||||||
extern crate libp2p_peerstore;
|
extern crate libp2p_peerstore;
|
||||||
|
extern crate pem;
|
||||||
extern crate secp256k1;
|
extern crate secp256k1;
|
||||||
|
extern crate slog;
|
||||||
|
|
||||||
pub mod floodsub;
|
pub mod floodsub;
|
||||||
pub mod state;
|
pub mod state;
|
||||||
|
@ -1,22 +1,26 @@
|
|||||||
use std::io::Read;
|
extern crate rand;
|
||||||
|
|
||||||
|
use std::io::{ Read, Write };
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::path::Path;
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
use super::hex;
|
use super::config::NetworkConfig;
|
||||||
|
use super::libp2p_core::Multiaddr;
|
||||||
|
use super::libp2p_peerstore::{ Peerstore, PeerAccess, PeerId };
|
||||||
|
use super::libp2p_peerstore::json_peerstore::JsonPeerstore;
|
||||||
|
use super::pem;
|
||||||
use super::secp256k1::Secp256k1;
|
use super::secp256k1::Secp256k1;
|
||||||
use super::secp256k1::key::{ SecretKey, PublicKey };
|
use super::secp256k1::key::{ SecretKey, PublicKey };
|
||||||
use super::libp2p_core::Multiaddr;
|
use super::slog::Logger;
|
||||||
use super::libp2p_peerstore::PeerId;
|
|
||||||
use super::libp2p_peerstore::json_peerstore::JsonPeerstore;
|
|
||||||
use super::config::NetworkConfig;
|
|
||||||
|
|
||||||
|
|
||||||
const PEERS_FILE: &str = "peerstore.json";
|
const PEERS_FILE: &str = "peerstore.json";
|
||||||
const LOCAL_SK_FILE: &str = "local.sk";
|
const LOCAL_PEM_FILE: &str = "local_peer_id.pem";
|
||||||
|
|
||||||
pub struct NetworkState {
|
pub struct NetworkState {
|
||||||
|
pub config: NetworkConfig,
|
||||||
pub pubkey: PublicKey,
|
pub pubkey: PublicKey,
|
||||||
pub seckey: SecretKey,
|
pub seckey: SecretKey,
|
||||||
pub peer_id: PeerId,
|
pub peer_id: PeerId,
|
||||||
@ -25,26 +29,26 @@ pub struct NetworkState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl NetworkState {
|
impl NetworkState {
|
||||||
pub fn new(config: &NetworkConfig) -> Result <Self, Box<Error>> {
|
pub fn new(config: NetworkConfig, log: &Logger) -> Result <Self, Box<Error>> {
|
||||||
let curve = Secp256k1::new();
|
let curve = Secp256k1::new();
|
||||||
let seckey = {
|
let seckey = match
|
||||||
let path = Path::new(&config.config_dir).join(LOCAL_SK_FILE);
|
NetworkState::load_secret_key_from_pem_file(&config, &curve)
|
||||||
let mut contents = String::new();
|
{
|
||||||
let mut file = File::open(path)?;
|
Ok(k) => k,
|
||||||
file.read_to_string(&mut contents)?;
|
_ => NetworkState::generate_new_secret_key(&config, &curve)?
|
||||||
let vec = hex::decode(contents)?;
|
|
||||||
SecretKey::from_slice(&curve, &vec)?
|
|
||||||
};
|
};
|
||||||
let pubkey = PublicKey::from_secret_key(&curve, &seckey)?;
|
let pubkey = PublicKey::from_secret_key(&curve, &seckey)?;
|
||||||
let peer_id = PeerId::from_public_key(
|
let peer_id = PeerId::from_public_key(
|
||||||
&pubkey.serialize_vec(&curve, false));
|
&pubkey.serialize_vec(&curve, false));
|
||||||
|
info!(log, "Loaded keys"; "peer_id" => &peer_id.to_base58());
|
||||||
let peer_store = {
|
let peer_store = {
|
||||||
let path = Path::new(&config.config_dir).join(PEERS_FILE);
|
let path = config.data_dir.join(PEERS_FILE);
|
||||||
let base = JsonPeerstore::new(path)?;
|
let base = JsonPeerstore::new(path)?;
|
||||||
Arc::new(base)
|
Arc::new(base)
|
||||||
};
|
};
|
||||||
let listen_multiaddr = "/ip4/0.0.0.0/tcp/0".parse::<Multiaddr>()?;
|
let listen_multiaddr = "/ip4/0.0.0.0/tcp/0".parse::<Multiaddr>()?;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
|
config: config,
|
||||||
seckey,
|
seckey,
|
||||||
pubkey,
|
pubkey,
|
||||||
peer_id,
|
peer_id,
|
||||||
@ -52,4 +56,57 @@ impl NetworkState {
|
|||||||
peer_store,
|
peer_store,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn add_peer(&mut self,
|
||||||
|
peer_id: PeerId,
|
||||||
|
multiaddr: Multiaddr,
|
||||||
|
duration_secs: u64) {
|
||||||
|
self.peer_store.peer_or_create(&peer_id)
|
||||||
|
.add_addr(multiaddr, Duration::from_secs(duration_secs));
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: this shouldn't be hard-coded; distribute with peers json.
|
||||||
|
pub fn add_sigp_peer(&mut self) {
|
||||||
|
let peer_id = {
|
||||||
|
let b58 = "Qmajfeei87f8V5N7SQwPw3wr57M1dNcGNwhTqf72v73E7U";
|
||||||
|
b58.parse::<PeerId>().unwrap()
|
||||||
|
};
|
||||||
|
let multiaddr = {
|
||||||
|
let string = "/dns/lh.sigp.io/tcp/10101";
|
||||||
|
string.parse::<Multiaddr>().unwrap()
|
||||||
|
};
|
||||||
|
self.add_peer(peer_id, multiaddr, 3600 * 24 * 356);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Instantiate a SecretKey from a .pem file on disk.
|
||||||
|
pub fn load_secret_key_from_pem_file(config: &NetworkConfig, curve: &Secp256k1)
|
||||||
|
-> Result<SecretKey, Box<Error>>
|
||||||
|
{
|
||||||
|
let path = config.data_dir.join(LOCAL_PEM_FILE);
|
||||||
|
let mut contents = String::new();
|
||||||
|
let mut file = File::open(path)?;
|
||||||
|
file.read_to_string(&mut contents)?;
|
||||||
|
let pem_key = pem::parse(contents)?;
|
||||||
|
let key = SecretKey::from_slice(curve, &pem_key.contents)?;
|
||||||
|
Ok(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generate a new SecretKey and store it on disk as a .pem file.
|
||||||
|
pub fn generate_new_secret_key(
|
||||||
|
config: &NetworkConfig,
|
||||||
|
curve: &Secp256k1)
|
||||||
|
-> Result<SecretKey, Box<Error>>
|
||||||
|
{
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
let sk = SecretKey::new(&curve, &mut rng);
|
||||||
|
let pem_key = pem::Pem {
|
||||||
|
tag: String::from("EC PRIVATE KEY"),
|
||||||
|
contents: sk[..].to_vec()
|
||||||
|
};
|
||||||
|
let s_string = pem::encode(&pem_key);
|
||||||
|
let path = config.data_dir.join(LOCAL_PEM_FILE);
|
||||||
|
let mut s_file = File::create(path)?;
|
||||||
|
s_file.write(s_string.as_bytes())?;
|
||||||
|
Ok(sk)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user