use crate::cli;
use bitcoin::secp256k1::key::PublicKey;
+use bitcoin::BlockHash;
+use lightning::routing::network_graph::NetworkGraph;
use lightning::util::logger::{Logger, Record};
-use lightning::util::ser::Writer;
+use lightning::util::ser::{Readable, Writeable, Writer};
use std::collections::HashMap;
use std::fs;
use std::fs::File;
-use std::io::{BufRead, BufReader};
+use std::io::{BufRead, BufReader, BufWriter};
use std::net::SocketAddr;
use std::path::Path;
use time::OffsetDateTime;
}
Ok(peer_data)
}
+
+pub(crate) fn persist_network(path: &Path, network_graph: &NetworkGraph) -> std::io::Result<()> {
+ let mut tmp_path = path.to_path_buf().into_os_string();
+ tmp_path.push(".tmp");
+ let file = fs::OpenOptions::new().write(true).create(true).open(&tmp_path)?;
+ let write_res = network_graph.write(&mut BufWriter::new(file));
+ if let Err(e) = write_res.and_then(|_| fs::rename(&tmp_path, path)) {
+ let _ = fs::remove_file(&tmp_path);
+ Err(e)
+ } else {
+ Ok(())
+ }
+}
+
+pub(crate) fn read_network(path: &Path, genesis_hash: BlockHash) -> NetworkGraph {
+ if let Ok(file) = File::open(path) {
+ if let Ok(graph) = NetworkGraph::read(&mut BufReader::new(file)) {
+ return graph;
+ }
+ }
+ NetworkGraph::new(genesis_hash)
+}
}
// Step 11: Optional: Initialize the NetGraphMsgHandler
- // XXX persist routing data
let genesis = genesis_block(args.network).header.block_hash();
- let router = Arc::new(NetGraphMsgHandler::new(
- genesis,
+ let network_graph_path = format!("{}/network_graph", ldk_data_dir.clone());
+ let network_graph = disk::read_network(Path::new(&network_graph_path), genesis);
+ let router = Arc::new(NetGraphMsgHandler::from_net_graph(
None::<Arc<dyn chain::Access + Send + Sync>>,
logger.clone(),
+ network_graph,
));
+ let router_persist = Arc::clone(&router);
+ tokio::spawn(async move {
+ let mut interval = tokio::time::interval(Duration::from_secs(600));
+ loop {
+ interval.tick().await;
+ if disk::persist_network(
+ Path::new(&network_graph_path),
+ &*router_persist.network_graph.read().unwrap(),
+ )
+ .is_err()
+ {
+ // Persistence errors here are non-fatal as we can just fetch the routing graph
+ // again later, but they may indicate a disk error which could be fatal elsewhere.
+ eprintln!(
+ "Warning: Failed to persist network graph, check your disk and permissions"
+ );
+ }
+ }
+ });
// Step 12: Initialize the PeerManager
let channel_manager: Arc<ChannelManager> = Arc::new(channel_manager);