Execute Alice's on-chain protocol after handshake

Co-authored-by: Tobin C. Harding <tobin@coblox.tech>
This commit is contained in:
Lucas Soriano del Pino 2020-10-27 12:11:03 +11:00
parent dbd7f2b0c9
commit 4ee82a5a2a
13 changed files with 402 additions and 65 deletions

View file

@ -24,7 +24,7 @@ use std::{
sync::Arc,
time::Duration,
};
use tokio::time::timeout;
use tokio::{sync::Mutex, time::timeout};
use tracing::error;
pub mod message;
@ -62,7 +62,7 @@ pub trait ReceiveBitcoinRedeemEncsig {
/// The argument `bitcoin_tx_lock_timeout` is used to determine how long we will
/// wait for Bob, the counterparty, to lock up the bitcoin.
pub fn action_generator<N, B>(
mut network: N,
network: Arc<Mutex<N>>,
bitcoin_client: Arc<B>,
// TODO: Replace this with a new, slimmer struct?
State3 {
@ -86,7 +86,7 @@ pub fn action_generator<N, B>(
bitcoin_tx_lock_timeout: u64,
) -> GenBoxed<Action, (), ()>
where
N: ReceiveBitcoinRedeemEncsig + Send + Sync + 'static,
N: ReceiveBitcoinRedeemEncsig + Send + 'static,
B: bitcoin::BlockHeight
+ bitcoin::TransactionBlockHeight
+ bitcoin::WatchForRawTransaction
@ -158,19 +158,24 @@ where
// TODO: Watch for LockXmr using watch-only wallet. Doing so will prevent Alice
// from cancelling/refunding unnecessarily.
let tx_redeem_encsig = match select(
network.receive_bitcoin_redeem_encsig(),
poll_until_btc_has_expired.clone(),
)
.await
{
Either::Left((encsig, _)) => encsig,
Either::Right(_) => {
return Err(SwapFailed::AfterXmrLock {
reason: Reason::BtcExpired,
tx_lock_height,
})
}
let tx_redeem_encsig = {
let mut guard = network.as_ref().lock().await;
let tx_redeem_encsig = match select(
guard.receive_bitcoin_redeem_encsig(),
poll_until_btc_has_expired.clone(),
)
.await
{
Either::Left((encsig, _)) => encsig,
Either::Right(_) => {
return Err(SwapFailed::AfterXmrLock {
reason: Reason::BtcExpired,
tx_lock_height,
})
}
};
tx_redeem_encsig
};
let (signed_tx_redeem, tx_redeem_txid) = {

View file

@ -31,7 +31,7 @@ pub struct Message1 {
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Message2 {
pub(crate) tx_lock_proof: monero::TransferProof,
pub tx_lock_proof: monero::TransferProof,
}
impl_try_from_parent_enum!(Message0, Message);

View file

@ -1,7 +1,5 @@
pub mod harness;
use std::{convert::TryInto, sync::Arc};
use anyhow::Result;
use async_trait::async_trait;
use futures::{
@ -16,7 +14,9 @@ use harness::{
};
use monero_harness::Monero;
use rand::rngs::OsRng;
use std::{convert::TryInto, sync::Arc};
use testcontainers::clients::Cli;
use tokio::sync::Mutex;
use tracing::info;
use tracing_subscriber::util::SubscriberInitExt;
use xmr_btc::{
@ -102,7 +102,7 @@ impl Default for BobBehaviour {
}
async fn swap_as_alice(
network: AliceNetwork,
network: Arc<Mutex<AliceNetwork>>,
// FIXME: It would be more intuitive to have a single network/transport struct instead of
// splitting into two, but Rust ownership rules make this tedious
mut sender: Sender<TransferProof>,
@ -274,6 +274,8 @@ async fn on_chain_happy_path() {
let (alice_network, bob_sender) = Network::<EncryptedSignature>::new();
let (bob_network, alice_sender) = Network::<TransferProof>::new();
let alice_network = Arc::new(Mutex::new(alice_network));
try_join(
swap_as_alice(
alice_network,
@ -365,6 +367,8 @@ async fn on_chain_both_refund_if_alice_never_redeems() {
let (alice_network, bob_sender) = Network::<EncryptedSignature>::new();
let (bob_network, alice_sender) = Network::<TransferProof>::new();
let alice_network = Arc::new(Mutex::new(alice_network));
try_join(
swap_as_alice(
alice_network,
@ -460,6 +464,8 @@ async fn on_chain_alice_punishes_if_bob_never_acts_after_fund() {
let (alice_network, bob_sender) = Network::<EncryptedSignature>::new();
let (bob_network, alice_sender) = Network::<TransferProof>::new();
let alice_network = Arc::new(Mutex::new(alice_network));
let alice_swap = swap_as_alice(
alice_network,
alice_sender,