mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2025-04-20 07:56:05 -04:00
Deterministic peer id from seed for alice
This includes the introduction of the --data-dir parameter instead of the --database. Both the seed file and the database are stored in the data-dir, the database in sub-folder `database`.
This commit is contained in:
parent
64ba8d6a87
commit
0a21040e08
12
Cargo.lock
generated
12
Cargo.lock
generated
@ -2212,6 +2212,17 @@ dependencies = [
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pem"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4c220d01f863d13d96ca82359d1e81e64a7c6bf0637bcde7b2349630addf0c6"
|
||||
dependencies = [
|
||||
"base64 0.13.0",
|
||||
"once_cell",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.1.0"
|
||||
@ -3293,6 +3304,7 @@ dependencies = [
|
||||
"miniscript",
|
||||
"monero",
|
||||
"monero-harness",
|
||||
"pem",
|
||||
"port_check",
|
||||
"prettytable-rs",
|
||||
"rand 0.7.3",
|
||||
|
@ -27,6 +27,7 @@ log = { version = "0.4", features = ["serde"] }
|
||||
miniscript = { version = "4", features = ["serde"] }
|
||||
monero = { version = "0.9", features = ["serde_support"] }
|
||||
monero-harness = { path = "../monero-harness" }
|
||||
pem = "0.8"
|
||||
prettytable-rs = "0.8"
|
||||
rand = "0.7"
|
||||
reqwest = { version = "0.10", default-features = false, features = ["socks"] }
|
||||
|
@ -7,8 +7,8 @@ use crate::{bitcoin, monero};
|
||||
#[derive(structopt::StructOpt, Debug)]
|
||||
pub struct Options {
|
||||
// TODO: Default value should points to proper configuration folder in home folder
|
||||
#[structopt(long = "database", default_value = "./.swap-db/")]
|
||||
pub db_path: String,
|
||||
#[structopt(long = "data-dir", default_value = "./.swap-data/")]
|
||||
pub data_dir: String,
|
||||
|
||||
#[structopt(subcommand)]
|
||||
pub cmd: Command,
|
||||
|
@ -1,3 +1,5 @@
|
||||
pub mod seed;
|
||||
|
||||
use crate::bitcoin::Timelock;
|
||||
use conquer_once::Lazy;
|
||||
use std::time::Duration;
|
||||
|
196
swap/src/config/seed.rs
Normal file
196
swap/src/config/seed.rs
Normal file
@ -0,0 +1,196 @@
|
||||
use crate::{fs::ensure_directory_exists, seed};
|
||||
use pem::{encode, Pem};
|
||||
use seed::SEED_LENGTH;
|
||||
use std::{
|
||||
ffi::OsStr,
|
||||
fmt,
|
||||
fs::{self, File},
|
||||
io::{self, Write},
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub struct Seed(seed::Seed);
|
||||
|
||||
impl Seed {
|
||||
pub fn random() -> Result<Self, Error> {
|
||||
Ok(Seed(seed::Seed::random()?))
|
||||
}
|
||||
|
||||
pub fn from_file_or_generate(data_dir: &PathBuf) -> Result<Self, Error> {
|
||||
let file_path_buf = data_dir.join("seed.pem");
|
||||
let file_path = Path::new(&file_path_buf);
|
||||
|
||||
if file_path.exists() {
|
||||
return Self::from_file(&file_path);
|
||||
}
|
||||
|
||||
tracing::info!("No seed file found, creating at: {}", file_path.display());
|
||||
|
||||
let random_seed = Seed::random()?;
|
||||
random_seed.write_to(file_path.to_path_buf())?;
|
||||
|
||||
Ok(random_seed)
|
||||
}
|
||||
|
||||
fn from_file<D>(seed_file: D) -> Result<Self, Error>
|
||||
where
|
||||
D: AsRef<OsStr>,
|
||||
{
|
||||
let file = Path::new(&seed_file);
|
||||
let contents = fs::read_to_string(file)?;
|
||||
let pem = pem::parse(contents)?;
|
||||
|
||||
tracing::info!("Read in seed from file: {}", file.display());
|
||||
|
||||
Self::from_pem(pem)
|
||||
}
|
||||
|
||||
fn from_pem(pem: pem::Pem) -> Result<Self, Error> {
|
||||
if pem.contents.len() != SEED_LENGTH {
|
||||
Err(Error::IncorrectLength(pem.contents.len()))
|
||||
} else {
|
||||
let mut array = [0; SEED_LENGTH];
|
||||
for (i, b) in pem.contents.iter().enumerate() {
|
||||
array[i] = *b;
|
||||
}
|
||||
|
||||
Ok(Self::from(array))
|
||||
}
|
||||
}
|
||||
|
||||
fn write_to(&self, seed_file: PathBuf) -> Result<(), Error> {
|
||||
ensure_directory_exists(&seed_file)?;
|
||||
|
||||
let data = (self.0).bytes();
|
||||
let pem = Pem {
|
||||
tag: String::from("SEED"),
|
||||
contents: data.to_vec(),
|
||||
};
|
||||
|
||||
let pem_string = encode(&pem);
|
||||
|
||||
let mut file = File::create(seed_file)?;
|
||||
file.write_all(pem_string.as_bytes())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Seed {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "Seed([*****])")
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Seed {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{:?}", self)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<[u8; SEED_LENGTH]> for Seed {
|
||||
fn from(bytes: [u8; 32]) -> Self {
|
||||
Seed(seed::Seed::from(bytes))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Seed> for seed::Seed {
|
||||
fn from(seed: Seed) -> Self {
|
||||
seed.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum Error {
|
||||
#[error("Seed generation: ")]
|
||||
SeedGeneration(#[from] crate::seed::Error),
|
||||
#[error("io: ")]
|
||||
Io(#[from] io::Error),
|
||||
#[error("PEM parse: ")]
|
||||
PemParse(#[from] pem::PemError),
|
||||
#[error("expected 32 bytes of base64 encode, got {0} bytes")]
|
||||
IncorrectLength(usize),
|
||||
#[error("RNG: ")]
|
||||
Rand(#[from] rand::Error),
|
||||
#[error("no default path")]
|
||||
NoDefaultPath,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use std::env::temp_dir;
|
||||
|
||||
#[test]
|
||||
fn seed_byte_string_must_be_32_bytes_long() {
|
||||
let _seed = Seed::from(*b"this string is exactly 32 bytes!");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn seed_from_pem_works() {
|
||||
let payload: &str = "syl9wSYaruvgxg9P5Q1qkZaq5YkM6GvXkxe+VYrL/XM=";
|
||||
|
||||
// 32 bytes base64 encoded.
|
||||
let pem_string: &str = "-----BEGIN SEED-----
|
||||
syl9wSYaruvgxg9P5Q1qkZaq5YkM6GvXkxe+VYrL/XM=
|
||||
-----END SEED-----
|
||||
";
|
||||
|
||||
let want = base64::decode(payload).unwrap();
|
||||
let pem = pem::parse(pem_string).unwrap();
|
||||
let got = Seed::from_pem(pem).unwrap();
|
||||
|
||||
assert_eq!((got.0).bytes(), *want);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn seed_from_pem_fails_for_short_seed() {
|
||||
let short = "-----BEGIN SEED-----
|
||||
VnZUNFZ4dlY=
|
||||
-----END SEED-----
|
||||
";
|
||||
let pem = pem::parse(short).unwrap();
|
||||
match Seed::from_pem(pem) {
|
||||
Ok(_) => panic!("should fail for short payload"),
|
||||
Err(e) => {
|
||||
match e {
|
||||
Error::IncorrectLength(_) => {} // pass
|
||||
_ => panic!("should fail with IncorrectLength error"),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn seed_from_pem_fails_for_long_seed() {
|
||||
let long = "-----BEGIN SEED-----
|
||||
mbKANv2qKGmNVg1qtquj6Hx1pFPelpqOfE2JaJJAMEg1FlFhNRNlFlE=
|
||||
mbKANv2qKGmNVg1qtquj6Hx1pFPelpqOfE2JaJJAMEg1FlFhNRNlFlE=
|
||||
-----END SEED-----
|
||||
";
|
||||
let pem = pem::parse(long).unwrap();
|
||||
match Seed::from_pem(pem) {
|
||||
Ok(_) => panic!("should fail for long payload"),
|
||||
Err(e) => {
|
||||
match e {
|
||||
Error::IncorrectLength(_) => {} // pass
|
||||
_ => panic!("should fail with IncorrectLength error"),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn round_trip_through_file_write_read() {
|
||||
let tmpfile = temp_dir().join("seed.pem");
|
||||
|
||||
let seed = Seed::random().unwrap();
|
||||
seed.write_to(tmpfile.clone())
|
||||
.expect("Write seed to temp file");
|
||||
|
||||
let rinsed = Seed::from_file(tmpfile).expect("Read from temp file");
|
||||
assert_eq!(seed.0, rinsed.0);
|
||||
}
|
||||
}
|
14
swap/src/fs.rs
Normal file
14
swap/src/fs.rs
Normal file
@ -0,0 +1,14 @@
|
||||
use std::path::Path;
|
||||
|
||||
pub fn ensure_directory_exists(file: &Path) -> Result<(), std::io::Error> {
|
||||
if let Some(path) = file.parent() {
|
||||
if !path.exists() {
|
||||
tracing::info!(
|
||||
"Parent directory does not exist, creating recursively: {}",
|
||||
file.display()
|
||||
);
|
||||
return std::fs::create_dir_all(path);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
@ -23,9 +23,11 @@ pub mod bitcoin;
|
||||
pub mod cli;
|
||||
pub mod config;
|
||||
pub mod database;
|
||||
pub mod fs;
|
||||
pub mod monero;
|
||||
pub mod network;
|
||||
pub mod protocol;
|
||||
pub mod seed;
|
||||
pub mod trace;
|
||||
|
||||
pub type Never = std::convert::Infallible;
|
||||
|
@ -24,9 +24,10 @@ use swap::{
|
||||
cli::{Command, Options, Resume},
|
||||
config::Config,
|
||||
database::{Database, Swap},
|
||||
monero,
|
||||
monero, network,
|
||||
network::transport::build,
|
||||
protocol::{alice, alice::AliceState, bob, bob::BobState},
|
||||
seed::Seed,
|
||||
trace::init_tracing,
|
||||
SwapAmounts,
|
||||
};
|
||||
@ -41,12 +42,19 @@ async fn main() -> Result<()> {
|
||||
init_tracing(LevelFilter::Info).expect("initialize tracing");
|
||||
|
||||
let opt = Options::from_args();
|
||||
|
||||
let config = Config::testnet();
|
||||
|
||||
info!("Database: {}", opt.db_path);
|
||||
let db = Database::open(std::path::Path::new(opt.db_path.as_str()))
|
||||
.context("Could not open database")?;
|
||||
info!(
|
||||
"Database and Seed will be stored in directory: {}",
|
||||
opt.data_dir
|
||||
);
|
||||
let data_dir = std::path::Path::new(opt.data_dir.as_str()).to_path_buf();
|
||||
let db =
|
||||
Database::open(data_dir.join("database").as_path()).context("Could not open database")?;
|
||||
|
||||
let seed = swap::config::seed::Seed::from_file_or_generate(&data_dir)
|
||||
.expect("Could not retrieve/initialize seed")
|
||||
.into();
|
||||
|
||||
match opt.cmd {
|
||||
Command::SellXmr {
|
||||
@ -106,6 +114,7 @@ async fn main() -> Result<()> {
|
||||
monero_wallet,
|
||||
config,
|
||||
db,
|
||||
&seed,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
@ -201,6 +210,7 @@ async fn main() -> Result<()> {
|
||||
monero_wallet,
|
||||
config,
|
||||
db,
|
||||
&seed,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
@ -267,7 +277,7 @@ async fn setup_wallets(
|
||||
|
||||
Ok((bitcoin_wallet, monero_wallet))
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
async fn alice_swap(
|
||||
swap_id: Uuid,
|
||||
state: AliceState,
|
||||
@ -276,12 +286,11 @@ async fn alice_swap(
|
||||
monero_wallet: Arc<swap::monero::Wallet>,
|
||||
config: Config,
|
||||
db: Database,
|
||||
seed: &Seed,
|
||||
) -> Result<AliceState> {
|
||||
let alice_behaviour = alice::Behaviour::default();
|
||||
|
||||
let alice_behaviour = alice::Behaviour::new(network::Seed::new(seed.bytes()));
|
||||
let alice_peer_id = alice_behaviour.peer_id();
|
||||
info!("Own Peer-ID: {}", alice_peer_id);
|
||||
|
||||
let alice_transport = build(alice_behaviour.identity())?;
|
||||
|
||||
let (mut event_loop, handle) =
|
||||
|
@ -1,5 +1,7 @@
|
||||
use crate::seed::SEED_LENGTH;
|
||||
use bitcoin::hashes::{sha256, Hash, HashEngine};
|
||||
use futures::prelude::*;
|
||||
use libp2p::core::Executor;
|
||||
use libp2p::{core::Executor, identity::ed25519};
|
||||
use std::pin::Pin;
|
||||
use tokio::runtime::Handle;
|
||||
|
||||
@ -17,3 +19,35 @@ impl Executor for TokioExecutor {
|
||||
let _ = self.handle.spawn(future);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
||||
pub struct Seed([u8; SEED_LENGTH]);
|
||||
|
||||
impl Seed {
|
||||
/// prefix "NETWORK" to the provided seed and apply sha256
|
||||
pub fn new(seed: [u8; crate::seed::SEED_LENGTH]) -> Self {
|
||||
let mut engine = sha256::HashEngine::default();
|
||||
|
||||
engine.input(&seed);
|
||||
engine.input(b"NETWORK");
|
||||
|
||||
let hash = sha256::Hash::from_engine(engine);
|
||||
Self(hash.into_inner())
|
||||
}
|
||||
|
||||
pub fn bytes(&self) -> [u8; SEED_LENGTH] {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub fn derive_libp2p_identity(&self) -> libp2p::identity::Keypair {
|
||||
let mut engine = sha256::HashEngine::default();
|
||||
|
||||
engine.input(&self.bytes());
|
||||
engine.input(b"LIBP2P_IDENTITY");
|
||||
|
||||
let hash = sha256::Hash::from_engine(engine);
|
||||
let key =
|
||||
ed25519::SecretKey::from_bytes(hash.into_inner()).expect("we always pass 32 bytes");
|
||||
libp2p::identity::Keypair::Ed25519(key.into())
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ use crate::{
|
||||
peer_tracker::{self, PeerTracker},
|
||||
request_response::AliceToBob,
|
||||
transport::SwapTransport,
|
||||
TokioExecutor,
|
||||
Seed, TokioExecutor,
|
||||
},
|
||||
protocol::bob,
|
||||
SwapAmounts,
|
||||
@ -145,6 +145,20 @@ pub struct Behaviour {
|
||||
}
|
||||
|
||||
impl Behaviour {
|
||||
pub fn new(seed: Seed) -> Self {
|
||||
let identity = seed.derive_libp2p_identity();
|
||||
|
||||
Self {
|
||||
pt: PeerTracker::default(),
|
||||
amounts: Amounts::default(),
|
||||
message0: message0::Behaviour::default(),
|
||||
message1: message1::Behaviour::default(),
|
||||
message2: message2::Behaviour::default(),
|
||||
message3: message3::Behaviour::default(),
|
||||
identity,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn identity(&self) -> Keypair {
|
||||
self.identity.clone()
|
||||
}
|
||||
@ -178,19 +192,3 @@ impl Behaviour {
|
||||
debug!("Sent Message2");
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Behaviour {
|
||||
fn default() -> Self {
|
||||
let identity = Keypair::generate_ed25519();
|
||||
|
||||
Self {
|
||||
pt: PeerTracker::default(),
|
||||
amounts: Amounts::default(),
|
||||
message0: message0::Behaviour::default(),
|
||||
message1: message1::Behaviour::default(),
|
||||
message2: message2::Behaviour::default(),
|
||||
message3: message3::Behaviour::default(),
|
||||
identity,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
58
swap/src/seed.rs
Normal file
58
swap/src/seed.rs
Normal file
@ -0,0 +1,58 @@
|
||||
use ::bitcoin::secp256k1::{self, constants::SECRET_KEY_SIZE, SecretKey};
|
||||
use rand::prelude::*;
|
||||
use std::fmt;
|
||||
|
||||
pub const SEED_LENGTH: usize = 32;
|
||||
|
||||
#[derive(Clone, Copy, Eq, PartialEq)]
|
||||
pub struct Seed([u8; SEED_LENGTH]);
|
||||
|
||||
impl Seed {
|
||||
pub fn random() -> Result<Self, Error> {
|
||||
let mut bytes = [0u8; SECRET_KEY_SIZE];
|
||||
rand::thread_rng().fill_bytes(&mut bytes);
|
||||
|
||||
// If it succeeds once, it'll always succeed
|
||||
let _ = SecretKey::from_slice(&bytes)?;
|
||||
|
||||
Ok(Seed(bytes))
|
||||
}
|
||||
|
||||
pub fn bytes(&self) -> [u8; SEED_LENGTH] {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Seed {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "Seed([*****])")
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Seed {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{:?}", self)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<[u8; SEED_LENGTH]> for Seed {
|
||||
fn from(bytes: [u8; SEED_LENGTH]) -> Self {
|
||||
Seed(bytes)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, thiserror::Error)]
|
||||
pub enum Error {
|
||||
#[error("Secp256k1: ")]
|
||||
Secp256k1(#[from] secp256k1::Error),
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn generate_random_seed() {
|
||||
let _ = Seed::random().unwrap();
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@ use swap::{
|
||||
config::Config,
|
||||
monero,
|
||||
protocol::{alice, bob},
|
||||
seed::Seed,
|
||||
};
|
||||
use testcontainers::clients::Cli;
|
||||
use testutils::init_tracing;
|
||||
@ -65,6 +66,7 @@ async fn happy_path() {
|
||||
xmr_alice,
|
||||
alice_multiaddr.clone(),
|
||||
config,
|
||||
&Seed::random().unwrap(),
|
||||
)
|
||||
.await;
|
||||
|
||||
|
@ -8,6 +8,7 @@ use swap::{
|
||||
database::Database,
|
||||
monero,
|
||||
protocol::{alice, alice::AliceState, bob},
|
||||
seed::Seed,
|
||||
};
|
||||
use tempfile::tempdir;
|
||||
use testcontainers::clients::Cli;
|
||||
@ -42,6 +43,7 @@ async fn given_alice_restarts_after_encsig_is_learned_resume_swap() {
|
||||
|
||||
let config = Config::regtest();
|
||||
|
||||
let alice_seed = Seed::random().unwrap();
|
||||
let (
|
||||
start_state,
|
||||
mut alice_event_loop,
|
||||
@ -57,6 +59,7 @@ async fn given_alice_restarts_after_encsig_is_learned_resume_swap() {
|
||||
alice_xmr_starting_balance,
|
||||
alice_multiaddr.clone(),
|
||||
config,
|
||||
&alice_seed,
|
||||
)
|
||||
.await;
|
||||
|
||||
@ -125,7 +128,7 @@ async fn given_alice_restarts_after_encsig_is_learned_resume_swap() {
|
||||
};
|
||||
|
||||
let (mut event_loop_after_restart, event_loop_handle_after_restart) =
|
||||
testutils::init_alice_event_loop(alice_multiaddr);
|
||||
testutils::init_alice_event_loop(alice_multiaddr, &alice_seed);
|
||||
tokio::spawn(async move { event_loop_after_restart.run().await });
|
||||
|
||||
let alice_state = alice::swap::swap(
|
||||
|
@ -8,6 +8,7 @@ use swap::{
|
||||
database::Database,
|
||||
monero,
|
||||
protocol::{alice, bob, bob::BobState},
|
||||
seed::Seed,
|
||||
};
|
||||
use tempfile::tempdir;
|
||||
use testcontainers::clients::Cli;
|
||||
@ -57,6 +58,7 @@ async fn given_bob_restarts_after_encsig_is_sent_resume_swap() {
|
||||
alice_xmr_starting_balance,
|
||||
alice_multiaddr.clone(),
|
||||
config,
|
||||
&Seed::random().unwrap(),
|
||||
)
|
||||
.await;
|
||||
|
||||
|
@ -8,6 +8,7 @@ use swap::{
|
||||
database::Database,
|
||||
monero,
|
||||
protocol::{alice, alice::AliceState, bob, bob::BobState},
|
||||
seed::Seed,
|
||||
};
|
||||
use tempfile::tempdir;
|
||||
use testcontainers::clients::Cli;
|
||||
@ -59,6 +60,7 @@ async fn given_bob_restarts_after_xmr_is_locked_resume_swap() {
|
||||
alice_xmr_starting_balance,
|
||||
alice_multiaddr.clone(),
|
||||
Config::regtest(),
|
||||
&Seed::random().unwrap(),
|
||||
)
|
||||
.await;
|
||||
|
||||
|
@ -11,6 +11,7 @@ use swap::{
|
||||
config::Config,
|
||||
monero,
|
||||
protocol::{alice, alice::AliceState, bob, bob::BobState},
|
||||
seed::Seed,
|
||||
};
|
||||
use testcontainers::clients::Cli;
|
||||
use testutils::init_tracing;
|
||||
@ -63,6 +64,7 @@ async fn alice_punishes_if_bob_never_acts_after_fund() {
|
||||
alice_xmr_starting_balance,
|
||||
alice_multiaddr.clone(),
|
||||
config,
|
||||
&Seed::random().unwrap(),
|
||||
)
|
||||
.await;
|
||||
|
||||
|
@ -9,6 +9,7 @@ use swap::{
|
||||
database::Database,
|
||||
monero,
|
||||
protocol::{alice, alice::AliceState, bob, bob::BobState},
|
||||
seed::Seed,
|
||||
};
|
||||
use tempfile::tempdir;
|
||||
use testcontainers::clients::Cli;
|
||||
@ -47,6 +48,7 @@ async fn given_alice_restarts_after_xmr_is_locked_abort_swap() {
|
||||
.parse()
|
||||
.expect("failed to parse Alice's address");
|
||||
|
||||
let alice_seed = Seed::random().unwrap();
|
||||
let (
|
||||
alice_state,
|
||||
mut alice_event_loop_1,
|
||||
@ -62,6 +64,7 @@ async fn given_alice_restarts_after_xmr_is_locked_abort_swap() {
|
||||
alice_xmr_starting_balance,
|
||||
alice_multiaddr.clone(),
|
||||
Config::regtest(),
|
||||
&alice_seed,
|
||||
)
|
||||
.await;
|
||||
|
||||
@ -121,7 +124,7 @@ async fn given_alice_restarts_after_xmr_is_locked_abort_swap() {
|
||||
};
|
||||
|
||||
let (mut alice_event_loop_2, alice_event_loop_handle_2) =
|
||||
testutils::init_alice_event_loop(alice_multiaddr);
|
||||
testutils::init_alice_event_loop(alice_multiaddr, &alice_seed);
|
||||
|
||||
let alice_final_state = {
|
||||
let alice_db = Database::open(alice_db_datadir.path()).unwrap();
|
||||
|
@ -7,9 +7,10 @@ use swap::{
|
||||
bitcoin,
|
||||
config::Config,
|
||||
database::Database,
|
||||
monero,
|
||||
monero, network,
|
||||
network::transport::build,
|
||||
protocol::{alice, alice::AliceState, bob, bob::BobState},
|
||||
seed::Seed,
|
||||
SwapAmounts,
|
||||
};
|
||||
use tempfile::tempdir;
|
||||
@ -106,13 +107,13 @@ pub async fn init_alice_state(
|
||||
|
||||
pub fn init_alice_event_loop(
|
||||
listen: Multiaddr,
|
||||
seed: &Seed,
|
||||
) -> (
|
||||
alice::event_loop::EventLoop,
|
||||
alice::event_loop::EventLoopHandle,
|
||||
) {
|
||||
let alice_behaviour = alice::Behaviour::default();
|
||||
let alice_behaviour = alice::Behaviour::new(network::Seed::new(seed.bytes()));
|
||||
let alice_transport = build(alice_behaviour.identity()).unwrap();
|
||||
|
||||
alice::event_loop::EventLoop::new(alice_transport, alice_behaviour, listen).unwrap()
|
||||
}
|
||||
|
||||
@ -125,6 +126,7 @@ pub async fn init_alice(
|
||||
xmr_starting_balance: monero::Amount,
|
||||
listen: Multiaddr,
|
||||
config: Config,
|
||||
seed: &Seed,
|
||||
) -> (
|
||||
AliceState,
|
||||
alice::event_loop::EventLoop,
|
||||
@ -146,7 +148,7 @@ pub async fn init_alice(
|
||||
let alice_start_state =
|
||||
init_alice_state(btc_to_swap, xmr_to_swap, alice_btc_wallet.clone(), config).await;
|
||||
|
||||
let (event_loop, event_loop_handle) = init_alice_event_loop(listen);
|
||||
let (event_loop, event_loop_handle) = init_alice_event_loop(listen, seed);
|
||||
|
||||
let alice_db_datadir = tempdir().unwrap();
|
||||
let alice_db = Database::open(alice_db_datadir.path()).unwrap();
|
||||
|
Loading…
x
Reference in New Issue
Block a user