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() {
|
fn ping_queue() {
|
||||||
let key = Random.generate();
|
let key = Random.generate();
|
||||||
let ep = NodeEndpoint { address: SocketAddr::from_str("127.0.0.1:40445").unwrap(), udp_port: 40445 };
|
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());
|
let mut discovery = Discovery::new(&key, ep.clone(), enr, IpFilter::default());
|
||||||
|
|
||||||
for i in 1..(MAX_NODES_PING+1) {
|
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),
|
address: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 41000 + i),
|
||||||
udp_port: 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())
|
Discovery::new(&key, ep, enr, IpFilter::default())
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
@ -1014,7 +1014,7 @@ mod tests {
|
|||||||
fn removes_expired() {
|
fn removes_expired() {
|
||||||
let key = Random.generate();
|
let key = Random.generate();
|
||||||
let ep = NodeEndpoint { address: SocketAddr::from_str("127.0.0.1:40446").unwrap(), udp_port: 40447 };
|
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 discovery = Discovery::new(&key, ep.clone(), enr, IpFilter::default());
|
||||||
|
|
||||||
let mut discovery = Discovery { request_backoff: &[], ..discovery };
|
let mut discovery = Discovery { request_backoff: &[], ..discovery };
|
||||||
@ -1107,7 +1107,7 @@ mod tests {
|
|||||||
|
|
||||||
let key = Random.generate();
|
let key = Random.generate();
|
||||||
let ep = NodeEndpoint { address: SocketAddr::from_str("127.0.0.1:40447").unwrap(), udp_port: 40447 };
|
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());
|
let mut discovery = Discovery::new(&key, ep.clone(), enr, IpFilter::default());
|
||||||
|
|
||||||
for _ in 0..(16 + 10) {
|
for _ in 0..(16 + 10) {
|
||||||
@ -1165,7 +1165,7 @@ mod tests {
|
|||||||
let key = Secret::from_str(secret_hex)
|
let key = Secret::from_str(secret_hex)
|
||||||
.and_then(|secret| KeyPair::from_secret(secret))
|
.and_then(|secret| KeyPair::from_secret(secret))
|
||||||
.unwrap();
|
.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());
|
let mut discovery = Discovery::new(&key, ep.clone(), enr, IpFilter::default());
|
||||||
|
|
||||||
discovery.init_node_list(node_entries.clone());
|
discovery.init_node_list(node_entries.clone());
|
||||||
@ -1211,7 +1211,7 @@ mod tests {
|
|||||||
fn packets() {
|
fn packets() {
|
||||||
let key = Random.generate();
|
let key = Random.generate();
|
||||||
let ep = NodeEndpoint { address: SocketAddr::from_str("127.0.0.1:40449").unwrap(), udp_port: 40449 };
|
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());
|
let mut discovery = Discovery::new(&key, ep.clone(), enr, IpFilter::default());
|
||||||
discovery.check_timestamps = false;
|
discovery.check_timestamps = false;
|
||||||
let from = SocketAddr::from_str("99.99.99.99:40445").unwrap();
|
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 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 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 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 enr1 = EnrManager::new(None, 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 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 discovery1 = Discovery::new(&key1, ep1.clone(), enr1, IpFilter::default());
|
||||||
let mut discovery2 = Discovery::new(&key2, ep2.clone(), enr2, IpFilter::default());
|
let mut discovery2 = Discovery::new(&key2, ep2.clone(), enr2, IpFilter::default());
|
||||||
|
|
||||||
|
@ -305,12 +305,14 @@ impl Host {
|
|||||||
let mut enr = None;
|
let mut enr = None;
|
||||||
if !key_created {
|
if !key_created {
|
||||||
if let Some(path) = &config.config_path {
|
if let Some(path) = &config.config_path {
|
||||||
if let Some(data) = load(Path::new(&path)) {
|
enr = EnrManager::load(path.as_str(), keys.secret().clone());
|
||||||
enr = EnrManager::load(keys.secret().clone(), data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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();
|
let path = config.net_config_path.clone();
|
||||||
// Setup the server socket
|
// Setup the server socket
|
||||||
let tcp_listener = TcpListener::bind(&listen_address)?;
|
let tcp_listener = TcpListener::bind(&listen_address)?;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use log::*;
|
use log::*;
|
||||||
use parity_crypto::publickey::Secret;
|
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>;
|
pub type Enr = enr::Enr<secp256k1::SecretKey>;
|
||||||
|
|
||||||
@ -9,18 +10,32 @@ const ENR_VERSION: &str = "v4";
|
|||||||
pub struct EnrManager {
|
pub struct EnrManager {
|
||||||
secret: secp256k1::SecretKey,
|
secret: secp256k1::SecretKey,
|
||||||
inner: Enr,
|
inner: Enr,
|
||||||
|
path: Option<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EnrManager {
|
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 secret = key.to_secp256k1_secret().ok()?;
|
||||||
let mut b = enr::EnrBuilder::new(ENR_VERSION);
|
let mut b = enr::EnrBuilder::new(ENR_VERSION);
|
||||||
b.seq(seq);
|
b.seq(seq);
|
||||||
let inner = b.build(&secret).ok()?;
|
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 secret = key.to_secp256k1_secret().ok()?;
|
||||||
let public = secp256k1::PublicKey::from_secret_key(&secp256k1::Secp256k1::new(), &secret);
|
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");
|
warn!("ENR does not match the provided key");
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
Some(Self { secret, inner })
|
Some(Self { secret, inner, path: Some(path) })
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -45,6 +60,7 @@ impl EnrManager {
|
|||||||
self.inner.set_udp(endpoint.udp_port, &self.secret).expect(ENR_PROOF);
|
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.
|
// 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.inner.set_seq(seq.wrapping_add(1), &self.secret).expect(ENR_PROOF);
|
||||||
|
self.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_enr(&self) -> &Enr {
|
pub fn as_enr(&self) -> &Enr {
|
||||||
@ -69,3 +85,26 @@ impl DiskEntity for Enr {
|
|||||||
Ok(s.parse()?)
|
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