Skip to content

Commit e499d12

Browse files
committed
Initial implementation of LdkLite
1 parent 9af3fdd commit e499d12

File tree

2 files changed

+1088
-0
lines changed

2 files changed

+1088
-0
lines changed

src/io.rs

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
use crate::error::LdkLiteError as Error;
2+
3+
use crate::hex;
4+
use crate::{FilesystemLogger, LdkLiteConfig, NetworkGraph, Scorer};
5+
6+
use lightning::routing::scoring::{ProbabilisticScorer, ProbabilisticScoringParameters};
7+
use lightning::util::ser::ReadableArgs;
8+
9+
use bitcoin::secp256k1::PublicKey;
10+
11+
use rand::{thread_rng, RngCore};
12+
13+
use std::collections::HashMap;
14+
use std::fs;
15+
use std::io::{BufRead, BufReader, Write};
16+
use std::net::{SocketAddr, ToSocketAddrs};
17+
use std::sync::Arc;
18+
19+
pub(crate) fn read_or_generate_seed_file(config: Arc<LdkLiteConfig>) -> Result<[u8; 32], Error> {
20+
let keys_seed_path = format!("{}/keys_seed", config.storage_dir_path);
21+
let keys_seed = if let Ok(seed) = fs::read(keys_seed_path.clone()) {
22+
assert_eq!(seed.len(), 32);
23+
let mut key = [0; 32];
24+
key.copy_from_slice(&seed);
25+
key
26+
} else {
27+
let mut key = [0; 32];
28+
thread_rng().fill_bytes(&mut key);
29+
30+
let mut f = fs::File::create(keys_seed_path.clone()).map_err(|e| Error::StdIo(e))?;
31+
f.write_all(&key).expect("Failed to write node keys seed to disk");
32+
f.sync_all().expect("Failed to sync node keys seed to disk");
33+
key
34+
};
35+
36+
Ok(keys_seed)
37+
}
38+
39+
pub(crate) fn read_network_graph(
40+
config: Arc<LdkLiteConfig>, logger: Arc<FilesystemLogger>,
41+
) -> Result<NetworkGraph, Error> {
42+
let ldk_data_dir = format!("{}/ldk", &config.storage_dir_path.clone());
43+
let network_graph_path = format!("{}/network_graph", ldk_data_dir.clone());
44+
45+
if let Ok(file) = fs::File::open(network_graph_path) {
46+
if let Ok(graph) = NetworkGraph::read(&mut BufReader::new(file), Arc::clone(&logger)) {
47+
return Ok(graph);
48+
}
49+
}
50+
51+
let genesis_hash =
52+
bitcoin::blockdata::constants::genesis_block(config.network).header.block_hash();
53+
Ok(NetworkGraph::new(genesis_hash, logger))
54+
}
55+
56+
pub(crate) fn read_scorer(
57+
config: Arc<LdkLiteConfig>, network_graph: Arc<NetworkGraph>, logger: Arc<FilesystemLogger>,
58+
) -> Scorer {
59+
let ldk_data_dir = format!("{}/ldk", &config.storage_dir_path.clone());
60+
let scorer_path = format!("{}/scorer", ldk_data_dir.clone());
61+
62+
let params = ProbabilisticScoringParameters::default();
63+
if let Ok(file) = fs::File::open(scorer_path) {
64+
let args = (params.clone(), Arc::clone(&network_graph), Arc::clone(&logger));
65+
if let Ok(scorer) = ProbabilisticScorer::read(&mut BufReader::new(file), args) {
66+
return scorer;
67+
}
68+
}
69+
ProbabilisticScorer::new(params, network_graph, logger)
70+
}
71+
72+
pub(crate) fn read_channel_peer_data(
73+
config: Arc<LdkLiteConfig>,
74+
) -> Result<HashMap<PublicKey, SocketAddr>, Error> {
75+
let ldk_data_dir = format!("{}/ldk", &config.storage_dir_path.clone());
76+
let peer_data_path = format!("{}/channel_peer_data", ldk_data_dir.clone());
77+
let mut peer_data = HashMap::new();
78+
79+
if let Ok(file) = fs::File::open(peer_data_path) {
80+
let reader = BufReader::new(file);
81+
for line in reader.lines() {
82+
match parse_peer_info(line.unwrap()) {
83+
Ok((pubkey, socket_addr)) => {
84+
peer_data.insert(pubkey, socket_addr);
85+
}
86+
Err(e) => return Err(e),
87+
}
88+
}
89+
}
90+
Ok(peer_data)
91+
}
92+
93+
pub(crate) fn persist_channel_peer(
94+
config: Arc<LdkLiteConfig>, peer_info: &str,
95+
) -> std::io::Result<()> {
96+
let ldk_data_dir = format!("{}/ldk", &config.storage_dir_path.clone());
97+
let peer_data_path = format!("{}/channel_peer_data", ldk_data_dir.clone());
98+
let mut file = fs::OpenOptions::new().create(true).append(true).open(peer_data_path)?;
99+
file.write_all(format!("{}\n", peer_info).as_bytes())
100+
}
101+
102+
// TODO: handle different kinds of NetAddress, e.g., the Hostname field.
103+
pub(crate) fn parse_peer_info(
104+
peer_pubkey_and_ip_addr: String,
105+
) -> Result<(PublicKey, SocketAddr), Error> {
106+
let mut pubkey_and_addr = peer_pubkey_and_ip_addr.split("@");
107+
let pubkey = pubkey_and_addr.next();
108+
let peer_addr_str = pubkey_and_addr.next();
109+
if peer_addr_str.is_none() || peer_addr_str.is_none() {
110+
return Err(Error::PeerInfoParse(
111+
"Incorrect format. Should be formatted as: `pubkey@host:port`.",
112+
));
113+
}
114+
115+
let peer_addr = peer_addr_str.unwrap().to_socket_addrs().map(|mut r| r.next());
116+
if peer_addr.is_err() || peer_addr.as_ref().unwrap().is_none() {
117+
return Err(Error::PeerInfoParse("Couldn't parse pubkey@host:port into a socket address."));
118+
}
119+
120+
let pubkey = hex::to_compressed_pubkey(pubkey.unwrap());
121+
if pubkey.is_none() {
122+
return Err(Error::PeerInfoParse("Unable to parse pubkey for node."));
123+
}
124+
125+
Ok((pubkey.unwrap(), peer_addr.unwrap().unwrap()))
126+
}

0 commit comments

Comments
 (0)