Actually save ENR on creation and modification (#11602)
* Actually save ENR on creation and modification * Add test
This commit is contained in:
parent
78a0e8d312
commit
c92a15dad0
@ -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());
|
||||
|
||||
|
@ -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)?;
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user