Skip to content

Commit

Permalink
feat(swap): Initialize both wallets and our Tor client simultaneously
Browse files Browse the repository at this point in the history
  • Loading branch information
binarybaron committed Nov 20, 2024
1 parent 43c9dcf commit f418d65
Showing 1 changed file with 70 additions and 70 deletions.
140 changes: 70 additions & 70 deletions swap/src/cli/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,9 +274,13 @@ impl ContextBuilder {

/// Takes the builder, initializes the context by initializing the wallets and other components and returns the Context.
pub async fn build(self) -> Result<Context> {
// These are needed for everything else, and are blocking calls
let data_dir = data::data_dir_from(self.data, self.is_testnet)?;
let env_config = env_config_from(self.is_testnet);
let seed = Seed::from_file_or_generate(data_dir.as_path())
.context("Failed to read seed in file")?;

// Initialize logging
let format = if self.json { Format::Json } else { Format::Raw };
let level_filter = if self.debug {
LevelFilter::from_level(Level::DEBUG)
Expand All @@ -293,67 +297,73 @@ impl ContextBuilder {
);
});

let seed = Seed::from_file_or_generate(data_dir.as_path())
.context("Failed to read seed in file")?;

let swap_lock = Arc::new(SwapLock::new());

// We initialize the Bitcoin wallet below
// To display the progress to the user, we emit events to the Tauri frontend
self.tauri_handle
.emit_context_init_progress_event(TauriContextStatusEvent::Initializing(
TauriContextInitializationProgress::OpeningBitcoinWallet,
));

let bitcoin_wallet = if let Some(bitcoin) = self.bitcoin {
let (url, target_block) = bitcoin.apply_defaults(self.is_testnet)?;
Some(Arc::new(
init_bitcoin_wallet(url, &seed, data_dir.clone(), env_config, target_block).await?,
))
} else {
None
};

// Initialize the database
let db = open_db(
data_dir.join("sqlite"),
AccessMode::ReadWrite,
self.tauri_handle.clone(),
)
.await?;

// We initialize the Monero wallet below
// To display the progress to the user, we emit events to the Tauri frontend
self.tauri_handle
.emit_context_init_progress_event(TauriContextStatusEvent::Initializing(
TauriContextInitializationProgress::OpeningMoneroWallet,
));

let (monero_wallet, monero_rpc_process) = {
if let Some(monero) = self.monero {
let monero_daemon_address = monero.apply_defaults(self.is_testnet);
let (wlt, prc) = init_monero_wallet(
data_dir.clone(),
monero_daemon_address,
env_config,
self.tauri_handle.clone(),
)
.await?;
// Create the data structure we use to manage the swap lock
let swap_lock = Arc::new(SwapLock::new());
let tasks = PendingTaskList::default().into();

// Initialize these components concurrently
let initialize_bitcoin_wallet = async {
match self.bitcoin {
Some(bitcoin) => {
let (url, target_block) = bitcoin.apply_defaults(self.is_testnet)?;

let wallet =
init_bitcoin_wallet(url, &seed, data_dir.clone(), env_config, target_block)
.await?;

Ok::<std::option::Option<Arc<bitcoin::wallet::Wallet>>, Error>(Some(Arc::new(
wallet,
)))
}
None => Ok(None),
}
};

(Some(Arc::new(wlt)), Some(Arc::new(SyncMutex::new(prc))))
} else {
(None, None)
let initialize_monero_wallet = async {
match self.monero {
Some(monero) => {
let monero_daemon_address = monero.apply_defaults(self.is_testnet);

let (wlt, prc) = init_monero_wallet(
data_dir.clone(),
monero_daemon_address,
env_config,
self.tauri_handle.clone(),
)
.await?;

Ok((Some(Arc::new(wlt)), Some(Arc::new(SyncMutex::new(prc)))))
}
None => Ok((None, None)),
}
};

// We initialize the Database below
// To display the progress to the user, we emit events to the Tauri frontend
self.tauri_handle
.emit_context_init_progress_event(TauriContextStatusEvent::Initializing(
TauriContextInitializationProgress::OpeningDatabase,
));
let initialize_tor_client = async {
let maybe_tor_client = init_tor_client(&data_dir)
.await
.inspect_err(|err| {
tracing::warn!(%err, "Failed to create Tor client. We will continue without Tor");
})
.ok();

Ok(maybe_tor_client)
};

let (bitcoin_wallet, (monero_wallet, monero_rpc_process), tor) = tokio::try_join!(
initialize_bitcoin_wallet,
initialize_monero_wallet,
initialize_tor_client,
)?;

// If we are connected to the Bitcoin blockchain and if there is a handle to Tauri present,
// we start a background task to watch for timelock changes.
// If we have a bitcoin wallet and a tauri handle, we start a background task
if let Some(wallet) = bitcoin_wallet.clone() {
if self.tauri_handle.is_some() {
let watcher = Watcher::new(
Expand All @@ -366,18 +376,6 @@ impl ContextBuilder {
}
}

self.tauri_handle
.emit_context_init_progress_event(TauriContextStatusEvent::Initializing(
TauriContextInitializationProgress::EstablishingTorCircuits,
));

let tor = init_tor_client(&data_dir)
.await
.inspect_err(|err| {
tracing::error!(%err, "Failed to establish Tor client");
})
.ok();

let context = Context {
db,
bitcoin_wallet,
Expand All @@ -386,17 +384,19 @@ impl ContextBuilder {
config: Config {
namespace: XmrBtcNamespace::from_is_testnet(self.is_testnet),
env_config,
seed: Some(seed),
seed: seed.into(),
debug: self.debug,
json: self.json,
is_testnet: self.is_testnet,
data_dir,
},
swap_lock,
tasks: Arc::new(PendingTaskList::default()),
tasks,
tauri_handle: self.tauri_handle,
tor_client: tor,
};
let context = context;
let context = context;

Ok(context)
}
Expand All @@ -419,15 +419,15 @@ impl Context {
let config = Config::for_harness(seed, env_config);

Self {
bitcoin_wallet: Some(bob_bitcoin_wallet),
monero_wallet: Some(bob_monero_wallet),
bitcoin_wallet: bob_bitcoin_wallet.into(),
monero_wallet: bob_monero_wallet.into(),
config,
db: open_db(db_path, AccessMode::ReadWrite, None)
.await
.expect("Could not open sqlite database"),
monero_rpc_process: None,
swap_lock: Arc::new(SwapLock::new()),
tasks: Arc::new(PendingTaskList::default()),
swap_lock: SwapLock::new().into(),
tasks: PendingTaskList::default().into(),
tauri_handle: None,
tor_client: None,
}
Expand Down Expand Up @@ -499,7 +499,7 @@ async fn init_monero_wallet(
);

let monero_wallet_rpc_process = monero_wallet_rpc
.run(network, Some(monero_daemon_address))
.run(network, monero_daemon_address.into())
.await
.context("Failed to start monero-wallet-rpc process")?;

Expand Down Expand Up @@ -548,7 +548,7 @@ impl Config {
Self {
namespace: XmrBtcNamespace::from_is_testnet(false),
env_config,
seed: Some(seed),
seed: seed.into(),
debug: false,
json: false,
is_testnet: false,
Expand Down Expand Up @@ -584,7 +584,7 @@ pub mod api_test {
Self {
namespace: XmrBtcNamespace::from_is_testnet(is_testnet),
env_config,
seed: Some(seed),
seed: seed.into(),
debug,
json,
is_testnet,
Expand Down

0 comments on commit f418d65

Please sign in to comment.