2024-04-16 18:16:53 +03:00
|
|
|
use std::iter;
|
|
|
|
use std::net::TcpListener;
|
|
|
|
use std::sync::Arc;
|
|
|
|
|
2023-12-19 03:12:05 +03:00
|
|
|
use grin_core::core::Transaction;
|
2024-04-16 18:16:53 +03:00
|
|
|
use tor_rtcompat::PreferredRuntime;
|
|
|
|
use x25519_dalek::{PublicKey as xPublicKey, StaticSecret};
|
|
|
|
|
2023-12-19 03:12:05 +03:00
|
|
|
use grin_onion::crypto::comsig::ComSignature;
|
|
|
|
use grin_onion::crypto::dalek::DalekPublicKey;
|
|
|
|
use grin_onion::onion::Onion;
|
2024-04-16 18:16:53 +03:00
|
|
|
use mwixnet::mix_client::MixClientImpl;
|
|
|
|
use mwixnet::tor::TorService;
|
2023-12-19 03:12:05 +03:00
|
|
|
use mwixnet::{tor, SwapError, SwapServer, SwapStore};
|
|
|
|
use secp256k1zkp::SecretKey;
|
|
|
|
|
2024-04-16 18:16:53 +03:00
|
|
|
use crate::common::node::IntegrationGrinNode;
|
|
|
|
use crate::common::wallet::{GrinWalletManager, IntegrationGrinWallet};
|
|
|
|
|
|
|
|
pub struct IntegrationSwapServer<R: tor_rtcompat::Runtime> {
|
2023-12-19 03:12:05 +03:00
|
|
|
server_key: SecretKey,
|
2024-04-16 18:16:53 +03:00
|
|
|
tor_instance: Arc<grin_util::Mutex<TorService<R>>>,
|
2023-12-19 03:12:05 +03:00
|
|
|
swap_server: Arc<tokio::sync::Mutex<dyn SwapServer>>,
|
|
|
|
rpc_server: jsonrpc_http_server::Server,
|
|
|
|
_wallet: Arc<grin_util::Mutex<IntegrationGrinWallet>>,
|
|
|
|
}
|
|
|
|
|
2024-04-16 18:16:53 +03:00
|
|
|
impl<R: tor_rtcompat::Runtime> IntegrationSwapServer<R> {
|
2023-12-19 03:12:05 +03:00
|
|
|
pub async fn async_swap(&self, onion: &Onion, comsig: &ComSignature) -> Result<(), SwapError> {
|
|
|
|
self.swap_server.lock().await.swap(&onion, &comsig).await
|
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn async_execute_round(&self) -> Result<Option<Arc<Transaction>>, SwapError> {
|
|
|
|
self.swap_server.lock().await.execute_round().await
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-16 18:16:53 +03:00
|
|
|
pub struct IntegrationMixServer<R: tor_rtcompat::Runtime> {
|
2023-12-19 03:12:05 +03:00
|
|
|
server_key: SecretKey,
|
2024-04-16 18:16:53 +03:00
|
|
|
tor_instance: Arc<grin_util::Mutex<TorService<R>>>,
|
2023-12-19 03:12:05 +03:00
|
|
|
rpc_server: jsonrpc_http_server::Server,
|
|
|
|
_wallet: Arc<grin_util::Mutex<IntegrationGrinWallet>>,
|
|
|
|
}
|
|
|
|
|
2024-04-16 18:16:53 +03:00
|
|
|
async fn async_new_swap_server<R>(
|
2023-12-19 03:12:05 +03:00
|
|
|
data_dir: &str,
|
|
|
|
rt_handle: &tokio::runtime::Handle,
|
2024-04-16 18:16:53 +03:00
|
|
|
tor_runtime: R,
|
2023-12-19 03:12:05 +03:00
|
|
|
wallets: &mut GrinWalletManager,
|
|
|
|
server_key: &SecretKey,
|
|
|
|
node: &Arc<grin_util::Mutex<IntegrationGrinNode>>,
|
2024-04-16 18:16:53 +03:00
|
|
|
next_server: Option<&IntegrationMixServer<R>>,
|
|
|
|
) -> IntegrationSwapServer<R>
|
|
|
|
where
|
|
|
|
R: tor_rtcompat::Runtime,
|
|
|
|
{
|
2023-12-19 03:12:05 +03:00
|
|
|
let wallet = wallets.async_new_wallet(&node.lock().api_address()).await;
|
|
|
|
|
|
|
|
let server_config = mwixnet::ServerConfig {
|
|
|
|
key: server_key.clone(),
|
|
|
|
interval_s: 15,
|
|
|
|
addr: TcpListener::bind("127.0.0.1:0")
|
|
|
|
.unwrap()
|
|
|
|
.local_addr()
|
|
|
|
.unwrap(),
|
2024-07-29 15:40:21 +03:00
|
|
|
grin_node_url: node.lock().api_address().to_string(),
|
2023-12-19 03:12:05 +03:00
|
|
|
grin_node_secret_path: None,
|
2024-07-29 15:40:21 +03:00
|
|
|
wallet_owner_url: wallet.lock().owner_address().to_string(),
|
2023-12-19 03:12:05 +03:00
|
|
|
wallet_owner_secret_path: None,
|
|
|
|
prev_server: None,
|
|
|
|
next_server: match next_server {
|
|
|
|
Some(s) => Some(DalekPublicKey::from_secret(&s.server_key)),
|
|
|
|
None => None,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
// Open SwapStore
|
|
|
|
let store = SwapStore::new(format!("{}/db", data_dir).as_str()).unwrap();
|
2024-04-16 18:16:53 +03:00
|
|
|
let tor_instance = tor::async_init_tor(tor_runtime, &data_dir, &server_config)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
let tor_instance = Arc::new(grin_util::Mutex::new(tor_instance));
|
2023-12-19 03:12:05 +03:00
|
|
|
|
|
|
|
let (swap_server, rpc_server) = mwixnet::swap_listen(
|
|
|
|
rt_handle,
|
|
|
|
&server_config,
|
|
|
|
match next_server {
|
|
|
|
Some(s) => Some(Arc::new(MixClientImpl::new(
|
|
|
|
server_config.clone(),
|
2024-04-16 18:16:53 +03:00
|
|
|
tor_instance.clone(),
|
2023-12-19 03:12:05 +03:00
|
|
|
DalekPublicKey::from_secret(&s.server_key),
|
|
|
|
))),
|
|
|
|
None => None,
|
|
|
|
},
|
|
|
|
wallet.lock().get_client(),
|
|
|
|
node.lock().to_client(),
|
|
|
|
store,
|
|
|
|
)
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
IntegrationSwapServer {
|
|
|
|
server_key: server_key.clone(),
|
2024-04-16 18:16:53 +03:00
|
|
|
tor_instance,
|
2023-12-19 03:12:05 +03:00
|
|
|
swap_server,
|
|
|
|
rpc_server,
|
|
|
|
_wallet: wallet,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-16 18:16:53 +03:00
|
|
|
async fn async_new_mix_server<R>(
|
2023-12-19 03:12:05 +03:00
|
|
|
data_dir: &str,
|
|
|
|
rt_handle: &tokio::runtime::Handle,
|
2024-04-16 18:16:53 +03:00
|
|
|
tor_runtime: R,
|
2023-12-19 03:12:05 +03:00
|
|
|
wallets: &mut GrinWalletManager,
|
|
|
|
server_key: &SecretKey,
|
|
|
|
node: &Arc<grin_util::Mutex<IntegrationGrinNode>>,
|
|
|
|
prev_server: DalekPublicKey,
|
2024-04-16 18:16:53 +03:00
|
|
|
next_server: Option<&IntegrationMixServer<R>>,
|
|
|
|
) -> IntegrationMixServer<R>
|
|
|
|
where
|
|
|
|
R: tor_rtcompat::Runtime,
|
|
|
|
{
|
2023-12-19 03:12:05 +03:00
|
|
|
let wallet = wallets.async_new_wallet(&node.lock().api_address()).await;
|
|
|
|
let server_config = mwixnet::ServerConfig {
|
|
|
|
key: server_key.clone(),
|
|
|
|
interval_s: 15,
|
|
|
|
addr: TcpListener::bind("127.0.0.1:0")
|
|
|
|
.unwrap()
|
|
|
|
.local_addr()
|
|
|
|
.unwrap(),
|
2024-07-29 15:40:21 +03:00
|
|
|
grin_node_url: node.lock().api_address().to_string(),
|
2023-12-19 03:12:05 +03:00
|
|
|
grin_node_secret_path: None,
|
2024-07-29 15:40:21 +03:00
|
|
|
wallet_owner_url: wallet.lock().owner_address().to_string(),
|
2023-12-19 03:12:05 +03:00
|
|
|
wallet_owner_secret_path: None,
|
|
|
|
prev_server: Some(prev_server),
|
|
|
|
next_server: match next_server {
|
|
|
|
Some(s) => Some(DalekPublicKey::from_secret(&s.server_key)),
|
|
|
|
None => None,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2024-04-16 18:16:53 +03:00
|
|
|
let tor_instance = tor::async_init_tor(tor_runtime, &data_dir, &server_config)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
let tor_instance = Arc::new(grin_util::Mutex::new(tor_instance));
|
2023-12-19 03:12:05 +03:00
|
|
|
|
|
|
|
let (_, rpc_server) = mwixnet::mix_listen(
|
|
|
|
rt_handle,
|
|
|
|
server_config.clone(),
|
|
|
|
match next_server {
|
|
|
|
Some(s) => Some(Arc::new(MixClientImpl::new(
|
|
|
|
server_config.clone(),
|
2024-04-16 18:16:53 +03:00
|
|
|
tor_instance.clone(),
|
2023-12-19 03:12:05 +03:00
|
|
|
DalekPublicKey::from_secret(&s.server_key),
|
|
|
|
))),
|
|
|
|
None => None,
|
|
|
|
},
|
|
|
|
wallet.lock().get_client(),
|
|
|
|
node.lock().to_client(),
|
|
|
|
)
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
IntegrationMixServer {
|
|
|
|
server_key: server_key.clone(),
|
2024-04-16 18:16:53 +03:00
|
|
|
tor_instance,
|
2023-12-19 03:12:05 +03:00
|
|
|
rpc_server,
|
|
|
|
_wallet: wallet,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct Servers {
|
2024-04-16 18:16:53 +03:00
|
|
|
pub swapper: IntegrationSwapServer<PreferredRuntime>,
|
2023-12-19 03:12:05 +03:00
|
|
|
|
2024-04-16 18:16:53 +03:00
|
|
|
pub mixers: Vec<IntegrationMixServer<PreferredRuntime>>,
|
2023-12-19 03:12:05 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Servers {
|
|
|
|
pub async fn async_setup(
|
|
|
|
test_dir: &str,
|
|
|
|
rt_handle: &tokio::runtime::Handle,
|
|
|
|
wallets: &mut GrinWalletManager,
|
|
|
|
node: &Arc<grin_util::Mutex<IntegrationGrinNode>>,
|
|
|
|
num_mixers: usize,
|
|
|
|
) -> Servers {
|
|
|
|
// Pre-generate all server keys
|
|
|
|
let server_keys: Vec<SecretKey> =
|
|
|
|
iter::repeat_with(|| grin_onion::crypto::secp::random_secret())
|
|
|
|
.take(num_mixers + 1)
|
|
|
|
.collect();
|
|
|
|
|
2024-04-16 18:16:53 +03:00
|
|
|
// Setup mock tor network
|
|
|
|
let tor_runtime = PreferredRuntime::current().unwrap();
|
|
|
|
|
2023-12-19 03:12:05 +03:00
|
|
|
// Build mixers in reverse order
|
|
|
|
let mut mixers = Vec::new();
|
|
|
|
for i in (0..num_mixers).rev() {
|
|
|
|
let mix_server = async_new_mix_server(
|
|
|
|
format!("{}/mixers/{}", test_dir, i).as_str(),
|
|
|
|
rt_handle,
|
2024-04-16 18:16:53 +03:00
|
|
|
tor_runtime.clone(),
|
2023-12-19 03:12:05 +03:00
|
|
|
wallets,
|
|
|
|
&server_keys[i + 1],
|
|
|
|
&node,
|
|
|
|
DalekPublicKey::from_secret(&server_keys[i]),
|
|
|
|
mixers.last(),
|
|
|
|
)
|
|
|
|
.await;
|
|
|
|
println!(
|
|
|
|
"Mixer {}: server_key={}, prev_server={}, next_server={}",
|
|
|
|
i,
|
|
|
|
DalekPublicKey::from_secret(&server_keys[i + 1]).to_hex(),
|
|
|
|
DalekPublicKey::from_secret(&server_keys[i]).to_hex(),
|
|
|
|
match mixers.last() {
|
|
|
|
Some(s) => DalekPublicKey::from_secret(&s.server_key).to_hex(),
|
|
|
|
None => "NONE".to_string(),
|
|
|
|
},
|
|
|
|
);
|
|
|
|
mixers.push(mix_server);
|
|
|
|
}
|
|
|
|
mixers.reverse();
|
|
|
|
|
|
|
|
let swapper = async_new_swap_server(
|
|
|
|
format!("{}/swapper", test_dir).as_str(),
|
|
|
|
rt_handle,
|
2024-04-16 18:16:53 +03:00
|
|
|
tor_runtime.clone(),
|
2023-12-19 03:12:05 +03:00
|
|
|
wallets,
|
|
|
|
&server_keys[0],
|
|
|
|
&node,
|
|
|
|
mixers.first(),
|
|
|
|
)
|
|
|
|
.await;
|
|
|
|
println!(
|
|
|
|
"Swapper: server_key={}",
|
|
|
|
DalekPublicKey::from_secret(&server_keys[0]).to_hex()
|
|
|
|
);
|
|
|
|
|
|
|
|
Servers { swapper, mixers }
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_pub_keys(&self) -> Vec<xPublicKey> {
|
|
|
|
let mut pub_keys = vec![xPublicKey::from(&StaticSecret::from(
|
|
|
|
self.swapper.server_key.0.clone(),
|
|
|
|
))];
|
|
|
|
for mixer in &self.mixers {
|
|
|
|
pub_keys.push(xPublicKey::from(&StaticSecret::from(
|
|
|
|
mixer.server_key.0.clone(),
|
|
|
|
)))
|
|
|
|
}
|
|
|
|
pub_keys
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn stop_all(&mut self) {
|
|
|
|
self.swapper.rpc_server.close_handle().close();
|
2024-04-16 18:16:53 +03:00
|
|
|
self.swapper.tor_instance.lock().stop();
|
2023-12-19 03:12:05 +03:00
|
|
|
|
|
|
|
self.mixers.iter_mut().for_each(|mixer| {
|
|
|
|
mixer.rpc_server.close_handle().close();
|
2024-04-16 18:16:53 +03:00
|
|
|
mixer.tor_instance.lock().stop();
|
2023-12-19 03:12:05 +03:00
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|