Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

start work on tor support #768

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ tonic = "0.7.2"
tonic-web = "0.3.0"
uuid = { version = "1.1", features = ["v4", "serde"] }
zmq = { package = "zmq2", version = "0.5.0" }
socks = "0.3.4"
torut = "0.2.1"

[build-dependencies]
tonic-build = "0.7"
Expand Down
10 changes: 8 additions & 2 deletions src/bin/peerd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,14 @@ fn main() {
PeerSocket::Connect(remote_node) => {
debug!("Peerd running in CONNECT mode");
debug!("Connecting to {}", &remote_node.addr());
peerd::run_from_connect(service_config, remote_node, local_socket, local_node)
.expect("Error running peerd runtime");
peerd::run_from_connect(
service_config,
remote_node,
local_socket,
local_node,
opts.shared.tor_proxy,
)
.expect("Error running peerd runtime");
unreachable!()
}
};
Expand Down
7 changes: 7 additions & 0 deletions src/bus/ctl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ use crate::syncerd::{Health, SweepAddressAddendum};
use crate::{Error, ServiceId};

use super::p2p::Commit;
use super::{HiddenServiceInfo, WrapOnionAddressV3};

#[derive(Clone, Debug, Display, From, NetworkEncode, NetworkDecode)]
#[non_exhaustive]
Expand Down Expand Up @@ -134,6 +135,12 @@ pub enum CtlMsg {
#[display("get_balance")]
GetBalance(AddressSecretKey),

#[display("set_hidden_service_info")]
SetHiddenServiceInfo(HiddenServiceInfo),

#[display("delete_hidden_service_info")]
DeleteHiddenServiceInfo(WrapOnionAddressV3),

#[display("funding_updated()")]
FundingUpdated,

Expand Down
8 changes: 8 additions & 0 deletions src/bus/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ use crate::Error;
use super::ctl::FundingInfo;
use super::StateTransition;

use super::HiddenServiceInfo;

#[derive(Clone, Debug, Display, From, NetworkEncode, NetworkDecode)]
#[non_exhaustive]
pub enum InfoMsg {
Expand Down Expand Up @@ -67,6 +69,9 @@ pub enum InfoMsg {
#[display("get_checkpoint_entry({0})")]
GetCheckpointEntry(SwapId),

#[display("get_all_hidden_service_info")]
GetAllHiddenServiceInfo,

// Progress functionalities
// ----------------
// Returns a SwapProgress message
Expand Down Expand Up @@ -179,6 +184,9 @@ pub enum InfoMsg {

#[display("{0}")]
AddressBalance(AddressBalance),

#[display("hidden_service_info_list")]
HiddenServiceInfoList(List<HiddenServiceInfo>),
}

#[derive(Clone, PartialEq, Eq, Debug, Display, NetworkEncode, NetworkDecode)]
Expand Down
43 changes: 41 additions & 2 deletions src/bus/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// https://opensource.org/licenses/MIT.

use std::{
convert::TryInto,
fmt::{self, Debug, Display, Formatter},
str::FromStr,
};
Expand All @@ -16,10 +17,11 @@ use farcaster_core::{
};

use amplify::{ToYamlString, Wrapper};
use internet2::addr::NodeId;
use internet2::addr::{InetSocketAddr, NodeId};
use microservices::rpc;
use serde_with::DisplayFromStr;
use strict_encoding::{NetworkDecode, NetworkEncode};
use strict_encoding::{NetworkDecode, NetworkEncode, StrictDecode, StrictEncode};
use torut::onion::{OnionAddressV3, TorPublicKeyV3};

use crate::swapd::StateReport;
use crate::syncerd::Health;
Expand All @@ -39,6 +41,43 @@ pub struct CheckpointEntry {
pub expected_counterparty_node_id: Option<NodeId>,
}

#[derive(Clone, Debug, Display, Eq, PartialEq, NetworkDecode, NetworkEncode)]
#[cfg_attr(
feature = "serde",
derive(Serialize, Deserialize),
serde(crate = "serde_crate")
)]
#[display(Debug)]
pub struct HiddenServiceInfo {
pub onion_address: WrapOnionAddressV3,
pub bind_address: InetSocketAddr,
}

#[derive(Clone, PartialEq, Eq, Debug, Display)]
#[cfg_attr(
feature = "serde",
derive(Serialize, Deserialize),
serde(crate = "serde_crate")
)]
#[display(Debug)]
pub struct WrapOnionAddressV3(pub OnionAddressV3);

impl StrictEncode for WrapOnionAddressV3 {
fn strict_encode<E: std::io::Write>(&self, mut e: E) -> Result<usize, strict_encoding::Error> {
let address_encoding = self.0.get_public_key().as_bytes().to_vec();
address_encoding.strict_encode(&mut e)
}
}

impl StrictDecode for WrapOnionAddressV3 {
fn strict_decode<D: std::io::Read>(mut d: D) -> Result<Self, strict_encoding::Error> {
let onion_address = Vec::<u8>::strict_decode(&mut d)?;
Ok(WrapOnionAddressV3(OnionAddressV3::from(
&TorPublicKeyV3::from_bytes(&onion_address.try_into().unwrap()).unwrap(),
)))
}
}

#[derive(Clone, Debug, Display, Eq, PartialEq, Hash, NetworkDecode, NetworkEncode)]
#[cfg_attr(
feature = "serde",
Expand Down
1 change: 1 addition & 0 deletions src/cli/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use farcaster_core::swap::btcxmr::{Deal, DealParameters};
use farcaster_core::Uuid;
use std::io::{self, Read};

use std::str::FromStr;

use internet2::addr::{InetSocketAddr, NodeAddr};
Expand Down
35 changes: 34 additions & 1 deletion src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
use crate::{AccordantBlockchain, ArbitratingBlockchain, Error};
use farcaster_core::blockchain::Network;
use internet2::addr::InetSocketAddr;
use std::fs::File;
use std::io::prelude::*;
use std::path::Path;
use std::str::FromStr;
use std::{fs::File, net::SocketAddr};

use serde::{Deserialize, Serialize};

Expand Down Expand Up @@ -139,6 +139,32 @@ impl Config {
}
}

/// Returns the addr of the tor control socket if it is set, or the default
/// socket at localhost:9051 if not.
pub fn get_tor_control_socket(&self) -> Result<SocketAddr, Error> {
if let Some(FarcasterdConfig {
tor_control_socket: Some(addr),
..
}) = &self.farcasterd
{
Ok(SocketAddr::from_str(addr)?)
} else {
Ok(SocketAddr::from_str("127.0.0.1:9051")?)
}
}

pub fn create_hidden_service(&self) -> bool {
if let Some(FarcasterdConfig {
create_hidden_service: Some(create_hidden_service),
..
}) = &self.farcasterd
{
*create_hidden_service
} else {
false
}
}

/// Returns the swap config for the specified network and arbitrating/accordant blockchains
pub fn get_swap_config(
&self,
Expand Down Expand Up @@ -230,6 +256,11 @@ pub struct FarcasterdConfig {
pub bind_ip: Option<String>,
/// Whether checkpoints should be auto restored at start-up, or not
pub auto_restore: Option<bool>,
/// Tor control socket for creating the hidden service
pub tor_control_socket: Option<String>,
/// Whether to create a hidden service or not. If set, the node will only
/// run in hidden service mode
pub create_hidden_service: Option<bool>,
}

#[derive(Deserialize, Serialize, Debug, Clone)]
Expand Down Expand Up @@ -432,6 +463,8 @@ impl Default for FarcasterdConfig {
// write the default port and ip in the generated config
bind_port: Some(FARCASTER_BIND_PORT),
bind_ip: Some(FARCASTER_BIND_IP.to_string()),
tor_control_socket: None,
create_hidden_service: None,
}
}
}
Expand Down
79 changes: 79 additions & 0 deletions src/databased/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.

use crate::bus::{HiddenServiceInfo, WrapOnionAddressV3};
use farcaster_core::swap::btcxmr::Deal;
use farcaster_core::swap::SwapId;
use farcaster_core::{blockchain::Blockchain, role::TradeRole};
use internet2::addr::InetSocketAddr;
use lmdb::{Cursor, Transaction as LMDBTransaction};
use std::convert::TryInto;
use std::io::Cursor as IoCursor;
use std::path::PathBuf;
use strict_encoding::{StrictDecode, StrictEncode};
use torut::onion::{OnionAddressV3, TorPublicKeyV3};

use crate::bus::{
ctl::{Checkpoint, CtlMsg},
Expand Down Expand Up @@ -212,6 +216,23 @@ impl Runtime {
})?;
}

CtlMsg::SetHiddenServiceInfo(HiddenServiceInfo {
onion_address,
bind_address,
}) => {
self.database
.set_hidden_service_info(&onion_address.0, &bind_address)?;
}

CtlMsg::DeleteHiddenServiceInfo(onion_address) => {
if let Err(err) = self.database.delete_hidden_service_info(&onion_address.0) {
warn!(
"Did not delete hidden service info: {} due to {}",
onion_address, err
);
}
}

_ => {
error!("BusMsg {} is not supported by the CTL interface", request);
}
Expand Down Expand Up @@ -255,6 +276,16 @@ impl Runtime {
};
}

InfoMsg::GetAllHiddenServiceInfo => {
let hidden_service_infos = self.database.get_all_hidden_service_info()?.into();
endpoints.send_to(
ServiceBus::Info,
self.identity(),
source,
BusMsg::Info(InfoMsg::HiddenServiceInfoList(hidden_service_infos)),
)?;
}

InfoMsg::GetCheckpointEntry(swap_id) => {
match self.database.get_checkpoint_info(&swap_id) {
Ok(entry) => {
Expand Down Expand Up @@ -400,6 +431,7 @@ const LMDB_CHECKPOINT_INFOS: &str = "checkpoint_infos";
const LMDB_BITCOIN_ADDRESSES: &str = "bitcoin_addresses";
const LMDB_MONERO_ADDRESSES: &str = "monero_addresses";
const LMDB_DEAL_HISTORY: &str = "deal_history";
const LMDB_HIDDEN_SERVICE_INFO: &str = "hidden_service_info";

impl Database {
fn new(path: PathBuf) -> Result<Database, lmdb::Error> {
Expand All @@ -412,6 +444,7 @@ impl Database {
env.create_db(Some(LMDB_BITCOIN_ADDRESSES), lmdb::DatabaseFlags::empty())?;
env.create_db(Some(LMDB_DEAL_HISTORY), lmdb::DatabaseFlags::empty())?;
env.create_db(Some(LMDB_MONERO_ADDRESSES), lmdb::DatabaseFlags::empty())?;
env.create_db(Some(LMDB_HIDDEN_SERVICE_INFO), lmdb::DatabaseFlags::empty())?;
Ok(Database(env))
}

Expand Down Expand Up @@ -644,6 +677,52 @@ impl Database {
res
}

fn set_hidden_service_info(
&mut self,
onion_address: &OnionAddressV3,
socket_address: &InetSocketAddr,
) -> Result<(), Error> {
let db = self.0.open_db(Some(LMDB_HIDDEN_SERVICE_INFO))?;
let mut tx = self.0.begin_rw_txn()?;
let key_bytes = onion_address.get_public_key().to_bytes();
if tx.get(db, &key_bytes).is_ok() {
tx.del(db, &key_bytes, None)?;
}
let mut val = vec![];
socket_address.strict_encode(&mut val)?;
tx.put(db, &key_bytes, &val, lmdb::WriteFlags::empty())?;
tx.commit()?;
Ok(())
}

fn get_all_hidden_service_info(&mut self) -> Result<Vec<HiddenServiceInfo>, Error> {
let db = self.0.open_db(Some(LMDB_HIDDEN_SERVICE_INFO))?;
let tx = self.0.begin_ro_txn()?;
let mut cursor = tx.open_ro_cursor(db)?;
let res = cursor
.iter()
.map(|(key, value)| {
Ok(HiddenServiceInfo {
onion_address: WrapOnionAddressV3(OnionAddressV3::from(
&TorPublicKeyV3::from_bytes(key.try_into().unwrap()).unwrap(),
)),
bind_address: InetSocketAddr::strict_decode(std::io::Cursor::new(value))?,
})
})
.collect();
drop(cursor);
tx.abort();
res
}

fn delete_hidden_service_info(&mut self, key: &OnionAddressV3) -> Result<(), lmdb::Error> {
let db = self.0.open_db(Some(LMDB_HIDDEN_SERVICE_INFO))?;
let mut tx = self.0.begin_rw_txn()?;
tx.del(db, &key.get_public_key().as_bytes(), None)?;
tx.commit()?;
Ok(())
}

fn get_checkpoint_state(&mut self, checkpoint_key: &CheckpointKey) -> Result<Vec<u8>, Error> {
let db = self.0.open_db(Some(LMDB_CHECKPOINTS))?;
let tx = self.0.begin_ro_txn()?;
Expand Down
5 changes: 5 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,11 @@ pub enum Error {
#[from]
Inet2AddrParseError(internet2::addr::AddrParseError),

/// Net socket address parsing errors
#[display(inner)]
#[from]
SocketAddrError(std::net::AddrParseError),

/// Tonic gRPC deamon transport errors
#[display(inner)]
#[from]
Expand Down
1 change: 1 addition & 0 deletions src/farcasterd/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ mod opts;
mod runtime;
pub mod stats;
mod syncer_state_machine;
mod tor_control;
mod trade_state_machine;

#[cfg(feature = "shell")]
Expand Down
Loading