xmr-btc-swap/xmr-btc/tests/on_chain.rs
Lucas Soriano del Pino 5daa3ea9a8 [WIP] Generate actions for Bob's on-chain protocol
Mimics what @thomaseizinger did here [1] and here [2].

This has the advantage that the consumer has more freedom to execute
`Action`s without having to implement particular traits. The error
handling required inside this protocol-executing function is also
reduced.

As discussed with Thomas, for this approach to work well, the
trait functions such as `receive_transfer_proof` should be infallible,
and the implementer should be forced to hide IO errors behind a retry
mechanism.

All of these asynchronous calls need to be "raced" against
the abort condition (determined by the `refund_timelock`), which is
missing in the current state of the implementation.

The initial handshake of the protocol has not been included here,
because it may not be easy to integrate this approach with libp2p, but
a couple of messages still need to exchanged. I need @tcharding to
tell me if it's feasible/good to do it like this.

[1]
https://github.com/comit-network/comit-rs/blob/move-nectar-swap-to-comit/nectar/src/swap/comit/herc20_hbit.rs#L57-L184.
[2] e584d2b14f/nectar/src/swap.rs (L716-L751).
2020-10-13 10:53:20 +11:00

68 lines
2.0 KiB
Rust

mod harness;
use anyhow::Result;
use genawaiter::GeneratorState;
use harness::wallet::{bitcoin, monero};
use xmr_btc::{
action_generator_bob,
bitcoin::{BroadcastSignedTransaction, SignTxLock},
bob,
monero::CreateWalletForOutput,
Action, ReceiveTransferProof,
};
struct Network;
impl ReceiveTransferProof for Network {
fn receive_transfer_proof(&self) -> xmr_btc::monero::TransferProof {
todo!("use libp2p")
}
}
async fn swap_as_bob(
network: &'static Network,
monero_wallet: &'static monero::BobWallet<'static>,
bitcoin_wallet: &'static bitcoin::Wallet,
state: bob::State2,
) -> Result<()> {
let mut action_generator = action_generator_bob(network, monero_wallet, bitcoin_wallet, state);
loop {
match action_generator.async_resume().await {
GeneratorState::Yielded(Action::LockBitcoin(tx_lock)) => {
let signed_tx_lock = bitcoin_wallet.sign_tx_lock(tx_lock).await?;
let _ = bitcoin_wallet
.broadcast_signed_transaction(signed_tx_lock)
.await?;
}
GeneratorState::Yielded(Action::SendBitcoinRedeemEncsig(_tx_redeem_encsig)) => {
todo!("use libp2p")
}
GeneratorState::Yielded(Action::CreateMoneroWalletForOutput {
spend_key,
view_key,
}) => {
monero_wallet
.create_and_load_wallet_for_output(spend_key, view_key)
.await?;
}
GeneratorState::Yielded(Action::RefundBitcoin {
tx_cancel,
tx_refund,
}) => {
let _ = bitcoin_wallet
.broadcast_signed_transaction(tx_cancel)
.await?;
let _ = bitcoin_wallet
.broadcast_signed_transaction(tx_refund)
.await?;
}
GeneratorState::Complete(()) => return Ok(()),
}
}
}
#[test]
fn on_chain_happy_path() {}