Update to LDK 0.0.106
[ldk-sample] / src / disk.rs
1 use crate::cli;
2 use bitcoin::secp256k1::key::PublicKey;
3 use bitcoin::BlockHash;
4 use chrono::Utc;
5 use lightning::routing::network_graph::NetworkGraph;
6 use lightning::routing::scoring::{ProbabilisticScorer, ProbabilisticScoringParameters};
7 use lightning::util::logger::{Logger, Record};
8 use lightning::util::ser::{Readable, ReadableArgs, Writeable, Writer};
9 use std::collections::HashMap;
10 use std::fs;
11 use std::fs::File;
12 use std::io::{BufRead, BufReader, BufWriter};
13 use std::net::SocketAddr;
14 use std::path::Path;
15 use std::sync::Arc;
16
17 pub(crate) struct FilesystemLogger {
18         data_dir: String,
19 }
20 impl FilesystemLogger {
21         pub(crate) fn new(data_dir: String) -> Self {
22                 let logs_path = format!("{}/logs", data_dir);
23                 fs::create_dir_all(logs_path.clone()).unwrap();
24                 Self { data_dir: logs_path }
25         }
26 }
27 impl Logger for FilesystemLogger {
28         fn log(&self, record: &Record) {
29                 let raw_log = record.args.to_string();
30                 let log = format!(
31                         "{} {:<5} [{}:{}] {}\n",
32                         // Note that a "real" lightning node almost certainly does *not* want subsecond
33                         // precision for message-receipt information as it makes log entries a target for
34                         // deanonymization attacks. For testing, however, its quite useful.
35                         Utc::now().format("%Y-%m-%d %H:%M:%S%.3f"),
36                         record.level.to_string(),
37                         record.module_path,
38                         record.line,
39                         raw_log
40                 );
41                 let logs_file_path = format!("{}/logs.txt", self.data_dir.clone());
42                 fs::OpenOptions::new()
43                         .create(true)
44                         .append(true)
45                         .open(logs_file_path)
46                         .unwrap()
47                         .write_all(log.as_bytes())
48                         .unwrap();
49         }
50 }
51 pub(crate) fn persist_channel_peer(path: &Path, peer_info: &str) -> std::io::Result<()> {
52         let mut file = fs::OpenOptions::new().create(true).append(true).open(path)?;
53         file.write_all(format!("{}\n", peer_info).as_bytes())
54 }
55
56 pub(crate) fn read_channel_peer_data(
57         path: &Path,
58 ) -> Result<HashMap<PublicKey, SocketAddr>, std::io::Error> {
59         let mut peer_data = HashMap::new();
60         if !Path::new(&path).exists() {
61                 return Ok(HashMap::new());
62         }
63         let file = File::open(path)?;
64         let reader = BufReader::new(file);
65         for line in reader.lines() {
66                 match cli::parse_peer_info(line.unwrap()) {
67                         Ok((pubkey, socket_addr)) => {
68                                 peer_data.insert(pubkey, socket_addr);
69                         }
70                         Err(e) => return Err(e),
71                 }
72         }
73         Ok(peer_data)
74 }
75
76 pub(crate) fn read_network(path: &Path, genesis_hash: BlockHash) -> NetworkGraph {
77         if let Ok(file) = File::open(path) {
78                 if let Ok(graph) = NetworkGraph::read(&mut BufReader::new(file)) {
79                         return graph;
80                 }
81         }
82         NetworkGraph::new(genesis_hash)
83 }
84
85 pub(crate) fn persist_scorer(
86         path: &Path, scorer: &ProbabilisticScorer<Arc<NetworkGraph>>,
87 ) -> std::io::Result<()> {
88         let mut tmp_path = path.to_path_buf().into_os_string();
89         tmp_path.push(".tmp");
90         let file = fs::OpenOptions::new().write(true).create(true).open(&tmp_path)?;
91         let write_res = scorer.write(&mut BufWriter::new(file));
92         if let Err(e) = write_res.and_then(|_| fs::rename(&tmp_path, path)) {
93                 let _ = fs::remove_file(&tmp_path);
94                 Err(e)
95         } else {
96                 Ok(())
97         }
98 }
99
100 pub(crate) fn read_scorer(
101         path: &Path, graph: Arc<NetworkGraph>,
102 ) -> ProbabilisticScorer<Arc<NetworkGraph>> {
103         let params = ProbabilisticScoringParameters::default();
104         if let Ok(file) = File::open(path) {
105                 if let Ok(scorer) =
106                         ProbabilisticScorer::read(&mut BufReader::new(file), (params, Arc::clone(&graph)))
107                 {
108                         return scorer;
109                 }
110         }
111         ProbabilisticScorer::new(params, graph)
112 }