@ -22,6 +22,7 @@ from basicswap.util import (
make_int ,
format_amount ,
)
from basicswap . interface import Curves
from tests . basicswap . util import (
read_json_api ,
)
@ -51,11 +52,24 @@ from .test_xmr import BaseTest, test_delay_event, callnoderpc
logger = logging . getLogger ( )
class BasicSwap Test( BaseTest ) :
class TestFunctions ( BaseTest ) :
base_rpc_port = None
def getBalance ( self , js_wallets , coin ) :
return float ( js_wallets [ coin . name ] [ ' balance ' ] ) + float ( js_wallets [ coin . name ] [ ' unconfirmed ' ] )
def getBalance ( self , js_wallets , coin ) - > float :
if coin == Coins . PART_BLIND :
coin_ticker : str = ' PART '
balance_type : str = ' blind_balance '
unconfirmed_name : str = ' blind_unconfirmed '
elif coin == Coins . PART_ANON :
coin_ticker : str = ' PART '
balance_type : str = ' anon_balance '
unconfirmed_name : str = ' anon_pending '
else :
coin_ticker : str = coin . name
balance_type : str = ' balance '
unconfirmed_name : str = ' unconfirmed '
return float ( js_wallets [ coin_ticker ] [ balance_type ] ) + float ( js_wallets [ coin_ticker ] [ unconfirmed_name ] )
def callnoderpc ( self , method , params = [ ] , wallet = None , node_id = 0 ) :
return callnoderpc ( node_id , method , params , wallet , self . base_rpc_port )
@ -63,17 +77,276 @@ 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 :
def prepare_balance ( self , coin , amount : float , port_target_node : int , port_take_from_node : int ) - > None :
if coin == Coins . PART_BLIND :
coin_ticker : str = ' PART '
balance_type : str = ' blind_balance '
address_type : str = ' stealth_address '
type_to : str = ' blind '
elif coin == Coins . PART_ANON :
coin_ticker : str = ' PART '
balance_type : str = ' anon_balance '
address_type : str = ' stealth_address '
type_to : str = ' anon '
else :
coin_ticker : str = coin . name
balance_type : str = ' balance '
address_type : str = ' deposit_address '
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 )
if float ( js_w [ coin_ticker ] [ balance_type ] ) > = amount :
return
post_json = {
' value ' : amount ,
' address ' : js_w [ coin_ticker ] [ address_type ] ,
' subfee ' : False ,
}
if coin in ( Coins . PART_BLIND , Coins . PART_ANON ) :
post_json [ ' type_to ' ] = type_to
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_type , amount )
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
reverse_bid : bool = coin_from in swap_clients [ 0 ] . scriptless_coins
ci_from = swap_clients [ 0 ] . ci ( coin_from )
ci_to = swap_clients [ 1 ] . ci ( coin_to )
ci_part0 = swap_clients [ 0 ] . ci ( Coins . PART )
ci_part1 = swap_clients [ 1 ] . ci ( Coins . PART )
# 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_0 = read_json_api ( 1800 , ' wallets ' )
node0_from_before : float = self . getBalance ( js_0 , coin_from )
js_1 = read_json_api ( 1801 , ' wallets ' )
node1_from_before : float = self . getBalance ( js_1 , coin_from )
node0_sent_messages_before : int = ci_part0 . rpc_callback ( ' smsgoutbox ' , [ ' count ' , ] ) [ ' num_messages ' ]
node1_sent_messages_before : int = ci_part1 . rpc_callback ( ' smsgoutbox ' , [ ' count ' , ] ) [ ' num_messages ' ]
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 [ id_offerer ] . postOffer ( coin_from , coin_to , amt_swap , rate_swap , amt_swap , SwapTypes . XMR_SWAP )
wait_for_offer ( test_delay_event , swap_clients [ id_bidder ] , offer_id )
offer = swap_clients [ id_bidder ] . listOffers ( filters = { ' offer_id ' : offer_id } ) [ 0 ]
assert ( offer . offer_id == offer_id )
bid_id = swap_clients [ 1 ] . postXmrBid ( offer_id , offer . amount_from )
wait_for_bid ( test_delay_event , swap_clients [ id_offerer ] , bid_id , BidStates . BID_RECEIVED )
swap_clients [ id_offerer ] . acceptBid ( bid_id )
wait_for_bid ( test_delay_event , swap_clients [ id_offerer ] , bid_id , BidStates . SWAP_COMPLETED , wait_for = 180 )
wait_for_bid ( test_delay_event , swap_clients [ id_bidder ] , bid_id , BidStates . SWAP_COMPLETED , sent = True )
amount_from = float ( ci_from . format_amount ( amt_swap ) )
js_1_after = read_json_api ( 1801 , ' wallets ' )
node1_from_after = self . getBalance ( js_1_after , coin_from )
if coin_from is not Coins . PART : # TODO: staking
assert ( node1_from_after > node1_from_before + ( amount_from - 0.05 ) )
js_0_after = read_json_api ( 1800 , ' wallets ' )
node0_from_after : float = self . getBalance ( js_0_after , coin_from )
# TODO: Discard block rewards
# assert (node0_from_after < node0_from_before - amount_from)
scale_from = 8
amount_to = int ( ( amt_swap * rate_swap ) / / ( 10 * * scale_from ) )
amount_to_float = float ( ci_to . format_amount ( amount_to ) )
node1_to_after : float = self . getBalance ( js_1_after , coin_to )
node1_to_before : float = self . getBalance ( js_1 , coin_to )
if False : # TODO: set stakeaddress and xmr rewards to non wallet addresses
assert ( node1_to_after < node1_to_before - amount_to_float )
node0_sent_messages_after : int = ci_part0 . rpc_callback ( ' smsgoutbox ' , [ ' count ' , ] ) [ ' num_messages ' ]
node1_sent_messages_after : int = ci_part1 . rpc_callback ( ' smsgoutbox ' , [ ' count ' , ] ) [ ' num_messages ' ]
node0_sent_messages : int = node0_sent_messages_after - node0_sent_messages_before
node1_sent_messages : int = node1_sent_messages_after - node1_sent_messages_before
split_msgs : int = 2 if ( ci_from . curve_type ( ) != Curves . secp256k1 or ci_to . curve_type ( ) != Curves . secp256k1 ) else 0
assert ( node0_sent_messages == ( 3 + split_msgs if reverse_bid else 4 + split_msgs ) )
assert ( node1_sent_messages == ( 4 + split_msgs if reverse_bid else 2 + split_msgs ) )
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 )
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_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 [ 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 [ id_bidder ] , offer_id )
offer = swap_clients [ id_bidder ] . getOffer ( offer_id )
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 [ id_follower ] . setBidDebugInd ( bid_id , DebugTypes . BID_STOP_AFTER_COIN_A_LOCK )
swap_clients [ id_offerer ] . acceptBid ( bid_id )
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 ) )
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 do_test_03_follower_recover_a_lock_tx ( self , coin_from , coin_to , lock_value = 32 ) :
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 [ id_offerer ] . postOffer (
coin_from , coin_to , amt_swap , rate_swap , amt_swap , SwapTypes . XMR_SWAP ,
lock_type = TxLockTypes . SEQUENCE_LOCK_BLOCKS , lock_value = lock_value )
wait_for_offer ( test_delay_event , swap_clients [ 1 ] , offer_id )
offer = swap_clients [ id_bidder ] . getOffer ( offer_id )
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 [ 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 [ id_offerer ] . acceptBid ( bid_id )
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 ' )
node1_from_before = self . getBalance ( js_w1_before , coin_from )
node1_from_after = self . getBalance ( js_w1_after , coin_from )
amount_from = float ( format_amount ( amt_swap , 8 ) )
# TODO: Discard block rewards
# assert (node1_from_after - node1_from_before > (amount_from - 0.02))
swap_clients [ 0 ] . abandonBid ( bid_id )
wait_for_none_active ( test_delay_event , 1800 )
wait_for_none_active ( test_delay_event , 1801 )
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 [ 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 [ id_bidder ] , offer_id )
offer = swap_clients [ id_bidder ] . getOffer ( offer_id )
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 [ id_follower ] . setBidDebugInd ( bid_id , DebugTypes . CREATE_INVALID_COIN_B_LOCK )
swap_clients [ id_offerer ] . acceptBid ( bid_id )
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 ( ' 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 ) )
max_fee_from : float = 0.1 if coin_from == Coins . PART_ANON else 0.02
if coin_from != Coins . PART : # TODO: Discard block rewards
assert ( node0_from_before - node0_from_after < max_fee_from )
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 ) )
max_fee_to : float = 0.1 if coin_to == Coins . PART_ANON else 0.02
assert ( node1_to_before - node1_to_after < max_fee_to )
def do_test_05_self_bid ( self , coin_from , coin_to ) :
logging . info ( ' ---------- Test {} to {} same client ' . format ( coin_from . name , coin_to . name ) )
swap_clients = self . swap_clients
ci_from = swap_clients [ 0 ] . ci ( coin_from )
ci_to = swap_clients [ 0 ] . ci ( coin_to )
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 [ 1 ] . postOffer ( coin_from , coin_to , amt_swap , rate_swap , amt_swap , SwapTypes . XMR_SWAP , auto_accept_bids = True )
bid_id = swap_clients [ 1 ] . postXmrBid ( offer_id , amt_swap )
wait_for_bid ( test_delay_event , swap_clients [ 1 ] , bid_id , BidStates . SWAP_COMPLETED , wait_for = 180 )
class BasicSwapTest ( TestFunctions ) :
def test_001_nested_segwit ( self ) :
logging . info ( ' ---------- Test {} p2sh nested segwit ' . format ( self . test_coin_from . name ) )
@ -275,83 +548,6 @@ class BasicSwapTest(BaseTest):
rv = read_json_api ( 1800 , ' getcoinseed ' , { ' coin ' : ' XMR ' } )
assert ( rv [ ' address ' ] == ' 47H7UDLzYEsR28BWttxp59SP1UVSxs4VKDJYSfmz7Wd4Fue5VWuoV9x9eejunwzVSmHWN37gBkaAPNf9VD4bTvwQKsBVWyK ' )
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
reverse_bid : bool = coin_from in swap_clients [ 0 ] . scriptless_coins
ci_from = swap_clients [ 0 ] . ci ( coin_from )
ci_to = swap_clients [ 1 ] . ci ( coin_to )
ci_part0 = swap_clients [ 0 ] . ci ( Coins . PART )
ci_part1 = swap_clients [ 1 ] . ci ( Coins . PART )
# 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_0 = read_json_api ( 1800 , ' wallets ' )
node0_from_before = self . getBalance ( js_0 , coin_from )
js_1 = read_json_api ( 1801 , ' wallets ' )
node1_from_before = self . getBalance ( js_1 , coin_from )
js_0_to = read_json_api ( 1800 , ' wallets/ {} ' . format ( coin_to . name . lower ( ) ) )
js_1_to = read_json_api ( 1801 , ' wallets/ {} ' . format ( coin_to . name . lower ( ) ) )
node0_sent_messages_before : int = ci_part0 . rpc_callback ( ' smsgoutbox ' , [ ' count ' , ] ) [ ' num_messages ' ]
node1_sent_messages_before : int = ci_part1 . rpc_callback ( ' smsgoutbox ' , [ ' count ' , ] ) [ ' num_messages ' ]
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 [ id_offerer ] . postOffer ( coin_from , coin_to , amt_swap , rate_swap , amt_swap , SwapTypes . XMR_SWAP )
wait_for_offer ( test_delay_event , swap_clients [ id_bidder ] , offer_id )
offer = swap_clients [ id_bidder ] . listOffers ( filters = { ' offer_id ' : offer_id } ) [ 0 ]
assert ( offer . offer_id == offer_id )
bid_id = swap_clients [ 1 ] . postXmrBid ( offer_id , offer . amount_from )
wait_for_bid ( test_delay_event , swap_clients [ id_offerer ] , bid_id , BidStates . BID_RECEIVED )
swap_clients [ id_offerer ] . acceptBid ( bid_id )
wait_for_bid ( test_delay_event , swap_clients [ id_offerer ] , bid_id , BidStates . SWAP_COMPLETED , wait_for = 180 )
wait_for_bid ( test_delay_event , swap_clients [ id_bidder ] , bid_id , BidStates . SWAP_COMPLETED , sent = True )
amount_from = float ( ci_from . format_amount ( amt_swap ) )
js_1 = read_json_api ( 1801 , ' wallets ' )
node1_from_after = self . getBalance ( js_1 , coin_from )
if coin_from is not Coins . PART : # TODO: staking
assert ( node1_from_after > node1_from_before + ( amount_from - 0.05 ) )
js_0 = read_json_api ( 1800 , ' wallets ' )
node0_from_after = self . getBalance ( js_0 , coin_from )
# TODO: Discard block rewards
# assert (node0_from_after < node0_from_before - amount_from)
js_0_to_after = read_json_api ( 1800 , ' wallets/ {} ' . format ( coin_to . name . lower ( ) ) )
js_1_to_after = read_json_api ( 1801 , ' wallets/ {} ' . format ( coin_to . name . lower ( ) ) )
scale_from = 8
amount_to = int ( ( amt_swap * rate_swap ) / / ( 10 * * scale_from ) )
amount_to_float = float ( ci_to . format_amount ( amount_to ) )
node1_to_after = float ( js_1_to_after [ ' unconfirmed ' ] ) + float ( js_1_to_after [ ' balance ' ] )
node1_to_before = float ( js_1_to [ ' unconfirmed ' ] ) + float ( js_1_to [ ' balance ' ] )
if False : # TODO: set stakeaddress and xmr rewards to non wallet addresses
assert ( node1_to_after < node1_to_before - amount_to_float )
node0_sent_messages_after : int = ci_part0 . rpc_callback ( ' smsgoutbox ' , [ ' count ' , ] ) [ ' num_messages ' ]
node1_sent_messages_after : int = ci_part1 . rpc_callback ( ' smsgoutbox ' , [ ' count ' , ] ) [ ' num_messages ' ]
node0_sent_messages : int = node0_sent_messages_after - node0_sent_messages_before
node1_sent_messages : int = node1_sent_messages_after - node1_sent_messages_before
assert ( node0_sent_messages == ( 5 if reverse_bid else 6 ) )
assert ( node1_sent_messages == ( 6 if reverse_bid else 4 ) )
def test_01_a_full_swap ( self ) :
if not self . has_segwit :
return
@ -360,7 +556,7 @@ class BasicSwapTest(BaseTest):
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 . prepare_balance ( Coins . XMR , 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 ) :
@ -371,47 +567,6 @@ class BasicSwapTest(BaseTest):
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 : 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 )
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_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 [ 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 [ id_bidder ] , offer_id )
offer = swap_clients [ id_bidder ] . getOffer ( offer_id )
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 [ id_follower ] . setBidDebugInd ( bid_id , DebugTypes . BID_STOP_AFTER_COIN_A_LOCK )
swap_clients [ id_offerer ] . acceptBid ( bid_id )
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 ) )
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_a_leader_recover_a_lock_tx ( self ) :
if not self . has_segwit :
return
@ -420,7 +575,7 @@ class BasicSwapTest(BaseTest):
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 . prepare_balance ( Coins . XMR , 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 ) :
@ -431,59 +586,6 @@ class BasicSwapTest(BaseTest):
def test_02_leader_recover_a_lock_tx_from_part ( self ) :
self . do_test_02_leader_recover_a_lock_tx ( Coins . PART , self . test_coin_from )
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 [ 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 [ id_bidder ] . getOffer ( offer_id )
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 [ 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 [ id_offerer ] . acceptBid ( bid_id )
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 ' )
node1_from_before = self . getBalance ( js_w1_before , coin_from )
node1_from_after = self . getBalance ( js_w1_after , coin_from )
amount_from = float ( format_amount ( amt_swap , 8 ) )
# TODO: Discard block rewards
# assert (node1_from_after - node1_from_before > (amount_from - 0.02))
swap_clients [ 0 ] . abandonBid ( bid_id )
wait_for_none_active ( test_delay_event , 1800 )
wait_for_none_active ( test_delay_event , 1801 )
def test_03_a_follower_recover_a_lock_tx ( self ) :
if not self . has_segwit :
return
@ -492,7 +594,7 @@ class BasicSwapTest(BaseTest):
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 . prepare_balance ( Coins . XMR , 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 ) :
@ -503,61 +605,6 @@ class BasicSwapTest(BaseTest):
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 [ 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 [ id_bidder ] , offer_id )
offer = swap_clients [ id_bidder ] . getOffer ( offer_id )
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 [ id_follower ] . setBidDebugInd ( bid_id , DebugTypes . CREATE_INVALID_COIN_B_LOCK )
swap_clients [ id_offerer ] . acceptBid ( bid_id )
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 ( ' 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_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_a_follower_recover_b_lock_tx ( self ) :
if not self . has_segwit :
return
@ -566,7 +613,7 @@ class BasicSwapTest(BaseTest):
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 . prepare_balance ( Coins . XMR , 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 ) :
@ -577,20 +624,6 @@ class BasicSwapTest(BaseTest):
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 ) :
logging . info ( ' ---------- Test {} to {} same client ' . format ( coin_from . name , coin_to . name ) )
swap_clients = self . swap_clients
ci_to = swap_clients [ 0 ] . ci ( coin_to )
amt_swap = make_int ( random . uniform ( 0.1 , 2.0 ) , scale = 8 , r = 1 )
rate_swap = ci_to . make_int ( random . uniform ( 0.2 , 20.0 ) , r = 1 )
offer_id = swap_clients [ 1 ] . postOffer ( coin_from , coin_to , amt_swap , rate_swap , amt_swap , SwapTypes . XMR_SWAP , auto_accept_bids = True )
bid_id = swap_clients [ 1 ] . postXmrBid ( offer_id , amt_swap )
wait_for_bid ( test_delay_event , swap_clients [ 1 ] , bid_id , BidStates . SWAP_COMPLETED , wait_for = 180 )
def test_05_self_bid ( self ) :
if not self . has_segwit :
return
@ -604,12 +637,17 @@ class BasicSwapTest(BaseTest):
def test_05_self_bid_from_part ( self ) :
self . do_test_05_self_bid ( Coins . PART , self . test_coin_from )
def test_05_self_bid_rev ( self ) :
if not self . has_segwit :
return
self . do_test_05_self_bid ( Coins . XMR , self . test_coin_from )
def test_06_preselect_inputs ( self ) :
tla_from = self . test_coin_from . name
logging . info ( ' ---------- Test {} Preselected inputs ' . format ( tla_from ) )
swap_clients = self . swap_clients
self . prepare_balance ( tla _from, 100.0 , 1802 , 1800 )
self . prepare_balance ( self . test_coin _from, 100.0 , 1802 , 1800 )
js_w2 = read_json_api ( 1802 , ' wallets ' )
assert ( float ( js_w2 [ tla_from ] [ ' balance ' ] ) > = 100.0 )
@ -739,7 +777,52 @@ class TestBTC(BasicSwapTest):
assert ( js_0 [ ' PART ' ] [ ' encrypted ' ] is True )
assert ( js_0 [ ' PART ' ] [ ' locked ' ] is False )
super ( ) . test_01_full_swap ( )
super ( ) . test_01_a_full_swap ( )
class TestBTC_PARTB ( TestFunctions ) :
__test__ = True
test_coin_from = Coins . BTC
test_coin_to = Coins . PART_BLIND
start_ltc_nodes = False
base_rpc_port = BTC_BASE_RPC_PORT
def test_01_a_full_swap ( self ) :
self . prepare_balance ( self . test_coin_to , 100.0 , 1801 , 1800 )
self . do_test_01_full_swap ( self . test_coin_from , self . test_coin_to )
def test_01_b_full_swap_reverse ( self ) :
self . prepare_balance ( self . test_coin_to , 100.0 , 1800 , 1800 )
self . do_test_01_full_swap ( self . test_coin_to , self . test_coin_from )
def test_02_a_leader_recover_a_lock_tx ( self ) :
self . prepare_balance ( self . test_coin_to , 100.0 , 1801 , 1800 )
self . do_test_02_leader_recover_a_lock_tx ( self . test_coin_from , self . test_coin_to )
def test_02_b_leader_recover_a_lock_tx_reverse ( self ) :
self . prepare_balance ( self . test_coin_to , 100.0 , 1800 , 1800 )
self . do_test_02_leader_recover_a_lock_tx ( self . test_coin_to , self . test_coin_from )
def test_03_a_follower_recover_a_lock_tx ( self ) :
self . prepare_balance ( self . test_coin_to , 100.0 , 1801 , 1800 )
self . do_test_03_follower_recover_a_lock_tx ( self . test_coin_from , self . test_coin_to )
def test_03_b_follower_recover_a_lock_tx_reverse ( self ) :
self . prepare_balance ( self . test_coin_to , 100.0 , 1800 , 1800 )
self . do_test_03_follower_recover_a_lock_tx ( self . test_coin_to , self . test_coin_from , lock_value = 12 )
def test_04_a_follower_recover_b_lock_tx ( self ) :
self . prepare_balance ( self . test_coin_to , 100.0 , 1801 , 1800 )
self . do_test_04_follower_recover_b_lock_tx ( self . test_coin_from , self . test_coin_to )
def test_04_b_follower_recover_b_lock_tx_reverse ( self ) :
self . prepare_balance ( self . test_coin_to , 100.0 , 1800 , 1800 )
self . do_test_04_follower_recover_b_lock_tx ( self . test_coin_to , self . test_coin_from )
class TestBTC_PARTA ( TestBTC_PARTB ) :
__test__ = True
test_coin_to = Coins . PART_ANON
if __name__ == ' __main__ ' :