404: Generate from keys can fall back to opening wallet if already generated r=da-kami a=da-kami



Co-authored-by: Daniel Karzel <daniel@comit.network>
This commit is contained in:
bors[bot] 2021-04-08 09:25:09 +00:00 committed by GitHub
commit 688364cb41
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 40 additions and 7 deletions

View File

@ -287,6 +287,7 @@ impl Client {
pub async fn generate_from_keys( pub async fn generate_from_keys(
&self, &self,
filename: &str,
address: &str, address: &str,
spend_key: &str, spend_key: &str,
view_key: &str, view_key: &str,
@ -294,7 +295,7 @@ impl Client {
) -> Result<GenerateFromKeys> { ) -> Result<GenerateFromKeys> {
let params = GenerateFromKeysParams { let params = GenerateFromKeysParams {
restore_height, restore_height,
filename: view_key.into(), filename: filename.into(),
address: address.into(), address: address.into(),
spendkey: spend_key.into(), spendkey: spend_key.into(),
viewkey: view_key.into(), viewkey: view_key.into(),

View File

@ -64,10 +64,16 @@ impl Wallet {
Ok(()) Ok(())
} }
pub async fn open(&self, filename: &str) -> Result<()> {
self.inner.lock().await.open_wallet(filename).await?;
Ok(())
}
/// Close the wallet and open (load) another wallet by generating it from /// Close the wallet and open (load) another wallet by generating it from
/// keys. The generated wallet will remain loaded. /// keys. The generated wallet will remain loaded.
pub async fn create_from_and_load( pub async fn create_from_and_load(
&self, &self,
file_name: &str,
private_spend_key: PrivateKey, private_spend_key: PrivateKey,
private_view_key: PrivateViewKey, private_view_key: PrivateViewKey,
restore_height: BlockHeight, restore_height: BlockHeight,
@ -85,6 +91,7 @@ impl Wallet {
let _ = wallet let _ = wallet
.generate_from_keys( .generate_from_keys(
file_name,
&address.to_string(), &address.to_string(),
&private_spend_key.to_string(), &private_spend_key.to_string(),
&PrivateKey::from(private_view_key).to_string(), &PrivateKey::from(private_view_key).to_string(),
@ -101,6 +108,7 @@ impl Wallet {
/// stored name. /// stored name.
pub async fn create_from( pub async fn create_from(
&self, &self,
file_name: &str,
private_spend_key: PrivateKey, private_spend_key: PrivateKey,
private_view_key: PrivateViewKey, private_view_key: PrivateViewKey,
restore_height: BlockHeight, restore_height: BlockHeight,
@ -119,6 +127,7 @@ impl Wallet {
let _ = wallet let _ = wallet
.generate_from_keys( .generate_from_keys(
file_name,
&temp_wallet_address.to_string(), &temp_wallet_address.to_string(),
&private_spend_key.to_string(), &private_spend_key.to_string(),
&PrivateKey::from(private_view_key).to_string(), &PrivateKey::from(private_view_key).to_string(),

View File

@ -11,6 +11,7 @@ use anyhow::{bail, Context, Result};
use tokio::select; use tokio::select;
use tokio::time::timeout; use tokio::time::timeout;
use tracing::{error, info}; use tracing::{error, info};
use uuid::Uuid;
pub async fn run(swap: alice::Swap) -> Result<AliceState> { pub async fn run(swap: alice::Swap) -> Result<AliceState> {
run_until(swap, |_| false).await run_until(swap, |_| false).await
@ -25,6 +26,7 @@ pub async fn run_until(
while !is_complete(&current_state) && !exit_early(&current_state) { while !is_complete(&current_state) && !exit_early(&current_state) {
current_state = next_state( current_state = next_state(
swap.swap_id,
current_state, current_state,
&mut swap.event_loop_handle, &mut swap.event_loop_handle,
swap.bitcoin_wallet.as_ref(), swap.bitcoin_wallet.as_ref(),
@ -43,6 +45,7 @@ pub async fn run_until(
} }
async fn next_state( async fn next_state(
swap_id: Uuid,
state: AliceState, state: AliceState,
event_loop_handle: &mut EventLoopHandle, event_loop_handle: &mut EventLoopHandle,
bitcoin_wallet: &bitcoin::Wallet, bitcoin_wallet: &bitcoin::Wallet,
@ -296,7 +299,12 @@ async fn next_state(
.await?; .await?;
monero_wallet monero_wallet
.create_from(spend_key, view_key, monero_wallet_restore_blockheight) .create_from(
&swap_id.to_string(),
spend_key,
view_key,
monero_wallet_restore_blockheight,
)
.await?; .await?;
AliceState::XmrRefunded AliceState::XmrRefunded

View File

@ -8,6 +8,7 @@ use crate::{bitcoin, monero};
use anyhow::{bail, Context, Result}; use anyhow::{bail, Context, Result};
use rand::rngs::OsRng; use rand::rngs::OsRng;
use tokio::select; use tokio::select;
use uuid::Uuid;
pub fn is_complete(state: &BobState) -> bool { pub fn is_complete(state: &BobState) -> bool {
matches!( matches!(
@ -32,6 +33,7 @@ pub async fn run_until(
while !is_target_state(&current_state) { while !is_target_state(&current_state) {
current_state = next_state( current_state = next_state(
swap.swap_id,
current_state, current_state,
&mut swap.event_loop_handle, &mut swap.event_loop_handle,
swap.bitcoin_wallet.as_ref(), swap.bitcoin_wallet.as_ref(),
@ -51,6 +53,7 @@ pub async fn run_until(
} }
async fn next_state( async fn next_state(
swap_id: Uuid,
state: BobState, state: BobState,
event_loop_handle: &mut EventLoopHandle, event_loop_handle: &mut EventLoopHandle,
bitcoin_wallet: &bitcoin::Wallet, bitcoin_wallet: &bitcoin::Wallet,
@ -193,11 +196,23 @@ async fn next_state(
BobState::BtcRedeemed(state) => { BobState::BtcRedeemed(state) => {
let (spend_key, view_key) = state.xmr_keys(); let (spend_key, view_key) = state.xmr_keys();
// NOTE: This actually generates and opens a new wallet, closing the currently let generated_wallet_file_name = &swap_id.to_string();
// open one. if monero_wallet
monero_wallet .create_from_and_load(
.create_from_and_load(spend_key, view_key, state.monero_wallet_restore_blockheight) generated_wallet_file_name,
.await?; spend_key,
view_key,
state.monero_wallet_restore_blockheight,
)
.await
.is_err()
{
// In case we failed to refresh/sweep, when resuming the wallet might already
// exist! This is a very unlikely scenario, but if we don't take care of it we
// might not be able to ever transfer the Monero.
tracing::warn!("Failed to generate monero wallet from keys, falling back to trying to open the the wallet if it already exists: {}", swap_id);
monero_wallet.open(generated_wallet_file_name).await?;
}
// Ensure that the generated wallet is synced so we have a proper balance // Ensure that the generated wallet is synced so we have a proper balance
monero_wallet.refresh().await?; monero_wallet.refresh().await?;