From 3492c46e7131209db511d3fb2205b28851dd0c67 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Fri, 16 Oct 2020 10:43:32 +1100 Subject: [PATCH] Verify amounts with user --- swap/src/alice.rs | 34 ++++++++++++++++------------------ swap/src/bob/messenger.rs | 4 +--- swap/src/lib.rs | 11 +++++++++-- swap/src/main.rs | 36 ++++++++++++++++++++++++++++++------ 4 files changed, 56 insertions(+), 29 deletions(-) diff --git a/swap/src/alice.rs b/swap/src/alice.rs index 5addb61f..80ddc09c 100644 --- a/swap/src/alice.rs +++ b/swap/src/alice.rs @@ -6,8 +6,8 @@ use libp2p::{ request_response::ResponseChannel, NetworkBehaviour, PeerId, }; -use std::{thread, time::Duration}; -use tracing::{debug, warn}; +use std::time::Duration; +use tracing::debug; mod messenger; @@ -27,24 +27,22 @@ pub type Swarm = libp2p::Swarm; pub async fn swap(listen: Multiaddr) -> Result<()> { let mut swarm = new_swarm(listen)?; - match swarm.next().await { - BehaviourOutEvent::Request(messenger::BehaviourOutEvent::Btc { btc, channel }) => { - debug!("Got request from Bob"); - let params = SwapParams { - btc, - // TODO: Do a real calculation. - xmr: monero::Amount::from_piconero(10), - }; - - let msg = AliceToBob::Amounts(params); - swarm.send(channel, msg); + loop { + match swarm.next().await { + BehaviourOutEvent::Request(messenger::BehaviourOutEvent::Btc { btc, channel }) => { + debug!("Got request from Bob to swap {}", btc); + let params = SwapParams { + btc, + // TODO: Do a real calculation. + xmr: monero::Amount::from_piconero(10), + }; + + let msg = AliceToBob::Amounts(params); + swarm.send(channel, msg); + } + other => panic!("unexpected event: {:?}", other), } - other => panic!("unexpected event: {:?}", other), } - - warn!("parking thread ..."); - thread::park(); - Ok(()) } fn new_swarm(listen: Multiaddr) -> Result { diff --git a/swap/src/bob/messenger.rs b/swap/src/bob/messenger.rs index e153addc..6d57804e 100644 --- a/swap/src/bob/messenger.rs +++ b/swap/src/bob/messenger.rs @@ -12,7 +12,7 @@ use std::{ task::{Context, Poll}, time::Duration, }; -use tracing::{debug, error}; +use tracing::error; use crate::{ bitcoin, @@ -55,10 +55,8 @@ impl Messenger { alice: PeerId, btc: bitcoin::Amount, ) -> Result { - debug!("Sending request ..."); let msg = BobToAlice::AmountsFromBtc(btc); let id = self.rr.send_request(&alice, msg); - debug!("Sent."); Ok(id) } diff --git a/swap/src/lib.rs b/swap/src/lib.rs index c5c22421..f9ba9a32 100644 --- a/swap/src/lib.rs +++ b/swap/src/lib.rs @@ -1,4 +1,5 @@ use serde::{Deserialize, Serialize}; +use std::fmt::{self, Display}; pub mod alice; pub mod bob; @@ -9,13 +10,13 @@ pub const ONE_BTC: u64 = 100_000_000; pub type Never = std::convert::Infallible; /// Commands sent from Bob to the main task. -#[derive(Debug)] +#[derive(Clone, Copy, Debug)] pub enum Cmd { VerifyAmounts(SwapParams), } /// Responses send from the main task back to Bob. -#[derive(Debug, PartialEq)] +#[derive(Clone, Copy, Debug, PartialEq)] pub enum Rsp { Verified, Abort, @@ -30,6 +31,12 @@ pub struct SwapParams { pub xmr: monero::Amount, } +impl Display for SwapParams { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{} for {}", self.btc, self.xmr) + } +} + // FIXME: Amount modules are a quick hack so we can derive serde. pub mod monero { diff --git a/swap/src/main.rs b/swap/src/main.rs index b95e5ba2..fc2997ee 100644 --- a/swap/src/main.rs +++ b/swap/src/main.rs @@ -16,9 +16,9 @@ use anyhow::{bail, Result}; use futures::{channel::mpsc, StreamExt}; use libp2p::Multiaddr; use log::LevelFilter; +use std::{io, io::Write, process}; use structopt::StructOpt; use tracing::info; - mod cli; mod trace; @@ -77,8 +77,10 @@ async fn swap_as_bob(sats: u64, addr: Multiaddr) -> Result<()> { match read { Some(cmd) => match cmd { Cmd::VerifyAmounts(p) => { - if verified(p) { - rsp_tx.try_send(Rsp::Verified)?; + let rsp = verify(p); + rsp_tx.try_send(rsp)?; + if rsp == Rsp::Abort { + process::exit(0); } } }, @@ -90,7 +92,29 @@ async fn swap_as_bob(sats: u64, addr: Multiaddr) -> Result<()> { } } -fn verified(_p: SwapParams) -> bool { - // TODO: Read input from the shell. - true +fn verify(p: SwapParams) -> Rsp { + let mut s = String::new(); + println!("Got rate from Alice for XMR/BTC swap\n"); + println!("{}", p); + print!("Would you like to continue with this swap [y/N]: "); + let _ = io::stdout().flush(); + io::stdin() + .read_line(&mut s) + .expect("Did not enter a correct string"); + if let Some('\n') = s.chars().next_back() { + s.pop(); + } + if let Some('\r') = s.chars().next_back() { + s.pop(); + } + if !is_yes(&s) { + println!("No worries, try again later - Alice updates her rate regularly"); + return Rsp::Abort; + } + + Rsp::Verified +} + +fn is_yes(s: &str) -> bool { + matches!(s, "y" | "Y" | "yes" | "YES" | "Yes") }