127: Deterministic peer id for alice and bob r=da-kami a=da-kami

The first commit introduces a seed file similar to Nectar. Note, that the parameter --database was changed to --data-dir where the database is stored in the sub-folder database inside that data directory. This is breaking change, run commands will have to be adapted.
I opted for keeping the structure of generating an overall seed and then deriving the network seed from it (as in Nectar, where we use the seed for wallet creation as well). I feel this is cleaner than just using the seed for the network only.

The second commit applies the deterministic peer id to Bob as well. We don't have to do this because in the current setup Bob can have a new identity every time. I would still harmonize this to avoid confusion in the future. I don't see a reason why Bob's setup should be different from Alice here.

Co-authored-by: Daniel Karzel <daniel@comit.network>
This commit is contained in:
bors[bot] 2021-01-11 03:07:11 +00:00 committed by GitHub
commit 485220929e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 439 additions and 38 deletions

14
Cargo.lock generated
View File

@ -1945,6 +1945,8 @@ dependencies = [
"testcontainers", "testcontainers",
"tokio", "tokio",
"tracing", "tracing",
"tracing-log",
"tracing-subscriber",
"url", "url",
] ]
@ -2212,6 +2214,17 @@ dependencies = [
"winapi 0.3.9", "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]] [[package]]
name = "percent-encoding" name = "percent-encoding"
version = "2.1.0" version = "2.1.0"
@ -3293,6 +3306,7 @@ dependencies = [
"miniscript", "miniscript",
"monero", "monero",
"monero-harness", "monero-harness",
"pem",
"port_check", "port_check",
"prettytable-rs", "prettytable-rs",
"rand 0.7.3", "rand 0.7.3",

View File

@ -17,4 +17,6 @@ spectral = "0.6"
testcontainers = "0.11" testcontainers = "0.11"
tokio = { version = "0.2", default-features = false, features = ["blocking", "macros", "rt-core", "time"] } tokio = { version = "0.2", default-features = false, features = ["blocking", "macros", "rt-core", "time"] }
tracing = "0.1" tracing = "0.1"
tracing-log = "0.1"
tracing-subscriber = { version = "0.2", default-features = false, features = ["fmt", "ansi", "env-filter"] }
url = "2" url = "2"

View File

@ -1,11 +1,16 @@
use crate::testutils::init_tracing;
use monero_harness::Monero; use monero_harness::Monero;
use spectral::prelude::*; use spectral::prelude::*;
use std::time::Duration; use std::time::Duration;
use testcontainers::clients::Cli; use testcontainers::clients::Cli;
use tokio::time; use tokio::time;
mod testutils;
#[tokio::test] #[tokio::test]
async fn init_miner_and_mine_to_miner_address() { async fn init_miner_and_mine_to_miner_address() {
let _guard = init_tracing();
let tc = Cli::default(); let tc = Cli::default();
let (monero, _monerod_container) = Monero::new(&tc, None, vec![]).await.unwrap(); let (monero, _monerod_container) = Monero::new(&tc, None, vec![]).await.unwrap();

View File

@ -0,0 +1,27 @@
use tracing::subscriber::DefaultGuard;
use tracing_log::LogTracer;
/// Utility function to initialize logging in the test environment.
/// Note that you have to keep the `_guard` in scope after calling in test:
///
/// ```rust
/// let _guard = init_tracing();
/// ```
pub fn init_tracing() -> DefaultGuard {
// converts all log records into tracing events
// Note: Make sure to initialize without unwrapping, otherwise this causes
// trouble when running multiple tests.
let _ = LogTracer::init();
let global_filter = tracing::Level::WARN;
let test_filter = tracing::Level::DEBUG;
let monero_harness_filter = tracing::Level::INFO;
use tracing_subscriber::util::SubscriberInitExt as _;
tracing_subscriber::fmt()
.with_env_filter(format!(
"{},test={},monero_harness={}",
global_filter, test_filter, monero_harness_filter,
))
.set_default()
}

View File

@ -1,9 +1,14 @@
use crate::testutils::init_tracing;
use monero_harness::Monero; use monero_harness::Monero;
use spectral::prelude::*; use spectral::prelude::*;
use testcontainers::clients::Cli; use testcontainers::clients::Cli;
mod testutils;
#[tokio::test] #[tokio::test]
async fn fund_transfer_and_check_tx_key() { async fn fund_transfer_and_check_tx_key() {
let _guard = init_tracing();
let fund_alice: u64 = 1_000_000_000_000; let fund_alice: u64 = 1_000_000_000_000;
let fund_bob = 0; let fund_bob = 0;
let send_to_bob = 5_000_000_000; let send_to_bob = 5_000_000_000;

View File

@ -27,6 +27,7 @@ log = { version = "0.4", features = ["serde"] }
miniscript = { version = "4", features = ["serde"] } miniscript = { version = "4", features = ["serde"] }
monero = { version = "0.9", features = ["serde_support"] } monero = { version = "0.9", features = ["serde_support"] }
monero-harness = { path = "../monero-harness" } monero-harness = { path = "../monero-harness" }
pem = "0.8"
prettytable-rs = "0.8" prettytable-rs = "0.8"
rand = "0.7" rand = "0.7"
reqwest = { version = "0.10", default-features = false, features = ["socks"] } reqwest = { version = "0.10", default-features = false, features = ["socks"] }

View File

@ -7,8 +7,8 @@ use crate::{bitcoin, monero};
#[derive(structopt::StructOpt, Debug)] #[derive(structopt::StructOpt, Debug)]
pub struct Options { pub struct Options {
// TODO: Default value should points to proper configuration folder in home folder // TODO: Default value should points to proper configuration folder in home folder
#[structopt(long = "database", default_value = "./.swap-db/")] #[structopt(long = "data-dir", default_value = "./.swap-data/")]
pub db_path: String, pub data_dir: String,
#[structopt(subcommand)] #[structopt(subcommand)]
pub cmd: Command, pub cmd: Command,

View File

@ -1,3 +1,5 @@
pub mod seed;
use crate::bitcoin::Timelock; use crate::bitcoin::Timelock;
use conquer_once::Lazy; use conquer_once::Lazy;
use std::time::Duration; use std::time::Duration;

196
swap/src/config/seed.rs Normal file
View 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
View 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(())
}

View File

@ -23,9 +23,11 @@ pub mod bitcoin;
pub mod cli; pub mod cli;
pub mod config; pub mod config;
pub mod database; pub mod database;
pub mod fs;
pub mod monero; pub mod monero;
pub mod network; pub mod network;
pub mod protocol; pub mod protocol;
pub mod seed;
pub mod trace; pub mod trace;
pub type Never = std::convert::Infallible; pub type Never = std::convert::Infallible;

View File

@ -24,9 +24,10 @@ use swap::{
cli::{Command, Options, Resume}, cli::{Command, Options, Resume},
config::Config, config::Config,
database::{Database, Swap}, database::{Database, Swap},
monero, monero, network,
network::transport::build, network::transport::build,
protocol::{alice, alice::AliceState, bob, bob::BobState}, protocol::{alice, alice::AliceState, bob, bob::BobState},
seed::Seed,
trace::init_tracing, trace::init_tracing,
SwapAmounts, SwapAmounts,
}; };
@ -41,12 +42,19 @@ async fn main() -> Result<()> {
init_tracing(LevelFilter::Info).expect("initialize tracing"); init_tracing(LevelFilter::Info).expect("initialize tracing");
let opt = Options::from_args(); let opt = Options::from_args();
let config = Config::testnet(); let config = Config::testnet();
info!("Database: {}", opt.db_path); info!(
let db = Database::open(std::path::Path::new(opt.db_path.as_str())) "Database and Seed will be stored in directory: {}",
.context("Could not open database")?; 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 { match opt.cmd {
Command::SellXmr { Command::SellXmr {
@ -106,6 +114,7 @@ async fn main() -> Result<()> {
monero_wallet, monero_wallet,
config, config,
db, db,
seed,
) )
.await?; .await?;
} }
@ -158,6 +167,7 @@ async fn main() -> Result<()> {
db, db,
alice_peer_id, alice_peer_id,
alice_addr, alice_addr,
seed,
) )
.await?; .await?;
} }
@ -201,6 +211,7 @@ async fn main() -> Result<()> {
monero_wallet, monero_wallet,
config, config,
db, db,
seed,
) )
.await?; .await?;
} }
@ -233,6 +244,7 @@ async fn main() -> Result<()> {
db, db,
alice_peer_id, alice_peer_id,
alice_addr, alice_addr,
seed,
) )
.await?; .await?;
} }
@ -267,7 +279,7 @@ async fn setup_wallets(
Ok((bitcoin_wallet, monero_wallet)) Ok((bitcoin_wallet, monero_wallet))
} }
#[allow(clippy::too_many_arguments)]
async fn alice_swap( async fn alice_swap(
swap_id: Uuid, swap_id: Uuid,
state: AliceState, state: AliceState,
@ -276,12 +288,11 @@ async fn alice_swap(
monero_wallet: Arc<swap::monero::Wallet>, monero_wallet: Arc<swap::monero::Wallet>,
config: Config, config: Config,
db: Database, db: Database,
seed: Seed,
) -> Result<AliceState> { ) -> Result<AliceState> {
let alice_behaviour = alice::Behaviour::default(); let alice_behaviour = alice::Behaviour::new(network::Seed::new(seed));
let alice_peer_id = alice_behaviour.peer_id(); let alice_peer_id = alice_behaviour.peer_id();
info!("Own Peer-ID: {}", alice_peer_id); info!("Own Peer-ID: {}", alice_peer_id);
let alice_transport = build(alice_behaviour.identity())?; let alice_transport = build(alice_behaviour.identity())?;
let (mut event_loop, handle) = let (mut event_loop, handle) =
@ -310,8 +321,9 @@ async fn bob_swap(
db: Database, db: Database,
alice_peer_id: PeerId, alice_peer_id: PeerId,
alice_addr: Multiaddr, alice_addr: Multiaddr,
seed: Seed,
) -> Result<BobState> { ) -> Result<BobState> {
let bob_behaviour = bob::Behaviour::default(); let bob_behaviour = bob::Behaviour::new(network::Seed::new(seed));
let bob_transport = build(bob_behaviour.identity())?; let bob_transport = build(bob_behaviour.identity())?;
let (event_loop, handle) = let (event_loop, handle) =

View File

@ -1,5 +1,7 @@
use crate::seed::SEED_LENGTH;
use bitcoin::hashes::{sha256, Hash, HashEngine};
use futures::prelude::*; use futures::prelude::*;
use libp2p::core::Executor; use libp2p::{core::Executor, identity::ed25519};
use std::pin::Pin; use std::pin::Pin;
use tokio::runtime::Handle; use tokio::runtime::Handle;
@ -17,3 +19,35 @@ impl Executor for TokioExecutor {
let _ = self.handle.spawn(future); 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: crate::seed::Seed) -> Self {
let mut engine = sha256::HashEngine::default();
engine.input(&seed.bytes());
engine.input(b"NETWORK");
let hash = sha256::Hash::from_engine(engine);
Self(hash.into_inner())
}
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())
}
}

View File

@ -13,7 +13,7 @@ use crate::{
peer_tracker::{self, PeerTracker}, peer_tracker::{self, PeerTracker},
request_response::AliceToBob, request_response::AliceToBob,
transport::SwapTransport, transport::SwapTransport,
TokioExecutor, Seed, TokioExecutor,
}, },
protocol::bob, protocol::bob,
SwapAmounts, SwapAmounts,
@ -145,6 +145,20 @@ pub struct Behaviour {
} }
impl 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 { pub fn identity(&self) -> Keypair {
self.identity.clone() self.identity.clone()
} }
@ -178,19 +192,3 @@ impl Behaviour {
debug!("Sent Message2"); 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,
}
}
}

View File

@ -12,7 +12,7 @@ use crate::{
network::{ network::{
peer_tracker::{self, PeerTracker}, peer_tracker::{self, PeerTracker},
transport::SwapTransport, transport::SwapTransport,
TokioExecutor, Seed, TokioExecutor,
}, },
protocol::{alice, bob}, protocol::{alice, bob},
SwapAmounts, SwapAmounts,
@ -124,6 +124,20 @@ pub struct Behaviour {
} }
impl 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 { pub fn identity(&self) -> Keypair {
self.identity.clone() self.identity.clone()
} }

58
swap/src/seed.rs Normal file
View 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();
}
}

View File

@ -11,6 +11,7 @@ use swap::{
config::Config, config::Config,
monero, monero,
protocol::{alice, bob}, protocol::{alice, bob},
seed::Seed,
}; };
use testcontainers::clients::Cli; use testcontainers::clients::Cli;
use testutils::init_tracing; use testutils::init_tracing;
@ -65,6 +66,7 @@ async fn happy_path() {
xmr_alice, xmr_alice,
alice_multiaddr.clone(), alice_multiaddr.clone(),
config, config,
Seed::random().unwrap(),
) )
.await; .await;

View File

@ -8,6 +8,7 @@ use swap::{
database::Database, database::Database,
monero, monero,
protocol::{alice, alice::AliceState, bob}, protocol::{alice, alice::AliceState, bob},
seed::Seed,
}; };
use tempfile::tempdir; use tempfile::tempdir;
use testcontainers::clients::Cli; use testcontainers::clients::Cli;
@ -42,6 +43,7 @@ async fn given_alice_restarts_after_encsig_is_learned_resume_swap() {
let config = Config::regtest(); let config = Config::regtest();
let alice_seed = Seed::random().unwrap();
let ( let (
start_state, start_state,
mut alice_event_loop, mut alice_event_loop,
@ -57,6 +59,7 @@ async fn given_alice_restarts_after_encsig_is_learned_resume_swap() {
alice_xmr_starting_balance, alice_xmr_starting_balance,
alice_multiaddr.clone(), alice_multiaddr.clone(),
config, config,
alice_seed,
) )
.await; .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) = 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 }); tokio::spawn(async move { event_loop_after_restart.run().await });
let alice_state = alice::swap::swap( let alice_state = alice::swap::swap(

View File

@ -8,6 +8,7 @@ use swap::{
database::Database, database::Database,
monero, monero,
protocol::{alice, bob, bob::BobState}, protocol::{alice, bob, bob::BobState},
seed::Seed,
}; };
use tempfile::tempdir; use tempfile::tempdir;
use testcontainers::clients::Cli; use testcontainers::clients::Cli;
@ -57,6 +58,7 @@ async fn given_bob_restarts_after_encsig_is_sent_resume_swap() {
alice_xmr_starting_balance, alice_xmr_starting_balance,
alice_multiaddr.clone(), alice_multiaddr.clone(),
config, config,
Seed::random().unwrap(),
) )
.await; .await;

View File

@ -8,6 +8,7 @@ use swap::{
database::Database, database::Database,
monero, monero,
protocol::{alice, alice::AliceState, bob, bob::BobState}, protocol::{alice, alice::AliceState, bob, bob::BobState},
seed::Seed,
}; };
use tempfile::tempdir; use tempfile::tempdir;
use testcontainers::clients::Cli; use testcontainers::clients::Cli;
@ -59,6 +60,7 @@ async fn given_bob_restarts_after_xmr_is_locked_resume_swap() {
alice_xmr_starting_balance, alice_xmr_starting_balance,
alice_multiaddr.clone(), alice_multiaddr.clone(),
Config::regtest(), Config::regtest(),
Seed::random().unwrap(),
) )
.await; .await;

View File

@ -11,6 +11,7 @@ use swap::{
config::Config, config::Config,
monero, monero,
protocol::{alice, alice::AliceState, bob, bob::BobState}, protocol::{alice, alice::AliceState, bob, bob::BobState},
seed::Seed,
}; };
use testcontainers::clients::Cli; use testcontainers::clients::Cli;
use testutils::init_tracing; use testutils::init_tracing;
@ -63,6 +64,7 @@ async fn alice_punishes_if_bob_never_acts_after_fund() {
alice_xmr_starting_balance, alice_xmr_starting_balance,
alice_multiaddr.clone(), alice_multiaddr.clone(),
config, config,
Seed::random().unwrap(),
) )
.await; .await;

View File

@ -9,6 +9,7 @@ use swap::{
database::Database, database::Database,
monero, monero,
protocol::{alice, alice::AliceState, bob, bob::BobState}, protocol::{alice, alice::AliceState, bob, bob::BobState},
seed::Seed,
}; };
use tempfile::tempdir; use tempfile::tempdir;
use testcontainers::clients::Cli; use testcontainers::clients::Cli;
@ -47,6 +48,7 @@ async fn given_alice_restarts_after_xmr_is_locked_abort_swap() {
.parse() .parse()
.expect("failed to parse Alice's address"); .expect("failed to parse Alice's address");
let alice_seed = Seed::random().unwrap();
let ( let (
alice_state, alice_state,
mut alice_event_loop_1, 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_xmr_starting_balance,
alice_multiaddr.clone(), alice_multiaddr.clone(),
Config::regtest(), Config::regtest(),
alice_seed,
) )
.await; .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) = 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_final_state = {
let alice_db = Database::open(alice_db_datadir.path()).unwrap(); let alice_db = Database::open(alice_db_datadir.path()).unwrap();

View File

@ -7,9 +7,10 @@ use swap::{
bitcoin, bitcoin,
config::Config, config::Config,
database::Database, database::Database,
monero, monero, network,
network::transport::build, network::transport::build,
protocol::{alice, alice::AliceState, bob, bob::BobState}, protocol::{alice, alice::AliceState, bob, bob::BobState},
seed::Seed,
SwapAmounts, SwapAmounts,
}; };
use tempfile::tempdir; use tempfile::tempdir;
@ -106,13 +107,13 @@ pub async fn init_alice_state(
pub fn init_alice_event_loop( pub fn init_alice_event_loop(
listen: Multiaddr, listen: Multiaddr,
seed: Seed,
) -> ( ) -> (
alice::event_loop::EventLoop, alice::event_loop::EventLoop,
alice::event_loop::EventLoopHandle, alice::event_loop::EventLoopHandle,
) { ) {
let alice_behaviour = alice::Behaviour::default(); let alice_behaviour = alice::Behaviour::new(network::Seed::new(seed));
let alice_transport = build(alice_behaviour.identity()).unwrap(); let alice_transport = build(alice_behaviour.identity()).unwrap();
alice::event_loop::EventLoop::new(alice_transport, alice_behaviour, listen).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, xmr_starting_balance: monero::Amount,
listen: Multiaddr, listen: Multiaddr,
config: Config, config: Config,
seed: Seed,
) -> ( ) -> (
AliceState, AliceState,
alice::event_loop::EventLoop, alice::event_loop::EventLoop,
@ -146,7 +148,7 @@ pub async fn init_alice(
let alice_start_state = let alice_start_state =
init_alice_state(btc_to_swap, xmr_to_swap, alice_btc_wallet.clone(), config).await; 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_datadir = tempdir().unwrap();
let alice_db = Database::open(alice_db_datadir.path()).unwrap(); let alice_db = Database::open(alice_db_datadir.path()).unwrap();
@ -190,7 +192,8 @@ pub fn init_bob_event_loop(
alice_peer_id: PeerId, alice_peer_id: PeerId,
alice_addr: Multiaddr, alice_addr: Multiaddr,
) -> (bob::event_loop::EventLoop, bob::event_loop::EventLoopHandle) { ) -> (bob::event_loop::EventLoop, bob::event_loop::EventLoopHandle) {
let bob_behaviour = bob::Behaviour::default(); let seed = Seed::random().unwrap();
let bob_behaviour = bob::Behaviour::new(network::Seed::new(seed));
let bob_transport = build(bob_behaviour.identity()).unwrap(); let bob_transport = build(bob_behaviour.identity()).unwrap();
bob::event_loop::EventLoop::new(bob_transport, bob_behaviour, alice_peer_id, alice_addr) bob::event_loop::EventLoop::new(bob_transport, bob_behaviour, alice_peer_id, alice_addr)
.unwrap() .unwrap()