@ -63,6 +63,18 @@ class BasicSwapTest(BaseTest):
def mineBlock ( self , num_blocks = 1 ) :
self . callnoderpc ( ' generatetoaddress ' , [ num_blocks , self . btc_addr ] )
def prepare_balance ( self , coin_ticker : str , amount : float , port_target_node : int , port_take_from_node : int ) - > None :
js_w = read_json_api ( port_target_node , ' wallets ' )
if float ( js_w [ coin_ticker ] [ ' balance ' ] ) < amount :
post_json = {
' value ' : amount ,
' address ' : js_w [ coin_ticker ] [ ' deposit_address ' ] ,
' subfee ' : False ,
}
json_rv = read_json_api ( port_take_from_node , ' wallets/ {} /withdraw ' . format ( coin_ticker . lower ( ) ) , post_json )
assert ( len ( json_rv [ ' txid ' ] ) == 64 )
wait_for_balance ( test_delay_event , ' http://127.0.0.1: {} /json/wallets/ {} ' . format ( port_target_node , coin_ticker . lower ( ) ) , ' balance ' , amount )
def test_001_nested_segwit ( self ) :
logging . info ( ' ---------- Test {} p2sh nested segwit ' . format ( self . test_coin_from . name ) )
@ -263,7 +275,7 @@ class BasicSwapTest(BaseTest):
rv = read_json_api ( 1800 , ' getcoinseed ' , { ' coin ' : ' XMR ' } )
assert ( rv [ ' address ' ] == ' 47H7UDLzYEsR28BWttxp59SP1UVSxs4VKDJYSfmz7Wd4Fue5VWuoV9x9eejunwzVSmHWN37gBkaAPNf9VD4bTvwQKsBVWyK ' )
def do_test_01_full_swap ( self , coin_from , coin_to ) :
def do_test_01_full_swap ( self , coin_from : Coins , coin_to : Coins ) - > None :
logging . info ( ' ---------- Test {} to {} ' . format ( coin_from . name , coin_to . name ) )
swap_clients = self . swap_clients
@ -289,8 +301,7 @@ class BasicSwapTest(BaseTest):
bid_id = swap_clients [ 1 ] . postXmrBid ( offer_id , offer . amount_from )
wait_for_bid ( test_delay_event , swap_clients [ 0 ] , bid_id , BidStates . BID_RECEIVED )
swap_clients [ 0 ] . acceptXmrBid ( bid_id )
swap_clients [ 0 ] . acceptBid ( bid_id )
wait_for_bid ( test_delay_event , swap_clients [ 0 ] , bid_id , BidStates . SWAP_COMPLETED , wait_for = 180 )
wait_for_bid ( test_delay_event , swap_clients [ 1 ] , bid_id , BidStates . SWAP_COMPLETED , sent = True )
@ -317,63 +328,83 @@ class BasicSwapTest(BaseTest):
if False : # TODO: set stakeaddress and xmr rewards to non wallet addresses
assert ( node1_to_after < node1_to_before - amount_to_float )
def test_01_full_swap ( self ) :
def test_01_a_ full_swap ( self ) :
if not self . has_segwit :
return
self . do_test_01_full_swap ( self . test_coin_from , Coins . XMR )
def test_01_full_swap_to_part ( self ) :
def test_01_b_full_swap_reverse ( self ) :
if not self . has_segwit :
return
self . prepare_balance ( Coins . XMR . name , 100.0 , 1800 , 1801 )
self . do_test_01_full_swap ( Coins . XMR , self . test_coin_from )
def test_01_c_full_swap_to_part ( self ) :
if not self . has_segwit :
return
self . do_test_01_full_swap ( self . test_coin_from , Coins . PART )
def test_01_full_swap_from_part ( self ) :
def test_01_d_ full_swap_from_part ( self ) :
self . do_test_01_full_swap ( Coins . PART , self . test_coin_from )
def do_test_02_leader_recover_a_lock_tx ( self , coin_from , coin_to ) :
def do_test_02_leader_recover_a_lock_tx ( self , coin_from : Coins , coin_to : Coins ) - > None :
logging . info ( ' ---------- Test {} to {} leader recovers coin a lock tx ' . format ( coin_from . name , coin_to . name ) )
swap_clients = self . swap_clients
reverse_bid : bool = coin_from in swap_clients [ 0 ] . scriptless_coins
ci_from = swap_clients [ 0 ] . ci ( coin_from )
ci_to = swap_clients [ 0 ] . ci ( coin_to )
js_w0_before = read_json_api ( 1800 , ' wallets ' )
node0_from_before = self . getBalance ( js_w0_before , coin_from )
# Offerer sends the offer
# Bidder sends the bid
id_offerer : int = 0
id_bidder : int = 1
# Leader sends the initial (chain a) lock tx.
# Follower sends the participate (chain b) lock tx.
id_leader : int = 1 if reverse_bid else 0
id_follower : int = 0 if reverse_bid else 1
logging . info ( f ' Offerer, bidder, leader, follower: { id_offerer } , { id_bidder } , { id_leader } , { id_follower } ' )
js_wl_before = read_json_api ( 1800 + id_leader , ' wallets ' )
wl_from_before = self . getBalance ( js_wl_before , coin_from )
amt_swap = ci_from . make_int ( random . uniform ( 0.1 , 2.0 ) , r = 1 )
rate_swap = ci_to . make_int ( random . uniform ( 0.2 , 20.0 ) , r = 1 )
offer_id = swap_clients [ 0 ] . postOffer (
offer_id = swap_clients [ id_offerer ] . postOffer (
coin_from , coin_to , amt_swap , rate_swap , amt_swap , SwapTypes . XMR_SWAP ,
lock_type = TxLockTypes . SEQUENCE_LOCK_BLOCKS , lock_value = 32 )
wait_for_offer ( test_delay_event , swap_clients [ 1 ] , offer_id )
offer = swap_clients [ 1 ] . getOffer ( offer_id )
wait_for_offer ( test_delay_event , swap_clients [ id_bidder ] , offer_id )
offer = swap_clients [ id_bidder ] . getOffer ( offer_id )
bid_id = swap_clients [ 1 ] . postXmrBid ( offer_id , offer . amount_from )
bid_id = swap_clients [ id_bidder ] . postXmrBid ( offer_id , offer . amount_from )
wait_for_bid ( test_delay_event , swap_clients [ id_offerer ] , bid_id , BidStates . BID_RECEIVED )
wait_for_bid ( test_delay_event , swap_clients [ 0 ] , bid_id , BidStates . BID_RECEIVED )
swap_clients [ id_follower ] . setBidDebugInd ( bid_id , DebugTypes . BID_STOP_AFTER_COIN_A_LOCK )
swap_clients [ id_offerer ] . acceptBid ( bid_id )
bid , xmr_swap = swap_clients [ 0 ] . getXmrBid ( bid_id )
assert ( xmr_swap )
leader_sent_bid : bool = True if reverse_bid else False
wait_for_bid ( test_delay_event , swap_clients [ id_leader ] , bid_id , BidStates . XMR_SWAP_FAILED_REFUNDED , sent = leader_sent_bid , wait_for = 180 )
wait_for_bid ( test_delay_event , swap_clients [ id_follower ] , bid_id , [ BidStates . BID_STALLED_FOR_TEST , BidStates . XMR_SWAP_FAILED ] , sent = ( not leader_sent_bid ) )
swap_clients [ 1 ] . setBidDebugInd ( bid_id , DebugTypes . BID_STOP_AFTER_COIN_A_LOCK )
swap_clients [ 0 ] . acceptXmrBid ( bid_id )
wait_for_bid ( test_delay_event , swap_clients [ 0 ] , bid_id , BidStates . XMR_SWAP_FAILED_REFUNDED , wait_for = 180 )
wait_for_bid ( test_delay_event , swap_clients [ 1 ] , bid_id , [ BidStates . BID_STALLED_FOR_TEST , BidStates . XMR_SWAP_FAILED ] , sent = True )
js_w0_after = read_json_api ( 1800 , ' wallets ' )
node0_from_after = self . getBalance ( js_w0_after , coin_from )
js_wl_after = read_json_api ( 1800 + id_leader , ' wallets ' )
wl_from_after = self . getBalance ( js_wl_after , coin_from )
# TODO: Discard block rewards
# assert (node0_from_before - node0_from_after < 0.02)
def test_02_leader_recover_a_lock_tx ( self ) :
def test_02_a_leader_recover_a_lock_tx ( self ) :
if not self . has_segwit :
return
self . do_test_02_leader_recover_a_lock_tx ( self . test_coin_from , Coins . XMR )
def test_02_leader_recover_a_lock_tx_to_part ( self ) :
def test_02_b_leader_recover_a_lock_tx_reverse ( self ) :
if not self . has_segwit :
return
self . prepare_balance ( Coins . XMR . name , 100.0 , 1800 , 1801 )
self . do_test_02_leader_recover_a_lock_tx ( Coins . XMR , self . test_coin_from )
def test_02_c_leader_recover_a_lock_tx_to_part ( self ) :
if not self . has_segwit :
return
self . do_test_02_leader_recover_a_lock_tx ( self . test_coin_from , Coins . PART )
@ -384,34 +415,42 @@ class BasicSwapTest(BaseTest):
def do_test_03_follower_recover_a_lock_tx ( self , coin_from , coin_to ) :
logging . info ( ' ---------- Test {} to {} follower recovers coin a lock tx ' . format ( coin_from . name , coin_to . name ) )
# Leader is too slow to recover the coin a lock tx and follower swipes it
# coin b lock tx remains unspent
swap_clients = self . swap_clients
reverse_bid : bool = coin_from in swap_clients [ 0 ] . scriptless_coins
ci_from = swap_clients [ 0 ] . ci ( coin_from )
ci_to = swap_clients [ 0 ] . ci ( coin_to )
id_offerer : int = 0
id_bidder : int = 1
id_leader : int = 1 if reverse_bid else 0
id_follower : int = 0 if reverse_bid else 1
logging . info ( f ' Offerer, bidder, leader, follower: { id_offerer } , { id_bidder } , { id_leader } , { id_follower } ' )
js_w0_before = read_json_api ( 1800 , ' wallets ' )
js_w1_before = read_json_api ( 1801 , ' wallets ' )
amt_swap = ci_from . make_int ( random . uniform ( 0.1 , 2.0 ) , r = 1 )
rate_swap = ci_to . make_int ( random . uniform ( 0.2 , 20.0 ) , r = 1 )
offer_id = swap_clients [ 0 ] . postOffer (
offer_id = swap_clients [ id_offerer ] . postOffer (
coin_from , coin_to , amt_swap , rate_swap , amt_swap , SwapTypes . XMR_SWAP ,
lock_type = TxLockTypes . SEQUENCE_LOCK_BLOCKS , lock_value = 32 )
wait_for_offer ( test_delay_event , swap_clients [ 1 ] , offer_id )
offer = swap_clients [ 1 ] . getOffer ( offer_id )
offer = swap_clients [ id_bidder ] . getOffer ( offer_id )
bid_id = swap_clients [ 1 ] . postXmrBid ( offer_id , offer . amount_from )
wait_for_bid ( test_delay_event , swap_clients [ 0 ] , bid_id , BidStates . BID_RECEIVED )
bid_id = swap_clients [ id_bidder ] . postXmrBid ( offer_id , offer . amount_from )
wait_for_bid ( test_delay_event , swap_clients [ id_offerer ] , bid_id , BidStates . BID_RECEIVED )
bid , xmr_swap = swap_clients [ 0 ] . getXmrBid ( bid_id )
assert ( xmr_swap )
swap_clients [ id_follower ] . setBidDebugInd ( bid_id , DebugTypes . BID_STOP_AFTER_COIN_A_LOCK )
swap_clients [ id_leader ] . setBidDebugInd ( bid_id , DebugTypes . BID_DONT_SPEND_COIN_A_LOCK_REFUND )
swap_clients [ 1 ] . setBidDebugInd ( bid_id , DebugTypes . BID_STOP_AFTER_COIN_A_LOCK )
swap_clients [ 0 ] . setBidDebugInd ( bid_id , DebugTypes . BID_DONT_SPEND_COIN_A_LOCK_REFUND )
swap_clients [ id_offerer ] . acceptBid ( bid_id )
swap_clients [ 0 ] . acceptXmrBid ( bid_id )
wait_for_bid ( test_delay_event , swap_clients [ 0 ] , bid_id , BidStates . BID_STALLED_FOR_TEST , wait_for = 180 )
wait_for_bid ( test_delay_event , swap_clients [ 1 ] , bid_id , BidStates . XMR_SWAP_FAILED_SWIPED , wait_for = 80 , sent = True )
leader_sent_bid : bool = True if reverse_bid else False
wait_for_bid ( test_delay_event , swap_clients [ id_leader ] , bid_id , BidStates . BID_STALLED_FOR_TEST , wait_for = 180 , sent = leader_sent_bid )
wait_for_bid ( test_delay_event , swap_clients [ id_follower ] , bid_id , BidStates . XMR_SWAP_FAILED_SWIPED , wait_for = 80 , sent = ( not leader_sent_bid ) )
js_w1_after = read_json_api ( 1801 , ' wallets ' )
@ -426,74 +465,97 @@ class BasicSwapTest(BaseTest):
wait_for_none_active ( test_delay_event , 1800 )
wait_for_none_active ( test_delay_event , 1801 )
def test_03_follower_recover_a_lock_tx ( self ) :
def test_03_a_ follower_recover_a_lock_tx ( self ) :
if not self . has_segwit :
return
self . do_test_03_follower_recover_a_lock_tx ( self . test_coin_from , Coins . XMR )
def test_03_follower_recover_a_lock_tx_to_part ( self ) :
def test_03_b_follower_recover_a_lock_tx_reverse ( self ) :
if not self . has_segwit :
return
self . prepare_balance ( Coins . XMR . name , 100.0 , 1800 , 1801 )
self . do_test_03_follower_recover_a_lock_tx ( Coins . XMR , self . test_coin_from )
def test_03_c_follower_recover_a_lock_tx_to_part ( self ) :
if not self . has_segwit :
return
self . do_test_03_follower_recover_a_lock_tx ( self . test_coin_from , Coins . PART )
def test_03_follower_recover_a_lock_tx_from_part ( self ) :
def test_03_d_ follower_recover_a_lock_tx_from_part ( self ) :
self . do_test_03_follower_recover_a_lock_tx ( Coins . PART , self . test_coin_from )
def do_test_04_follower_recover_b_lock_tx ( self , coin_from , coin_to ) :
logging . info ( ' ---------- Test {} to {} follower recovers coin b lock tx ' . format ( coin_from . name , coin_to . name ) )
swap_clients = self . swap_clients
reverse_bid : bool = coin_from in swap_clients [ 0 ] . scriptless_coins
ci_from = swap_clients [ 0 ] . ci ( coin_from )
ci_to = swap_clients [ 0 ] . ci ( coin_to )
id_offerer : int = 0
id_bidder : int = 1
id_leader : int = 1 if reverse_bid else 0
id_follower : int = 0 if reverse_bid else 1
logging . info ( f ' Offerer, bidder, leader, follower: { id_offerer } , { id_bidder } , { id_leader } , { id_follower } ' )
js_w0_before = read_json_api ( 1800 , ' wallets ' )
js_w1_before = read_json_api ( 1801 , ' wallets ' )
amt_swap = ci_from . make_int ( random . uniform ( 0.1 , 2.0 ) , r = 1 )
rate_swap = ci_to . make_int ( random . uniform ( 0.2 , 20.0 ) , r = 1 )
offer_id = swap_clients [ 0 ] . postOffer (
offer_id = swap_clients [ id_offerer ] . postOffer (
coin_from , coin_to , amt_swap , rate_swap , amt_swap , SwapTypes . XMR_SWAP ,
lock_type = TxLockTypes . SEQUENCE_LOCK_BLOCKS , lock_value = 32 )
wait_for_offer ( test_delay_event , swap_clients [ 1 ] , offer_id )
offer = swap_clients [ 1 ] . getOffer ( offer_id )
bid_id = swap_clients [ 1 ] . postXmrBid ( offer_id , offer . amount_from )
wait_for_bid ( test_delay_event , swap_clients [ 0 ] , bid_id , BidStates . BID_RECEIVED )
wait_for_offer ( test_delay_event , swap_clients [ id_bidder ] , offer_id )
offer = swap_clients [ id_bidder ] . getOffer ( offer_id )
bid , xmr_swap = swap_clients [ 0 ] . getXmrBid ( bid_id )
assert ( xmr_swap )
bid_id = swap_clients [ id_bidder ] . postXmrBid ( offer_id , offer . amount_from )
wait_for_bid ( test_delay_event , swap_clients [ id_offerer ] , bid_id , BidStates . BID_RECEIVED )
swap_clients [ 1 ] . setBidDebugInd ( bid_id , DebugTypes . CREATE_INVALID_COIN_B_LOCK )
swap_clients [ 0 ] . acceptXmr Bid ( bid_id )
swap_clients [ id_follower ] . setBidDebugInd ( bid_id , DebugTypes . CREATE_INVALID_COIN_B_LOCK )
swap_clients [ id_offerer ] . acceptBid ( bid_id )
wait_for_bid ( test_delay_event , swap_clients [ 0 ] , bid_id , BidStates . XMR_SWAP_FAILED_REFUNDED , wait_for = 180 )
wait_for_bid ( test_delay_event , swap_clients [ 1 ] , bid_id , BidStates . XMR_SWAP_FAILED_REFUNDED , sent = True )
leader_sent_bid : bool = True if reverse_bid else False
wait_for_bid ( test_delay_event , swap_clients [ id_leader ] , bid_id , BidStates . XMR_SWAP_FAILED_REFUNDED , wait_for = 200 , sent = leader_sent_bid )
wait_for_bid ( test_delay_event , swap_clients [ id_follower ] , bid_id , BidStates . XMR_SWAP_FAILED_REFUNDED , sent = ( not leader_sent_bid ) )
js_w0_after = read_json_api ( 1800 , ' wallets ' )
js_w1_after = read_json_api ( 1801 , ' wallets ' )
node0_from_before = self . getBalance ( js_w0_before , coin_from )
node0_from_after = self . getBalance ( js_w0_after , coin_from )
logging . info ( ' End coin_from balance {} , diff {} ' . format ( node0_from_after , node0_from_after - node0_from_before ) )
# TODO: Discard block rewards
# assert (node0_from_before - node0_from_after < 0.02)
logging . info ( ' node0 end coin_from balance {} , diff {} ' . format ( node0_from_after , node0_from_after - node0_from_before ) )
node0_to_before = self . getBalance ( js_w0_before , coin_to )
node0_to_after = self . getBalance ( js_w0_after , coin_to )
logging . info ( ' node0 end coin_to balance {} , diff {} ' . format ( node0_to_after , node0_to_after - node0_to_before ) )
if coin_from != Coins . PART : # TODO: Discard block rewards
assert ( node0_from_before - node0_from_after < 0.02 )
node1_coin_to_before = self . getBalance ( js_w1_before , coin_to )
node1_coin_to_after = self . getBalance ( js_w1_after , coin_to )
logging . info ( ' End coin_to balance {} , diff {} ' . format ( node1_coin_to_after , node1_coin_to_after - node1_coin_to_before ) )
assert ( node1_coin_to_before - node1_coin_to_after < 0.02 )
node1_from_before = self . getBalance ( js_w1_before , coin_from )
node1_from_after = self . getBalance ( js_w1_after , coin_from )
logging . info ( ' node1 end coin_from balance {} , diff {} ' . format ( node1_from_after , node1_from_after - node1_from_before ) )
node1_to_before = self . getBalance ( js_w1_before , coin_to )
node1_to_after = self . getBalance ( js_w1_after , coin_to )
logging . info ( ' node1 end coin_to balance {} , diff {} ' . format ( node1_to_after , node1_to_after - node1_to_before ) )
assert ( node1_to_before - node1_to_after < 0.02 )
def test_04_follower_recover_b_lock_tx ( self ) :
def test_04_a_ follower_recover_b_lock_tx ( self ) :
if not self . has_segwit :
return
self . do_test_04_follower_recover_b_lock_tx ( self . test_coin_from , Coins . XMR )
def test_04_follower_recover_b_lock_tx_to_part ( self ) :
def test_04_b_follower_recover_b_lock_tx_reverse ( self ) :
if not self . has_segwit :
return
self . prepare_balance ( Coins . XMR . name , 100.0 , 1800 , 1801 )
self . do_test_04_follower_recover_b_lock_tx ( Coins . XMR , self . test_coin_from )
def test_04_c_follower_recover_b_lock_tx_to_part ( self ) :
if not self . has_segwit :
return
self . do_test_04_follower_recover_b_lock_tx ( self . test_coin_from , Coins . PART )
def test_04_follower_recover_b_lock_tx_from_part ( self ) :
def test_04_d_ follower_recover_b_lock_tx_from_part ( self ) :
self . do_test_04_follower_recover_b_lock_tx ( Coins . PART , self . test_coin_from )
def do_test_05_self_bid ( self , coin_from , coin_to ) :
@ -528,17 +590,7 @@ class BasicSwapTest(BaseTest):
logging . info ( ' ---------- Test {} Preselected inputs ' . format ( tla_from ) )
swap_clients = self . swap_clients
# Prepare balance
js_w2 = read_json_api ( 1802 , ' wallets ' )
if float ( js_w2 [ tla_from ] [ ' balance ' ] ) < 100.0 :
post_json = {
' value ' : 100 ,
' address ' : js_w2 [ tla_from ] [ ' deposit_address ' ] ,
' subfee ' : False ,
}
json_rv = read_json_api ( 1800 , ' wallets/ {} /withdraw ' . format ( tla_from . lower ( ) ) , post_json )
assert ( len ( json_rv [ ' txid ' ] ) == 64 )
wait_for_balance ( test_delay_event , ' http://127.0.0.1:1802/json/wallets/ {} ' . format ( tla_from . lower ( ) ) , ' balance ' , 100.0 )
self . prepare_balance ( tla_from , 100.0 , 1802 , 1800 )
js_w2 = read_json_api ( 1802 , ' wallets ' )
assert ( float ( js_w2 [ tla_from ] [ ' balance ' ] ) > = 100.0 )