Merge #161
161: Introduce configuration file and initial setup through CLI r=da-kami a=da-kami PRs chained on top of this one: - [x] https://github.com/comit-network/xmr-btc-swap/pull/163 Configurable config with `--config` option on CLI (we will need this for swaps with ourselves...) - [x] ~~https://github.com/comit-network/xmr-btc-swap/pull/165 Reset config with `--reset-config` option on CLI (this makes it easier for the user to clean up)~~ - [x] https://github.com/comit-network/xmr-btc-swap/pull/166 data-dir, in accordance to config-dir, should be pointed to the appropriate default directory using `directory-next` Looks n' feel: Initial startup: ``` 2021-01-28T01:35:45.000205Z INFO swap::trace: Initialized tracing with level: INFO 2021-01-28T01:35:45.001286Z INFO swap: Database and Seed will be stored in directory: /Users/dakami/CoBloX/TEMP/swap-data-dir/alice 2021-01-28T01:35:45.003391Z INFO swap::config::seed: Read in seed from file: /Users/dakami/CoBloX/TEMP/swap-data-dir/alice/seed.pem 2021-01-28T01:35:45.003603Z INFO swap::config: Config file not found, running initial setup... ? Enter Bitcoind URL (including username and password if applicable) or hit return to use default (http://127.0.0.1:18332) › http://dakami:xkz4nyywpKf3BigwKIRdVijmWzaHCOmUisepQpDlsXnhpNd6uO@127.0.0.1:18332/ ✔ Enter Bitcoind URL (including username and password if applicable) or hit return to use default · http://dakami:xkz4nyywpKf3BigwKIRdVijmWzaHCOmUisepQpDlsXnhpNd6uO@127.0.0.1:18332/ ? Enter Bitcoind wallet name › alice ✔ Enter Bitcoind wallet name · alice ? Enter Monero Wallet RPC URL or hit enter to use default (http://127.0.0.1:38083/json_rpc) › ✔ Enter Monero Wallet RPC URL or hit enter to use default · http://127.0.0.1:38083/json_rpc 2021-01-28T01:35:58.553401Z INFO swap::config: Initial setup complete, config file created at /Users/dakami/Library/Application Support/xmr-btc-swap/config.toml 2021-01-28T01:35:58.647761Z INFO swap: Connection to Bitcoin wallet succeeded, balance: 0.00744521 BTC 2021-01-28T01:35:58.650060Z INFO swap: Connection to Monero wallet succeeded, balance: 29.095359550000 XMR 2021-01-28T01:35:58.650258Z INFO swap: Swap sending 0.030000000000 XMR and receiving 0.00060000 BTC started with ID e07b2cc1-3749-48fd-931a-6cbaf57b8124 2021-01-28T01:35:59.004306Z INFO swap::protocol::alice::swap: Current state:started ``` After: ``` 2021-01-28T01:36:57.881654Z INFO swap::trace: Initialized tracing with level: INFO 2021-01-28T01:36:57.882691Z INFO swap: Database and Seed will be stored in directory: /Users/dakami/CoBloX/TEMP/swap-data-dir/alice 2021-01-28T01:36:57.884171Z INFO swap::config::seed: Read in seed from file: /Users/dakami/CoBloX/TEMP/swap-data-dir/alice/seed.pem 2021-01-28T01:36:57.884353Z INFO swap::config: Using config file at default path: /Users/dakami/Library/Application Support/xmr-btc-swap/config.toml 2021-01-28T01:36:57.996153Z INFO swap: Connection to Bitcoin wallet succeeded, balance: 0.00744521 BTC 2021-01-28T01:36:57.998648Z INFO swap: Connection to Monero wallet succeeded, balance: 29.095359550000 XMR 2021-01-28T01:36:57.998928Z INFO swap: Swap sending 0.030000000000 XMR and receiving 0.00060000 BTC started with ID 08dd6dc1-9460-4c0a-91ef-a05df309b6ed 2021-01-28T01:36:58.353738Z INFO swap::protocol::alice::swap: Current state:started ``` Command: ``` run --package swap --bin swap -- --data-dir /Users/dakami/CoBloX/TEMP/swap-data-dir/alice sell-xmr --receive-btc 0.0006 --send-xmr 0.03 ``` Co-authored-by: Daniel Karzel <daniel@comit.network> Co-authored-by: Daniel Karzel <daniel.karzel@coblox.tech>pull/171/head
commit
5fe8f3108a
File diff suppressed because it is too large
Load Diff
@ -1,127 +1,145 @@
|
|||||||
|
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;
|
pub mod seed;
|
||||||
|
|
||||||
use crate::bitcoin::Timelock;
|
const DEFAULT_BITCOIND_TESTNET_URL: &str = "http://127.0.0.1:18332";
|
||||||
use conquer_once::Lazy;
|
const DEFAULT_MONERO_WALLET_RPC_TESTNET_URL: &str = "http://127.0.0.1:38083/json_rpc";
|
||||||
use std::time::Duration;
|
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
|
||||||
pub struct Config {
|
|
||||||
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 bitcoin_network: bitcoin::Network,
|
|
||||||
pub monero_network: monero::Network,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait GetConfig {
|
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, PartialEq)]
|
||||||
fn get_config() -> Config;
|
pub struct File {
|
||||||
|
pub bitcoin: Bitcoin,
|
||||||
|
pub monero: Monero,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
impl File {
|
||||||
pub struct Mainnet;
|
pub fn read<D>(config_file: D) -> Result<Self, ConfigError>
|
||||||
|
where
|
||||||
#[derive(Clone, Copy)]
|
D: AsRef<OsStr>,
|
||||||
pub struct Testnet;
|
{
|
||||||
|
let config_file = Path::new(&config_file);
|
||||||
#[derive(Clone, Copy)]
|
|
||||||
pub struct Regtest;
|
|
||||||
|
|
||||||
impl GetConfig for Mainnet {
|
|
||||||
fn get_config() -> Config {
|
|
||||||
Config {
|
|
||||||
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,
|
|
||||||
bitcoin_network: bitcoin::Network::Bitcoin,
|
|
||||||
monero_network: monero::Network::Mainnet,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GetConfig for Testnet {
|
let mut config = Config::new();
|
||||||
fn get_config() -> Config {
|
config.merge(config::File::from(config_file))?;
|
||||||
Config {
|
config.try_into()
|
||||||
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,
|
|
||||||
bitcoin_network: bitcoin::Network::Testnet,
|
|
||||||
monero_network: monero::Network::Stagenet,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GetConfig for Regtest {
|
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
|
||||||
fn get_config() -> Config {
|
#[serde(deny_unknown_fields)]
|
||||||
Config {
|
pub struct Bitcoin {
|
||||||
bob_time_to_act: *regtest::BOB_TIME_TO_ACT,
|
pub bitcoind_url: Url,
|
||||||
bitcoin_finality_confirmations: regtest::BITCOIN_FINALITY_CONFIRMATIONS,
|
pub wallet_name: String,
|
||||||
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,
|
|
||||||
bitcoin_network: bitcoin::Network::Regtest,
|
|
||||||
monero_network: monero::Network::default(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mod mainnet {
|
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
|
||||||
use super::*;
|
#[serde(deny_unknown_fields)]
|
||||||
|
pub struct Monero {
|
||||||
// For each step, we are giving Bob 10 minutes to act.
|
pub wallet_rpc_url: Url,
|
||||||
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 {
|
#[derive(thiserror::Error, Debug, Clone, Copy)]
|
||||||
use super::*;
|
#[error("config not initialized")]
|
||||||
|
pub struct ConfigNotInitialized {}
|
||||||
pub static BOB_TIME_TO_ACT: Lazy<Duration> = Lazy::new(|| Duration::from_secs(60 * 60));
|
|
||||||
|
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 {}));
|
||||||
|
}
|
||||||
|
|
||||||
// This does not reflect recommended values for mainnet!
|
let file = File::read(&config_path)
|
||||||
pub static BITCOIN_FINALITY_CONFIRMATIONS: u32 = 1;
|
.with_context(|| format!("failed to read config file {}", config_path.display()))?;
|
||||||
|
|
||||||
pub static BITCOIN_AVG_BLOCK_TIME: Lazy<Duration> = Lazy::new(|| Duration::from_secs(5 * 60));
|
Ok(Ok(file))
|
||||||
|
}
|
||||||
|
|
||||||
// This does not reflect recommended values for mainnet!
|
pub fn initial_setup<F>(config_path: PathBuf, config_file: F) -> Result<()>
|
||||||
pub static MONERO_FINALITY_CONFIRMATIONS: u32 = 5;
|
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(())
|
||||||
|
}
|
||||||
|
|
||||||
// This does not reflect recommended values for mainnet!
|
pub fn query_user_for_initial_testnet_config() -> Result<File> {
|
||||||
pub static BITCOIN_CANCEL_TIMELOCK: Timelock = Timelock::new(12);
|
println!();
|
||||||
pub static BITCOIN_PUNISH_TIMELOCK: Timelock = Timelock::new(6);
|
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,
|
||||||
|
},
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
mod regtest {
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use std::str::FromStr;
|
||||||
// In test, we set a shorter time to fail fast
|
use tempfile::tempdir;
|
||||||
pub static BOB_TIME_TO_ACT: Lazy<Duration> = Lazy::new(|| Duration::from_secs(30));
|
|
||||||
|
#[test]
|
||||||
pub static BITCOIN_FINALITY_CONFIRMATIONS: u32 = 1;
|
fn config_roundtrip() {
|
||||||
|
let temp_dir = tempdir().unwrap().path().to_path_buf();
|
||||||
pub static BITCOIN_AVG_BLOCK_TIME: Lazy<Duration> = Lazy::new(|| Duration::from_secs(5));
|
let config_path = Path::join(&temp_dir, "config.toml");
|
||||||
|
|
||||||
pub static MONERO_FINALITY_CONFIRMATIONS: u32 = 1;
|
let expected = File {
|
||||||
|
bitcoin: Bitcoin {
|
||||||
pub static BITCOIN_CANCEL_TIMELOCK: Timelock = Timelock::new(100);
|
bitcoind_url: Url::from_str("http://127.0.0.1:18332").unwrap(),
|
||||||
|
wallet_name: "alice".to_string(),
|
||||||
pub static BITCOIN_PUNISH_TIMELOCK: Timelock = Timelock::new(50);
|
},
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
}
|
Loading…
Reference in New Issue