2021-05-27 04:17:18 +00:00
use crate ::asb ::config ::GetDefaults ;
2021-03-02 05:22:39 +00:00
use crate ::bitcoin ::Amount ;
2021-05-27 04:17:18 +00:00
use crate ::env ;
use crate ::env ::GetConfig ;
use anyhow ::{ bail , Result } ;
2021-05-07 03:25:25 +00:00
use bitcoin ::Address ;
2021-05-27 04:17:18 +00:00
use serde ::Serialize ;
use std ::ffi ::OsString ;
2021-02-11 04:07:01 +00:00
use std ::path ::PathBuf ;
2021-05-27 04:17:18 +00:00
use structopt ::StructOpt ;
2021-04-27 04:51:53 +00:00
use uuid ::Uuid ;
2021-02-11 04:07:01 +00:00
2021-05-27 04:17:18 +00:00
pub fn parse_args < I , T > ( raw_args : I ) -> Result < Arguments >
where
I : IntoIterator < Item = T > ,
T : Into < OsString > + Clone ,
{
let matches = RawArguments ::clap ( ) . get_matches_from_safe ( raw_args ) ? ;
let args = RawArguments ::from_clap ( & matches ) ;
2021-09-09 11:14:57 +00:00
let json = args . json ;
2021-09-10 05:35:59 +00:00
let disable_timestamp = args . disable_timestamp ;
2021-09-09 11:14:57 +00:00
let testnet = args . testnet ;
2021-05-27 04:17:18 +00:00
let config = args . config ;
let command : RawCommand = args . cmd ;
let arguments = match command {
RawCommand ::Start { resume_only } = > Arguments {
2021-09-09 11:14:57 +00:00
testnet ,
json ,
2021-09-10 05:35:59 +00:00
disable_timestamp ,
2021-09-09 11:14:57 +00:00
config_path : config_path ( config , testnet ) ? ,
env_config : env_config ( testnet ) ,
2021-05-27 04:17:18 +00:00
cmd : Command ::Start { resume_only } ,
} ,
RawCommand ::History = > Arguments {
2021-09-09 11:14:57 +00:00
testnet ,
json ,
2021-09-10 05:35:59 +00:00
disable_timestamp ,
2021-09-09 11:14:57 +00:00
config_path : config_path ( config , testnet ) ? ,
env_config : env_config ( testnet ) ,
2021-05-27 04:17:18 +00:00
cmd : Command ::History ,
} ,
RawCommand ::WithdrawBtc { amount , address } = > Arguments {
2021-09-09 11:14:57 +00:00
testnet ,
json ,
2021-09-10 05:35:59 +00:00
disable_timestamp ,
2021-09-09 11:14:57 +00:00
config_path : config_path ( config , testnet ) ? ,
env_config : env_config ( testnet ) ,
2021-05-27 04:17:18 +00:00
cmd : Command ::WithdrawBtc {
amount ,
2021-09-09 11:14:57 +00:00
address : bitcoin_address ( address , testnet ) ? ,
2021-05-27 04:17:18 +00:00
} ,
} ,
RawCommand ::Balance = > Arguments {
2021-09-09 11:14:57 +00:00
testnet ,
json ,
2021-09-10 05:35:59 +00:00
disable_timestamp ,
2021-09-09 11:14:57 +00:00
config_path : config_path ( config , testnet ) ? ,
env_config : env_config ( testnet ) ,
2021-05-27 04:17:18 +00:00
cmd : Command ::Balance ,
} ,
2021-09-27 23:37:51 +00:00
RawCommand ::Config = > Arguments {
testnet ,
json ,
disable_timestamp ,
config_path : config_path ( config , testnet ) ? ,
env_config : env_config ( testnet ) ,
cmd : Command ::Config ,
} ,
2021-10-01 00:36:08 +00:00
RawCommand ::ExportBitcoinWallet = > Arguments {
testnet ,
json ,
disable_timestamp ,
config_path : config_path ( config , testnet ) ? ,
env_config : env_config ( testnet ) ,
cmd : Command ::ExportBitcoinWallet ,
} ,
2021-06-21 01:22:45 +00:00
RawCommand ::ManualRecovery ( ManualRecovery ::Redeem {
2021-09-01 23:16:25 +00:00
redeem_params : RecoverCommandParams { swap_id } ,
2021-06-21 01:22:45 +00:00
do_not_await_finality ,
} ) = > Arguments {
2021-09-09 11:14:57 +00:00
testnet ,
json ,
2021-09-10 05:35:59 +00:00
disable_timestamp ,
2021-09-09 11:14:57 +00:00
config_path : config_path ( config , testnet ) ? ,
env_config : env_config ( testnet ) ,
2021-06-21 01:22:45 +00:00
cmd : Command ::Redeem {
swap_id ,
2021-09-01 23:16:25 +00:00
2021-05-27 04:17:18 +00:00
do_not_await_finality ,
} ,
} ,
2021-06-21 01:22:45 +00:00
RawCommand ::ManualRecovery ( ManualRecovery ::Cancel {
2021-09-01 23:16:25 +00:00
cancel_params : RecoverCommandParams { swap_id } ,
2021-06-21 01:22:45 +00:00
} ) = > Arguments {
2021-09-09 11:14:57 +00:00
testnet ,
json ,
2021-09-10 05:35:59 +00:00
disable_timestamp ,
2021-09-09 11:14:57 +00:00
config_path : config_path ( config , testnet ) ? ,
env_config : env_config ( testnet ) ,
2021-09-01 23:16:25 +00:00
cmd : Command ::Cancel { swap_id } ,
2021-06-21 01:22:45 +00:00
} ,
RawCommand ::ManualRecovery ( ManualRecovery ::Refund {
2021-09-01 23:16:25 +00:00
refund_params : RecoverCommandParams { swap_id } ,
2021-06-21 01:22:45 +00:00
} ) = > Arguments {
2021-09-09 11:14:57 +00:00
testnet ,
json ,
2021-09-10 05:35:59 +00:00
disable_timestamp ,
2021-09-09 11:14:57 +00:00
config_path : config_path ( config , testnet ) ? ,
env_config : env_config ( testnet ) ,
2021-09-01 23:16:25 +00:00
cmd : Command ::Refund { swap_id } ,
2021-06-21 01:22:45 +00:00
} ,
RawCommand ::ManualRecovery ( ManualRecovery ::Punish {
2021-09-01 23:16:25 +00:00
punish_params : RecoverCommandParams { swap_id } ,
2021-06-21 01:22:45 +00:00
} ) = > Arguments {
2021-09-09 11:14:57 +00:00
testnet ,
json ,
2021-09-10 05:35:59 +00:00
disable_timestamp ,
2021-09-09 11:14:57 +00:00
config_path : config_path ( config , testnet ) ? ,
env_config : env_config ( testnet ) ,
2021-09-01 23:16:25 +00:00
cmd : Command ::Punish { swap_id } ,
2021-06-21 01:22:45 +00:00
} ,
RawCommand ::ManualRecovery ( ManualRecovery ::SafelyAbort { swap_id } ) = > Arguments {
2021-09-09 11:14:57 +00:00
testnet ,
json ,
2021-09-10 05:35:59 +00:00
disable_timestamp ,
2021-09-09 11:14:57 +00:00
config_path : config_path ( config , testnet ) ? ,
env_config : env_config ( testnet ) ,
2021-06-21 01:22:45 +00:00
cmd : Command ::SafelyAbort { swap_id } ,
} ,
2021-05-27 04:17:18 +00:00
} ;
Ok ( arguments )
}
fn bitcoin_address ( address : Address , is_testnet : bool ) -> Result < Address > {
let network = if is_testnet {
bitcoin ::Network ::Testnet
} else {
bitcoin ::Network ::Bitcoin
} ;
if address . network ! = network {
bail! ( BitcoinAddressNetworkMismatch {
expected : network ,
actual : address . network
} ) ;
}
Ok ( address )
}
fn config_path ( config : Option < PathBuf > , is_testnet : bool ) -> Result < PathBuf > {
let config_path = if let Some ( config_path ) = config {
config_path
} else if is_testnet {
env ::Testnet ::getConfigFileDefaults ( ) ? . config_path
} else {
env ::Mainnet ::getConfigFileDefaults ( ) ? . config_path
} ;
Ok ( config_path )
}
fn env_config ( is_testnet : bool ) -> env ::Config {
if is_testnet {
env ::Testnet ::get_config ( )
} else {
env ::Mainnet ::get_config ( )
}
}
2023-01-10 12:43:07 +00:00
#[ derive(thiserror::Error, Debug, Clone, Copy, PartialEq, Eq, Serialize) ]
2021-05-27 04:17:18 +00:00
#[ error( " Invalid Bitcoin address provided, expected address on network {expected:?} but address provided is on {actual:?} " ) ]
pub struct BitcoinAddressNetworkMismatch {
#[ serde(with = " crate::bitcoin::network " ) ]
expected : bitcoin ::Network ,
#[ serde(with = " crate::bitcoin::network " ) ]
actual : bitcoin ::Network ,
}
2023-01-10 12:43:07 +00:00
#[ derive(Debug, PartialEq, Eq) ]
2021-05-27 04:17:18 +00:00
pub struct Arguments {
pub testnet : bool ,
pub json : bool ,
2021-09-10 05:35:59 +00:00
pub disable_timestamp : bool ,
2021-05-27 04:17:18 +00:00
pub config_path : PathBuf ,
pub env_config : env ::Config ,
pub cmd : Command ,
}
2023-01-10 12:43:07 +00:00
#[ derive(Debug, PartialEq, Eq) ]
2021-05-27 04:17:18 +00:00
pub enum Command {
Start {
resume_only : bool ,
} ,
History ,
2021-09-27 23:37:51 +00:00
Config ,
2021-05-27 04:17:18 +00:00
WithdrawBtc {
amount : Option < Amount > ,
address : Address ,
} ,
Balance ,
Redeem {
swap_id : Uuid ,
do_not_await_finality : bool ,
} ,
Cancel {
swap_id : Uuid ,
} ,
Refund {
swap_id : Uuid ,
} ,
Punish {
swap_id : Uuid ,
} ,
SafelyAbort {
swap_id : Uuid ,
} ,
2021-10-01 00:36:08 +00:00
ExportBitcoinWallet ,
2021-05-27 04:17:18 +00:00
}
2021-02-11 04:07:01 +00:00
#[ derive(structopt::StructOpt, Debug) ]
2021-03-18 00:25:31 +00:00
#[ structopt(
name = " asb " ,
2021-03-26 03:31:14 +00:00
about = " Automated Swap Backend for swapping XMR for BTC " ,
2021-07-07 07:44:49 +00:00
author ,
version = env! ( " VERGEN_GIT_SEMVER_LIGHTWEIGHT " )
2021-03-18 00:25:31 +00:00
) ]
2021-05-27 04:17:18 +00:00
pub struct RawArguments {
2021-05-10 08:06:10 +00:00
#[ structopt(long, help = " Swap on testnet " ) ]
pub testnet : bool ,
2021-05-10 02:03:43 +00:00
#[ structopt(
short ,
long = " json " ,
help = " Changes the log messages to json vs plain-text. If you run ASB as a service, it is recommended to set this to true to simplify log analyses. "
) ]
pub json : bool ,
2021-09-09 11:35:03 +00:00
#[ structopt(
short ,
2021-09-10 05:35:59 +00:00
long = " disable-timestamp " ,
help = " Disable timestamping of log messages "
2021-09-09 11:35:03 +00:00
) ]
2021-09-10 05:35:59 +00:00
pub disable_timestamp : bool ,
2021-09-09 11:35:03 +00:00
2021-02-11 04:07:01 +00:00
#[ structopt(
long = " config " ,
help = " Provide a custom path to the configuration file. The configuration file must be a toml file. " ,
parse ( from_os_str )
) ]
pub config : Option < PathBuf > ,
#[ structopt(subcommand) ]
2021-05-27 04:17:18 +00:00
pub cmd : RawCommand ,
2021-02-11 04:07:01 +00:00
}
#[ derive(structopt::StructOpt, Debug) ]
#[ structopt(name = " xmr_btc-swap " , about = " XMR BTC atomic swap " ) ]
2021-05-27 04:17:18 +00:00
pub enum RawCommand {
2021-04-28 07:29:25 +00:00
#[ structopt(about = " Main command to run the ASB. " ) ]
2021-02-25 02:54:12 +00:00
Start {
2021-04-29 09:26:19 +00:00
#[ structopt(
long = " resume-only " ,
help = " For maintenance only. When set, no new swap requests will be accepted, but existing unfinished swaps will be resumed. "
) ]
resume_only : bool ,
2021-02-25 02:54:12 +00:00
} ,
2021-04-28 07:29:25 +00:00
#[ structopt(about = " Prints swap-id and the state of each swap ever made. " ) ]
2021-02-11 04:07:01 +00:00
History ,
2021-09-27 23:37:51 +00:00
#[ structopt(about = " Prints the current config " ) ]
Config ,
2021-04-28 07:29:25 +00:00
#[ structopt(about = " Allows withdrawing BTC from the internal Bitcoin wallet. " ) ]
2021-03-31 05:55:28 +00:00
WithdrawBtc {
#[ structopt(
long = " amount " ,
2022-01-16 20:11:35 +00:00
help = " Optionally specify the amount of Bitcoin to be withdrawn. If not specified the wallet will be drained. Amount must be specified in quotes with denomination, e.g `--amount '0.1 BTC'` "
2021-03-31 05:55:28 +00:00
) ]
amount : Option < Amount > ,
#[ structopt(long = " address " , help = " The address to receive the Bitcoin. " ) ]
address : Address ,
} ,
2021-04-28 07:29:25 +00:00
#[ structopt(
about = " Prints the Bitcoin and Monero balance. Requires the monero-wallet-rpc to be running. "
) ]
2021-03-31 06:03:51 +00:00
Balance ,
2021-10-01 00:36:08 +00:00
#[ structopt(about = " Print the internal bitcoin wallet descriptor. " ) ]
ExportBitcoinWallet ,
2021-04-27 04:51:53 +00:00
#[ structopt(about = " Contains sub-commands for recovering a swap manually. " ) ]
ManualRecovery ( ManualRecovery ) ,
}
#[ derive(structopt::StructOpt, Debug) ]
pub enum ManualRecovery {
2021-04-28 06:13:04 +00:00
#[ structopt(
about = " Publishes the Bitcoin redeem transaction. This requires that we learned the encrypted signature from Bob and is only safe if no timelock has expired. "
) ]
Redeem {
#[ structopt(flatten) ]
redeem_params : RecoverCommandParams ,
#[ structopt(
long = " do_not_await_finality " ,
help = " If this flag is present we exit directly after publishing the redeem transaction without waiting for the transaction to be included in a block "
) ]
do_not_await_finality : bool ,
} ,
2021-04-27 04:51:53 +00:00
#[ structopt(
about = " Publishes the Bitcoin cancel transaction. By default, the cancel timelock will be enforced. A confirmed cancel transaction enables refund and punish. "
) ]
Cancel {
#[ structopt(flatten) ]
cancel_params : RecoverCommandParams ,
} ,
#[ structopt(
about = " Publishes the Monero refund transaction. By default, a swap-state where the cancel transaction was already published will be enforced. This command requires the counterparty Bitcoin refund transaction and will error if it was not published yet. "
) ]
Refund {
#[ structopt(flatten) ]
refund_params : RecoverCommandParams ,
} ,
2021-04-28 06:13:04 +00:00
#[ structopt(
about = " Publishes the Bitcoin punish transaction. By default, the punish timelock and a swap-state where the cancel transaction was already published will be enforced. "
) ]
Punish {
#[ structopt(flatten) ]
punish_params : RecoverCommandParams ,
} ,
#[ structopt(about = " Safely Abort requires the swap to be in a state prior to locking XMR. " ) ]
SafelyAbort {
#[ structopt(
long = " swap-id " ,
help = " The swap id can be retrieved using the history subcommand "
) ]
swap_id : Uuid ,
} ,
2021-04-27 04:51:53 +00:00
}
#[ derive(structopt::StructOpt, Debug) ]
pub struct RecoverCommandParams {
#[ structopt(
long = " swap-id " ,
help = " The swap id can be retrieved using the history subcommand "
) ]
pub swap_id : Uuid ,
2021-02-11 04:07:01 +00:00
}
2021-05-27 04:17:18 +00:00
#[ cfg(test) ]
mod tests {
use super ::* ;
use std ::str ::FromStr ;
const BINARY_NAME : & str = " asb " ;
const BITCOIN_MAINNET_ADDRESS : & str = " 1KFHE7w8BhaENAswwryaoccDb6qcT6DbYY " ;
const BITCOIN_TESTNET_ADDRESS : & str = " tb1qyccwk4yun26708qg5h6g6we8kxln232wclxf5a " ;
const SWAP_ID : & str = " ea030832-3be9-454f-bb98-5ea9a788406b " ;
#[ test ]
2021-09-10 05:12:54 +00:00
fn ensure_start_command_mapping_mainnet ( ) {
2021-05-27 04:17:18 +00:00
let default_mainnet_conf_path = env ::Mainnet ::getConfigFileDefaults ( ) . unwrap ( ) . config_path ;
let mainnet_env_config = env ::Mainnet ::get_config ( ) ;
let raw_ars = vec! [ BINARY_NAME , " start " ] ;
let expected_args = Arguments {
testnet : false ,
json : false ,
2021-09-10 05:35:59 +00:00
disable_timestamp : false ,
2021-09-10 05:12:54 +00:00
config_path : default_mainnet_conf_path ,
2021-05-27 04:17:18 +00:00
env_config : mainnet_env_config ,
cmd : Command ::Start { resume_only : false } ,
} ;
let args = parse_args ( raw_ars ) . unwrap ( ) ;
assert_eq! ( expected_args , args ) ;
2021-09-10 05:12:54 +00:00
}
#[ test ]
fn ensure_history_command_mapping_mainnet ( ) {
let default_mainnet_conf_path = env ::Mainnet ::getConfigFileDefaults ( ) . unwrap ( ) . config_path ;
let mainnet_env_config = env ::Mainnet ::get_config ( ) ;
2021-05-27 04:17:18 +00:00
let raw_ars = vec! [ BINARY_NAME , " history " ] ;
let expected_args = Arguments {
testnet : false ,
json : false ,
2021-09-10 05:35:59 +00:00
disable_timestamp : false ,
2021-09-10 05:12:54 +00:00
config_path : default_mainnet_conf_path ,
2021-05-27 04:17:18 +00:00
env_config : mainnet_env_config ,
cmd : Command ::History ,
} ;
let args = parse_args ( raw_ars ) . unwrap ( ) ;
assert_eq! ( expected_args , args ) ;
2021-09-10 05:12:54 +00:00
}
#[ test ]
fn ensure_balance_command_mapping_mainnet ( ) {
let default_mainnet_conf_path = env ::Mainnet ::getConfigFileDefaults ( ) . unwrap ( ) . config_path ;
let mainnet_env_config = env ::Mainnet ::get_config ( ) ;
2021-05-27 04:17:18 +00:00
let raw_ars = vec! [ BINARY_NAME , " balance " ] ;
let expected_args = Arguments {
testnet : false ,
json : false ,
2021-09-10 05:35:59 +00:00
disable_timestamp : false ,
2021-09-10 05:12:54 +00:00
config_path : default_mainnet_conf_path ,
2021-05-27 04:17:18 +00:00
env_config : mainnet_env_config ,
cmd : Command ::Balance ,
} ;
let args = parse_args ( raw_ars ) . unwrap ( ) ;
assert_eq! ( expected_args , args ) ;
2021-09-10 05:12:54 +00:00
}
2021-05-27 04:17:18 +00:00
2021-09-10 05:12:54 +00:00
#[ test ]
fn ensure_withdraw_command_mapping_mainnet ( ) {
let default_mainnet_conf_path = env ::Mainnet ::getConfigFileDefaults ( ) . unwrap ( ) . config_path ;
let mainnet_env_config = env ::Mainnet ::get_config ( ) ;
2021-05-27 04:17:18 +00:00
let raw_ars = vec! [
BINARY_NAME ,
" withdraw-btc " ,
" --address " ,
BITCOIN_MAINNET_ADDRESS ,
] ;
let expected_args = Arguments {
testnet : false ,
json : false ,
2021-09-10 05:35:59 +00:00
disable_timestamp : false ,
2021-09-10 05:12:54 +00:00
config_path : default_mainnet_conf_path ,
2021-05-27 04:17:18 +00:00
env_config : mainnet_env_config ,
cmd : Command ::WithdrawBtc {
amount : None ,
address : Address ::from_str ( BITCOIN_MAINNET_ADDRESS ) . unwrap ( ) ,
} ,
} ;
let args = parse_args ( raw_ars ) . unwrap ( ) ;
assert_eq! ( expected_args , args ) ;
2021-09-10 05:12:54 +00:00
}
#[ test ]
fn ensure_cancel_command_mapping_mainnet ( ) {
let default_mainnet_conf_path = env ::Mainnet ::getConfigFileDefaults ( ) . unwrap ( ) . config_path ;
let mainnet_env_config = env ::Mainnet ::get_config ( ) ;
2021-05-27 04:17:18 +00:00
let raw_ars = vec! [
BINARY_NAME ,
" manual-recovery " ,
" cancel " ,
" --swap-id " ,
SWAP_ID ,
] ;
let expected_args = Arguments {
testnet : false ,
json : false ,
2021-09-10 05:35:59 +00:00
disable_timestamp : false ,
2021-09-10 05:12:54 +00:00
config_path : default_mainnet_conf_path ,
2021-05-27 04:17:18 +00:00
env_config : mainnet_env_config ,
cmd : Command ::Cancel {
swap_id : Uuid ::parse_str ( SWAP_ID ) . unwrap ( ) ,
} ,
} ;
let args = parse_args ( raw_ars ) . unwrap ( ) ;
assert_eq! ( expected_args , args ) ;
2021-09-10 05:12:54 +00:00
}
#[ test ]
fn ensure_refund_command_mappin_mainnet ( ) {
let default_mainnet_conf_path = env ::Mainnet ::getConfigFileDefaults ( ) . unwrap ( ) . config_path ;
let mainnet_env_config = env ::Mainnet ::get_config ( ) ;
2021-05-27 04:17:18 +00:00
let raw_ars = vec! [
BINARY_NAME ,
" manual-recovery " ,
" refund " ,
" --swap-id " ,
SWAP_ID ,
] ;
let expected_args = Arguments {
testnet : false ,
json : false ,
2021-09-10 05:35:59 +00:00
disable_timestamp : false ,
2021-09-10 05:12:54 +00:00
config_path : default_mainnet_conf_path ,
2021-05-27 04:17:18 +00:00
env_config : mainnet_env_config ,
cmd : Command ::Refund {
swap_id : Uuid ::parse_str ( SWAP_ID ) . unwrap ( ) ,
} ,
} ;
let args = parse_args ( raw_ars ) . unwrap ( ) ;
assert_eq! ( expected_args , args ) ;
2021-09-10 05:12:54 +00:00
}
#[ test ]
fn ensure_punish_command_mapping_mainnet ( ) {
let default_mainnet_conf_path = env ::Mainnet ::getConfigFileDefaults ( ) . unwrap ( ) . config_path ;
let mainnet_env_config = env ::Mainnet ::get_config ( ) ;
2021-05-27 04:17:18 +00:00
let raw_ars = vec! [
BINARY_NAME ,
" manual-recovery " ,
" punish " ,
" --swap-id " ,
SWAP_ID ,
] ;
let expected_args = Arguments {
testnet : false ,
json : false ,
2021-09-10 05:35:59 +00:00
disable_timestamp : false ,
2021-09-10 05:12:54 +00:00
config_path : default_mainnet_conf_path ,
2021-05-27 04:17:18 +00:00
env_config : mainnet_env_config ,
cmd : Command ::Punish {
swap_id : Uuid ::parse_str ( SWAP_ID ) . unwrap ( ) ,
} ,
} ;
let args = parse_args ( raw_ars ) . unwrap ( ) ;
assert_eq! ( expected_args , args ) ;
2021-09-10 05:12:54 +00:00
}
#[ test ]
fn ensure_safely_abort_command_mapping_mainnet ( ) {
let default_mainnet_conf_path = env ::Mainnet ::getConfigFileDefaults ( ) . unwrap ( ) . config_path ;
let mainnet_env_config = env ::Mainnet ::get_config ( ) ;
2021-05-27 04:17:18 +00:00
let raw_ars = vec! [
BINARY_NAME ,
" manual-recovery " ,
" safely-abort " ,
" --swap-id " ,
SWAP_ID ,
] ;
let expected_args = Arguments {
testnet : false ,
json : false ,
2021-09-10 05:35:59 +00:00
disable_timestamp : false ,
2021-05-27 04:17:18 +00:00
config_path : default_mainnet_conf_path ,
env_config : mainnet_env_config ,
cmd : Command ::SafelyAbort {
swap_id : Uuid ::parse_str ( SWAP_ID ) . unwrap ( ) ,
} ,
} ;
let args = parse_args ( raw_ars ) . unwrap ( ) ;
assert_eq! ( expected_args , args ) ;
}
#[ test ]
2021-09-10 05:12:54 +00:00
fn ensure_start_command_mapping_for_testnet ( ) {
2021-05-27 04:17:18 +00:00
let default_testnet_conf_path = env ::Testnet ::getConfigFileDefaults ( ) . unwrap ( ) . config_path ;
let testnet_env_config = env ::Testnet ::get_config ( ) ;
let raw_ars = vec! [ BINARY_NAME , " --testnet " , " start " ] ;
let expected_args = Arguments {
testnet : true ,
json : false ,
2021-09-10 05:35:59 +00:00
disable_timestamp : false ,
2021-09-10 05:12:54 +00:00
config_path : default_testnet_conf_path ,
2021-05-27 04:17:18 +00:00
env_config : testnet_env_config ,
cmd : Command ::Start { resume_only : false } ,
} ;
let args = parse_args ( raw_ars ) . unwrap ( ) ;
assert_eq! ( expected_args , args ) ;
2021-09-10 05:12:54 +00:00
}
#[ test ]
fn ensure_history_command_mapping_testnet ( ) {
let default_testnet_conf_path = env ::Testnet ::getConfigFileDefaults ( ) . unwrap ( ) . config_path ;
let testnet_env_config = env ::Testnet ::get_config ( ) ;
2021-05-27 04:17:18 +00:00
let raw_ars = vec! [ BINARY_NAME , " --testnet " , " history " ] ;
let expected_args = Arguments {
testnet : true ,
json : false ,
2021-09-10 05:35:59 +00:00
disable_timestamp : false ,
2021-09-10 05:12:54 +00:00
config_path : default_testnet_conf_path ,
2021-05-27 04:17:18 +00:00
env_config : testnet_env_config ,
cmd : Command ::History ,
} ;
let args = parse_args ( raw_ars ) . unwrap ( ) ;
assert_eq! ( expected_args , args ) ;
2021-09-10 05:12:54 +00:00
}
#[ test ]
fn ensure_balance_command_mapping_testnet ( ) {
let default_testnet_conf_path = env ::Testnet ::getConfigFileDefaults ( ) . unwrap ( ) . config_path ;
let testnet_env_config = env ::Testnet ::get_config ( ) ;
2021-05-27 04:17:18 +00:00
let raw_ars = vec! [ BINARY_NAME , " --testnet " , " balance " ] ;
let expected_args = Arguments {
testnet : true ,
json : false ,
2021-09-10 05:35:59 +00:00
disable_timestamp : false ,
2021-09-10 05:12:54 +00:00
config_path : default_testnet_conf_path ,
2021-05-27 04:17:18 +00:00
env_config : testnet_env_config ,
cmd : Command ::Balance ,
} ;
let args = parse_args ( raw_ars ) . unwrap ( ) ;
assert_eq! ( expected_args , args ) ;
2021-09-10 05:12:54 +00:00
}
#[ test ]
fn ensure_withdraw_command_mapping_testnet ( ) {
let default_testnet_conf_path = env ::Testnet ::getConfigFileDefaults ( ) . unwrap ( ) . config_path ;
let testnet_env_config = env ::Testnet ::get_config ( ) ;
2021-05-27 04:17:18 +00:00
let raw_ars = vec! [
BINARY_NAME ,
" --testnet " ,
" withdraw-btc " ,
" --address " ,
BITCOIN_TESTNET_ADDRESS ,
] ;
let expected_args = Arguments {
testnet : true ,
json : false ,
2021-09-10 05:35:59 +00:00
disable_timestamp : false ,
2021-09-10 05:12:54 +00:00
config_path : default_testnet_conf_path ,
2021-05-27 04:17:18 +00:00
env_config : testnet_env_config ,
cmd : Command ::WithdrawBtc {
amount : None ,
address : Address ::from_str ( BITCOIN_TESTNET_ADDRESS ) . unwrap ( ) ,
} ,
} ;
let args = parse_args ( raw_ars ) . unwrap ( ) ;
assert_eq! ( expected_args , args ) ;
2021-09-10 05:12:54 +00:00
}
#[ test ]
fn ensure_cancel_command_mapping_testnet ( ) {
let default_testnet_conf_path = env ::Testnet ::getConfigFileDefaults ( ) . unwrap ( ) . config_path ;
let testnet_env_config = env ::Testnet ::get_config ( ) ;
2021-05-27 04:17:18 +00:00
let raw_ars = vec! [
BINARY_NAME ,
" --testnet " ,
" manual-recovery " ,
" cancel " ,
" --swap-id " ,
SWAP_ID ,
] ;
let expected_args = Arguments {
testnet : true ,
json : false ,
2021-09-10 05:35:59 +00:00
disable_timestamp : false ,
2021-09-10 05:12:54 +00:00
config_path : default_testnet_conf_path ,
2021-05-27 04:17:18 +00:00
env_config : testnet_env_config ,
cmd : Command ::Cancel {
swap_id : Uuid ::parse_str ( SWAP_ID ) . unwrap ( ) ,
} ,
} ;
let args = parse_args ( raw_ars ) . unwrap ( ) ;
assert_eq! ( expected_args , args ) ;
2021-09-10 05:12:54 +00:00
}
#[ test ]
fn ensure_refund_command_mapping_testnet ( ) {
let default_testnet_conf_path = env ::Testnet ::getConfigFileDefaults ( ) . unwrap ( ) . config_path ;
let testnet_env_config = env ::Testnet ::get_config ( ) ;
2021-05-27 04:17:18 +00:00
let raw_ars = vec! [
BINARY_NAME ,
" --testnet " ,
" manual-recovery " ,
" refund " ,
" --swap-id " ,
SWAP_ID ,
] ;
let expected_args = Arguments {
testnet : true ,
json : false ,
2021-09-10 05:35:59 +00:00
disable_timestamp : false ,
2021-09-10 05:12:54 +00:00
config_path : default_testnet_conf_path ,
2021-05-27 04:17:18 +00:00
env_config : testnet_env_config ,
cmd : Command ::Refund {
swap_id : Uuid ::parse_str ( SWAP_ID ) . unwrap ( ) ,
} ,
} ;
let args = parse_args ( raw_ars ) . unwrap ( ) ;
assert_eq! ( expected_args , args ) ;
2021-09-10 05:12:54 +00:00
}
#[ test ]
fn ensure_punish_command_mapping_testnet ( ) {
let default_testnet_conf_path = env ::Testnet ::getConfigFileDefaults ( ) . unwrap ( ) . config_path ;
let testnet_env_config = env ::Testnet ::get_config ( ) ;
2021-05-27 04:17:18 +00:00
let raw_ars = vec! [
BINARY_NAME ,
" --testnet " ,
" manual-recovery " ,
" punish " ,
" --swap-id " ,
SWAP_ID ,
] ;
let expected_args = Arguments {
testnet : true ,
json : false ,
2021-09-10 05:35:59 +00:00
disable_timestamp : false ,
2021-09-10 05:12:54 +00:00
config_path : default_testnet_conf_path ,
2021-05-27 04:17:18 +00:00
env_config : testnet_env_config ,
cmd : Command ::Punish {
swap_id : Uuid ::parse_str ( SWAP_ID ) . unwrap ( ) ,
} ,
} ;
let args = parse_args ( raw_ars ) . unwrap ( ) ;
assert_eq! ( expected_args , args ) ;
2021-09-10 05:12:54 +00:00
}
#[ test ]
fn ensure_safely_abort_command_mapping_testnet ( ) {
let default_testnet_conf_path = env ::Testnet ::getConfigFileDefaults ( ) . unwrap ( ) . config_path ;
let testnet_env_config = env ::Testnet ::get_config ( ) ;
2021-05-27 04:17:18 +00:00
let raw_ars = vec! [
BINARY_NAME ,
" --testnet " ,
" manual-recovery " ,
" safely-abort " ,
" --swap-id " ,
SWAP_ID ,
] ;
let expected_args = Arguments {
testnet : true ,
json : false ,
2021-09-10 05:35:59 +00:00
disable_timestamp : false ,
2021-05-27 04:17:18 +00:00
config_path : default_testnet_conf_path ,
env_config : testnet_env_config ,
cmd : Command ::SafelyAbort {
swap_id : Uuid ::parse_str ( SWAP_ID ) . unwrap ( ) ,
} ,
} ;
let args = parse_args ( raw_ars ) . unwrap ( ) ;
assert_eq! ( expected_args , args ) ;
}
2021-09-10 05:35:59 +00:00
#[ test ]
fn ensure_disable_timestamp_mapping ( ) {
let default_mainnet_conf_path = env ::Mainnet ::getConfigFileDefaults ( ) . unwrap ( ) . config_path ;
let mainnet_env_config = env ::Mainnet ::get_config ( ) ;
let raw_ars = vec! [ BINARY_NAME , " --disable-timestamp " , " start " ] ;
let expected_args = Arguments {
testnet : false ,
json : false ,
disable_timestamp : true ,
config_path : default_mainnet_conf_path ,
env_config : mainnet_env_config ,
cmd : Command ::Start { resume_only : false } ,
} ;
let args = parse_args ( raw_ars ) . unwrap ( ) ;
assert_eq! ( expected_args , args ) ;
}
2021-05-27 04:17:18 +00:00
#[ test ]
fn given_user_provides_config_path_then_no_default_config_path_returned ( ) {
let cp = PathBuf ::from_str ( " /some/config/path " ) . unwrap ( ) ;
let expected = config_path ( Some ( cp . clone ( ) ) , true ) . unwrap ( ) ;
assert_eq! ( expected , cp ) ;
let expected = config_path ( Some ( cp . clone ( ) ) , false ) . unwrap ( ) ;
assert_eq! ( expected , cp )
}
#[ test ]
fn given_bitcoin_address_network_mismatch_then_error ( ) {
let error =
bitcoin_address ( Address ::from_str ( BITCOIN_MAINNET_ADDRESS ) . unwrap ( ) , true ) . unwrap_err ( ) ;
assert_eq! (
error
. downcast_ref ::< BitcoinAddressNetworkMismatch > ( )
. unwrap ( ) ,
& BitcoinAddressNetworkMismatch {
expected : bitcoin ::Network ::Testnet ,
actual : bitcoin ::Network ::Bitcoin
}
) ;
let error = bitcoin_address ( Address ::from_str ( BITCOIN_TESTNET_ADDRESS ) . unwrap ( ) , false )
. unwrap_err ( ) ;
assert_eq! (
error
. downcast_ref ::< BitcoinAddressNetworkMismatch > ( )
. unwrap ( ) ,
& BitcoinAddressNetworkMismatch {
expected : bitcoin ::Network ::Bitcoin ,
actual : bitcoin ::Network ::Testnet
}
) ;
}
}