Actually save ENR on creation and modification (#11602)

* Actually save ENR on creation and modification

* Add test
This commit is contained in:
Artem Vorotnikov 2020-04-07 21:40:54 +03:00 committed by GitHub
parent 78a0e8d312
commit c92a15dad0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 58 additions and 17 deletions

View File

@ -941,7 +941,7 @@ mod tests {
fn ping_queue() {
let key = Random.generate();
let ep = NodeEndpoint { address: SocketAddr::from_str("127.0.0.1:40445").unwrap(), udp_port: 40445 };
let enr = EnrManager::new(key.secret().clone(), 0).unwrap().with_node_endpoint(&ep).into_enr();
let enr = EnrManager::new(None, key.secret().clone(), 0).unwrap().with_node_endpoint(&ep).into_enr();
let mut discovery = Discovery::new(&key, ep.clone(), enr, IpFilter::default());
for i in 1..(MAX_NODES_PING+1) {
@ -966,7 +966,7 @@ mod tests {
address: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 41000 + i),
udp_port: 41000 + i,
};
let enr = EnrManager::new(key.secret().clone(), 0).unwrap().with_node_endpoint(&ep).into_enr();
let enr = EnrManager::new(None, key.secret().clone(), 0).unwrap().with_node_endpoint(&ep).into_enr();
Discovery::new(&key, ep, enr, IpFilter::default())
})
.collect::<Vec<_>>();
@ -1014,7 +1014,7 @@ mod tests {
fn removes_expired() {
let key = Random.generate();
let ep = NodeEndpoint { address: SocketAddr::from_str("127.0.0.1:40446").unwrap(), udp_port: 40447 };
let enr = EnrManager::new(key.secret().clone(), 0).unwrap().with_node_endpoint(&ep).into_enr();
let enr = EnrManager::new(None, key.secret().clone(), 0).unwrap().with_node_endpoint(&ep).into_enr();
let discovery = Discovery::new(&key, ep.clone(), enr, IpFilter::default());
let mut discovery = Discovery { request_backoff: &[], ..discovery };
@ -1107,7 +1107,7 @@ mod tests {
let key = Random.generate();
let ep = NodeEndpoint { address: SocketAddr::from_str("127.0.0.1:40447").unwrap(), udp_port: 40447 };
let enr = EnrManager::new(key.secret().clone(), 0).unwrap().with_node_endpoint(&ep).into_enr();
let enr = EnrManager::new(None, key.secret().clone(), 0).unwrap().with_node_endpoint(&ep).into_enr();
let mut discovery = Discovery::new(&key, ep.clone(), enr, IpFilter::default());
for _ in 0..(16 + 10) {
@ -1165,7 +1165,7 @@ mod tests {
let key = Secret::from_str(secret_hex)
.and_then(|secret| KeyPair::from_secret(secret))
.unwrap();
let enr = EnrManager::new(key.secret().clone(), 0).unwrap().with_node_endpoint(&ep).into_enr();
let enr = EnrManager::new(None, key.secret().clone(), 0).unwrap().with_node_endpoint(&ep).into_enr();
let mut discovery = Discovery::new(&key, ep.clone(), enr, IpFilter::default());
discovery.init_node_list(node_entries.clone());
@ -1211,7 +1211,7 @@ mod tests {
fn packets() {
let key = Random.generate();
let ep = NodeEndpoint { address: SocketAddr::from_str("127.0.0.1:40449").unwrap(), udp_port: 40449 };
let enr = EnrManager::new(key.secret().clone(), 0).unwrap().with_node_endpoint(&ep).into_enr();
let enr = EnrManager::new(None, key.secret().clone(), 0).unwrap().with_node_endpoint(&ep).into_enr();
let mut discovery = Discovery::new(&key, ep.clone(), enr, IpFilter::default());
discovery.check_timestamps = false;
let from = SocketAddr::from_str("99.99.99.99:40445").unwrap();
@ -1281,8 +1281,8 @@ mod tests {
let ep1 = NodeEndpoint { address: SocketAddr::from_str("127.0.0.1:40344").unwrap(), udp_port: 40344 };
let ep2 = NodeEndpoint { address: SocketAddr::from_str("127.0.0.1:40345").unwrap(), udp_port: 40345 };
let ep3 = NodeEndpoint { address: SocketAddr::from_str("127.0.0.1:40346").unwrap(), udp_port: 40345 };
let enr1 = EnrManager::new(key1.secret().clone(), 0).unwrap().with_node_endpoint(&ep1).into_enr();
let enr2 = EnrManager::new(key2.secret().clone(), 0).unwrap().with_node_endpoint(&ep2).into_enr();
let enr1 = EnrManager::new(None, key1.secret().clone(), 0).unwrap().with_node_endpoint(&ep1).into_enr();
let enr2 = EnrManager::new(None, key2.secret().clone(), 0).unwrap().with_node_endpoint(&ep2).into_enr();
let mut discovery1 = Discovery::new(&key1, ep1.clone(), enr1, IpFilter::default());
let mut discovery2 = Discovery::new(&key2, ep2.clone(), enr2, IpFilter::default());

View File

@ -305,12 +305,14 @@ impl Host {
let mut enr = None;
if !key_created {
if let Some(path) = &config.config_path {
if let Some(data) = load(Path::new(&path)) {
enr = EnrManager::load(keys.secret().clone(), data);
}
enr = EnrManager::load(path.as_str(), keys.secret().clone());
}
}
let enr = enr.unwrap_or_else(|| EnrManager::new(keys.secret().clone(), 0).expect("keys.secret() is a valid secp256k1 secret; Enr does not fail given valid secp256k1 secret; qed"));
let enr = enr.unwrap_or_else(|| EnrManager::new(
config.config_path.as_ref().map(|v| v.into()),
keys.secret().clone(),
0)
.expect("keys.secret() is a valid secp256k1 secret; Enr does not fail given valid secp256k1 secret; qed"));
let path = config.net_config_path.clone();
// Setup the server socket
let tcp_listener = TcpListener::bind(&listen_address)?;

View File

@ -1,6 +1,7 @@
use log::*;
use parity_crypto::publickey::Secret;
use crate::{persistence::DiskEntity, node_table::NodeEndpoint};
use std::path::PathBuf;
use crate::{persistence::{save, load, DiskEntity}, node_table::NodeEndpoint};
pub type Enr = enr::Enr<secp256k1::SecretKey>;
@ -9,18 +10,32 @@ const ENR_VERSION: &str = "v4";
pub struct EnrManager {
secret: secp256k1::SecretKey,
inner: Enr,
path: Option<PathBuf>,
}
impl EnrManager {
pub fn new(key: Secret, seq: u64) -> Option<Self> {
fn save(&mut self) {
if let Some(path) = &self.path {
save(path, &self.inner);
}
}
pub fn new(path: Option<PathBuf>, key: Secret, seq: u64) -> Option<Self> {
let secret = key.to_secp256k1_secret().ok()?;
let mut b = enr::EnrBuilder::new(ENR_VERSION);
b.seq(seq);
let inner = b.build(&secret).ok()?;
Some(Self { secret, inner })
let mut this = Self { secret, inner, path };
this.save();
Some(this)
}
pub fn load(key: Secret, inner: Enr) -> Option<Self> {
pub fn load<P>(path: P, key: Secret) -> Option<Self>
where
PathBuf: From<P>
{
let path = PathBuf::from(path);
let inner = load::<Enr>(&path)?;
let secret = key.to_secp256k1_secret().ok()?;
let public = secp256k1::PublicKey::from_secret_key(&secp256k1::Secp256k1::new(), &secret);
@ -28,7 +43,7 @@ impl EnrManager {
warn!("ENR does not match the provided key");
return None;
}
Some(Self { secret, inner })
Some(Self { secret, inner, path: Some(path) })
}
#[cfg(test)]
@ -45,6 +60,7 @@ impl EnrManager {
self.inner.set_udp(endpoint.udp_port, &self.secret).expect(ENR_PROOF);
// We just wrap here, unlikely to be a problem in our lifetimes unless the user sets seq high enough on purpose.
self.inner.set_seq(seq.wrapping_add(1), &self.secret).expect(ENR_PROOF);
self.save();
}
pub fn as_enr(&self) -> &Enr {
@ -69,3 +85,26 @@ impl DiskEntity for Enr {
Ok(s.parse()?)
}
}
#[cfg(test)]
mod tests {
#[test]
fn save_load() {
use super::*;
use ethereum_types::H256;
use std::net::SocketAddr;
use tempfile::TempDir;
let tempdir = TempDir::new().unwrap();
let key = Secret::from(H256::random());
let mut enr = EnrManager::new(Some(tempdir.path().into()), key.clone(), 0).unwrap();
assert_eq!(*enr.as_enr(), EnrManager::load(tempdir.path(), key.clone()).unwrap().into_enr());
let endpoint = NodeEndpoint {
address: SocketAddr::from((rand::random::<[u8; 4]>(), rand::random())),
udp_port: rand::random(),
};
enr.set_node_endpoint(&endpoint);
assert_eq!(*enr.as_enr(), EnrManager::load(tempdir.path(), key).unwrap().into_enr());
}
}