2018-08-01 00:27:05 +00:00
|
|
|
extern crate rand;
|
|
|
|
|
|
|
|
use std::io::{ Read, Write };
|
2018-07-29 05:06:42 +00:00
|
|
|
use std::error::Error;
|
|
|
|
use std::fs::File;
|
|
|
|
use std::sync::Arc;
|
2018-08-01 00:27:05 +00:00
|
|
|
use std::time::Duration;
|
2018-07-29 05:06:42 +00:00
|
|
|
|
2018-08-01 00:27:05 +00:00
|
|
|
use super::config::NetworkConfig;
|
2018-07-29 05:06:42 +00:00
|
|
|
use super::libp2p_core::Multiaddr;
|
2018-08-01 00:27:05 +00:00
|
|
|
use super::libp2p_peerstore::{ Peerstore, PeerAccess, PeerId };
|
2018-07-29 05:06:42 +00:00
|
|
|
use super::libp2p_peerstore::json_peerstore::JsonPeerstore;
|
2018-08-01 00:27:05 +00:00
|
|
|
use super::pem;
|
|
|
|
use super::secp256k1::Secp256k1;
|
|
|
|
use super::secp256k1::key::{ SecretKey, PublicKey };
|
|
|
|
use super::slog::Logger;
|
2018-07-29 05:06:42 +00:00
|
|
|
|
|
|
|
|
|
|
|
const PEERS_FILE: &str = "peerstore.json";
|
2018-08-01 00:27:05 +00:00
|
|
|
const LOCAL_PEM_FILE: &str = "local_peer_id.pem";
|
2018-07-29 05:06:42 +00:00
|
|
|
|
|
|
|
pub struct NetworkState {
|
2018-08-01 00:27:05 +00:00
|
|
|
pub config: NetworkConfig,
|
2018-07-29 05:06:42 +00:00
|
|
|
pub pubkey: PublicKey,
|
|
|
|
pub seckey: SecretKey,
|
|
|
|
pub peer_id: PeerId,
|
|
|
|
pub listen_multiaddr: Multiaddr,
|
|
|
|
pub peer_store: Arc<JsonPeerstore>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl NetworkState {
|
2018-08-01 00:27:05 +00:00
|
|
|
pub fn new(config: NetworkConfig, log: &Logger) -> Result <Self, Box<Error>> {
|
2018-07-29 05:06:42 +00:00
|
|
|
let curve = Secp256k1::new();
|
2018-08-01 00:27:05 +00:00
|
|
|
let seckey = match
|
|
|
|
NetworkState::load_secret_key_from_pem_file(&config, &curve)
|
|
|
|
{
|
|
|
|
Ok(k) => k,
|
|
|
|
_ => NetworkState::generate_new_secret_key(&config, &curve)?
|
2018-07-29 05:06:42 +00:00
|
|
|
};
|
|
|
|
let pubkey = PublicKey::from_secret_key(&curve, &seckey)?;
|
|
|
|
let peer_id = PeerId::from_public_key(
|
|
|
|
&pubkey.serialize_vec(&curve, false));
|
2018-08-01 00:27:05 +00:00
|
|
|
info!(log, "Loaded keys"; "peer_id" => &peer_id.to_base58());
|
2018-07-29 05:06:42 +00:00
|
|
|
let peer_store = {
|
2018-08-01 00:27:05 +00:00
|
|
|
let path = config.data_dir.join(PEERS_FILE);
|
2018-07-29 05:06:42 +00:00
|
|
|
let base = JsonPeerstore::new(path)?;
|
|
|
|
Arc::new(base)
|
|
|
|
};
|
2018-08-02 12:38:54 +00:00
|
|
|
info!(log, "Loaded peerstore"; "peer_count" => &peer_store.peers().count());
|
|
|
|
let listen_multiaddr = config.listen_multiaddr.clone();
|
2018-07-29 05:06:42 +00:00
|
|
|
Ok(Self {
|
2018-08-01 00:27:05 +00:00
|
|
|
config: config,
|
2018-07-29 05:06:42 +00:00
|
|
|
seckey,
|
|
|
|
pubkey,
|
|
|
|
peer_id,
|
|
|
|
listen_multiaddr,
|
|
|
|
peer_store,
|
|
|
|
})
|
|
|
|
}
|
2018-08-01 00:27:05 +00:00
|
|
|
|
|
|
|
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));
|
|
|
|
}
|
|
|
|
|
|
|
|
/// 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)
|
|
|
|
}
|
2018-07-29 05:06:42 +00:00
|
|
|
}
|