Skip to content
This repository was archived by the owner on Sep 12, 2023. It is now read-only.

Commit 5770509

Browse files
committed
feat(taker): import seed
1 parent 5248978 commit 5770509

File tree

14 files changed

+555
-51
lines changed

14 files changed

+555
-51
lines changed

crates/daemon-tests/src/mocks/wallet.rs

+7
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ impl WalletActor {
5252
async fn handle(&mut self, msg: wallet::Sync) {
5353
self.mock.lock().await.sync(msg)
5454
}
55+
async fn handle(&mut self, msg: wallet::ImportSeed) -> Result<()> {
56+
self.mock.lock().await.import_seed(msg)
57+
}
5558
}
5659

5760
#[automock]
@@ -71,6 +74,10 @@ pub trait Wallet {
7174
fn sync(&mut self, _msg: wallet::Sync) {
7275
unreachable!("mockall will reimplement this method")
7376
}
77+
78+
fn import_seed(&mut self, _msg: wallet::ImportSeed) -> Result<()> {
79+
unreachable!("mockall will reimplement this method")
80+
}
7481
}
7582

7683
pub fn build_party_params(msg: wallet::BuildPartyParams) -> Result<PartyParams> {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
use daemon::bdk::bitcoin;
2+
use daemon::seed::RandomSeed;
3+
use daemon::seed::Seed;
4+
use daemon_tests::open_cfd;
5+
use daemon_tests::start_both;
6+
use daemon_tests::OpenCfdArgs;
7+
use otel_tests::otel_test;
8+
use rand::distributions::Alphanumeric;
9+
use rand::thread_rng;
10+
use rand::Rng;
11+
use std::env;
12+
use std::path::Path;
13+
14+
#[otel_test]
15+
async fn fail_to_import_seed_with_open_cfds() {
16+
let (mut maker, mut taker) = start_both().await;
17+
18+
let cfd_args = OpenCfdArgs::default();
19+
open_cfd(&mut taker, &mut maker, cfd_args.clone()).await;
20+
21+
let random_folder: String = thread_rng()
22+
.sample_iter(&Alphanumeric)
23+
.take(7)
24+
.map(char::from)
25+
.collect();
26+
let data_dir = env::temp_dir().join(Path::new(&random_folder));
27+
tokio::fs::create_dir_all(&data_dir)
28+
.await
29+
.expect("failed to create random temp folder");
30+
31+
taker
32+
.system
33+
.import_seed(
34+
RandomSeed::default().seed(),
35+
data_dir,
36+
bitcoin::Network::Testnet,
37+
)
38+
.await
39+
.expect_err("import seed should be rejected as open CFDs exist");
40+
}

crates/daemon-tests/tests/main/main.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
mod collaborative_settlement;
22
mod connectivity;
3+
mod import_seed;
34
mod liquidation;
45
mod non_collaborative_settlement;
56
mod offer;

crates/daemon/src/lib.rs

+43-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
#![cfg_attr(not(test), warn(clippy::unwrap_used))]
22

33
use crate::bitcoin::util::psbt::PartiallySignedTransaction;
4+
use crate::bitcoin::Network;
45
use crate::bitcoin::Txid;
56
use crate::listen_protocols::TAKER_LISTEN_PROTOCOLS;
7+
use anyhow::anyhow;
68
use anyhow::bail;
79
use anyhow::Context as _;
810
use anyhow::Result;
@@ -30,7 +32,9 @@ use parse_display::Display;
3032
use ping_pong::ping;
3133
use ping_pong::pong;
3234
use seed::Identities;
35+
use serde::Serialize;
3336
use std::collections::HashSet;
37+
use std::path::PathBuf;
3438
use std::sync::Arc;
3539
use std::time::Duration;
3640
use time::ext::NumericalDuration;
@@ -78,7 +82,7 @@ pub const N_PAYOUTS: usize = 200;
7882

7983
pub struct TakerActorSystem<O, W, P> {
8084
pub cfd_actor: Address<taker_cfd::Actor>,
81-
wallet_actor: Address<W>,
85+
pub wallet_actor: Address<W>,
8286
_oracle_actor: Address<O>,
8387
pub auto_rollover_actor: Address<auto_rollover::Actor>,
8488
pub price_feed_actor: Address<P>,
@@ -93,6 +97,8 @@ pub struct TakerActorSystem<O, W, P> {
9397
pub identify_info_feed_receiver: watch::Receiver<Option<PeerInfo>>,
9498

9599
_tasks: Tasks,
100+
101+
db: sqlite_db::Connection,
96102
}
97103

98104
impl<O, W, P> TakerActorSystem<O, W, P>
@@ -105,6 +111,7 @@ where
105111
W: Handler<wallet::BuildPartyParams, Return = Result<maia_core::PartyParams>>
106112
+ Handler<wallet::Sign, Return = Result<PartiallySignedTransaction>>
107113
+ Handler<wallet::Withdraw, Return = Result<Txid>>
114+
+ Handler<wallet::ImportSeed, Return = Result<()>>
108115
+ Handler<wallet::Sync, Return = ()>
109116
+ Actor<Stop = ()>,
110117
P: Handler<
@@ -333,7 +340,7 @@ where
333340
let close_cfds_actor = archive_closed_cfds::Actor::new(db.clone())
334341
.create(None)
335342
.spawn(&mut tasks);
336-
let archive_failed_cfds_actor = archive_failed_cfds::Actor::new(db)
343+
let archive_failed_cfds_actor = archive_failed_cfds::Actor::new(db.clone())
337344
.create(None)
338345
.spawn(&mut tasks);
339346

@@ -354,6 +361,7 @@ where
354361
_online_status_actor: online_status_actor,
355362
_pong_actor: pong_address,
356363
_identify_dialer_actor: identify_dialer_actor,
364+
db,
357365
})
358366
}
359367

@@ -445,14 +453,46 @@ where
445453
self.wallet_actor.send(wallet::Sync).await?;
446454
Ok(())
447455
}
456+
457+
#[instrument(skip(self, seed), err)]
458+
pub async fn import_seed(
459+
&self,
460+
seed: Vec<u8>,
461+
data_dir: PathBuf,
462+
network: Network,
463+
) -> Result<()> {
464+
let open_cfd_ids = self.db.load_open_cfd_ids().await?;
465+
466+
if !open_cfd_ids.is_empty() {
467+
tracing::warn!("Rejecting imported seed as open CFDs exist.");
468+
// in case of open cfds we do not accept an imported seed.
469+
return Err(anyhow!(
470+
"Can not accept imported seed since open CFDs exist."
471+
));
472+
}
473+
474+
// recreate the wallet within the wallet actor
475+
self.wallet_actor
476+
.send(wallet::ImportSeed {
477+
seed,
478+
seed_path: data_dir.join(seed::TAKER_WALLET_SEED_FILE),
479+
network,
480+
})
481+
.await??;
482+
483+
// sync imported wallet
484+
self.wallet_actor.send(wallet::Sync).await?;
485+
486+
Ok(())
487+
}
448488
}
449489

450490
/// A struct defining our environment
451491
///
452492
/// We can run on all kinds of environment, hence this is just a wrapper around string.
453493
/// However, for backwards compatibility with <=0.6.x we need to support to support
454494
/// `Unknown`. For all other we format the string to lowercase.
455-
#[derive(Debug, Clone, Display, PartialEq, Eq)]
495+
#[derive(Debug, Clone, Display, PartialEq, Eq, Serialize)]
456496
pub struct Environment(String);
457497

458498
impl Environment {

crates/daemon/src/seed.rs

+14
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,15 @@ impl Identities {
3030
}
3131
}
3232

33+
pub const TAKER_WALLET_SEED_FILE: &str = "taker_seed";
34+
pub const TAKER_IDENTITY_SEED_FILE: &str = "taker_id_seed";
35+
36+
pub const MAKER_WALLET_SEED_FILE: &str = "maker_seed";
37+
pub const MAKER_IDENTITY_SEED_FILE: &str = "maker_id_seed";
38+
3339
pub trait Seed {
40+
41+
3442
fn seed(&self) -> Vec<u8>;
3543

3644
fn derive_extended_priv_key(&self, network: Network) -> Result<ExtendedPrivKey> {
@@ -133,6 +141,12 @@ impl RandomSeed {
133141
}
134142
}
135143

144+
impl From<[u8; 256]> for RandomSeed {
145+
fn from(bytes: [u8; 256]) -> Self {
146+
Self(bytes)
147+
}
148+
}
149+
136150
impl Default for RandomSeed {
137151
fn default() -> Self {
138152
let mut seed = [0u8; 256];

0 commit comments

Comments
 (0)