mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2024-12-26 16:09:41 -05:00
Merge #608
608: Smoothen the CLI's interface a bit r=da-kami a=thomaseizinger - Add `--change-address` to the `buy-xmr` command. - Remove `--receive-address` from the `resume` command. Co-authored-by: Thomas Eizinger <thomas@eizinger.io>
This commit is contained in:
commit
fa1a5e6efb
@ -19,6 +19,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
The rendezvous node address (`rendezvous_point`), as well as the ASB's external addresses (`external_addresses`) to be registered, is configured in the `network` section of the ASB config file.
|
The rendezvous node address (`rendezvous_point`), as well as the ASB's external addresses (`external_addresses`) to be registered, is configured in the `network` section of the ASB config file.
|
||||||
A rendezvous node is provided at `/dnsaddr/rendezvous.coblox.tech/p2p/12D3KooWQUt9DkNZxEn2R5ymJzWj15MpG6mTW84kyd8vDaRZi46o` which is used as default for discovery in the CLI.
|
A rendezvous node is provided at `/dnsaddr/rendezvous.coblox.tech/p2p/12D3KooWQUt9DkNZxEn2R5ymJzWj15MpG6mTW84kyd8vDaRZi46o` which is used as default for discovery in the CLI.
|
||||||
Upon discovery using `list-sellers` CLI users are provided with quote and connection information for each ASB discovered through the rendezvous node.
|
Upon discovery using `list-sellers` CLI users are provided with quote and connection information for each ASB discovered through the rendezvous node.
|
||||||
|
- A mandatory `--change-address` parameter to the CLI's `buy-xmr` command.
|
||||||
|
The provided address is used to transfer Bitcoin in case of a refund and in case the user transfers more than the specified amount into the swap.
|
||||||
|
For more information see [#513](https://github.com/comit-network/xmr-btc-swap/issues/513).
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
@ -39,6 +42,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
The CLI can use regular TCP connections and having both - TCP and websockets - causes problems and unnecessary overhead.
|
The CLI can use regular TCP connections and having both - TCP and websockets - causes problems and unnecessary overhead.
|
||||||
- The `--seller-addr` parameter from the CLI's `resume` command.
|
- The `--seller-addr` parameter from the CLI's `resume` command.
|
||||||
This information is now loaded from the database.
|
This information is now loaded from the database.
|
||||||
|
- The `--receive-address` parameter from the CLI's `resume` command.
|
||||||
|
This information is now loaded from the database.
|
||||||
|
|
||||||
## [0.7.0] - 2021-05-28
|
## [0.7.0] - 2021-05-28
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ rust_decimal_macros = "1"
|
|||||||
serde = { version = "1", features = [ "derive" ] }
|
serde = { version = "1", features = [ "derive" ] }
|
||||||
serde_cbor = "0.11"
|
serde_cbor = "0.11"
|
||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
serde_with = { version = "1.9.4", features = [ "macros" ] }
|
serde_with = { version = "1", features = [ "macros" ] }
|
||||||
sha2 = "0.9"
|
sha2 = "0.9"
|
||||||
sigma_fun = { git = "https://github.com/LLFourn/secp256kfun", default-features = false, features = [ "ed25519", "serde" ] }
|
sigma_fun = { git = "https://github.com/LLFourn/secp256kfun", default-features = false, features = [ "ed25519", "serde" ] }
|
||||||
sled = "0.34"
|
sled = "0.34"
|
||||||
|
@ -231,7 +231,9 @@ async fn main() -> Result<()> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let psbt = bitcoin_wallet.send_to_address(address, amount).await?;
|
let psbt = bitcoin_wallet
|
||||||
|
.send_to_address(address, amount, None)
|
||||||
|
.await?;
|
||||||
let signed_tx = bitcoin_wallet.sign_and_finalize(psbt).await?;
|
let signed_tx = bitcoin_wallet.sign_and_finalize(psbt).await?;
|
||||||
|
|
||||||
bitcoin_wallet.broadcast(signed_tx, "withdraw").await?;
|
bitcoin_wallet.broadcast(signed_tx, "withdraw").await?;
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
#![forbid(unsafe_code)]
|
#![forbid(unsafe_code)]
|
||||||
#![allow(non_snake_case)]
|
#![allow(non_snake_case)]
|
||||||
|
|
||||||
use anyhow::{bail, Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use comfy_table::Table;
|
use comfy_table::Table;
|
||||||
use qrcode::render::unicode;
|
use qrcode::render::unicode;
|
||||||
use qrcode::QrCode;
|
use qrcode::QrCode;
|
||||||
@ -59,6 +59,7 @@ async fn main() -> Result<()> {
|
|||||||
seller,
|
seller,
|
||||||
bitcoin_electrum_rpc_url,
|
bitcoin_electrum_rpc_url,
|
||||||
bitcoin_target_block,
|
bitcoin_target_block,
|
||||||
|
bitcoin_change_address,
|
||||||
monero_receive_address,
|
monero_receive_address,
|
||||||
monero_daemon_address,
|
monero_daemon_address,
|
||||||
tor_socks5_port,
|
tor_socks5_port,
|
||||||
@ -113,6 +114,8 @@ async fn main() -> Result<()> {
|
|||||||
info!(%amount, %fees, %swap_id, "Swapping");
|
info!(%amount, %fees, %swap_id, "Swapping");
|
||||||
|
|
||||||
db.insert_peer_id(swap_id, seller_peer_id).await?;
|
db.insert_peer_id(swap_id, seller_peer_id).await?;
|
||||||
|
db.insert_monero_address(swap_id, monero_receive_address)
|
||||||
|
.await?;
|
||||||
|
|
||||||
let swap = Swap::new(
|
let swap = Swap::new(
|
||||||
db,
|
db,
|
||||||
@ -122,6 +125,7 @@ async fn main() -> Result<()> {
|
|||||||
env_config,
|
env_config,
|
||||||
event_loop_handle,
|
event_loop_handle,
|
||||||
monero_receive_address,
|
monero_receive_address,
|
||||||
|
bitcoin_change_address,
|
||||||
amount,
|
amount,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -153,7 +157,6 @@ async fn main() -> Result<()> {
|
|||||||
swap_id,
|
swap_id,
|
||||||
bitcoin_electrum_rpc_url,
|
bitcoin_electrum_rpc_url,
|
||||||
bitcoin_target_block,
|
bitcoin_target_block,
|
||||||
monero_receive_address,
|
|
||||||
monero_daemon_address,
|
monero_daemon_address,
|
||||||
tor_socks5_port,
|
tor_socks5_port,
|
||||||
} => {
|
} => {
|
||||||
@ -163,10 +166,6 @@ async fn main() -> Result<()> {
|
|||||||
let seed = Seed::from_file_or_generate(data_dir.as_path())
|
let seed = Seed::from_file_or_generate(data_dir.as_path())
|
||||||
.context("Failed to read in seed file")?;
|
.context("Failed to read in seed file")?;
|
||||||
|
|
||||||
if monero_receive_address.network != env_config.monero_network {
|
|
||||||
bail!("The given monero address is on network {:?}, expected address of network {:?}.", monero_receive_address.network, env_config.monero_network)
|
|
||||||
}
|
|
||||||
|
|
||||||
let bitcoin_wallet = init_bitcoin_wallet(
|
let bitcoin_wallet = init_bitcoin_wallet(
|
||||||
bitcoin_electrum_rpc_url,
|
bitcoin_electrum_rpc_url,
|
||||||
&seed,
|
&seed,
|
||||||
@ -198,6 +197,7 @@ async fn main() -> Result<()> {
|
|||||||
EventLoop::new(swap_id, swarm, seller_peer_id, env_config)?;
|
EventLoop::new(swap_id, swarm, seller_peer_id, env_config)?;
|
||||||
let handle = tokio::spawn(event_loop.run());
|
let handle = tokio::spawn(event_loop.run());
|
||||||
|
|
||||||
|
let monero_receive_address = db.get_monero_address(swap_id)?;
|
||||||
let swap = Swap::from_db(
|
let swap = Swap::from_db(
|
||||||
db,
|
db,
|
||||||
swap_id,
|
swap_id,
|
||||||
|
@ -24,6 +24,7 @@ impl TxLock {
|
|||||||
amount: Amount,
|
amount: Amount,
|
||||||
A: PublicKey,
|
A: PublicKey,
|
||||||
B: PublicKey,
|
B: PublicKey,
|
||||||
|
change: bitcoin::Address,
|
||||||
) -> Result<Self>
|
) -> Result<Self>
|
||||||
where
|
where
|
||||||
C: EstimateFeeRate,
|
C: EstimateFeeRate,
|
||||||
@ -34,7 +35,9 @@ impl TxLock {
|
|||||||
.address(wallet.get_network())
|
.address(wallet.get_network())
|
||||||
.expect("can derive address from descriptor");
|
.expect("can derive address from descriptor");
|
||||||
|
|
||||||
let psbt = wallet.send_to_address(address, amount).await?;
|
let psbt = wallet
|
||||||
|
.send_to_address(address, amount, Some(change))
|
||||||
|
.await?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
inner: psbt,
|
inner: psbt,
|
||||||
@ -251,7 +254,11 @@ mod tests {
|
|||||||
wallet: &Wallet<(), bdk::database::MemoryDatabase, StaticFeeRate>,
|
wallet: &Wallet<(), bdk::database::MemoryDatabase, StaticFeeRate>,
|
||||||
amount: Amount,
|
amount: Amount,
|
||||||
) -> PartiallySignedTransaction {
|
) -> PartiallySignedTransaction {
|
||||||
TxLock::new(&wallet, amount, A, B).await.unwrap().into()
|
let change = wallet.new_address().await.unwrap();
|
||||||
|
TxLock::new(&wallet, amount, A, B, change)
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn alice_and_bob() -> (PublicKey, PublicKey) {
|
fn alice_and_bob() -> (PublicKey, PublicKey) {
|
||||||
|
@ -16,7 +16,6 @@ use reqwest::Url;
|
|||||||
use rust_decimal::prelude::*;
|
use rust_decimal::prelude::*;
|
||||||
use rust_decimal::Decimal;
|
use rust_decimal::Decimal;
|
||||||
use rust_decimal_macros::dec;
|
use rust_decimal_macros::dec;
|
||||||
use std::cmp::Ordering;
|
|
||||||
use std::collections::{BTreeMap, HashMap};
|
use std::collections::{BTreeMap, HashMap};
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
@ -310,11 +309,18 @@ where
|
|||||||
&self,
|
&self,
|
||||||
address: Address,
|
address: Address,
|
||||||
amount: Amount,
|
amount: Amount,
|
||||||
|
change_override: Option<Address>,
|
||||||
) -> Result<PartiallySignedTransaction> {
|
) -> Result<PartiallySignedTransaction> {
|
||||||
if self.network != address.network {
|
if self.network != address.network {
|
||||||
bail!("Cannot build PSBT because network of given address is {} but wallet is on network {}", address.network, self.network);
|
bail!("Cannot build PSBT because network of given address is {} but wallet is on network {}", address.network, self.network);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(change) = change_override.as_ref() {
|
||||||
|
if self.network != change.network {
|
||||||
|
bail!("Cannot build PSBT because network of given address is {} but wallet is on network {}", change.network, self.network);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let wallet = self.wallet.lock().await;
|
let wallet = self.wallet.lock().await;
|
||||||
let client = self.client.lock().await;
|
let client = self.client.lock().await;
|
||||||
let fee_rate = client.estimate_feerate(self.target_block)?;
|
let fee_rate = client.estimate_feerate(self.target_block)?;
|
||||||
@ -326,22 +332,31 @@ where
|
|||||||
let (psbt, _details) = tx_builder.finish()?;
|
let (psbt, _details) = tx_builder.finish()?;
|
||||||
let mut psbt: PartiallySignedTransaction = psbt;
|
let mut psbt: PartiallySignedTransaction = psbt;
|
||||||
|
|
||||||
// When subscribing to transactions we depend on the relevant script being at
|
match psbt.global.unsigned_tx.output.as_mut_slice() {
|
||||||
// output index 0, thus we ensure the relevant output to be at index `0`.
|
// our primary output is the 2nd one? reverse the vectors
|
||||||
psbt.outputs.sort_by(|a, _| {
|
[_, second_txout] if second_txout.script_pubkey == script => {
|
||||||
if a.witness_script.as_ref() == Some(&script) {
|
psbt.outputs.reverse();
|
||||||
Ordering::Less
|
psbt.global.unsigned_tx.output.reverse();
|
||||||
} else {
|
|
||||||
Ordering::Greater
|
|
||||||
}
|
}
|
||||||
});
|
[first_txout, _] if first_txout.script_pubkey == script => {
|
||||||
psbt.global.unsigned_tx.output.sort_by(|a, _| {
|
// no need to do anything
|
||||||
if a.script_pubkey == script {
|
|
||||||
Ordering::Less
|
|
||||||
} else {
|
|
||||||
Ordering::Greater
|
|
||||||
}
|
}
|
||||||
});
|
[_] => {
|
||||||
|
// single output, no need do anything
|
||||||
|
}
|
||||||
|
_ => bail!("Unexpected transaction layout"),
|
||||||
|
}
|
||||||
|
|
||||||
|
if let ([_, change], [_, psbt_output], Some(change_override)) = (
|
||||||
|
&mut psbt.global.unsigned_tx.output.as_mut_slice(),
|
||||||
|
&mut psbt.outputs.as_mut_slice(),
|
||||||
|
change_override,
|
||||||
|
) {
|
||||||
|
change.script_pubkey = change_override.script_pubkey();
|
||||||
|
// Might be populated based on the previously set change address, but for the
|
||||||
|
// overwrite we don't know unless we ask the user for more information.
|
||||||
|
psbt_output.bip32_derivation.clear();
|
||||||
|
}
|
||||||
|
|
||||||
Ok(psbt)
|
Ok(psbt)
|
||||||
}
|
}
|
||||||
@ -1062,7 +1077,8 @@ mod tests {
|
|||||||
// if the change output is below dust it will be dropped by the BDK
|
// if the change output is below dust it will be dropped by the BDK
|
||||||
for amount in above_dust..(balance - (above_dust - 1)) {
|
for amount in above_dust..(balance - (above_dust - 1)) {
|
||||||
let (A, B) = (PublicKey::random(), PublicKey::random());
|
let (A, B) = (PublicKey::random(), PublicKey::random());
|
||||||
let txlock = TxLock::new(&wallet, bitcoin::Amount::from_sat(amount), A, B)
|
let change = wallet.new_address().await.unwrap();
|
||||||
|
let txlock = TxLock::new(&wallet, bitcoin::Amount::from_sat(amount), A, B, change)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let txlock_output = txlock.script_pubkey();
|
let txlock_output = txlock.script_pubkey();
|
||||||
@ -1077,4 +1093,30 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn can_override_change_address() {
|
||||||
|
let wallet = Wallet::new_funded_default_fees(50_000);
|
||||||
|
let custom_change = "bcrt1q08pfqpsyrt7acllzyjm8q5qsz5capvyahm49rw"
|
||||||
|
.parse::<Address>()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let psbt = wallet
|
||||||
|
.send_to_address(
|
||||||
|
wallet.new_address().await.unwrap(),
|
||||||
|
Amount::from_sat(10_000),
|
||||||
|
Some(custom_change.clone()),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
let transaction = wallet.sign_and_finalize(psbt).await.unwrap();
|
||||||
|
|
||||||
|
match transaction.output.as_slice() {
|
||||||
|
[first, change] => {
|
||||||
|
assert_eq!(first.value, 10_000);
|
||||||
|
assert_eq!(change.script_pubkey, custom_change.script_pubkey());
|
||||||
|
}
|
||||||
|
_ => panic!("expected exactly two outputs"),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,11 +74,11 @@ where
|
|||||||
bitcoin_electrum_rpc_url,
|
bitcoin_electrum_rpc_url,
|
||||||
bitcoin_target_block,
|
bitcoin_target_block,
|
||||||
},
|
},
|
||||||
monero:
|
bitcoin_change_address,
|
||||||
Monero {
|
monero: Monero {
|
||||||
monero_receive_address,
|
monero_daemon_address,
|
||||||
monero_daemon_address,
|
},
|
||||||
},
|
monero_receive_address,
|
||||||
tor: Tor { tor_socks5_port },
|
tor: Tor { tor_socks5_port },
|
||||||
} => Arguments {
|
} => Arguments {
|
||||||
env_config: env_config_from(is_testnet),
|
env_config: env_config_from(is_testnet),
|
||||||
@ -92,6 +92,7 @@ where
|
|||||||
is_testnet,
|
is_testnet,
|
||||||
)?,
|
)?,
|
||||||
bitcoin_target_block: bitcoin_target_block_from(bitcoin_target_block, is_testnet),
|
bitcoin_target_block: bitcoin_target_block_from(bitcoin_target_block, is_testnet),
|
||||||
|
bitcoin_change_address,
|
||||||
monero_receive_address: validate_monero_address(
|
monero_receive_address: validate_monero_address(
|
||||||
monero_receive_address,
|
monero_receive_address,
|
||||||
is_testnet,
|
is_testnet,
|
||||||
@ -117,11 +118,9 @@ where
|
|||||||
bitcoin_electrum_rpc_url,
|
bitcoin_electrum_rpc_url,
|
||||||
bitcoin_target_block,
|
bitcoin_target_block,
|
||||||
},
|
},
|
||||||
monero:
|
monero: Monero {
|
||||||
Monero {
|
monero_daemon_address,
|
||||||
monero_receive_address,
|
},
|
||||||
monero_daemon_address,
|
|
||||||
},
|
|
||||||
tor: Tor { tor_socks5_port },
|
tor: Tor { tor_socks5_port },
|
||||||
} => Arguments {
|
} => Arguments {
|
||||||
env_config: env_config_from(is_testnet),
|
env_config: env_config_from(is_testnet),
|
||||||
@ -135,7 +134,6 @@ where
|
|||||||
is_testnet,
|
is_testnet,
|
||||||
)?,
|
)?,
|
||||||
bitcoin_target_block: bitcoin_target_block_from(bitcoin_target_block, is_testnet),
|
bitcoin_target_block: bitcoin_target_block_from(bitcoin_target_block, is_testnet),
|
||||||
monero_receive_address,
|
|
||||||
monero_daemon_address: monero_daemon_address_from(
|
monero_daemon_address: monero_daemon_address_from(
|
||||||
monero_daemon_address,
|
monero_daemon_address,
|
||||||
is_testnet,
|
is_testnet,
|
||||||
@ -214,6 +212,7 @@ pub enum Command {
|
|||||||
seller: Multiaddr,
|
seller: Multiaddr,
|
||||||
bitcoin_electrum_rpc_url: Url,
|
bitcoin_electrum_rpc_url: Url,
|
||||||
bitcoin_target_block: usize,
|
bitcoin_target_block: usize,
|
||||||
|
bitcoin_change_address: bitcoin::Address,
|
||||||
monero_receive_address: monero::Address,
|
monero_receive_address: monero::Address,
|
||||||
monero_daemon_address: String,
|
monero_daemon_address: String,
|
||||||
tor_socks5_port: u16,
|
tor_socks5_port: u16,
|
||||||
@ -223,7 +222,6 @@ pub enum Command {
|
|||||||
swap_id: Uuid,
|
swap_id: Uuid,
|
||||||
bitcoin_electrum_rpc_url: Url,
|
bitcoin_electrum_rpc_url: Url,
|
||||||
bitcoin_target_block: usize,
|
bitcoin_target_block: usize,
|
||||||
monero_receive_address: monero::Address,
|
|
||||||
monero_daemon_address: String,
|
monero_daemon_address: String,
|
||||||
tor_socks5_port: u16,
|
tor_socks5_port: u16,
|
||||||
},
|
},
|
||||||
@ -287,9 +285,21 @@ pub enum RawCommand {
|
|||||||
#[structopt(flatten)]
|
#[structopt(flatten)]
|
||||||
bitcoin: Bitcoin,
|
bitcoin: Bitcoin,
|
||||||
|
|
||||||
|
#[structopt(
|
||||||
|
long = "change-address",
|
||||||
|
help = "The bitcoin address where any form of change or excess funds should be sent to"
|
||||||
|
)]
|
||||||
|
bitcoin_change_address: bitcoin::Address,
|
||||||
|
|
||||||
#[structopt(flatten)]
|
#[structopt(flatten)]
|
||||||
monero: Monero,
|
monero: Monero,
|
||||||
|
|
||||||
|
#[structopt(long = "receive-address",
|
||||||
|
help = "The monero address where you would like to receive monero",
|
||||||
|
parse(try_from_str = parse_monero_address)
|
||||||
|
)]
|
||||||
|
monero_receive_address: monero::Address,
|
||||||
|
|
||||||
#[structopt(flatten)]
|
#[structopt(flatten)]
|
||||||
tor: Tor,
|
tor: Tor,
|
||||||
},
|
},
|
||||||
@ -346,12 +356,6 @@ pub enum RawCommand {
|
|||||||
|
|
||||||
#[derive(structopt::StructOpt, Debug)]
|
#[derive(structopt::StructOpt, Debug)]
|
||||||
pub struct Monero {
|
pub struct Monero {
|
||||||
#[structopt(long = "receive-address",
|
|
||||||
help = "Provide the monero address where you would like to receive monero",
|
|
||||||
parse(try_from_str = parse_monero_address)
|
|
||||||
)]
|
|
||||||
pub monero_receive_address: monero::Address,
|
|
||||||
|
|
||||||
#[structopt(
|
#[structopt(
|
||||||
long = "monero-daemon-address",
|
long = "monero-daemon-address",
|
||||||
help = "Specify to connect to a monero daemon of your choice: <host>:<port>"
|
help = "Specify to connect to a monero daemon of your choice: <host>:<port>"
|
||||||
@ -520,7 +524,9 @@ mod tests {
|
|||||||
const MAINNET: &str = "mainnet";
|
const MAINNET: &str = "mainnet";
|
||||||
|
|
||||||
const MONERO_STAGENET_ADDRESS: &str = "53gEuGZUhP9JMEBZoGaFNzhwEgiG7hwQdMCqFxiyiTeFPmkbt1mAoNybEUvYBKHcnrSgxnVWgZsTvRBaHBNXPa8tHiCU51a";
|
const MONERO_STAGENET_ADDRESS: &str = "53gEuGZUhP9JMEBZoGaFNzhwEgiG7hwQdMCqFxiyiTeFPmkbt1mAoNybEUvYBKHcnrSgxnVWgZsTvRBaHBNXPa8tHiCU51a";
|
||||||
|
const BITCOIN_TESTNET_ADDRESS: &str = "tb1qr3em6k3gfnyl8r7q0v7t4tlnyxzgxma3lressv";
|
||||||
const MONERO_MAINNET_ADDRESS: &str = "44Ato7HveWidJYUAVw5QffEcEtSH1DwzSP3FPPkHxNAS4LX9CqgucphTisH978FLHE34YNEx7FcbBfQLQUU8m3NUC4VqsRa";
|
const MONERO_MAINNET_ADDRESS: &str = "44Ato7HveWidJYUAVw5QffEcEtSH1DwzSP3FPPkHxNAS4LX9CqgucphTisH978FLHE34YNEx7FcbBfQLQUU8m3NUC4VqsRa";
|
||||||
|
const BITCOIN_MAINNET_ADDRESS: &str = "bc1qe4epnfklcaa0mun26yz5g8k24em5u9f92hy325";
|
||||||
const MULTI_ADDRESS: &str =
|
const MULTI_ADDRESS: &str =
|
||||||
"/ip4/127.0.0.1/tcp/9939/p2p/12D3KooWCdMKjesXMJz1SiZ7HgotrxuqhQJbP5sgBm2BwP1cqThi";
|
"/ip4/127.0.0.1/tcp/9939/p2p/12D3KooWCdMKjesXMJz1SiZ7HgotrxuqhQJbP5sgBm2BwP1cqThi";
|
||||||
const SWAP_ID: &str = "ea030832-3be9-454f-bb98-5ea9a788406b";
|
const SWAP_ID: &str = "ea030832-3be9-454f-bb98-5ea9a788406b";
|
||||||
@ -532,6 +538,8 @@ mod tests {
|
|||||||
"buy-xmr",
|
"buy-xmr",
|
||||||
"--receive-address",
|
"--receive-address",
|
||||||
MONERO_MAINNET_ADDRESS,
|
MONERO_MAINNET_ADDRESS,
|
||||||
|
"--change-address",
|
||||||
|
BITCOIN_MAINNET_ADDRESS,
|
||||||
"--seller",
|
"--seller",
|
||||||
MULTI_ADDRESS,
|
MULTI_ADDRESS,
|
||||||
];
|
];
|
||||||
@ -550,6 +558,8 @@ mod tests {
|
|||||||
"buy-xmr",
|
"buy-xmr",
|
||||||
"--receive-address",
|
"--receive-address",
|
||||||
MONERO_STAGENET_ADDRESS,
|
MONERO_STAGENET_ADDRESS,
|
||||||
|
"--change-address",
|
||||||
|
BITCOIN_TESTNET_ADDRESS,
|
||||||
"--seller",
|
"--seller",
|
||||||
MULTI_ADDRESS,
|
MULTI_ADDRESS,
|
||||||
];
|
];
|
||||||
@ -569,6 +579,8 @@ mod tests {
|
|||||||
"buy-xmr",
|
"buy-xmr",
|
||||||
"--receive-address",
|
"--receive-address",
|
||||||
MONERO_STAGENET_ADDRESS,
|
MONERO_STAGENET_ADDRESS,
|
||||||
|
"--change-address",
|
||||||
|
BITCOIN_TESTNET_ADDRESS,
|
||||||
"--seller",
|
"--seller",
|
||||||
MULTI_ADDRESS,
|
MULTI_ADDRESS,
|
||||||
];
|
];
|
||||||
@ -592,6 +604,8 @@ mod tests {
|
|||||||
"buy-xmr",
|
"buy-xmr",
|
||||||
"--receive-address",
|
"--receive-address",
|
||||||
MONERO_MAINNET_ADDRESS,
|
MONERO_MAINNET_ADDRESS,
|
||||||
|
"--change-address",
|
||||||
|
BITCOIN_MAINNET_ADDRESS,
|
||||||
"--seller",
|
"--seller",
|
||||||
MULTI_ADDRESS,
|
MULTI_ADDRESS,
|
||||||
];
|
];
|
||||||
@ -609,14 +623,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn given_resume_on_mainnet_then_defaults_to_mainnet() {
|
fn given_resume_on_mainnet_then_defaults_to_mainnet() {
|
||||||
let raw_ars = vec![
|
let raw_ars = vec![BINARY_NAME, "resume", "--swap-id", SWAP_ID];
|
||||||
BINARY_NAME,
|
|
||||||
"resume",
|
|
||||||
"--swap-id",
|
|
||||||
SWAP_ID,
|
|
||||||
"--receive-address",
|
|
||||||
MONERO_MAINNET_ADDRESS,
|
|
||||||
];
|
|
||||||
|
|
||||||
let args = parse_args_and_apply_defaults(raw_ars).unwrap();
|
let args = parse_args_and_apply_defaults(raw_ars).unwrap();
|
||||||
|
|
||||||
@ -628,15 +635,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn given_resume_on_testnet_then_defaults_to_testnet() {
|
fn given_resume_on_testnet_then_defaults_to_testnet() {
|
||||||
let raw_ars = vec![
|
let raw_ars = vec![BINARY_NAME, "--testnet", "resume", "--swap-id", SWAP_ID];
|
||||||
BINARY_NAME,
|
|
||||||
"--testnet",
|
|
||||||
"resume",
|
|
||||||
"--swap-id",
|
|
||||||
SWAP_ID,
|
|
||||||
"--receive-address",
|
|
||||||
MONERO_STAGENET_ADDRESS,
|
|
||||||
];
|
|
||||||
|
|
||||||
let args = parse_args_and_apply_defaults(raw_ars).unwrap();
|
let args = parse_args_and_apply_defaults(raw_ars).unwrap();
|
||||||
|
|
||||||
@ -703,6 +702,8 @@ mod tests {
|
|||||||
"--data-dir",
|
"--data-dir",
|
||||||
data_dir,
|
data_dir,
|
||||||
"buy-xmr",
|
"buy-xmr",
|
||||||
|
"--change-address",
|
||||||
|
BITCOIN_MAINNET_ADDRESS,
|
||||||
"--receive-address",
|
"--receive-address",
|
||||||
MONERO_MAINNET_ADDRESS,
|
MONERO_MAINNET_ADDRESS,
|
||||||
"--seller",
|
"--seller",
|
||||||
@ -725,6 +726,8 @@ mod tests {
|
|||||||
"--data-dir",
|
"--data-dir",
|
||||||
data_dir,
|
data_dir,
|
||||||
"buy-xmr",
|
"buy-xmr",
|
||||||
|
"--change-address",
|
||||||
|
BITCOIN_TESTNET_ADDRESS,
|
||||||
"--receive-address",
|
"--receive-address",
|
||||||
MONERO_STAGENET_ADDRESS,
|
MONERO_STAGENET_ADDRESS,
|
||||||
"--seller",
|
"--seller",
|
||||||
@ -748,8 +751,6 @@ mod tests {
|
|||||||
"resume",
|
"resume",
|
||||||
"--swap-id",
|
"--swap-id",
|
||||||
SWAP_ID,
|
SWAP_ID,
|
||||||
"--receive-address",
|
|
||||||
MONERO_MAINNET_ADDRESS,
|
|
||||||
];
|
];
|
||||||
|
|
||||||
let args = parse_args_and_apply_defaults(raw_ars).unwrap();
|
let args = parse_args_and_apply_defaults(raw_ars).unwrap();
|
||||||
@ -770,8 +771,6 @@ mod tests {
|
|||||||
"resume",
|
"resume",
|
||||||
"--swap-id",
|
"--swap-id",
|
||||||
SWAP_ID,
|
SWAP_ID,
|
||||||
"--receive-address",
|
|
||||||
MONERO_STAGENET_ADDRESS,
|
|
||||||
];
|
];
|
||||||
|
|
||||||
let args = parse_args_and_apply_defaults(raw_ars).unwrap();
|
let args = parse_args_and_apply_defaults(raw_ars).unwrap();
|
||||||
@ -791,6 +790,8 @@ mod tests {
|
|||||||
BINARY_NAME,
|
BINARY_NAME,
|
||||||
"--debug",
|
"--debug",
|
||||||
"buy-xmr",
|
"buy-xmr",
|
||||||
|
"--change-address",
|
||||||
|
BITCOIN_MAINNET_ADDRESS,
|
||||||
"--receive-address",
|
"--receive-address",
|
||||||
MONERO_MAINNET_ADDRESS,
|
MONERO_MAINNET_ADDRESS,
|
||||||
"--seller",
|
"--seller",
|
||||||
@ -808,6 +809,8 @@ mod tests {
|
|||||||
"--testnet",
|
"--testnet",
|
||||||
"--debug",
|
"--debug",
|
||||||
"buy-xmr",
|
"buy-xmr",
|
||||||
|
"--change-address",
|
||||||
|
BITCOIN_TESTNET_ADDRESS,
|
||||||
"--receive-address",
|
"--receive-address",
|
||||||
MONERO_STAGENET_ADDRESS,
|
MONERO_STAGENET_ADDRESS,
|
||||||
"--seller",
|
"--seller",
|
||||||
@ -820,15 +823,7 @@ mod tests {
|
|||||||
ParseResult::Arguments(Arguments::buy_xmr_testnet_defaults().with_debug())
|
ParseResult::Arguments(Arguments::buy_xmr_testnet_defaults().with_debug())
|
||||||
);
|
);
|
||||||
|
|
||||||
let raw_ars = vec![
|
let raw_ars = vec![BINARY_NAME, "--debug", "resume", "--swap-id", SWAP_ID];
|
||||||
BINARY_NAME,
|
|
||||||
"--debug",
|
|
||||||
"resume",
|
|
||||||
"--swap-id",
|
|
||||||
SWAP_ID,
|
|
||||||
"--receive-address",
|
|
||||||
MONERO_MAINNET_ADDRESS,
|
|
||||||
];
|
|
||||||
|
|
||||||
let args = parse_args_and_apply_defaults(raw_ars).unwrap();
|
let args = parse_args_and_apply_defaults(raw_ars).unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@ -843,8 +838,6 @@ mod tests {
|
|||||||
"resume",
|
"resume",
|
||||||
"--swap-id",
|
"--swap-id",
|
||||||
SWAP_ID,
|
SWAP_ID,
|
||||||
"--receive-address",
|
|
||||||
MONERO_STAGENET_ADDRESS,
|
|
||||||
];
|
];
|
||||||
|
|
||||||
let args = parse_args_and_apply_defaults(raw_ars).unwrap();
|
let args = parse_args_and_apply_defaults(raw_ars).unwrap();
|
||||||
@ -860,6 +853,8 @@ mod tests {
|
|||||||
BINARY_NAME,
|
BINARY_NAME,
|
||||||
"--json",
|
"--json",
|
||||||
"buy-xmr",
|
"buy-xmr",
|
||||||
|
"--change-address",
|
||||||
|
BITCOIN_MAINNET_ADDRESS,
|
||||||
"--receive-address",
|
"--receive-address",
|
||||||
MONERO_MAINNET_ADDRESS,
|
MONERO_MAINNET_ADDRESS,
|
||||||
"--seller",
|
"--seller",
|
||||||
@ -877,6 +872,8 @@ mod tests {
|
|||||||
"--testnet",
|
"--testnet",
|
||||||
"--json",
|
"--json",
|
||||||
"buy-xmr",
|
"buy-xmr",
|
||||||
|
"--change-address",
|
||||||
|
BITCOIN_TESTNET_ADDRESS,
|
||||||
"--receive-address",
|
"--receive-address",
|
||||||
MONERO_STAGENET_ADDRESS,
|
MONERO_STAGENET_ADDRESS,
|
||||||
"--seller",
|
"--seller",
|
||||||
@ -889,15 +886,7 @@ mod tests {
|
|||||||
ParseResult::Arguments(Arguments::buy_xmr_testnet_defaults().with_json())
|
ParseResult::Arguments(Arguments::buy_xmr_testnet_defaults().with_json())
|
||||||
);
|
);
|
||||||
|
|
||||||
let raw_ars = vec![
|
let raw_ars = vec![BINARY_NAME, "--json", "resume", "--swap-id", SWAP_ID];
|
||||||
BINARY_NAME,
|
|
||||||
"--json",
|
|
||||||
"resume",
|
|
||||||
"--swap-id",
|
|
||||||
SWAP_ID,
|
|
||||||
"--receive-address",
|
|
||||||
MONERO_MAINNET_ADDRESS,
|
|
||||||
];
|
|
||||||
|
|
||||||
let args = parse_args_and_apply_defaults(raw_ars).unwrap();
|
let args = parse_args_and_apply_defaults(raw_ars).unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@ -912,8 +901,6 @@ mod tests {
|
|||||||
"resume",
|
"resume",
|
||||||
"--swap-id",
|
"--swap-id",
|
||||||
SWAP_ID,
|
SWAP_ID,
|
||||||
"--receive-address",
|
|
||||||
MONERO_STAGENET_ADDRESS,
|
|
||||||
];
|
];
|
||||||
|
|
||||||
let args = parse_args_and_apply_defaults(raw_ars).unwrap();
|
let args = parse_args_and_apply_defaults(raw_ars).unwrap();
|
||||||
@ -935,6 +922,7 @@ mod tests {
|
|||||||
bitcoin_electrum_rpc_url: Url::from_str(DEFAULT_ELECTRUM_RPC_URL_TESTNET)
|
bitcoin_electrum_rpc_url: Url::from_str(DEFAULT_ELECTRUM_RPC_URL_TESTNET)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
bitcoin_target_block: DEFAULT_BITCOIN_CONFIRMATION_TARGET_TESTNET,
|
bitcoin_target_block: DEFAULT_BITCOIN_CONFIRMATION_TARGET_TESTNET,
|
||||||
|
bitcoin_change_address: BITCOIN_TESTNET_ADDRESS.parse().unwrap(),
|
||||||
monero_receive_address: monero::Address::from_str(MONERO_STAGENET_ADDRESS)
|
monero_receive_address: monero::Address::from_str(MONERO_STAGENET_ADDRESS)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
monero_daemon_address: DEFAULT_MONERO_DAEMON_ADDRESS_STAGENET.to_string(),
|
monero_daemon_address: DEFAULT_MONERO_DAEMON_ADDRESS_STAGENET.to_string(),
|
||||||
@ -953,6 +941,7 @@ mod tests {
|
|||||||
seller: Multiaddr::from_str(MULTI_ADDRESS).unwrap(),
|
seller: Multiaddr::from_str(MULTI_ADDRESS).unwrap(),
|
||||||
bitcoin_electrum_rpc_url: Url::from_str(DEFAULT_ELECTRUM_RPC_URL).unwrap(),
|
bitcoin_electrum_rpc_url: Url::from_str(DEFAULT_ELECTRUM_RPC_URL).unwrap(),
|
||||||
bitcoin_target_block: DEFAULT_BITCOIN_CONFIRMATION_TARGET,
|
bitcoin_target_block: DEFAULT_BITCOIN_CONFIRMATION_TARGET,
|
||||||
|
bitcoin_change_address: BITCOIN_MAINNET_ADDRESS.parse().unwrap(),
|
||||||
monero_receive_address: monero::Address::from_str(MONERO_MAINNET_ADDRESS)
|
monero_receive_address: monero::Address::from_str(MONERO_MAINNET_ADDRESS)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
monero_daemon_address: DEFAULT_MONERO_DAEMON_ADDRESS.to_string(),
|
monero_daemon_address: DEFAULT_MONERO_DAEMON_ADDRESS.to_string(),
|
||||||
@ -972,8 +961,6 @@ mod tests {
|
|||||||
bitcoin_electrum_rpc_url: Url::from_str(DEFAULT_ELECTRUM_RPC_URL_TESTNET)
|
bitcoin_electrum_rpc_url: Url::from_str(DEFAULT_ELECTRUM_RPC_URL_TESTNET)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
bitcoin_target_block: DEFAULT_BITCOIN_CONFIRMATION_TARGET_TESTNET,
|
bitcoin_target_block: DEFAULT_BITCOIN_CONFIRMATION_TARGET_TESTNET,
|
||||||
monero_receive_address: monero::Address::from_str(MONERO_STAGENET_ADDRESS)
|
|
||||||
.unwrap(),
|
|
||||||
monero_daemon_address: DEFAULT_MONERO_DAEMON_ADDRESS_STAGENET.to_string(),
|
monero_daemon_address: DEFAULT_MONERO_DAEMON_ADDRESS_STAGENET.to_string(),
|
||||||
tor_socks5_port: DEFAULT_SOCKS5_PORT,
|
tor_socks5_port: DEFAULT_SOCKS5_PORT,
|
||||||
},
|
},
|
||||||
@ -990,8 +977,6 @@ mod tests {
|
|||||||
swap_id: Uuid::from_str(SWAP_ID).unwrap(),
|
swap_id: Uuid::from_str(SWAP_ID).unwrap(),
|
||||||
bitcoin_electrum_rpc_url: Url::from_str(DEFAULT_ELECTRUM_RPC_URL).unwrap(),
|
bitcoin_electrum_rpc_url: Url::from_str(DEFAULT_ELECTRUM_RPC_URL).unwrap(),
|
||||||
bitcoin_target_block: DEFAULT_BITCOIN_CONFIRMATION_TARGET,
|
bitcoin_target_block: DEFAULT_BITCOIN_CONFIRMATION_TARGET,
|
||||||
monero_receive_address: monero::Address::from_str(MONERO_MAINNET_ADDRESS)
|
|
||||||
.unwrap(),
|
|
||||||
monero_daemon_address: DEFAULT_MONERO_DAEMON_ADDRESS.to_string(),
|
monero_daemon_address: DEFAULT_MONERO_DAEMON_ADDRESS.to_string(),
|
||||||
tor_socks5_port: DEFAULT_SOCKS5_PORT,
|
tor_socks5_port: DEFAULT_SOCKS5_PORT,
|
||||||
},
|
},
|
||||||
|
@ -69,6 +69,7 @@ pub struct Database {
|
|||||||
swaps: sled::Tree,
|
swaps: sled::Tree,
|
||||||
peers: sled::Tree,
|
peers: sled::Tree,
|
||||||
addresses: sled::Tree,
|
addresses: sled::Tree,
|
||||||
|
monero_addresses: sled::Tree,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Database {
|
impl Database {
|
||||||
@ -81,11 +82,13 @@ impl Database {
|
|||||||
let swaps = db.open_tree("swaps")?;
|
let swaps = db.open_tree("swaps")?;
|
||||||
let peers = db.open_tree("peers")?;
|
let peers = db.open_tree("peers")?;
|
||||||
let addresses = db.open_tree("addresses")?;
|
let addresses = db.open_tree("addresses")?;
|
||||||
|
let monero_addresses = db.open_tree("monero_addresses")?;
|
||||||
|
|
||||||
Ok(Database {
|
Ok(Database {
|
||||||
swaps,
|
swaps,
|
||||||
peers,
|
peers,
|
||||||
addresses,
|
addresses,
|
||||||
|
monero_addresses,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,6 +119,39 @@ impl Database {
|
|||||||
Ok(PeerId::from_str(peer_id.as_str())?)
|
Ok(PeerId::from_str(peer_id.as_str())?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn insert_monero_address(
|
||||||
|
&self,
|
||||||
|
swap_id: Uuid,
|
||||||
|
address: monero::Address,
|
||||||
|
) -> Result<()> {
|
||||||
|
let key = swap_id.as_bytes();
|
||||||
|
let value = serialize(&address)?;
|
||||||
|
|
||||||
|
self.monero_addresses.insert(key, value)?;
|
||||||
|
|
||||||
|
self.monero_addresses
|
||||||
|
.flush_async()
|
||||||
|
.await
|
||||||
|
.map(|_| ())
|
||||||
|
.context("Could not flush db")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_monero_address(&self, swap_id: Uuid) -> Result<monero::Address> {
|
||||||
|
let encoded = self
|
||||||
|
.monero_addresses
|
||||||
|
.get(swap_id.as_bytes())?
|
||||||
|
.ok_or_else(|| {
|
||||||
|
anyhow!(
|
||||||
|
"No Monero address found for swap id {} in database",
|
||||||
|
swap_id
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let monero_address = deserialize(&encoded)?;
|
||||||
|
|
||||||
|
Ok(monero_address)
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn insert_address(&self, peer_id: PeerId, address: Multiaddr) -> Result<()> {
|
pub async fn insert_address(&self, peer_id: PeerId, address: Multiaddr) -> Result<()> {
|
||||||
let key = peer_id.to_bytes();
|
let key = peer_id.to_bytes();
|
||||||
|
|
||||||
@ -425,4 +461,17 @@ mod tests {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn save_and_load_monero_address() -> Result<()> {
|
||||||
|
let db_dir = tempfile::tempdir()?;
|
||||||
|
let swap_id = Uuid::new_v4();
|
||||||
|
|
||||||
|
Database::open(db_dir.path())?.insert_monero_address(swap_id, "53gEuGZUhP9JMEBZoGaFNzhwEgiG7hwQdMCqFxiyiTeFPmkbt1mAoNybEUvYBKHcnrSgxnVWgZsTvRBaHBNXPa8tHiCU51a".parse()?).await?;
|
||||||
|
let loaded_monero_address = Database::open(db_dir.path())?.get_monero_address(swap_id)?;
|
||||||
|
|
||||||
|
assert_eq!(loaded_monero_address.to_string(), "53gEuGZUhP9JMEBZoGaFNzhwEgiG7hwQdMCqFxiyiTeFPmkbt1mAoNybEUvYBKHcnrSgxnVWgZsTvRBaHBNXPa8tHiCU51a");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,13 +3,17 @@ use crate::protocol::bob;
|
|||||||
use crate::protocol::bob::BobState;
|
use crate::protocol::bob::BobState;
|
||||||
use monero_rpc::wallet::BlockHeight;
|
use monero_rpc::wallet::BlockHeight;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use serde_with::{serde_as, DisplayFromStr};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
|
#[serde_as]
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
|
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
|
||||||
pub enum Bob {
|
pub enum Bob {
|
||||||
Started {
|
Started {
|
||||||
#[serde(with = "::bitcoin::util::amount::serde::as_sat")]
|
#[serde(with = "::bitcoin::util::amount::serde::as_sat")]
|
||||||
btc_amount: bitcoin::Amount,
|
btc_amount: bitcoin::Amount,
|
||||||
|
#[serde_as(as = "DisplayFromStr")]
|
||||||
|
change_address: bitcoin::Address,
|
||||||
},
|
},
|
||||||
ExecutionSetupDone {
|
ExecutionSetupDone {
|
||||||
state2: bob::State2,
|
state2: bob::State2,
|
||||||
@ -45,7 +49,13 @@ pub enum BobEndState {
|
|||||||
impl From<BobState> for Bob {
|
impl From<BobState> for Bob {
|
||||||
fn from(bob_state: BobState) -> Self {
|
fn from(bob_state: BobState) -> Self {
|
||||||
match bob_state {
|
match bob_state {
|
||||||
BobState::Started { btc_amount } => Bob::Started { btc_amount },
|
BobState::Started {
|
||||||
|
btc_amount,
|
||||||
|
change_address,
|
||||||
|
} => Bob::Started {
|
||||||
|
btc_amount,
|
||||||
|
change_address,
|
||||||
|
},
|
||||||
BobState::SwapSetupCompleted(state2) => Bob::ExecutionSetupDone { state2 },
|
BobState::SwapSetupCompleted(state2) => Bob::ExecutionSetupDone { state2 },
|
||||||
BobState::BtcLocked(state3) => Bob::BtcLocked { state3 },
|
BobState::BtcLocked(state3) => Bob::BtcLocked { state3 },
|
||||||
BobState::XmrLockProofReceived {
|
BobState::XmrLockProofReceived {
|
||||||
@ -77,7 +87,13 @@ impl From<BobState> for Bob {
|
|||||||
impl From<Bob> for BobState {
|
impl From<Bob> for BobState {
|
||||||
fn from(db_state: Bob) -> Self {
|
fn from(db_state: Bob) -> Self {
|
||||||
match db_state {
|
match db_state {
|
||||||
Bob::Started { btc_amount } => BobState::Started { btc_amount },
|
Bob::Started {
|
||||||
|
btc_amount,
|
||||||
|
change_address,
|
||||||
|
} => BobState::Started {
|
||||||
|
btc_amount,
|
||||||
|
change_address,
|
||||||
|
},
|
||||||
Bob::ExecutionSetupDone { state2 } => BobState::SwapSetupCompleted(state2),
|
Bob::ExecutionSetupDone { state2 } => BobState::SwapSetupCompleted(state2),
|
||||||
Bob::BtcLocked { state3 } => BobState::BtcLocked(state3),
|
Bob::BtcLocked { state3 } => BobState::BtcLocked(state3),
|
||||||
Bob::XmrLockProofReceived {
|
Bob::XmrLockProofReceived {
|
||||||
|
@ -20,7 +20,7 @@ pub struct Swap {
|
|||||||
pub monero_wallet: Arc<monero::Wallet>,
|
pub monero_wallet: Arc<monero::Wallet>,
|
||||||
pub env_config: env::Config,
|
pub env_config: env::Config,
|
||||||
pub id: Uuid,
|
pub id: Uuid,
|
||||||
pub receive_monero_address: monero::Address,
|
pub monero_receive_address: monero::Address,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Swap {
|
impl Swap {
|
||||||
@ -32,21 +32,26 @@ impl Swap {
|
|||||||
monero_wallet: Arc<monero::Wallet>,
|
monero_wallet: Arc<monero::Wallet>,
|
||||||
env_config: env::Config,
|
env_config: env::Config,
|
||||||
event_loop_handle: cli::EventLoopHandle,
|
event_loop_handle: cli::EventLoopHandle,
|
||||||
receive_monero_address: monero::Address,
|
monero_receive_address: monero::Address,
|
||||||
|
bitcoin_change_address: bitcoin::Address,
|
||||||
btc_amount: bitcoin::Amount,
|
btc_amount: bitcoin::Amount,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
state: BobState::Started { btc_amount },
|
state: BobState::Started {
|
||||||
|
btc_amount,
|
||||||
|
change_address: bitcoin_change_address,
|
||||||
|
},
|
||||||
event_loop_handle,
|
event_loop_handle,
|
||||||
db,
|
db,
|
||||||
bitcoin_wallet,
|
bitcoin_wallet,
|
||||||
monero_wallet,
|
monero_wallet,
|
||||||
env_config,
|
env_config,
|
||||||
id,
|
id,
|
||||||
receive_monero_address,
|
monero_receive_address,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn from_db(
|
pub fn from_db(
|
||||||
db: Database,
|
db: Database,
|
||||||
id: Uuid,
|
id: Uuid,
|
||||||
@ -54,7 +59,7 @@ impl Swap {
|
|||||||
monero_wallet: Arc<monero::Wallet>,
|
monero_wallet: Arc<monero::Wallet>,
|
||||||
env_config: env::Config,
|
env_config: env::Config,
|
||||||
event_loop_handle: cli::EventLoopHandle,
|
event_loop_handle: cli::EventLoopHandle,
|
||||||
receive_monero_address: monero::Address,
|
monero_receive_address: monero::Address,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let state = db.get_state(id)?.try_into_bob()?.into();
|
let state = db.get_state(id)?.try_into_bob()?.into();
|
||||||
|
|
||||||
@ -66,7 +71,7 @@ impl Swap {
|
|||||||
monero_wallet,
|
monero_wallet,
|
||||||
env_config,
|
env_config,
|
||||||
id,
|
id,
|
||||||
receive_monero_address,
|
monero_receive_address,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ use uuid::Uuid;
|
|||||||
pub enum BobState {
|
pub enum BobState {
|
||||||
Started {
|
Started {
|
||||||
btc_amount: bitcoin::Amount,
|
btc_amount: bitcoin::Amount,
|
||||||
|
change_address: bitcoin::Address,
|
||||||
},
|
},
|
||||||
SwapSetupCompleted(State2),
|
SwapSetupCompleted(State2),
|
||||||
BtcLocked(State3),
|
BtcLocked(State3),
|
||||||
@ -169,7 +170,14 @@ impl State0 {
|
|||||||
bail!("Alice's dleq proof doesn't verify")
|
bail!("Alice's dleq proof doesn't verify")
|
||||||
}
|
}
|
||||||
|
|
||||||
let tx_lock = bitcoin::TxLock::new(wallet, self.btc, msg.A, self.b.public()).await?;
|
let tx_lock = bitcoin::TxLock::new(
|
||||||
|
wallet,
|
||||||
|
self.btc,
|
||||||
|
msg.A,
|
||||||
|
self.b.public(),
|
||||||
|
self.refund_address.clone(),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
let v = msg.v_a + self.v_b;
|
let v = msg.v_a + self.v_b;
|
||||||
|
|
||||||
Ok(State1 {
|
Ok(State1 {
|
||||||
|
@ -37,7 +37,7 @@ pub async fn run_until(
|
|||||||
&mut swap.event_loop_handle,
|
&mut swap.event_loop_handle,
|
||||||
swap.bitcoin_wallet.as_ref(),
|
swap.bitcoin_wallet.as_ref(),
|
||||||
swap.monero_wallet.as_ref(),
|
swap.monero_wallet.as_ref(),
|
||||||
swap.receive_monero_address,
|
swap.monero_receive_address,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
@ -56,13 +56,15 @@ async fn next_state(
|
|||||||
event_loop_handle: &mut EventLoopHandle,
|
event_loop_handle: &mut EventLoopHandle,
|
||||||
bitcoin_wallet: &bitcoin::Wallet,
|
bitcoin_wallet: &bitcoin::Wallet,
|
||||||
monero_wallet: &monero::Wallet,
|
monero_wallet: &monero::Wallet,
|
||||||
receive_monero_address: monero::Address,
|
monero_receive_address: monero::Address,
|
||||||
) -> Result<BobState> {
|
) -> Result<BobState> {
|
||||||
tracing::trace!(%state, "Advancing state");
|
tracing::trace!(%state, "Advancing state");
|
||||||
|
|
||||||
Ok(match state {
|
Ok(match state {
|
||||||
BobState::Started { btc_amount } => {
|
BobState::Started {
|
||||||
let bitcoin_refund_address = bitcoin_wallet.new_address().await?;
|
btc_amount,
|
||||||
|
change_address,
|
||||||
|
} => {
|
||||||
let tx_refund_fee = bitcoin_wallet
|
let tx_refund_fee = bitcoin_wallet
|
||||||
.estimate_fee(TxRefund::weight(), btc_amount)
|
.estimate_fee(TxRefund::weight(), btc_amount)
|
||||||
.await?;
|
.await?;
|
||||||
@ -76,7 +78,7 @@ async fn next_state(
|
|||||||
btc: btc_amount,
|
btc: btc_amount,
|
||||||
tx_refund_fee,
|
tx_refund_fee,
|
||||||
tx_cancel_fee,
|
tx_cancel_fee,
|
||||||
bitcoin_refund_address,
|
bitcoin_refund_address: change_address,
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
@ -224,10 +226,10 @@ async fn next_state(
|
|||||||
// Ensure that the generated wallet is synced so we have a proper balance
|
// Ensure that the generated wallet is synced so we have a proper balance
|
||||||
monero_wallet.refresh().await?;
|
monero_wallet.refresh().await?;
|
||||||
// Sweep (transfer all funds) to the given address
|
// Sweep (transfer all funds) to the given address
|
||||||
let tx_hashes = monero_wallet.sweep_all(receive_monero_address).await?;
|
let tx_hashes = monero_wallet.sweep_all(monero_receive_address).await?;
|
||||||
|
|
||||||
for tx_hash in tx_hashes {
|
for tx_hash in tx_hashes {
|
||||||
tracing::info!(%receive_monero_address, txid=%tx_hash.0, "Sent XMR to");
|
tracing::info!(%monero_receive_address, txid=%tx_hash.0, "Sent XMR to");
|
||||||
}
|
}
|
||||||
|
|
||||||
BobState::XmrRedeemed {
|
BobState::XmrRedeemed {
|
||||||
|
@ -434,6 +434,7 @@ impl BobParams {
|
|||||||
self.env_config,
|
self.env_config,
|
||||||
handle,
|
handle,
|
||||||
self.monero_wallet.get_main_address(),
|
self.monero_wallet.get_main_address(),
|
||||||
|
self.bitcoin_wallet.new_address().await?,
|
||||||
btc_amount,
|
btc_amount,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user