mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2025-01-27 15:57:14 -05:00
commit
110fc9bbd7
@ -10,7 +10,7 @@ pub use ::bitcoin::{util::amount::Amount, Address, Network, Transaction, Txid};
|
|||||||
pub use ecdsa_fun::{adaptor::EncryptedSignature, fun::Scalar, Signature};
|
pub use ecdsa_fun::{adaptor::EncryptedSignature, fun::Scalar, Signature};
|
||||||
pub use wallet::Wallet;
|
pub use wallet::Wallet;
|
||||||
|
|
||||||
use crate::{bitcoin::timelocks::BlockHeight, config::ExecutionParams};
|
use crate::{bitcoin::timelocks::BlockHeight, execution_params::ExecutionParams};
|
||||||
use ::bitcoin::{
|
use ::bitcoin::{
|
||||||
hashes::{hex::ToHex, Hash},
|
hashes::{hex::ToHex, Hash},
|
||||||
secp256k1,
|
secp256k1,
|
||||||
|
@ -4,7 +4,7 @@ use crate::{
|
|||||||
GetBlockHeight, GetNetwork, GetRawTransaction, SignTxLock, Transaction,
|
GetBlockHeight, GetNetwork, GetRawTransaction, SignTxLock, Transaction,
|
||||||
TransactionBlockHeight, TxLock, WaitForTransactionFinality, WatchForRawTransaction,
|
TransactionBlockHeight, TxLock, WaitForTransactionFinality, WatchForRawTransaction,
|
||||||
},
|
},
|
||||||
config::ExecutionParams,
|
execution_params::ExecutionParams,
|
||||||
};
|
};
|
||||||
use ::bitcoin::{util::psbt::PartiallySignedTransaction, Txid};
|
use ::bitcoin::{util::psbt::PartiallySignedTransaction, Txid};
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
|
@ -1,117 +1,145 @@
|
|||||||
use crate::bitcoin::Timelock;
|
use crate::fs::ensure_directory_exists;
|
||||||
use conquer_once::Lazy;
|
use anyhow::{Context, Result};
|
||||||
use std::time::Duration;
|
use config::{Config, ConfigError};
|
||||||
|
use dialoguer::{theme::ColorfulTheme, Input};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::{
|
||||||
|
ffi::OsStr,
|
||||||
|
fs,
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
};
|
||||||
|
use tracing::info;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
pub mod seed;
|
||||||
pub struct ExecutionParams {
|
|
||||||
pub bob_time_to_act: Duration,
|
const DEFAULT_BITCOIND_TESTNET_URL: &str = "http://127.0.0.1:18332";
|
||||||
pub bitcoin_finality_confirmations: u32,
|
const DEFAULT_MONERO_WALLET_RPC_TESTNET_URL: &str = "http://127.0.0.1:38083/json_rpc";
|
||||||
pub bitcoin_avg_block_time: Duration,
|
|
||||||
pub monero_finality_confirmations: u32,
|
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, PartialEq)]
|
||||||
pub bitcoin_cancel_timelock: Timelock,
|
pub struct File {
|
||||||
pub bitcoin_punish_timelock: Timelock,
|
pub bitcoin: Bitcoin,
|
||||||
|
pub monero: Monero,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait GetExecutionParams {
|
impl File {
|
||||||
fn get_execution_params() -> ExecutionParams;
|
pub fn read<D>(config_file: D) -> Result<Self, ConfigError>
|
||||||
}
|
where
|
||||||
|
D: AsRef<OsStr>,
|
||||||
|
{
|
||||||
|
let config_file = Path::new(&config_file);
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
let mut config = Config::new();
|
||||||
pub struct Mainnet;
|
config.merge(config::File::from(config_file))?;
|
||||||
|
config.try_into()
|
||||||
#[derive(Clone, Copy)]
|
|
||||||
pub struct Testnet;
|
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
|
||||||
pub struct Regtest;
|
|
||||||
|
|
||||||
impl GetExecutionParams for Mainnet {
|
|
||||||
fn get_execution_params() -> ExecutionParams {
|
|
||||||
ExecutionParams {
|
|
||||||
bob_time_to_act: *mainnet::BOB_TIME_TO_ACT,
|
|
||||||
bitcoin_finality_confirmations: mainnet::BITCOIN_FINALITY_CONFIRMATIONS,
|
|
||||||
bitcoin_avg_block_time: *mainnet::BITCOIN_AVG_BLOCK_TIME,
|
|
||||||
monero_finality_confirmations: mainnet::MONERO_FINALITY_CONFIRMATIONS,
|
|
||||||
bitcoin_cancel_timelock: mainnet::BITCOIN_CANCEL_TIMELOCK,
|
|
||||||
bitcoin_punish_timelock: mainnet::BITCOIN_PUNISH_TIMELOCK,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GetExecutionParams for Testnet {
|
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
|
||||||
fn get_execution_params() -> ExecutionParams {
|
#[serde(deny_unknown_fields)]
|
||||||
ExecutionParams {
|
pub struct Bitcoin {
|
||||||
bob_time_to_act: *testnet::BOB_TIME_TO_ACT,
|
pub bitcoind_url: Url,
|
||||||
bitcoin_finality_confirmations: testnet::BITCOIN_FINALITY_CONFIRMATIONS,
|
pub wallet_name: String,
|
||||||
bitcoin_avg_block_time: *testnet::BITCOIN_AVG_BLOCK_TIME,
|
}
|
||||||
monero_finality_confirmations: testnet::MONERO_FINALITY_CONFIRMATIONS,
|
|
||||||
bitcoin_cancel_timelock: testnet::BITCOIN_CANCEL_TIMELOCK,
|
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
|
||||||
bitcoin_punish_timelock: testnet::BITCOIN_PUNISH_TIMELOCK,
|
#[serde(deny_unknown_fields)]
|
||||||
}
|
pub struct Monero {
|
||||||
|
pub wallet_rpc_url: Url,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(thiserror::Error, Debug, Clone, Copy)]
|
||||||
|
#[error("config not initialized")]
|
||||||
|
pub struct ConfigNotInitialized {}
|
||||||
|
|
||||||
|
pub fn read_config(config_path: PathBuf) -> Result<Result<File, ConfigNotInitialized>> {
|
||||||
|
if config_path.exists() {
|
||||||
|
info!(
|
||||||
|
"Using config file at default path: {}",
|
||||||
|
config_path.display()
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return Ok(Err(ConfigNotInitialized {}));
|
||||||
|
}
|
||||||
|
|
||||||
|
let file = File::read(&config_path)
|
||||||
|
.with_context(|| format!("failed to read config file {}", config_path.display()))?;
|
||||||
|
|
||||||
|
Ok(Ok(file))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn initial_setup<F>(config_path: PathBuf, config_file: F) -> Result<()>
|
||||||
|
where
|
||||||
|
F: Fn() -> Result<File>,
|
||||||
|
{
|
||||||
|
info!("Config file not found, running initial setup...");
|
||||||
|
ensure_directory_exists(config_path.as_path())?;
|
||||||
|
let initial_config = config_file()?;
|
||||||
|
|
||||||
|
let toml = toml::to_string(&initial_config)?;
|
||||||
|
fs::write(&config_path, toml)?;
|
||||||
|
|
||||||
|
info!(
|
||||||
|
"Initial setup complete, config file created at {} ",
|
||||||
|
config_path.as_path().display()
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn query_user_for_initial_testnet_config() -> Result<File> {
|
||||||
|
println!();
|
||||||
|
let bitcoind_url: String = Input::with_theme(&ColorfulTheme::default())
|
||||||
|
.with_prompt("Enter Bitcoind URL (including username and password if applicable) or hit return to use default")
|
||||||
|
.default(DEFAULT_BITCOIND_TESTNET_URL.to_owned())
|
||||||
|
.interact_text()?;
|
||||||
|
let bitcoind_url = Url::parse(bitcoind_url.as_str())?;
|
||||||
|
|
||||||
|
let bitcoin_wallet_name: String = Input::with_theme(&ColorfulTheme::default())
|
||||||
|
.with_prompt("Enter Bitcoind wallet name")
|
||||||
|
.interact_text()?;
|
||||||
|
|
||||||
|
let monero_wallet_rpc_url: String = Input::with_theme(&ColorfulTheme::default())
|
||||||
|
.with_prompt("Enter Monero Wallet RPC URL or hit enter to use default")
|
||||||
|
.default(DEFAULT_MONERO_WALLET_RPC_TESTNET_URL.to_owned())
|
||||||
|
.interact_text()?;
|
||||||
|
let monero_wallet_rpc_url = Url::parse(monero_wallet_rpc_url.as_str())?;
|
||||||
|
println!();
|
||||||
|
|
||||||
|
Ok(File {
|
||||||
|
bitcoin: Bitcoin {
|
||||||
|
bitcoind_url,
|
||||||
|
wallet_name: bitcoin_wallet_name,
|
||||||
|
},
|
||||||
|
monero: Monero {
|
||||||
|
wallet_rpc_url: monero_wallet_rpc_url,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use std::str::FromStr;
|
||||||
|
use tempfile::tempdir;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn config_roundtrip() {
|
||||||
|
let temp_dir = tempdir().unwrap().path().to_path_buf();
|
||||||
|
let config_path = Path::join(&temp_dir, "config.toml");
|
||||||
|
|
||||||
|
let expected = File {
|
||||||
|
bitcoin: Bitcoin {
|
||||||
|
bitcoind_url: Url::from_str("http://127.0.0.1:18332").unwrap(),
|
||||||
|
wallet_name: "alice".to_string(),
|
||||||
|
},
|
||||||
|
monero: Monero {
|
||||||
|
wallet_rpc_url: Url::from_str("http://127.0.0.1:38083/json_rpc").unwrap(),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
initial_setup(config_path.clone(), || Ok(expected.clone())).unwrap();
|
||||||
|
let actual = read_config(config_path).unwrap().unwrap();
|
||||||
|
|
||||||
|
assert_eq!(expected, actual);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GetExecutionParams for Regtest {
|
|
||||||
fn get_execution_params() -> ExecutionParams {
|
|
||||||
ExecutionParams {
|
|
||||||
bob_time_to_act: *regtest::BOB_TIME_TO_ACT,
|
|
||||||
bitcoin_finality_confirmations: regtest::BITCOIN_FINALITY_CONFIRMATIONS,
|
|
||||||
bitcoin_avg_block_time: *regtest::BITCOIN_AVG_BLOCK_TIME,
|
|
||||||
monero_finality_confirmations: regtest::MONERO_FINALITY_CONFIRMATIONS,
|
|
||||||
bitcoin_cancel_timelock: regtest::BITCOIN_CANCEL_TIMELOCK,
|
|
||||||
bitcoin_punish_timelock: regtest::BITCOIN_PUNISH_TIMELOCK,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mod mainnet {
|
|
||||||
use crate::config::*;
|
|
||||||
|
|
||||||
// For each step, we are giving Bob 10 minutes to act.
|
|
||||||
pub static BOB_TIME_TO_ACT: Lazy<Duration> = Lazy::new(|| Duration::from_secs(10 * 60));
|
|
||||||
|
|
||||||
pub static BITCOIN_FINALITY_CONFIRMATIONS: u32 = 3;
|
|
||||||
|
|
||||||
pub static BITCOIN_AVG_BLOCK_TIME: Lazy<Duration> = Lazy::new(|| Duration::from_secs(10 * 60));
|
|
||||||
|
|
||||||
pub static MONERO_FINALITY_CONFIRMATIONS: u32 = 15;
|
|
||||||
|
|
||||||
// Set to 12 hours, arbitrary value to be reviewed properly
|
|
||||||
pub static BITCOIN_CANCEL_TIMELOCK: Timelock = Timelock::new(72);
|
|
||||||
pub static BITCOIN_PUNISH_TIMELOCK: Timelock = Timelock::new(72);
|
|
||||||
}
|
|
||||||
|
|
||||||
mod testnet {
|
|
||||||
use crate::config::*;
|
|
||||||
|
|
||||||
pub static BOB_TIME_TO_ACT: Lazy<Duration> = Lazy::new(|| Duration::from_secs(60 * 60));
|
|
||||||
|
|
||||||
// This does not reflect recommended values for mainnet!
|
|
||||||
pub static BITCOIN_FINALITY_CONFIRMATIONS: u32 = 1;
|
|
||||||
|
|
||||||
pub static BITCOIN_AVG_BLOCK_TIME: Lazy<Duration> = Lazy::new(|| Duration::from_secs(5 * 60));
|
|
||||||
|
|
||||||
// This does not reflect recommended values for mainnet!
|
|
||||||
pub static MONERO_FINALITY_CONFIRMATIONS: u32 = 5;
|
|
||||||
|
|
||||||
// This does not reflect recommended values for mainnet!
|
|
||||||
pub static BITCOIN_CANCEL_TIMELOCK: Timelock = Timelock::new(12);
|
|
||||||
pub static BITCOIN_PUNISH_TIMELOCK: Timelock = Timelock::new(6);
|
|
||||||
}
|
|
||||||
|
|
||||||
mod regtest {
|
|
||||||
use crate::config::*;
|
|
||||||
|
|
||||||
// In test, we set a shorter time to fail fast
|
|
||||||
pub static BOB_TIME_TO_ACT: Lazy<Duration> = Lazy::new(|| Duration::from_secs(30));
|
|
||||||
|
|
||||||
pub static BITCOIN_FINALITY_CONFIRMATIONS: u32 = 1;
|
|
||||||
|
|
||||||
pub static BITCOIN_AVG_BLOCK_TIME: Lazy<Duration> = Lazy::new(|| Duration::from_secs(5));
|
|
||||||
|
|
||||||
pub static MONERO_FINALITY_CONFIRMATIONS: u32 = 1;
|
|
||||||
|
|
||||||
pub static BITCOIN_CANCEL_TIMELOCK: Timelock = Timelock::new(100);
|
|
||||||
|
|
||||||
pub static BITCOIN_PUNISH_TIMELOCK: Timelock = Timelock::new(50);
|
|
||||||
}
|
|
||||||
|
@ -1,145 +0,0 @@
|
|||||||
use crate::fs::ensure_directory_exists;
|
|
||||||
use anyhow::{Context, Result};
|
|
||||||
use config::{Config, ConfigError};
|
|
||||||
use dialoguer::{theme::ColorfulTheme, Input};
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use std::{
|
|
||||||
ffi::OsStr,
|
|
||||||
fs,
|
|
||||||
path::{Path, PathBuf},
|
|
||||||
};
|
|
||||||
use tracing::info;
|
|
||||||
use url::Url;
|
|
||||||
|
|
||||||
pub mod seed;
|
|
||||||
|
|
||||||
const DEFAULT_BITCOIND_TESTNET_URL: &str = "http://127.0.0.1:18332";
|
|
||||||
const DEFAULT_MONERO_WALLET_RPC_TESTNET_URL: &str = "http://127.0.0.1:38083/json_rpc";
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, PartialEq)]
|
|
||||||
pub struct File {
|
|
||||||
pub bitcoin: Bitcoin,
|
|
||||||
pub monero: Monero,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl File {
|
|
||||||
pub fn read<D>(config_file: D) -> Result<Self, ConfigError>
|
|
||||||
where
|
|
||||||
D: AsRef<OsStr>,
|
|
||||||
{
|
|
||||||
let config_file = Path::new(&config_file);
|
|
||||||
|
|
||||||
let mut config = Config::new();
|
|
||||||
config.merge(config::File::from(config_file))?;
|
|
||||||
config.try_into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
|
|
||||||
#[serde(deny_unknown_fields)]
|
|
||||||
pub struct Bitcoin {
|
|
||||||
pub bitcoind_url: Url,
|
|
||||||
pub wallet_name: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
|
|
||||||
#[serde(deny_unknown_fields)]
|
|
||||||
pub struct Monero {
|
|
||||||
pub wallet_rpc_url: Url,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(thiserror::Error, Debug, Clone, Copy)]
|
|
||||||
#[error("config not initialized")]
|
|
||||||
pub struct ConfigNotInitialized {}
|
|
||||||
|
|
||||||
pub fn read_config(config_path: PathBuf) -> Result<Result<File, ConfigNotInitialized>> {
|
|
||||||
if config_path.exists() {
|
|
||||||
info!(
|
|
||||||
"Using config file at default path: {}",
|
|
||||||
config_path.display()
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return Ok(Err(ConfigNotInitialized {}));
|
|
||||||
}
|
|
||||||
|
|
||||||
let file = File::read(&config_path)
|
|
||||||
.with_context(|| format!("failed to read config file {}", config_path.display()))?;
|
|
||||||
|
|
||||||
Ok(Ok(file))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn initial_setup<F>(config_path: PathBuf, config_file: F) -> Result<()>
|
|
||||||
where
|
|
||||||
F: Fn() -> Result<File>,
|
|
||||||
{
|
|
||||||
info!("Config file not found, running initial setup...");
|
|
||||||
ensure_directory_exists(config_path.as_path())?;
|
|
||||||
let initial_config = config_file()?;
|
|
||||||
|
|
||||||
let toml = toml::to_string(&initial_config)?;
|
|
||||||
fs::write(&config_path, toml)?;
|
|
||||||
|
|
||||||
info!(
|
|
||||||
"Initial setup complete, config file created at {} ",
|
|
||||||
config_path.as_path().display()
|
|
||||||
);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn query_user_for_initial_testnet_config() -> Result<File> {
|
|
||||||
println!();
|
|
||||||
let bitcoind_url: String = Input::with_theme(&ColorfulTheme::default())
|
|
||||||
.with_prompt("Enter Bitcoind URL (including username and password if applicable) or hit return to use default")
|
|
||||||
.default(DEFAULT_BITCOIND_TESTNET_URL.to_owned())
|
|
||||||
.interact_text()?;
|
|
||||||
let bitcoind_url = Url::parse(bitcoind_url.as_str())?;
|
|
||||||
|
|
||||||
let bitcoin_wallet_name: String = Input::with_theme(&ColorfulTheme::default())
|
|
||||||
.with_prompt("Enter Bitcoind wallet name")
|
|
||||||
.interact_text()?;
|
|
||||||
|
|
||||||
let monero_wallet_rpc_url: String = Input::with_theme(&ColorfulTheme::default())
|
|
||||||
.with_prompt("Enter Monero Wallet RPC URL or hit enter to use default")
|
|
||||||
.default(DEFAULT_MONERO_WALLET_RPC_TESTNET_URL.to_owned())
|
|
||||||
.interact_text()?;
|
|
||||||
let monero_wallet_rpc_url = Url::parse(monero_wallet_rpc_url.as_str())?;
|
|
||||||
println!();
|
|
||||||
|
|
||||||
Ok(File {
|
|
||||||
bitcoin: Bitcoin {
|
|
||||||
bitcoind_url,
|
|
||||||
wallet_name: bitcoin_wallet_name,
|
|
||||||
},
|
|
||||||
monero: Monero {
|
|
||||||
wallet_rpc_url: monero_wallet_rpc_url,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
use std::str::FromStr;
|
|
||||||
use tempfile::tempdir;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn config_roundtrip() {
|
|
||||||
let temp_dir = tempdir().unwrap().path().to_path_buf();
|
|
||||||
let config_path = Path::join(&temp_dir, "config.toml");
|
|
||||||
|
|
||||||
let expected = File {
|
|
||||||
bitcoin: Bitcoin {
|
|
||||||
bitcoind_url: Url::from_str("http://127.0.0.1:18332").unwrap(),
|
|
||||||
wallet_name: "alice".to_string(),
|
|
||||||
},
|
|
||||||
monero: Monero {
|
|
||||||
wallet_rpc_url: Url::from_str("http://127.0.0.1:38083/json_rpc").unwrap(),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
initial_setup(config_path.clone(), || Ok(expected.clone())).unwrap();
|
|
||||||
let actual = read_config(config_path).unwrap().unwrap();
|
|
||||||
|
|
||||||
assert_eq!(expected, actual);
|
|
||||||
}
|
|
||||||
}
|
|
117
swap/src/execution_params.rs
Normal file
117
swap/src/execution_params.rs
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
use crate::bitcoin::Timelock;
|
||||||
|
use conquer_once::Lazy;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
pub struct ExecutionParams {
|
||||||
|
pub bob_time_to_act: Duration,
|
||||||
|
pub bitcoin_finality_confirmations: u32,
|
||||||
|
pub bitcoin_avg_block_time: Duration,
|
||||||
|
pub monero_finality_confirmations: u32,
|
||||||
|
pub bitcoin_cancel_timelock: Timelock,
|
||||||
|
pub bitcoin_punish_timelock: Timelock,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait GetExecutionParams {
|
||||||
|
fn get_execution_params() -> ExecutionParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct Mainnet;
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct Testnet;
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct Regtest;
|
||||||
|
|
||||||
|
impl GetExecutionParams for Mainnet {
|
||||||
|
fn get_execution_params() -> ExecutionParams {
|
||||||
|
ExecutionParams {
|
||||||
|
bob_time_to_act: *mainnet::BOB_TIME_TO_ACT,
|
||||||
|
bitcoin_finality_confirmations: mainnet::BITCOIN_FINALITY_CONFIRMATIONS,
|
||||||
|
bitcoin_avg_block_time: *mainnet::BITCOIN_AVG_BLOCK_TIME,
|
||||||
|
monero_finality_confirmations: mainnet::MONERO_FINALITY_CONFIRMATIONS,
|
||||||
|
bitcoin_cancel_timelock: mainnet::BITCOIN_CANCEL_TIMELOCK,
|
||||||
|
bitcoin_punish_timelock: mainnet::BITCOIN_PUNISH_TIMELOCK,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GetExecutionParams for Testnet {
|
||||||
|
fn get_execution_params() -> ExecutionParams {
|
||||||
|
ExecutionParams {
|
||||||
|
bob_time_to_act: *testnet::BOB_TIME_TO_ACT,
|
||||||
|
bitcoin_finality_confirmations: testnet::BITCOIN_FINALITY_CONFIRMATIONS,
|
||||||
|
bitcoin_avg_block_time: *testnet::BITCOIN_AVG_BLOCK_TIME,
|
||||||
|
monero_finality_confirmations: testnet::MONERO_FINALITY_CONFIRMATIONS,
|
||||||
|
bitcoin_cancel_timelock: testnet::BITCOIN_CANCEL_TIMELOCK,
|
||||||
|
bitcoin_punish_timelock: testnet::BITCOIN_PUNISH_TIMELOCK,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GetExecutionParams for Regtest {
|
||||||
|
fn get_execution_params() -> ExecutionParams {
|
||||||
|
ExecutionParams {
|
||||||
|
bob_time_to_act: *regtest::BOB_TIME_TO_ACT,
|
||||||
|
bitcoin_finality_confirmations: regtest::BITCOIN_FINALITY_CONFIRMATIONS,
|
||||||
|
bitcoin_avg_block_time: *regtest::BITCOIN_AVG_BLOCK_TIME,
|
||||||
|
monero_finality_confirmations: regtest::MONERO_FINALITY_CONFIRMATIONS,
|
||||||
|
bitcoin_cancel_timelock: regtest::BITCOIN_CANCEL_TIMELOCK,
|
||||||
|
bitcoin_punish_timelock: regtest::BITCOIN_PUNISH_TIMELOCK,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod mainnet {
|
||||||
|
use crate::execution_params::*;
|
||||||
|
|
||||||
|
// For each step, we are giving Bob 10 minutes to act.
|
||||||
|
pub static BOB_TIME_TO_ACT: Lazy<Duration> = Lazy::new(|| Duration::from_secs(10 * 60));
|
||||||
|
|
||||||
|
pub static BITCOIN_FINALITY_CONFIRMATIONS: u32 = 3;
|
||||||
|
|
||||||
|
pub static BITCOIN_AVG_BLOCK_TIME: Lazy<Duration> = Lazy::new(|| Duration::from_secs(10 * 60));
|
||||||
|
|
||||||
|
pub static MONERO_FINALITY_CONFIRMATIONS: u32 = 15;
|
||||||
|
|
||||||
|
// Set to 12 hours, arbitrary value to be reviewed properly
|
||||||
|
pub static BITCOIN_CANCEL_TIMELOCK: Timelock = Timelock::new(72);
|
||||||
|
pub static BITCOIN_PUNISH_TIMELOCK: Timelock = Timelock::new(72);
|
||||||
|
}
|
||||||
|
|
||||||
|
mod testnet {
|
||||||
|
use crate::execution_params::*;
|
||||||
|
|
||||||
|
pub static BOB_TIME_TO_ACT: Lazy<Duration> = Lazy::new(|| Duration::from_secs(60 * 60));
|
||||||
|
|
||||||
|
// This does not reflect recommended values for mainnet!
|
||||||
|
pub static BITCOIN_FINALITY_CONFIRMATIONS: u32 = 1;
|
||||||
|
|
||||||
|
pub static BITCOIN_AVG_BLOCK_TIME: Lazy<Duration> = Lazy::new(|| Duration::from_secs(5 * 60));
|
||||||
|
|
||||||
|
// This does not reflect recommended values for mainnet!
|
||||||
|
pub static MONERO_FINALITY_CONFIRMATIONS: u32 = 5;
|
||||||
|
|
||||||
|
// This does not reflect recommended values for mainnet!
|
||||||
|
pub static BITCOIN_CANCEL_TIMELOCK: Timelock = Timelock::new(12);
|
||||||
|
pub static BITCOIN_PUNISH_TIMELOCK: Timelock = Timelock::new(6);
|
||||||
|
}
|
||||||
|
|
||||||
|
mod regtest {
|
||||||
|
use crate::execution_params::*;
|
||||||
|
|
||||||
|
// In test, we set a shorter time to fail fast
|
||||||
|
pub static BOB_TIME_TO_ACT: Lazy<Duration> = Lazy::new(|| Duration::from_secs(30));
|
||||||
|
|
||||||
|
pub static BITCOIN_FINALITY_CONFIRMATIONS: u32 = 1;
|
||||||
|
|
||||||
|
pub static BITCOIN_AVG_BLOCK_TIME: Lazy<Duration> = Lazy::new(|| Duration::from_secs(5));
|
||||||
|
|
||||||
|
pub static MONERO_FINALITY_CONFIRMATIONS: u32 = 1;
|
||||||
|
|
||||||
|
pub static BITCOIN_CANCEL_TIMELOCK: Timelock = Timelock::new(100);
|
||||||
|
|
||||||
|
pub static BITCOIN_PUNISH_TIMELOCK: Timelock = Timelock::new(50);
|
||||||
|
}
|
@ -17,8 +17,8 @@
|
|||||||
)]
|
)]
|
||||||
|
|
||||||
pub mod bitcoin;
|
pub mod bitcoin;
|
||||||
pub mod config;
|
|
||||||
pub mod database;
|
pub mod database;
|
||||||
|
pub mod execution_params;
|
||||||
pub mod monero;
|
pub mod monero;
|
||||||
pub mod network;
|
pub mod network;
|
||||||
pub mod protocol;
|
pub mod protocol;
|
||||||
|
@ -14,10 +14,10 @@
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
cli::{Command, Options, Resume},
|
cli::{Command, Options, Resume},
|
||||||
config::GetExecutionParams,
|
config::{
|
||||||
configuration::{
|
|
||||||
initial_setup, query_user_for_initial_testnet_config, read_config, ConfigNotInitialized,
|
initial_setup, query_user_for_initial_testnet_config, read_config, ConfigNotInitialized,
|
||||||
},
|
},
|
||||||
|
execution_params::GetExecutionParams,
|
||||||
};
|
};
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use database::Database;
|
use database::Database;
|
||||||
@ -33,8 +33,8 @@ use uuid::Uuid;
|
|||||||
|
|
||||||
pub mod bitcoin;
|
pub mod bitcoin;
|
||||||
pub mod config;
|
pub mod config;
|
||||||
pub mod configuration;
|
|
||||||
pub mod database;
|
pub mod database;
|
||||||
|
pub mod execution_params;
|
||||||
pub mod monero;
|
pub mod monero;
|
||||||
pub mod network;
|
pub mod network;
|
||||||
pub mod protocol;
|
pub mod protocol;
|
||||||
@ -66,14 +66,14 @@ async fn main() -> Result<()> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let db_path = data_dir.join("database");
|
let db_path = data_dir.join("database");
|
||||||
let seed = configuration::seed::Seed::from_file_or_generate(&data_dir)
|
let seed = config::seed::Seed::from_file_or_generate(&data_dir)
|
||||||
.expect("Could not retrieve/initialize seed")
|
.expect("Could not retrieve/initialize seed")
|
||||||
.into();
|
.into();
|
||||||
|
|
||||||
// hardcode to testnet/stagenet
|
// hardcode to testnet/stagenet
|
||||||
let bitcoin_network = bitcoin::Network::Testnet;
|
let bitcoin_network = bitcoin::Network::Testnet;
|
||||||
let monero_network = monero::Network::Stagenet;
|
let monero_network = monero::Network::Stagenet;
|
||||||
let execution_params = config::Testnet::get_execution_params();
|
let execution_params = execution_params::Testnet::get_execution_params();
|
||||||
|
|
||||||
match opt.cmd {
|
match opt.cmd {
|
||||||
Command::SellXmr {
|
Command::SellXmr {
|
||||||
|
@ -10,10 +10,9 @@ pub use self::{
|
|||||||
transfer_proof::TransferProof,
|
transfer_proof::TransferProof,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
bitcoin,
|
bitcoin, database,
|
||||||
config::ExecutionParams,
|
|
||||||
database,
|
|
||||||
database::Database,
|
database::Database,
|
||||||
|
execution_params::ExecutionParams,
|
||||||
monero,
|
monero,
|
||||||
network::{
|
network::{
|
||||||
peer_tracker::{self, PeerTracker},
|
peer_tracker::{self, PeerTracker},
|
||||||
|
@ -7,7 +7,7 @@ use crate::{
|
|||||||
TransactionBlockHeight, TxCancel, TxLock, TxRefund, WaitForTransactionFinality,
|
TransactionBlockHeight, TxCancel, TxLock, TxRefund, WaitForTransactionFinality,
|
||||||
WatchForRawTransaction,
|
WatchForRawTransaction,
|
||||||
},
|
},
|
||||||
config::ExecutionParams,
|
execution_params::ExecutionParams,
|
||||||
monero,
|
monero,
|
||||||
monero::Transfer,
|
monero::Transfer,
|
||||||
protocol::{
|
protocol::{
|
||||||
|
@ -6,9 +6,9 @@ use crate::{
|
|||||||
timelocks::ExpiredTimelocks, TransactionBlockHeight, WaitForTransactionFinality,
|
timelocks::ExpiredTimelocks, TransactionBlockHeight, WaitForTransactionFinality,
|
||||||
WatchForRawTransaction,
|
WatchForRawTransaction,
|
||||||
},
|
},
|
||||||
config::ExecutionParams,
|
|
||||||
database,
|
database,
|
||||||
database::Database,
|
database::Database,
|
||||||
|
execution_params::ExecutionParams,
|
||||||
monero,
|
monero,
|
||||||
monero::CreateWalletForOutput,
|
monero::CreateWalletForOutput,
|
||||||
protocol::{
|
protocol::{
|
||||||
|
@ -28,7 +28,7 @@ pub use self::{
|
|||||||
swap::{run, run_until},
|
swap::{run, run_until},
|
||||||
swap_request::*,
|
swap_request::*,
|
||||||
};
|
};
|
||||||
use crate::{config::ExecutionParams, protocol::alice::TransferProof};
|
use crate::{execution_params::ExecutionParams, protocol::alice::TransferProof};
|
||||||
|
|
||||||
mod encrypted_signature;
|
mod encrypted_signature;
|
||||||
pub mod event_loop;
|
pub mod event_loop;
|
||||||
|
@ -6,7 +6,7 @@ use crate::{
|
|||||||
GetBlockHeight, GetNetwork, GetRawTransaction, Transaction, TransactionBlockHeight,
|
GetBlockHeight, GetNetwork, GetRawTransaction, Transaction, TransactionBlockHeight,
|
||||||
TxCancel, Txid, WatchForRawTransaction,
|
TxCancel, Txid, WatchForRawTransaction,
|
||||||
},
|
},
|
||||||
config::ExecutionParams,
|
execution_params::ExecutionParams,
|
||||||
monero,
|
monero,
|
||||||
monero::{monero_private_key, TransferProof},
|
monero::{monero_private_key, TransferProof},
|
||||||
protocol::{alice, bob, bob::EncryptedSignature, SwapAmounts},
|
protocol::{alice, bob, bob::EncryptedSignature, SwapAmounts},
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
bitcoin,
|
bitcoin,
|
||||||
bitcoin::timelocks::ExpiredTimelocks,
|
bitcoin::timelocks::ExpiredTimelocks,
|
||||||
config::ExecutionParams,
|
|
||||||
database::{Database, Swap},
|
database::{Database, Swap},
|
||||||
|
execution_params::ExecutionParams,
|
||||||
monero,
|
monero,
|
||||||
protocol::{
|
protocol::{
|
||||||
bob::{self, event_loop::EventLoopHandle, state::*, SwapRequest},
|
bob::{self, event_loop::EventLoopHandle, state::*, SwapRequest},
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
pub mod testutils;
|
pub mod testutils;
|
||||||
|
|
||||||
use swap::{
|
use swap::{
|
||||||
config,
|
execution_params,
|
||||||
protocol::{alice, alice::AliceState, bob},
|
protocol::{alice, alice::AliceState, bob},
|
||||||
};
|
};
|
||||||
use testutils::alice_run_until::is_encsig_learned;
|
use testutils::alice_run_until::is_encsig_learned;
|
||||||
@ -11,7 +11,7 @@ use testutils::alice_run_until::is_encsig_learned;
|
|||||||
/// redeem had the timelock not expired.
|
/// redeem had the timelock not expired.
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn given_alice_restarts_after_enc_sig_learned_and_bob_already_cancelled_refund_swap() {
|
async fn given_alice_restarts_after_enc_sig_learned_and_bob_already_cancelled_refund_swap() {
|
||||||
testutils::setup_test(config::Regtest, |mut ctx| async move {
|
testutils::setup_test(execution_params::Regtest, |mut ctx| async move {
|
||||||
let (alice_swap, alice_join_handle) = ctx.new_swap_as_alice().await;
|
let (alice_swap, alice_join_handle) = ctx.new_swap_as_alice().await;
|
||||||
let (bob_swap, _) = ctx.new_swap_as_bob().await;
|
let (bob_swap, _) = ctx.new_swap_as_bob().await;
|
||||||
|
|
||||||
|
@ -8,8 +8,8 @@ use std::{path::PathBuf, sync::Arc};
|
|||||||
use swap::{
|
use swap::{
|
||||||
bitcoin,
|
bitcoin,
|
||||||
bitcoin::Timelock,
|
bitcoin::Timelock,
|
||||||
config,
|
execution_params,
|
||||||
config::{ExecutionParams, GetExecutionParams},
|
execution_params::{ExecutionParams, GetExecutionParams},
|
||||||
monero,
|
monero,
|
||||||
protocol::{alice, alice::AliceState, bob, bob::BobState, SwapAmounts},
|
protocol::{alice, alice::AliceState, bob, bob::BobState, SwapAmounts},
|
||||||
seed::Seed,
|
seed::Seed,
|
||||||
@ -518,7 +518,7 @@ impl GetExecutionParams for SlowCancelConfig {
|
|||||||
fn get_execution_params() -> ExecutionParams {
|
fn get_execution_params() -> ExecutionParams {
|
||||||
ExecutionParams {
|
ExecutionParams {
|
||||||
bitcoin_cancel_timelock: Timelock::new(180),
|
bitcoin_cancel_timelock: Timelock::new(180),
|
||||||
..config::Regtest::get_execution_params()
|
..execution_params::Regtest::get_execution_params()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -529,7 +529,7 @@ impl GetExecutionParams for FastCancelConfig {
|
|||||||
fn get_execution_params() -> ExecutionParams {
|
fn get_execution_params() -> ExecutionParams {
|
||||||
ExecutionParams {
|
ExecutionParams {
|
||||||
bitcoin_cancel_timelock: Timelock::new(1),
|
bitcoin_cancel_timelock: Timelock::new(1),
|
||||||
..config::Regtest::get_execution_params()
|
..execution_params::Regtest::get_execution_params()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -541,7 +541,7 @@ impl GetExecutionParams for FastPunishConfig {
|
|||||||
ExecutionParams {
|
ExecutionParams {
|
||||||
bitcoin_cancel_timelock: Timelock::new(1),
|
bitcoin_cancel_timelock: Timelock::new(1),
|
||||||
bitcoin_punish_timelock: Timelock::new(1),
|
bitcoin_punish_timelock: Timelock::new(1),
|
||||||
..config::Regtest::get_execution_params()
|
..execution_params::Regtest::get_execution_params()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user