use eth2_libp2p::Enr; use std::sync::Arc; use store::{DBColumn, Error as StoreError, HotColdDB, ItemStore, StoreItem}; use types::{EthSpec, Hash256}; /// 32-byte key for accessing the `DhtEnrs`. pub const DHT_DB_KEY: &str = "PERSISTEDDHTPERSISTEDDHTPERSISTE"; pub fn load_dht, Cold: ItemStore>( store: Arc>, ) -> Vec { // Load DHT from store let key = Hash256::from_slice(&DHT_DB_KEY.as_bytes()); match store.get_item(&key) { Ok(Some(p)) => { let p: PersistedDht = p; p.enrs } _ => Vec::new(), } } /// Attempt to persist the ENR's in the DHT to `self.store`. pub fn persist_dht, Cold: ItemStore>( store: Arc>, enrs: Vec, ) -> Result<(), store::Error> { let key = Hash256::from_slice(&DHT_DB_KEY.as_bytes()); store.put_item(&key, &PersistedDht { enrs })?; Ok(()) } /// Wrapper around DHT for persistence to disk. pub struct PersistedDht { pub enrs: Vec, } impl StoreItem for PersistedDht { fn db_column() -> DBColumn { DBColumn::DhtEnrs } fn as_store_bytes(&self) -> Vec { rlp::encode_list(&self.enrs) } fn from_store_bytes(bytes: &[u8]) -> Result { let rlp = rlp::Rlp::new(bytes); let enrs: Vec = rlp .as_list() .map_err(|e| StoreError::RlpError(format!("{}", e)))?; Ok(PersistedDht { enrs }) } } #[cfg(test)] mod tests { use super::*; use eth2_libp2p::Enr; use sloggers::{null::NullLoggerBuilder, Build}; use std::str::FromStr; use store::config::StoreConfig; use store::{HotColdDB, MemoryStore}; use types::{ChainSpec, Hash256, MinimalEthSpec}; #[test] fn test_persisted_dht() { let log = NullLoggerBuilder.build().unwrap(); let store: HotColdDB< MinimalEthSpec, MemoryStore, MemoryStore, > = HotColdDB::open_ephemeral(StoreConfig::default(), ChainSpec::minimal(), log).unwrap(); let enrs = vec![Enr::from_str("enr:-IS4QHCYrYZbAKWCBRlAy5zzaDZXJBGkcnh4MHcBFZntXNFrdvJjX04jRzjzCBOonrkTfj499SZuOh8R33Ls8RRcy5wBgmlkgnY0gmlwhH8AAAGJc2VjcDI1NmsxoQPKY0yuDUmstAHYpMa2_oxVtw0RW_QAdpzBQA8yWM0xOIN1ZHCCdl8").unwrap()]; let key = Hash256::from_slice(&DHT_DB_KEY.as_bytes()); store .put_item(&key, &PersistedDht { enrs: enrs.clone() }) .unwrap(); let dht: PersistedDht = store.get_item(&key).unwrap().unwrap(); assert_eq!(dht.enrs, enrs); } }