Combine Cmd and Params

This commit is contained in:
binarybaron 2023-08-11 10:50:13 +02:00
parent 63c1edbdd3
commit 7d2b7bee92
4 changed files with 118 additions and 189 deletions

View file

@ -18,14 +18,13 @@ use std::future::Future;
use std::net::SocketAddr; use std::net::SocketAddr;
use std::sync::Arc; use std::sync::Arc;
use std::time::Duration; use std::time::Duration;
use structopt::lazy_static::lazy_static;
use tokio::sync::broadcast::Receiver; use tokio::sync::broadcast::Receiver;
use tokio::sync::Mutex;
use tracing::{debug_span, Instrument}; use tracing::{debug_span, Instrument};
use uuid::Uuid; use uuid::Uuid;
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug)]
pub struct Request { pub struct Request {
pub params: Params,
pub cmd: Method, pub cmd: Method,
pub shutdown: Shutdown, pub shutdown: Shutdown,
} }
@ -72,72 +71,72 @@ impl PartialEq for Shutdown {
} }
} }
#[derive(Default, PartialEq, Debug)]
pub struct Params {
pub seller: Option<Multiaddr>,
pub bitcoin_change_address: Option<bitcoin::Address>,
pub monero_receive_address: Option<monero::Address>,
pub rendezvous_point: Option<Multiaddr>,
pub swap_id: Option<Uuid>,
pub amount: Option<Amount>,
pub server_address: Option<SocketAddr>,
pub address: Option<bitcoin::Address>,
}
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub enum Method { pub enum Method {
BuyXmr, BuyXmr {
seller: Multiaddr,
bitcoin_change_address: bitcoin::Address,
monero_receive_address: monero::Address,
swap_id: Uuid,
},
History, History,
RawHistory, RawHistory,
Config, Config,
WithdrawBtc, WithdrawBtc {
amount: Option<Amount>,
address: bitcoin::Address,
},
Balance, Balance,
GetSeller, GetSeller {
SwapStartDate, swap_id: Uuid,
Resume, },
CancelAndRefund, SwapStartDate {
ListSellers, swap_id: Uuid,
},
Resume {
swap_id: Uuid,
},
CancelAndRefund {
swap_id: Uuid,
},
ListSellers {
rendezvous_point: Multiaddr,
},
ExportBitcoinWallet, ExportBitcoinWallet,
MoneroRecovery, MoneroRecovery {
StartDaemon, swap_id: Uuid,
},
StartDaemon {
server_address: Option<SocketAddr>,
}
} }
impl Request { impl Request {
pub fn new(shutdownReceiver: Receiver<()>, cmd: Method, params: Params) -> Request { pub fn new(shutdownReceiver: Receiver<()>, cmd: Method) -> Request {
Request { Request {
params,
cmd, cmd,
shutdown: Shutdown::new(shutdownReceiver), shutdown: Shutdown::new(shutdownReceiver),
} }
} }
async fn handle_cmd(&mut self, context: Arc<Context>) -> Result<serde_json::Value> { fn has_lockable_swap_id(&self) -> Option<Uuid> {
match self.cmd { match self.cmd {
Method::BuyXmr => { Method::BuyXmr { swap_id, .. }
let swap_id = self | Method::Resume { swap_id }
.params | Method::CancelAndRefund { swap_id } => Some(swap_id),
.swap_id _ => None,
.context("Parameter swap_id is missing")?; }
}
async fn handle_cmd(mut self, context: Arc<Context>) -> Result<serde_json::Value> {
match self.cmd {
Method::BuyXmr { seller, bitcoin_change_address, monero_receive_address, swap_id } => {
let seed = context.config.seed.as_ref().context("Could not get seed")?; let seed = context.config.seed.as_ref().context("Could not get seed")?;
let env_config = context.config.env_config; let env_config = context.config.env_config;
let btc = context let btc = context
.bitcoin_wallet .bitcoin_wallet
.as_ref() .as_ref()
.context("Could not get Bitcoin wallet")?; .context("Could not get Bitcoin wallet")?;
let seller = self
.params
.seller
.clone()
.context("Parameter seller is missing")?;
let monero_receive_address = self
.params
.monero_receive_address
.context("Parameter monero_receive_address is missing")?;
let bitcoin_change_address = self
.params
.bitcoin_change_address
.clone()
.context("Parameter bitcoin_change_address is missing")?;
let bitcoin_wallet = btc; let bitcoin_wallet = btc;
let seller_peer_id = seller let seller_peer_id = seller
@ -247,8 +246,7 @@ impl Request {
let raw_history = context.db.raw_all().await?; let raw_history = context.db.raw_all().await?;
Ok(json!({ "raw_history": raw_history })) Ok(json!({ "raw_history": raw_history }))
} }
Method::GetSeller => { Method::GetSeller { swap_id } => {
let swap_id = self.params.swap_id.context("Parameter swap_id is needed")?;
let peerId = context let peerId = context
.db .db
.get_peer_id(swap_id) .get_peer_id(swap_id)
@ -266,12 +264,7 @@ impl Request {
"addresses": addresses "addresses": addresses
})) }))
} }
Method::SwapStartDate => { Method::SwapStartDate { swap_id } => {
let swap_id = self
.params
.swap_id
.context("Parameter swap_id is missing")?;
let start_date = context.db.get_swap_start_date(swap_id).await?; let start_date = context.db.get_swap_start_date(swap_id).await?;
Ok(json!({ Ok(json!({
@ -295,19 +288,13 @@ impl Request {
"bitcoin_wallet": format!("{}/wallet", data_dir_display), "bitcoin_wallet": format!("{}/wallet", data_dir_display),
})) }))
} }
Method::WithdrawBtc => { Method::WithdrawBtc {address, amount} => {
let bitcoin_wallet = context let bitcoin_wallet = context
.bitcoin_wallet .bitcoin_wallet
.as_ref() .as_ref()
.context("Could not get Bitcoin wallet")?; .context("Could not get Bitcoin wallet")?;
let address = self let amount = match amount {
.params
.address
.clone()
.context("Parameter address is missing")?;
let amount = match self.params.amount {
Some(amount) => amount, Some(amount) => amount,
None => { None => {
bitcoin_wallet bitcoin_wallet
@ -330,12 +317,9 @@ impl Request {
"txid": signed_tx.txid(), "txid": signed_tx.txid(),
})) }))
} }
Method::StartDaemon => { Method::StartDaemon {server_address} => {
// Default to 127.0.0.1:1234 // Default to 127.0.0.1:1234
let server_address = self let server_address = server_address.unwrap_or("127.0.0.1:1234".parse().unwrap());
.params
.server_address
.unwrap_or("127.0.0.1:1234".parse().unwrap());
let (_, server_handle) = let (_, server_handle) =
rpc::run_server(server_address, Arc::clone(&context)).await?; rpc::run_server(server_address, Arc::clone(&context)).await?;
@ -368,12 +352,7 @@ impl Request {
"balance": bitcoin_balance.to_sat() "balance": bitcoin_balance.to_sat()
})) }))
} }
Method::Resume => { Method::Resume {swap_id} => {
let swap_id = self
.params
.swap_id
.context("Parameter swap_id is missing")?;
let seller_peer_id = context.db.get_peer_id(swap_id).await?; let seller_peer_id = context.db.get_peer_id(swap_id).await?;
let seller_addresses = context.db.get_addresses(seller_peer_id).await?; let seller_addresses = context.db.get_addresses(seller_peer_id).await?;
@ -452,16 +431,14 @@ impl Request {
"result": [] "result": []
})) }))
} }
Method::CancelAndRefund => { Method::CancelAndRefund {swap_id} => {
let bitcoin_wallet = context let bitcoin_wallet = context
.bitcoin_wallet .bitcoin_wallet
.as_ref() .as_ref()
.context("Could not get Bitcoin wallet")?; .context("Could not get Bitcoin wallet")?;
let state = cli::cancel_and_refund( let state = cli::cancel_and_refund(
self.params swap_id,
.swap_id
.context("Parameter swap_id is missing")?,
Arc::clone(bitcoin_wallet), Arc::clone(bitcoin_wallet),
Arc::clone(&context.db), Arc::clone(&context.db),
) )
@ -471,12 +448,7 @@ impl Request {
"result": state, "result": state,
})) }))
} }
Method::ListSellers => { Method::ListSellers {rendezvous_point} => {
let rendezvous_point = self
.params
.rendezvous_point
.clone()
.context("Parameter rendezvous_point is missing")?;
let rendezvous_node_peer_id = rendezvous_point let rendezvous_node_peer_id = rendezvous_point
.extract_peer_id() .extract_peer_id()
.context("Rendezvous node address must contain peer ID")?; .context("Rendezvous node address must contain peer ID")?;
@ -536,13 +508,11 @@ impl Request {
"result": [] "result": []
})) }))
} }
Method::MoneroRecovery => { Method::MoneroRecovery {swap_id} => {
let swap_state: BobState = context let swap_state: BobState = context
.db .db
.get_state( .get_state(
self.params swap_id,
.swap_id
.context("Parameter swap_id is missing")?,
) )
.await? .await?
.try_into()?; .try_into()?;
@ -585,22 +555,11 @@ impl Request {
} }
} }
pub async fn call(&mut self, context: Arc<Context>) -> Result<serde_json::Value> { pub async fn call(self, context: Arc<Context>) -> Result<serde_json::Value> {
// If the swap ID is set, we add it to the span // If the swap ID is set, we add it to the span
let call_span = self.params.swap_id.map_or_else( let call_span = debug_span!(
|| { "call",
debug_span!( method = ?self.cmd,
"call",
method = ?self.cmd,
)
},
|swap_id| {
debug_span!(
"call",
method = ?self.cmd,
swap_id = swap_id.to_string(),
)
},
); );
self.handle_cmd(context).instrument(call_span).await self.handle_cmd(context).instrument(call_span).await

View file

@ -22,7 +22,7 @@ use tokio::sync::broadcast;
#[tokio::main] #[tokio::main]
async fn main() -> Result<()> { async fn main() -> Result<()> {
let (tx, _) = broadcast::channel(1); let (tx, _) = broadcast::channel(1);
let (context, mut request) = match parse_args_and_apply_defaults(env::args_os(), tx).await? { let (context, request) = match parse_args_and_apply_defaults(env::args_os(), tx).await? {
ParseResult::Context(context, request) => (context, request), ParseResult::Context(context, request) => (context, request),
ParseResult::PrintAndExitZero { message } => { ParseResult::PrintAndExitZero { message } => {
println!("{}", message); println!("{}", message);

View file

@ -1,4 +1,4 @@
use crate::api::request::{Method, Params, Request}; use crate::api::request::{Method, Request};
use crate::api::Context; use crate::api::Context;
use crate::bitcoin::{bitcoin_address, Amount}; use crate::bitcoin::{bitcoin_address, Amount};
use crate::monero; use crate::monero;
@ -80,13 +80,12 @@ where
let request = Request::new( let request = Request::new(
rx.subscribe(), rx.subscribe(),
Method::BuyXmr, Method::BuyXmr {
Params { seller,
bitcoin_change_address: Some(bitcoin_change_address), bitcoin_change_address,
monero_receive_address: Some(monero_receive_address), monero_receive_address,
seller: Some(seller), swap_id: Uuid::new_v4(),
..Default::default() }
},
); );
let context = Context::build( let context = Context::build(
@ -104,21 +103,21 @@ where
(context, request) (context, request)
} }
CliCommand::History => { CliCommand::History => {
let request = Request::new(rx.subscribe(), Method::History, Params::default()); let request = Request::new(rx.subscribe(), Method::History);
let context = let context =
Context::build(None, None, None, data, is_testnet, debug, json, None, rx).await?; Context::build(None, None, None, data, is_testnet, debug, json, None, rx).await?;
(context, request) (context, request)
} }
CliCommand::Config => { CliCommand::Config => {
let request = Request::new(rx.subscribe(), Method::Config, Params::default()); let request = Request::new(rx.subscribe(), Method::Config);
let context = let context =
Context::build(None, None, None, data, is_testnet, debug, json, None, rx).await?; Context::build(None, None, None, data, is_testnet, debug, json, None, rx).await?;
(context, request) (context, request)
} }
CliCommand::Balance { bitcoin } => { CliCommand::Balance { bitcoin } => {
let request = Request::new(rx.subscribe(), Method::Balance, Params::default()); let request = Request::new(rx.subscribe(), Method::Balance);
let context = Context::build( let context = Context::build(
Some(bitcoin), Some(bitcoin),
@ -142,11 +141,9 @@ where
} => { } => {
let request = Request::new( let request = Request::new(
rx.subscribe(), rx.subscribe(),
Method::StartDaemon, Method::StartDaemon {
Params { server_address
server_address, }
..Default::default()
},
); );
let context = Context::build( let context = Context::build(
@ -172,11 +169,9 @@ where
let request = Request::new( let request = Request::new(
rx.subscribe(), rx.subscribe(),
Method::WithdrawBtc, Method::WithdrawBtc {
Params {
amount, amount,
address: Some(address), address,
..Default::default()
}, },
); );
@ -202,11 +197,9 @@ where
} => { } => {
let request = Request::new( let request = Request::new(
rx.subscribe(), rx.subscribe(),
Method::Resume, Method::Resume {
Params { swap_id
swap_id: Some(swap_id), }
..Default::default()
},
); );
let context = Context::build( let context = Context::build(
@ -230,11 +223,9 @@ where
} => { } => {
let request = Request::new( let request = Request::new(
rx.subscribe(), rx.subscribe(),
Method::CancelAndRefund, Method::CancelAndRefund {
Params { swap_id
swap_id: Some(swap_id), }
..Default::default()
},
); );
let context = Context::build( let context = Context::build(
@ -257,11 +248,9 @@ where
} => { } => {
let request = Request::new( let request = Request::new(
rx.subscribe(), rx.subscribe(),
Method::ListSellers, Method::ListSellers {
Params { rendezvous_point
rendezvous_point: Some(rendezvous_point), }
..Default::default()
},
); );
let context = Context::build( let context = Context::build(
@ -283,7 +272,6 @@ where
let request = Request::new( let request = Request::new(
rx.subscribe(), rx.subscribe(),
Method::ExportBitcoinWallet, Method::ExportBitcoinWallet,
Params::default(),
); );
let context = Context::build( let context = Context::build(
@ -305,11 +293,9 @@ where
} => { } => {
let request = Request::new( let request = Request::new(
rx.subscribe(), rx.subscribe(),
Method::MoneroRecovery, Method::MoneroRecovery {
Params { swap_id
swap_id: Some(swap_id), }
..Default::default()
},
); );
let context = let context =

View file

@ -1,4 +1,4 @@
use crate::api::request::{Method, Params, Request}; use crate::api::request::{Method, Request};
use crate::api::Context; use crate::api::Context;
use crate::bitcoin::bitcoin_address; use crate::bitcoin::bitcoin_address;
use crate::monero::monero_address; use crate::monero::monero_address;
@ -161,10 +161,9 @@ pub fn register_modules(context: Arc<Context>) -> RpcModule<Arc<Context>> {
async fn execute_request( async fn execute_request(
cmd: Method, cmd: Method,
params: Params,
context: &Arc<Context>, context: &Arc<Context>,
) -> Result<serde_json::Value, jsonrpsee_core::Error> { ) -> Result<serde_json::Value, jsonrpsee_core::Error> {
let mut request = Request::new(context.shutdown.subscribe(), cmd, params); let request = Request::new(context.shutdown.subscribe(), cmd);
request request
.call(Arc::clone(context)) .call(Arc::clone(context))
.await .await
@ -174,74 +173,64 @@ async fn execute_request(
async fn get_bitcoin_balance( async fn get_bitcoin_balance(
context: &Arc<Context>, context: &Arc<Context>,
) -> Result<serde_json::Value, jsonrpsee_core::Error> { ) -> Result<serde_json::Value, jsonrpsee_core::Error> {
execute_request(Method::Balance, Params::default(), context).await execute_request(Method::Balance, context).await
} }
async fn get_history(context: &Arc<Context>) -> Result<serde_json::Value, jsonrpsee_core::Error> { async fn get_history(context: &Arc<Context>) -> Result<serde_json::Value, jsonrpsee_core::Error> {
execute_request(Method::History, Params::default(), context).await execute_request(Method::History, context).await
} }
async fn get_raw_history( async fn get_raw_history(
context: &Arc<Context>, context: &Arc<Context>,
) -> Result<serde_json::Value, jsonrpsee_core::Error> { ) -> Result<serde_json::Value, jsonrpsee_core::Error> {
execute_request(Method::RawHistory, Params::default(), context).await execute_request(Method::RawHistory, context).await
} }
async fn get_seller( async fn get_seller(
swap_id: Uuid, swap_id: Uuid,
context: &Arc<Context>, context: &Arc<Context>,
) -> Result<serde_json::Value, jsonrpsee_core::Error> { ) -> Result<serde_json::Value, jsonrpsee_core::Error> {
let params = Params { execute_request(Method::GetSeller {
swap_id: Some(swap_id), swap_id
..Default::default() }, context).await
};
execute_request(Method::GetSeller, params, context).await
} }
async fn get_swap_start_date( async fn get_swap_start_date(
swap_id: Uuid, swap_id: Uuid,
context: &Arc<Context>, context: &Arc<Context>,
) -> Result<serde_json::Value, jsonrpsee_core::Error> { ) -> Result<serde_json::Value, jsonrpsee_core::Error> {
let params = Params { execute_request(Method::SwapStartDate {
swap_id: Some(swap_id), swap_id
..Default::default() }, context).await
};
execute_request(Method::SwapStartDate, params, context).await
} }
async fn resume_swap( async fn resume_swap(
swap_id: Uuid, swap_id: Uuid,
context: &Arc<Context>, context: &Arc<Context>,
) -> Result<serde_json::Value, jsonrpsee_core::Error> { ) -> Result<serde_json::Value, jsonrpsee_core::Error> {
let params = Params { execute_request(Method::Resume {
swap_id: Some(swap_id), swap_id
..Default::default() }, context).await
};
execute_request(Method::Resume, params, context).await
} }
async fn cancel_and_refund_swap( async fn cancel_and_refund_swap(
swap_id: Uuid, swap_id: Uuid,
context: &Arc<Context>, context: &Arc<Context>,
) -> Result<serde_json::Value, jsonrpsee_core::Error> { ) -> Result<serde_json::Value, jsonrpsee_core::Error> {
let params = Params { execute_request(Method::CancelAndRefund {
swap_id: Some(swap_id), swap_id
..Default::default() }, context).await
};
execute_request(Method::CancelAndRefund, params, context).await
} }
async fn withdraw_btc( async fn withdraw_btc(
withdraw_address: bitcoin::Address, address: bitcoin::Address,
amount: Option<bitcoin::Amount>, amount: Option<bitcoin::Amount>,
context: &Arc<Context>, context: &Arc<Context>,
) -> Result<serde_json::Value, jsonrpsee_core::Error> { ) -> Result<serde_json::Value, jsonrpsee_core::Error> {
let params = Params { execute_request(Method::WithdrawBtc {
amount, amount,
address: Some(withdraw_address), address,
..Default::default() }, context).await
};
execute_request(Method::WithdrawBtc, params, context).await
} }
async fn buy_xmr( async fn buy_xmr(
@ -250,24 +239,19 @@ async fn buy_xmr(
seller: Multiaddr, seller: Multiaddr,
context: &Arc<Context>, context: &Arc<Context>,
) -> Result<serde_json::Value, jsonrpsee_core::Error> { ) -> Result<serde_json::Value, jsonrpsee_core::Error> {
let params = Params { execute_request(Method::BuyXmr {
bitcoin_change_address: Some(bitcoin_change_address), seller,
monero_receive_address: Some(monero_receive_address), swap_id: Uuid::new_v4(),
seller: Some(seller), bitcoin_change_address,
swap_id: Some(Uuid::new_v4()), monero_receive_address
..Default::default() }, context).await
};
execute_request(Method::BuyXmr, params, context).await
} }
async fn list_sellers( async fn list_sellers(
rendezvous_point: Multiaddr, rendezvous_point: Multiaddr,
context: &Arc<Context>, context: &Arc<Context>,
) -> Result<serde_json::Value, jsonrpsee_core::Error> { ) -> Result<serde_json::Value, jsonrpsee_core::Error> {
let params = Params { execute_request(Method::ListSellers {
rendezvous_point: Some(rendezvous_point), rendezvous_point
..Default::default() }, context).await
};
execute_request(Method::ListSellers, params, context).await
} }