Adds addresses to gettowerinfo

This commit is contained in:
Sergi Delgado Segura 2022-11-12 14:33:34 -03:00
parent 441a37155d
commit 0c1b4c17b4
No known key found for this signature in database
GPG key ID: 35DDB7126CCB7618
9 changed files with 166 additions and 19 deletions

View file

@ -13,6 +13,7 @@ pub mod constants;
pub mod cryptography;
pub mod dbm;
pub mod errors;
pub mod net;
pub mod receipts;
pub mod ser;
pub mod test_utils;

39
teos-common/src/net.rs Normal file
View file

@ -0,0 +1,39 @@
use std::fmt;
/// Represents all types of teos network addresses
pub enum AddressType {
IpV4 = 0,
TorV3 = 1,
}
impl From<i32> for AddressType {
fn from(x: i32) -> Self {
match x {
0 => AddressType::IpV4,
1 => AddressType::TorV3,
x => panic!("Unknown address type {}", x),
}
}
}
impl std::str::FromStr for AddressType {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"ipv4" => Ok(AddressType::IpV4),
"torv3" => Ok(AddressType::TorV3),
_ => Err(format!("Unknown type: {}", s)),
}
}
}
impl fmt::Display for AddressType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let s = match self {
AddressType::IpV4 => "ipv4",
AddressType::TorV3 => "torv3",
};
write!(f, "{}", s)
}
}

View file

@ -12,6 +12,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
"GetUserResponse.appointments",
"#[serde(serialize_with = \"teos_common::ser::serde_vec_bytes::serialize\")]",
)
.field_attribute(
"NetworkAddress.address_type",
"#[serde(rename = \"type\", with = \"crate::api::serde::serde_address_type\")]",
)
.compile(
&[
"proto/teos/v2/appointment.proto",

View file

@ -7,15 +7,26 @@ import "common/teos/v2/appointment.proto";
import "common/teos/v2/user.proto";
import "google/protobuf/empty.proto";
message NetworkAddress {
// Tower public API endpoint.
enum AddressType {
IpV4 = 0;
TorV3 = 1;
}
AddressType address_type = 1;
string address = 2;
uint32 port = 3;
}
message GetTowerInfoResponse {
// Response with information about the tower.
bytes tower_id = 1;
uint32 n_registered_users = 2;
uint32 n_watcher_appointments = 3;
uint32 n_responder_trackers = 4;
bool bitcoind_reachable = 5;
repeated NetworkAddress addresses = 6;
}
service PublicTowerServices {

View file

@ -21,6 +21,8 @@ use teos_common::UserId;
pub struct InternalAPI {
/// A [Watcher] instance.
watcher: Arc<Watcher>,
/// A list of public API endpoints.
addresses: Vec<msgs::NetworkAddress>,
/// A flag that indicates wether bitcoind is reachable or not.
bitcoind_reachable: Arc<(Mutex<bool>, Condvar)>,
/// A signal indicating the tower is shuting down.
@ -31,16 +33,22 @@ impl InternalAPI {
/// Creates a new [InternalAPI] instance.
pub fn new(
watcher: Arc<Watcher>,
addresses: Vec<msgs::NetworkAddress>,
bitcoind_reachable: Arc<(Mutex<bool>, Condvar)>,
shutdown_trigger: Trigger,
) -> Self {
Self {
watcher,
addresses,
bitcoind_reachable,
shutdown_trigger,
}
}
pub fn get_addresses(&self) -> &Vec<msgs::NetworkAddress> {
&self.addresses
}
/// Checks whether bitcoind is reachable.
fn check_service_unavailable(&self) -> Result<(), Status> {
if *self.bitcoind_reachable.0.lock().unwrap() {
@ -305,6 +313,7 @@ impl PrivateTowerServices for Arc<InternalAPI> {
) -> Result<Response<msgs::GetTowerInfoResponse>, Status> {
Ok(Response::new(msgs::GetTowerInfoResponse {
tower_id: self.watcher.tower_id.to_vec(),
addresses: self.get_addresses().clone(),
n_registered_users: self.watcher.get_registered_users_count() as u32,
n_watcher_appointments: self.watcher.get_appointments_count() as u32,
n_responder_trackers: self.watcher.get_trackers_count() as u32,

View file

@ -1,3 +1,4 @@
pub mod http;
pub mod internal;
pub mod serde;
pub mod tor;

62
teos/src/api/serde.rs Normal file
View file

@ -0,0 +1,62 @@
use crate::protos as msgs;
use teos_common::net::AddressType;
impl msgs::NetworkAddress {
pub fn from_ipv4(address: String, port: u16) -> Self {
Self {
address_type: AddressType::IpV4 as i32,
address,
port: port as u32,
}
}
pub fn from_torv3(address: String, port: u16) -> Self {
Self {
address_type: AddressType::TorV3 as i32,
address,
port: port as u32,
}
}
}
pub mod serde_address_type {
use serde::de::{self, Deserializer};
use serde::Serializer;
use std::str::FromStr;
use super::AddressType;
pub fn serialize<S>(status: &i32, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(&AddressType::from(*status).to_string())
}
pub fn deserialize<'de, D>(deserializer: D) -> Result<i32, D::Error>
where
D: Deserializer<'de>,
{
struct StatusVisitor;
impl<'de> de::Visitor<'de> for StatusVisitor {
type Value = i32;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("a string containing the address type")
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
let status = AddressType::from_str(v)
.map_err(|_| E::custom("given address type is unknown"))?;
Ok(status as i32)
}
}
deserializer.deserialize_any(StatusVisitor)
}
}

View file

@ -19,13 +19,14 @@ use lightning_block_sync::poll::{
use lightning_block_sync::{BlockSource, SpvClient, UnboundedCache};
use teos::api::internal::InternalAPI;
use teos::api::{http, tor};
use teos::api::{http, tor::TorAPI};
use teos::bitcoin_cli::BitcoindClient;
use teos::carrier::Carrier;
use teos::chain_monitor::ChainMonitor;
use teos::config::{self, Config, Opt};
use teos::dbm::DBM;
use teos::gatekeeper::Gatekeeper;
use teos::protos as msgs;
use teos::protos::private_tower_services_server::PrivateTowerServicesServer;
use teos::protos::public_tower_services_server::PublicTowerServicesServer;
use teos::responder::Responder;
@ -273,8 +274,36 @@ async fn main() {
log::info!("Bootstrap completed. Turning on interfaces");
// Build interfaces
let http_api_addr = format!("{}:{}", conf.api_bind, conf.api_port)
.parse()
.unwrap();
let mut addresses = vec![msgs::NetworkAddress::from_ipv4(
conf.api_bind.clone(),
conf.api_port,
)];
// Create Tor endpoint if required
let tor_api = if conf.tor_support {
let tor_api = TorAPI::new(
http_api_addr,
conf.onion_hidden_service_port,
conf.tor_control_port,
path_network,
)
.await;
addresses.push(msgs::NetworkAddress::from_torv3(
tor_api.get_onion_address(),
conf.api_port,
));
Some(tor_api)
} else {
None
};
let rpc_api = Arc::new(InternalAPI::new(
watcher,
addresses,
bitcoind_reachable.clone(),
shutdown_trigger,
));
@ -290,9 +319,6 @@ async fn main() {
"http://{}:{}",
conf.internal_api_bind, conf.internal_api_port
);
let http_api_addr = format!("{}:{}", conf.api_bind, conf.api_port)
.parse()
.unwrap();
// Generate mtls certificates to data directory so the admin can securely connect
// to the server to perform administrative tasks.
@ -336,21 +362,13 @@ async fn main() {
// Add Tor Onion Service for public API
let mut tor_task = Option::None;
let (tor_service_ready, ready_signal_tor) = triggered::trigger();
if conf.tor_support {
if let Some(tor_api) = tor_api {
log::info!("Starting up Tor hidden service");
let tor_control_port = conf.tor_control_port;
let onion_port = conf.onion_hidden_service_port;
tor_task = Some(task::spawn(async move {
if let Err(e) = tor::expose_onion_service(
tor_control_port,
http_api_addr,
onion_port,
path_network,
tor_service_ready,
shutdown_signal_tor,
)
.await
if let Err(e) = tor_api
.expose_onion_service(tor_service_ready, shutdown_signal_tor)
.await
{
eprintln!("Cannot connect to the Tor backend: {}", e);
std::process::exit(1);
@ -367,8 +385,8 @@ async fn main() {
http_api_task.await.unwrap();
private_api_task.await.unwrap();
public_api_task.await.unwrap();
if conf.tor_support {
tor_task.unwrap().await.unwrap();
if let Some(tor_task) = tor_task {
tor_task.await.unwrap();
}
log::info!("Shutting down tower");

View file

@ -45,6 +45,7 @@ use crate::carrier::Carrier;
use crate::dbm::DBM;
use crate::extended_appointment::{ExtendedAppointment, UUID};
use crate::gatekeeper::{Gatekeeper, UserInfo};
use crate::protos as msgs;
use crate::responder::{ConfirmationStatus, Responder, TransactionTracker};
use crate::rpc_errors;
use crate::watcher::{Breach, Watcher};
@ -496,6 +497,7 @@ pub(crate) async fn create_api_with_config(
(
Arc::new(InternalAPI::new(
Arc::new(watcher),
vec![msgs::NetworkAddress::from_ipv4("address".to_string(), 21)],
bitcoind_reachable,
shutdown_trigger,
)),