@ -2,17 +2,14 @@ use crate::testutils;
use bitcoin_harness ::Bitcoind ;
use bitcoin_harness ::Bitcoind ;
use futures ::Future ;
use futures ::Future ;
use get_port ::get_port ;
use get_port ::get_port ;
use libp2p ::{ core ::Multiaddr , PeerId } ;
use libp2p ::core ::Multiaddr ;
use monero_harness ::{ image , Monero } ;
use monero_harness ::{ image , Monero } ;
use rand ::rngs ::OsRng ;
use std ::sync ::Arc ;
use std ::{ path ::PathBuf , sync ::Arc } ;
use swap ::{
use swap ::{
bitcoin ,
bitcoin ,
config ::Config ,
config ::Config ,
database ::Database ,
monero ,
monero , network ,
protocol ::{ alice , alice ::AliceState , bob , bob ::BobState , StartingBalances } ,
network ::transport ::build ,
protocol ::{ alice , alice ::AliceState , bob , bob ::BobState } ,
seed ::Seed ,
seed ::Seed ,
SwapAmounts ,
SwapAmounts ,
} ;
} ;
@ -22,347 +19,150 @@ use tracing_core::dispatcher::DefaultGuard;
use tracing_log ::LogTracer ;
use tracing_log ::LogTracer ;
use uuid ::Uuid ;
use uuid ::Uuid ;
pub async fn test < T , F > ( testfn : T )
pub struct TestContext {
where
swap_amounts : SwapAmounts ,
T : Fn ( AliceHarness , BobHarness ) -> F ,
F : Future < Output = ( ) > ,
{
let cli = Cli ::default ( ) ;
let _guard = init_tracing ( ) ;
let ( monero , containers ) = testutils ::init_containers ( & cli ) . await ;
let swap_amounts = SwapAmounts {
btc : bitcoin ::Amount ::from_sat ( 1_000_000 ) ,
xmr : monero ::Amount ::from_piconero ( 1_000_000_000_000 ) ,
} ;
let config = Config ::regtest ( ) ;
let alice_starting_balances = StartingBalances {
xmr : swap_amounts . xmr * 10 ,
btc : bitcoin ::Amount ::ZERO ,
} ;
let alice_harness = AliceHarness ::new (
config ,
swap_amounts ,
Uuid ::new_v4 ( ) ,
& monero ,
& containers . bitcoind ,
alice_starting_balances ,
)
. await ;
let bob_starting_balances = StartingBalances {
xmr : monero ::Amount ::ZERO ,
btc : swap_amounts . btc * 10 ,
} ;
let bob_harness = BobHarness ::new (
config ,
swap_amounts ,
Uuid ::new_v4 ( ) ,
& monero ,
& containers . bitcoind ,
bob_starting_balances ,
alice_harness . listen_address ( ) ,
alice_harness . peer_id ( ) ,
)
. await ;
testfn ( alice_harness , bob_harness ) . await
}
pub struct Alice {
alice_swap_factory : alice ::SwapFactory ,
pub state : AliceState ,
bob_swap_factory : bob ::SwapFactory ,
pub event_loop_handle : alice ::EventLoopHandle ,
pub bitcoin_wallet : Arc < bitcoin ::Wallet > ,
pub monero_wallet : Arc < monero ::Wallet > ,
pub config : Config ,
pub swap_id : Uuid ,
pub db : Database ,
}
}
pub struct AliceHarness {
impl TestContext {
listen_address : Multiaddr ,
pub async fn new_swap_as_alice ( & self ) -> alice ::Swap {
peer_id : PeerId ,
let ( swap , mut event_loop ) = self
. alice_swap_factory
seed : Seed ,
. new_swap_as_alice ( self . swap_amounts )
db_path : PathBuf ,
. await
swap_id : Uuid ,
. unwrap ( ) ;
swap_amounts : SwapAmounts ,
tokio ::spawn ( async move { event_loop . run ( ) . await } ) ;
bitcoin_wallet : Arc < bitcoin ::Wallet > ,
monero_wallet : Arc < monero ::Wallet > ,
config : Config ,
starting_balances : StartingBalances ,
}
impl AliceHarness {
swap
async fn new (
config : Config ,
swap_amounts : SwapAmounts ,
swap_id : Uuid ,
monero : & Monero ,
bitcoind : & Bitcoind < ' _ > ,
starting_balances : StartingBalances ,
) -> Self {
let port = get_port ( ) . expect ( "Failed to find a free port" ) ;
let listen_address : Multiaddr = format! ( "/ip4/127.0.0.1/tcp/{}" , port )
. parse ( )
. expect ( "failed to parse Alice's address" ) ;
let seed = Seed ::random ( ) . unwrap ( ) ;
let db_path = tempdir ( ) . unwrap ( ) . path ( ) . to_path_buf ( ) ;
let ( bitcoin_wallet , monero_wallet ) =
init_wallets ( "alice" , bitcoind , monero , starting_balances . clone ( ) , config ) . await ;
// TODO: This should be done by changing the production code
let network_seed = network ::Seed ::new ( seed ) ;
let identity = network_seed . derive_libp2p_identity ( ) ;
let peer_id = PeerId ::from ( identity . public ( ) ) ;
Self {
seed ,
db_path ,
listen_address ,
peer_id ,
swap_id ,
swap_amounts ,
bitcoin_wallet ,
monero_wallet ,
config ,
starting_balances ,
}
}
}
pub async fn new_alice ( & self ) -> Alice {
pub async fn new_swap_as_bob ( & self ) -> bob ::Swap {
let initial_state = init_alice_state (
let ( swap , event_loop ) = self
self . swap_amounts . btc ,
. bob_swap_factory
self . swap_amounts . xmr ,
. new_swap_as_bob ( self . swap_amounts )
self . bitcoin_wallet . clone ( ) ,
. await
self . config ,
. unwrap ( ) ;
)
. await ;
let ( mut event_loop , event_loop_handle ) =
init_alice_event_loop ( self . listen_address . clone ( ) , self . seed ) ;
tokio ::spawn ( async move { event_loop . run ( ) . await } ) ;
tokio ::spawn ( async move { event_loop . run ( ) . await } ) ;
let db = Database ::open ( self . db_path . as_path ( ) ) . unwrap ( ) ;
swap
Alice {
event_loop_handle ,
bitcoin_wallet : self . bitcoin_wallet . clone ( ) ,
monero_wallet : self . monero_wallet . clone ( ) ,
config : self . config ,
db ,
state : initial_state ,
swap_id : self . swap_id ,
}
}
}
pub async fn recover_alice_from_db ( & self ) -> Alice {
pub async fn recover_alice_from_db ( & self ) -> alice ::Swap {
// TODO: "simulated restart" issues:
let ( swap , mut event_loop ) = self
// - create new wallets instead of reusing (hard because of container
. alice_swap_factory
// lifetimes)
. recover_alice_from_db ( )
// - consider aborting the old event loop (currently just keeps running)
. await
. unwrap ( ) ;
// reopen the existing database
tokio ::spawn ( async move { event_loop . run ( ) . await } ) ;
let db = Database ::open ( self . db_path . clone ( ) . as_path ( ) ) . unwrap ( ) ;
let resume_state =
swap
if let swap ::database ::Swap ::Alice ( state ) = db . get_state ( self . swap_id ) . unwrap ( ) {
}
state . into ( )
} else {
unreachable! ( )
} ;
let ( mut event_loop , event_loop_handle ) =
pub async fn recover_bob_from_db ( & self ) -> bob ::Swap {
init_alice_event_loop ( self . listen_address . clone ( ) , self . seed ) ;
let ( swap , event_loop ) = self . bob_swap_factory . recover_bob_from_db ( ) . await . unwrap ( ) ;
tokio ::spawn ( async move { event_loop . run ( ) . await } ) ;
tokio ::spawn ( async move { event_loop . run ( ) . await } ) ;
Alice {
swap
state : resume_state ,
event_loop_handle ,
bitcoin_wallet : self . bitcoin_wallet . clone ( ) ,
monero_wallet : self . monero_wallet . clone ( ) ,
config : self . config ,
swap_id : self . swap_id ,
db ,
}
}
}
pub async fn assert_ redeemed( & self , state : AliceState ) {
pub async fn assert_alice_redeemed ( & self , state : AliceState ) {
assert! ( matches! ( state , AliceState ::BtcRedeemed ) ) ;
assert! ( matches! ( state , AliceState ::BtcRedeemed ) ) ;
let btc_balance_after_swap = self . bitcoin_wallet . as_ref ( ) . balance ( ) . await . unwrap ( ) ;
let btc_balance_after_swap = self
. alice_swap_factory
. bitcoin_wallet
. as_ref ( )
. balance ( )
. await
. unwrap ( ) ;
assert_eq! (
assert_eq! (
btc_balance_after_swap ,
btc_balance_after_swap ,
self . starting_balances . btc + self . swap_amounts . btc
self . alice_swap_factory. starting_balances. btc + self . swap_amounts . btc
- bitcoin ::Amount ::from_sat ( bitcoin ::TX_FEE )
- bitcoin ::Amount ::from_sat ( bitcoin ::TX_FEE )
) ;
) ;
let xmr_balance_after_swap = self . monero_wallet . as_ref ( ) . get_balance ( ) . await . unwrap ( ) ;
let xmr_balance_after_swap = self
assert! ( xmr_balance_after_swap < = self . starting_balances . xmr - self . swap_amounts . xmr ) ;
. alice_swap_factory
. monero_wallet
. as_ref ( )
. get_balance ( )
. await
. unwrap ( ) ;
assert! (
xmr_balance_after_swap
< = self . alice_swap_factory . starting_balances . xmr - self . swap_amounts . xmr
) ;
}
}
pub async fn assert_refunded ( & self , state : AliceState ) {
pub async fn assert_ alice_ refunded( & self , state : AliceState ) {
assert! ( matches! ( state , AliceState ::XmrRefunded ) ) ;
assert! ( matches! ( state , AliceState ::XmrRefunded ) ) ;
let btc_balance_after_swap = self . bitcoin_wallet . as_ref ( ) . balance ( ) . await . unwrap ( ) ;
let btc_balance_after_swap = self
assert_eq! ( btc_balance_after_swap , self . starting_balances . btc ) ;
. alice_swap_factory
. bitcoin_wallet
. as_ref ( )
. balance ( )
. await
. unwrap ( ) ;
assert_eq! (
btc_balance_after_swap ,
self . alice_swap_factory . starting_balances . btc
) ;
// Ensure that Alice's balance is refreshed as we use a newly created wallet
// Ensure that Alice's balance is refreshed as we use a newly created wallet
self . monero_wallet . as_ref ( ) . inner . refresh ( ) . await . unwrap ( ) ;
self . alice_swap_factory
let xmr_balance_after_swap = self . monero_wallet . as_ref ( ) . get_balance ( ) . await . unwrap ( ) ;
. monero_wallet
. as_ref ( )
. inner
. refresh ( )
. await
. unwrap ( ) ;
let xmr_balance_after_swap = self
. alice_swap_factory
. monero_wallet
. as_ref ( )
. get_balance ( )
. await
. unwrap ( ) ;
assert_eq! ( xmr_balance_after_swap , self . swap_amounts . xmr ) ;
assert_eq! ( xmr_balance_after_swap , self . swap_amounts . xmr ) ;
}
}
pub async fn assert_punished ( & self , state : AliceState ) {
pub async fn assert_ alice_ punished( & self , state : AliceState ) {
assert! ( matches! ( state , AliceState ::BtcPunished ) ) ;
assert! ( matches! ( state , AliceState ::BtcPunished ) ) ;
let btc_balance_after_swap = self . bitcoin_wallet . as_ref ( ) . balance ( ) . await . unwrap ( ) ;
let btc_balance_after_swap = self
. alice_swap_factory
. bitcoin_wallet
. as_ref ( )
. balance ( )
. await
. unwrap ( ) ;
assert_eq! (
assert_eq! (
btc_balance_after_swap ,
btc_balance_after_swap ,
self . starting_balances . btc + self . swap_amounts . btc
self . alice_swap_factory. starting_balances. btc + self . swap_amounts . btc
- bitcoin ::Amount ::from_sat ( 2 * bitcoin ::TX_FEE )
- bitcoin ::Amount ::from_sat ( 2 * bitcoin ::TX_FEE )
) ;
) ;
let xnr_balance_after_swap = self . monero_wallet . as_ref ( ) . get_balance ( ) . await . unwrap ( ) ;
let xmr_balance_after_swap = self
assert! ( xnr_balance_after_swap < = self . starting_balances . xmr - self . swap_amounts . xmr ) ;
. alice_swap_factory
}
. monero_wallet
. as_ref ( )
pub fn peer_id ( & self ) -> PeerId {
. get_balance ( )
self . peer_id . clone ( )
. await
}
. unwrap ( ) ;
assert! (
pub fn listen_address ( & self ) -> Multiaddr {
xmr_balance_after_swap
self . listen_address . clone ( )
< = self . alice_swap_factory . starting_balances . xmr - self . swap_amounts . xmr
}
}
pub struct Bob {
pub state : BobState ,
pub event_loop_handle : bob ::EventLoopHandle ,
pub db : Database ,
pub bitcoin_wallet : Arc < bitcoin ::Wallet > ,
pub monero_wallet : Arc < monero ::Wallet > ,
pub swap_id : Uuid ,
}
pub struct BobHarness {
db_path : PathBuf ,
swap_id : Uuid ,
swap_amounts : SwapAmounts ,
bitcoin_wallet : Arc < bitcoin ::Wallet > ,
monero_wallet : Arc < monero ::Wallet > ,
config : Config ,
starting_balances : StartingBalances ,
alice_connect_address : Multiaddr ,
alice_connect_peer_id : PeerId ,
}
impl BobHarness {
#[ allow(clippy::too_many_arguments) ]
async fn new (
config : Config ,
swap_amounts : SwapAmounts ,
swap_id : Uuid ,
monero : & Monero ,
bitcoind : & Bitcoind < ' _ > ,
starting_balances : StartingBalances ,
alice_connect_address : Multiaddr ,
alice_connect_peer_id : PeerId ,
) -> Self {
let db_path = tempdir ( ) . unwrap ( ) . path ( ) . to_path_buf ( ) ;
let ( bitcoin_wallet , monero_wallet ) =
init_wallets ( "bob" , bitcoind , monero , starting_balances . clone ( ) , config ) . await ;
Self {
db_path ,
swap_id ,
swap_amounts ,
bitcoin_wallet ,
monero_wallet ,
config ,
starting_balances ,
alice_connect_address ,
alice_connect_peer_id ,
}
}
pub async fn new_bob ( & self ) -> Bob {
let initial_state = init_bob_state (
self . swap_amounts . btc ,
self . swap_amounts . xmr ,
self . bitcoin_wallet . clone ( ) ,
self . config ,
)
. await ;
let ( event_loop , event_loop_handle ) = init_bob_event_loop (
self . alice_connect_peer_id . clone ( ) ,
self . alice_connect_address . clone ( ) ,
) ;
tokio ::spawn ( async move { event_loop . run ( ) . await } ) ;
let db = Database ::open ( self . db_path . as_path ( ) ) . unwrap ( ) ;
Bob {
state : initial_state ,
event_loop_handle ,
db ,
bitcoin_wallet : self . bitcoin_wallet . clone ( ) ,
monero_wallet : self . monero_wallet . clone ( ) ,
swap_id : self . swap_id ,
}
}
pub async fn recover_bob_from_db ( & self ) -> Bob {
// TODO: "simulated restart" issues:
// - create new wallets instead of reusing (hard because of container
// lifetimes)
// - consider aborting the old event loop (currently just keeps running)
// reopen the existing database
let db = Database ::open ( self . db_path . clone ( ) . as_path ( ) ) . unwrap ( ) ;
let resume_state =
if let swap ::database ::Swap ::Bob ( state ) = db . get_state ( self . swap_id ) . unwrap ( ) {
state . into ( )
} else {
unreachable! ( )
} ;
let ( event_loop , event_loop_handle ) = init_bob_event_loop (
self . alice_connect_peer_id . clone ( ) ,
self . alice_connect_address . clone ( ) ,
) ;
) ;
tokio ::spawn ( async move { event_loop . run ( ) . await } ) ;
Bob {
state : resume_state ,
event_loop_handle ,
db ,
bitcoin_wallet : self . bitcoin_wallet . clone ( ) ,
monero_wallet : self . monero_wallet . clone ( ) ,
swap_id : self . swap_id ,
}
}
}
pub async fn assert_ redeemed( & self , state : BobState ) {
pub async fn assert_bob_redeemed ( & self , state : BobState ) {
let lock_tx_id = if let BobState ::XmrRedeemed { tx_lock_id } = state {
let lock_tx_id = if let BobState ::XmrRedeemed { tx_lock_id } = state {
tx_lock_id
tx_lock_id
} else {
} else {
@ -370,47 +170,75 @@ impl BobHarness {
} ;
} ;
let lock_tx_bitcoin_fee = self
let lock_tx_bitcoin_fee = self
. bob_swap_factory
. bitcoin_wallet
. bitcoin_wallet
. transaction_fee ( lock_tx_id )
. transaction_fee ( lock_tx_id )
. await
. await
. unwrap ( ) ;
. unwrap ( ) ;
let btc_balance_after_swap = self . bitcoin_wallet . as_ref ( ) . balance ( ) . await . unwrap ( ) ;
let btc_balance_after_swap = self
. bob_swap_factory
. bitcoin_wallet
. as_ref ( )
. balance ( )
. await
. unwrap ( ) ;
assert_eq! (
assert_eq! (
btc_balance_after_swap ,
btc_balance_after_swap ,
self . starting_balances . btc - self . swap_amounts . btc - lock_tx_bitcoin_fee
self . bob_swap_factory . starting_balances . btc
- self . swap_amounts . btc
- lock_tx_bitcoin_fee
) ;
) ;
// Ensure that Bob's balance is refreshed as we use a newly created wallet
// Ensure that Bob's balance is refreshed as we use a newly created wallet
self . monero_wallet . as_ref ( ) . inner . refresh ( ) . await . unwrap ( ) ;
self . bob_swap_factory
let xmr_balance_after_swap = self . monero_wallet . as_ref ( ) . get_balance ( ) . await . unwrap ( ) ;
. monero_wallet
. as_ref ( )
. inner
. refresh ( )
. await
. unwrap ( ) ;
let xmr_balance_after_swap = self
. bob_swap_factory
. monero_wallet
. as_ref ( )
. get_balance ( )
. await
. unwrap ( ) ;
assert_eq! (
assert_eq! (
xmr_balance_after_swap ,
xmr_balance_after_swap ,
self . starting_balances . xmr + self . swap_amounts . xmr
self . bob_swap_factory. starting_balances. xmr + self . swap_amounts . xmr
) ;
) ;
}
}
pub async fn assert_refunded ( & self , state : BobState ) {
pub async fn assert_ bob_ refunded( & self , state : BobState ) {
let lock_tx_id = if let BobState ::BtcRefunded ( state4 ) = state {
let lock_tx_id = if let BobState ::BtcRefunded ( state4 ) = state {
state4 . tx_lock_id ( )
state4 . tx_lock_id ( )
} else {
} else {
panic! ( "Bob in unexpected state" ) ;
panic! ( "Bob in unexpected state" ) ;
} ;
} ;
let lock_tx_bitcoin_fee = self
let lock_tx_bitcoin_fee = self
. bob_swap_factory
. bitcoin_wallet
. bitcoin_wallet
. transaction_fee ( lock_tx_id )
. transaction_fee ( lock_tx_id )
. await
. await
. unwrap ( ) ;
. unwrap ( ) ;
let btc_balance_after_swap = self . bitcoin_wallet . as_ref ( ) . balance ( ) . await . unwrap ( ) ;
let btc_balance_after_swap = self
. bob_swap_factory
. bitcoin_wallet
. as_ref ( )
. balance ( )
. await
. unwrap ( ) ;
let alice_submitted_cancel = btc_balance_after_swap
let alice_submitted_cancel = btc_balance_after_swap
= = self . starting_balances . btc
= = self . bob_swap_factory. starting_balances. btc
- lock_tx_bitcoin_fee
- lock_tx_bitcoin_fee
- bitcoin ::Amount ::from_sat ( bitcoin ::TX_FEE ) ;
- bitcoin ::Amount ::from_sat ( bitcoin ::TX_FEE ) ;
let bob_submitted_cancel = btc_balance_after_swap
let bob_submitted_cancel = btc_balance_after_swap
= = self . starting_balances. btc
= = self . bob_swap_factory. starting_balances. btc
- lock_tx_bitcoin_fee
- lock_tx_bitcoin_fee
- bitcoin ::Amount ::from_sat ( 2 * bitcoin ::TX_FEE ) ;
- bitcoin ::Amount ::from_sat ( 2 * bitcoin ::TX_FEE ) ;
@ -418,11 +246,20 @@ impl BobHarness {
// Since we cannot be sure who submitted it we have to assert accordingly
// Since we cannot be sure who submitted it we have to assert accordingly
assert! ( alice_submitted_cancel | | bob_submitted_cancel ) ;
assert! ( alice_submitted_cancel | | bob_submitted_cancel ) ;
let xmr_balance_after_swap = self . monero_wallet . as_ref ( ) . get_balance ( ) . await . unwrap ( ) ;
let xmr_balance_after_swap = self
assert_eq! ( xmr_balance_after_swap , self . starting_balances . xmr ) ;
. bob_swap_factory
. monero_wallet
. as_ref ( )
. get_balance ( )
. await
. unwrap ( ) ;
assert_eq! (
xmr_balance_after_swap ,
self . bob_swap_factory . starting_balances . xmr
) ;
}
}
pub async fn assert_punished ( & self , state : BobState ) {
pub async fn assert_ bob_ punished( & self , state : BobState ) {
let lock_tx_id = if let BobState ::BtcPunished { tx_lock_id } = state {
let lock_tx_id = if let BobState ::BtcPunished { tx_lock_id } = state {
tx_lock_id
tx_lock_id
} else {
} else {
@ -430,26 +267,123 @@ impl BobHarness {
} ;
} ;
let lock_tx_bitcoin_fee = self
let lock_tx_bitcoin_fee = self
. bob_swap_factory
. bitcoin_wallet
. bitcoin_wallet
. transaction_fee ( lock_tx_id )
. transaction_fee ( lock_tx_id )
. await
. await
. unwrap ( ) ;
. unwrap ( ) ;
let btc_balance_after_swap = self . bitcoin_wallet . as_ref ( ) . balance ( ) . await . unwrap ( ) ;
let btc_balance_after_swap = self
. bob_swap_factory
. bitcoin_wallet
. as_ref ( )
. balance ( )
. await
. unwrap ( ) ;
assert_eq! (
assert_eq! (
btc_balance_after_swap ,
btc_balance_after_swap ,
self . starting_balances . btc - self . swap_amounts . btc - lock_tx_bitcoin_fee
self . bob_swap_factory . starting_balances . btc
- self . swap_amounts . btc
- lock_tx_bitcoin_fee
) ;
) ;
let xmr_balance_after_swap = self . monero_wallet . as_ref ( ) . get_balance ( ) . await . unwrap ( ) ;
let xmr_balance_after_swap = self
assert_eq! ( xmr_balance_after_swap , self . starting_balances . xmr ) ;
. bob_swap_factory
. monero_wallet
. as_ref ( )
. get_balance ( )
. await
. unwrap ( ) ;
assert_eq! (
xmr_balance_after_swap ,
self . bob_swap_factory . starting_balances . xmr
) ;
}
}
}
}
#[ derive(Debug, Clone) ]
pub async fn setup_test < T , F > ( testfn : T )
struct StartingBalances {
where
pub xmr : monero ::Amount ,
T : Fn ( TestContext ) -> F ,
pub btc : bitcoin ::Amount ,
F : Future < Output = ( ) > ,
{
let cli = Cli ::default ( ) ;
let _guard = init_tracing ( ) ;
let ( monero , containers ) = testutils ::init_containers ( & cli ) . await ;
let swap_amounts = SwapAmounts {
btc : bitcoin ::Amount ::from_sat ( 1_000_000 ) ,
xmr : monero ::Amount ::from_piconero ( 1_000_000_000_000 ) ,
} ;
let config = Config ::regtest ( ) ;
let alice_starting_balances = StartingBalances {
xmr : swap_amounts . xmr * 10 ,
btc : bitcoin ::Amount ::ZERO ,
} ;
let port = get_port ( ) . expect ( "Failed to find a free port" ) ;
let listen_address : Multiaddr = format! ( "/ip4/127.0.0.1/tcp/{}" , port )
. parse ( )
. expect ( "failed to parse Alice's address" ) ;
let ( alice_bitcoin_wallet , alice_monero_wallet ) = init_wallets (
"alice" ,
& containers . bitcoind ,
& monero ,
alice_starting_balances . clone ( ) ,
config ,
)
. await ;
let alice_swap_factory = alice ::SwapFactory ::new (
Seed ::random ( ) . unwrap ( ) ,
config ,
Uuid ::new_v4 ( ) ,
alice_bitcoin_wallet ,
alice_monero_wallet ,
alice_starting_balances ,
tempdir ( ) . unwrap ( ) . path ( ) . to_path_buf ( ) ,
listen_address ,
)
. await ;
let bob_starting_balances = StartingBalances {
xmr : monero ::Amount ::ZERO ,
btc : swap_amounts . btc * 10 ,
} ;
let ( bob_bitcoin_wallet , bob_monero_wallet ) = init_wallets (
"bob" ,
& containers . bitcoind ,
& monero ,
bob_starting_balances . clone ( ) ,
config ,
)
. await ;
let bob_swap_factory = bob ::SwapFactory ::new (
Seed ::random ( ) . unwrap ( ) ,
tempdir ( ) . unwrap ( ) . path ( ) . to_path_buf ( ) ,
Uuid ::new_v4 ( ) ,
bob_bitcoin_wallet ,
bob_monero_wallet ,
config ,
bob_starting_balances ,
alice_swap_factory . listen_address ( ) ,
alice_swap_factory . peer_id ( ) ,
) ;
let test = TestContext {
swap_amounts ,
alice_swap_factory ,
bob_swap_factory ,
} ;
testfn ( test ) . await
}
}
async fn init_containers ( cli : & Cli ) -> ( Monero , Containers < ' _ > ) {
async fn init_containers ( cli : & Cli ) -> ( Monero , Containers < ' _ > ) {
@ -498,87 +432,6 @@ async fn init_wallets(
( btc_wallet , xmr_wallet )
( btc_wallet , xmr_wallet )
}
}
async fn init_alice_state (
btc_to_swap : bitcoin ::Amount ,
xmr_to_swap : monero ::Amount ,
alice_btc_wallet : Arc < bitcoin ::Wallet > ,
config : Config ,
) -> AliceState {
let rng = & mut OsRng ;
let amounts = SwapAmounts {
btc : btc_to_swap ,
xmr : xmr_to_swap ,
} ;
let a = bitcoin ::SecretKey ::new_random ( rng ) ;
let s_a = cross_curve_dleq ::Scalar ::random ( rng ) ;
let v_a = monero ::PrivateViewKey ::new_random ( rng ) ;
let redeem_address = alice_btc_wallet . as_ref ( ) . new_address ( ) . await . unwrap ( ) ;
let punish_address = redeem_address . clone ( ) ;
let state0 = alice ::State0 ::new (
a ,
s_a ,
v_a ,
amounts . btc ,
amounts . xmr ,
config . bitcoin_cancel_timelock ,
config . bitcoin_punish_timelock ,
redeem_address ,
punish_address ,
) ;
AliceState ::Started { amounts , state0 }
}
fn init_alice_event_loop (
listen : Multiaddr ,
seed : Seed ,
) -> (
alice ::event_loop ::EventLoop ,
alice ::event_loop ::EventLoopHandle ,
) {
let alice_behaviour = alice ::Behaviour ::new ( network ::Seed ::new ( seed ) ) ;
let alice_transport = build ( alice_behaviour . identity ( ) ) . unwrap ( ) ;
alice ::event_loop ::EventLoop ::new ( alice_transport , alice_behaviour , listen ) . unwrap ( )
}
async fn init_bob_state (
btc_to_swap : bitcoin ::Amount ,
xmr_to_swap : monero ::Amount ,
bob_btc_wallet : Arc < bitcoin ::Wallet > ,
config : Config ,
) -> BobState {
let amounts = SwapAmounts {
btc : btc_to_swap ,
xmr : xmr_to_swap ,
} ;
let refund_address = bob_btc_wallet . new_address ( ) . await . unwrap ( ) ;
let state0 = bob ::State0 ::new (
& mut OsRng ,
btc_to_swap ,
xmr_to_swap ,
config . bitcoin_cancel_timelock ,
config . bitcoin_punish_timelock ,
refund_address ,
config . monero_finality_confirmations ,
) ;
BobState ::Started { state0 , amounts }
}
fn init_bob_event_loop (
alice_peer_id : PeerId ,
alice_addr : Multiaddr ,
) -> ( bob ::event_loop ::EventLoop , bob ::event_loop ::EventLoopHandle ) {
let seed = Seed ::random ( ) . unwrap ( ) ;
let bob_behaviour = bob ::Behaviour ::new ( network ::Seed ::new ( seed ) ) ;
let bob_transport = build ( bob_behaviour . identity ( ) ) . unwrap ( ) ;
bob ::event_loop ::EventLoop ::new ( bob_transport , bob_behaviour , alice_peer_id , alice_addr )
. unwrap ( )
}
// This is just to keep the containers alive
// This is just to keep the containers alive
#[ allow(dead_code) ]
#[ allow(dead_code) ]
struct Containers < ' a > {
struct Containers < ' a > {