-
Notifications
You must be signed in to change notification settings - Fork 74
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement directory servers for finding makers
Directory servers are http servers running somewhere on the tor dark net. Makers can publish their own tor onions to these servers. Takers can download the list of these maker onions and from there obtain a list of makers they can do coinswaps with. This commit adds code for obtaining the list of onions, and publishing your own onion. The commit also has the taker code obtain the list of onions, and also has the maker code publish and refresh its own entry.
- Loading branch information
1 parent
5f9d50b
commit 173a1c0
Showing
6 changed files
with
173 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
//configure this with your own tor port | ||
pub const TOR_ADDR: &str = "127.0.0.1:9150"; | ||
|
||
use bitcoin::Network; | ||
|
||
use crate::offerbook_sync::MakerAddress; | ||
|
||
//for now just one of these, but later we'll need multiple for good decentralization | ||
const DIRECTORY_SERVER_ADDR: &str = | ||
"zfwo4t5yfuf6epu7rhjbmkr6kiysi6v7kibta4i55zlp4y6xirpcr7qd.onion:8080"; | ||
|
||
#[derive(Debug)] | ||
pub enum DirectoryServerError { | ||
Reqwest(reqwest::Error), | ||
Other(&'static str), | ||
} | ||
|
||
impl From<reqwest::Error> for DirectoryServerError { | ||
fn from(e: reqwest::Error) -> DirectoryServerError { | ||
DirectoryServerError::Reqwest(e) | ||
} | ||
} | ||
|
||
fn network_enum_to_string(network: Network) -> &'static str { | ||
match network { | ||
Network::Bitcoin => "mainnet", | ||
Network::Testnet => "testnet", | ||
Network::Regtest => panic!("dont use directory servers if using regtest"), | ||
} | ||
} | ||
|
||
pub async fn sync_maker_hosts_from_directory_servers( | ||
network: Network, | ||
) -> Result<Vec<MakerAddress>, DirectoryServerError> { | ||
// https://github.com/seanmonstar/reqwest/blob/master/examples/tor_socks.rs | ||
let proxy = | ||
reqwest::Proxy::all(format!("socks5h://{}", TOR_ADDR)).expect("tor proxy should be there"); | ||
let client = reqwest::Client::builder() | ||
.proxy(proxy) | ||
.build() | ||
.expect("should be able to build reqwest client"); | ||
let res = client | ||
.get(format!( | ||
"http://{}/makers-{}.txt", | ||
DIRECTORY_SERVER_ADDR, | ||
network_enum_to_string(network) | ||
)) | ||
.send() | ||
.await?; | ||
if res.status().as_u16() != 200 { | ||
return Err(DirectoryServerError::Other("status code not success")); | ||
} | ||
let mut maker_addresses = Vec::<MakerAddress>::new(); | ||
for makers in res.text().await?.split("\n") { | ||
let csv_chunks = makers.split(",").collect::<Vec<&str>>(); | ||
if csv_chunks.len() < 2 { | ||
continue; | ||
} | ||
maker_addresses.push(MakerAddress::Tor { | ||
address: String::from(csv_chunks[1]), | ||
}); | ||
log::debug!(target:"directory_servers", "expiry timestamp = {} hostname = {}", | ||
csv_chunks[0], csv_chunks[1]); | ||
} | ||
Ok(maker_addresses) | ||
} | ||
|
||
pub async fn post_maker_host_to_directory_servers( | ||
network: Network, | ||
address: &str, | ||
) -> Result<u64, DirectoryServerError> { | ||
let proxy = | ||
reqwest::Proxy::all(format!("socks5h://{}", TOR_ADDR)).expect("tor proxy should be there"); | ||
let client = reqwest::Client::builder() | ||
.proxy(proxy) | ||
.build() | ||
.expect("should be able to build reqwest client"); | ||
let params = [ | ||
("address", address), | ||
("net", network_enum_to_string(network)), | ||
]; | ||
let res = client | ||
.post(format!("http://{}/directoryserver", DIRECTORY_SERVER_ADDR)) | ||
.form(¶ms) | ||
.send() | ||
.await?; | ||
if res.status().as_u16() != 200 { | ||
return Err(DirectoryServerError::Other("status code not success")); | ||
} | ||
let body = res.text().await?; | ||
let start_bytes = body | ||
.find("<b>") | ||
.ok_or(DirectoryServerError::Other("expiry time not parsable1"))? | ||
+ 3; | ||
let end_bytes = body | ||
.find("</b>") | ||
.ok_or(DirectoryServerError::Other("expiry time not parsable2"))?; | ||
let expiry_time_str = &body[start_bytes..end_bytes]; | ||
let expiry_time = expiry_time_str | ||
.parse::<u64>() | ||
.map_err(|_| DirectoryServerError::Other("expiry time not parsable3"))?; | ||
Ok(expiry_time) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters