mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2024-10-01 01:45:40 -04:00
Add resume-only mode for the ASB
Resume-only is a maintenance mode where no swaps are accepted but unfinished swaps are resumed. This is achieve by ignoring incoming spot-price requests (that would lead to execution setup) in the event-loop.
This commit is contained in:
parent
08d7d587cf
commit
f6497778ed
@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Resume-only mode for the ASB.
|
||||||
|
When started with `--resume-only` the ASB does not accept new, incoming swap requests but only finishes swaps that are resumed upon startup.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- An issue where both the ASB and the CLI point to the same default directory `xmr-btc-swap` for storing data.
|
- An issue where both the ASB and the CLI point to the same default directory `xmr-btc-swap` for storing data.
|
||||||
|
@ -34,6 +34,12 @@ pub enum Command {
|
|||||||
default_value = "0.02"
|
default_value = "0.02"
|
||||||
)]
|
)]
|
||||||
ask_spread: Decimal,
|
ask_spread: Decimal,
|
||||||
|
|
||||||
|
#[structopt(
|
||||||
|
long = "resume-only",
|
||||||
|
help = "For maintenance only. When set, no new swap requests will be accepted, but existing unfinished swaps will be resumed."
|
||||||
|
)]
|
||||||
|
resume_only: bool,
|
||||||
},
|
},
|
||||||
History,
|
History,
|
||||||
WithdrawBtc {
|
WithdrawBtc {
|
||||||
|
@ -81,6 +81,7 @@ async fn main() -> Result<()> {
|
|||||||
Command::Start {
|
Command::Start {
|
||||||
max_buy,
|
max_buy,
|
||||||
ask_spread,
|
ask_spread,
|
||||||
|
resume_only,
|
||||||
} => {
|
} => {
|
||||||
let bitcoin_wallet = init_bitcoin_wallet(&config, &seed, env_config).await?;
|
let bitcoin_wallet = init_bitcoin_wallet(&config, &seed, env_config).await?;
|
||||||
let monero_wallet = init_monero_wallet(&config, env_config).await?;
|
let monero_wallet = init_monero_wallet(&config, env_config).await?;
|
||||||
@ -133,6 +134,7 @@ async fn main() -> Result<()> {
|
|||||||
Arc::new(db),
|
Arc::new(db),
|
||||||
KrakenRate::new(ask_spread, kraken_price_updates),
|
KrakenRate::new(ask_spread, kraken_price_updates),
|
||||||
max_buy,
|
max_buy,
|
||||||
|
resume_only,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
@ -41,7 +41,16 @@ pub struct Request {
|
|||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
pub struct Response {
|
pub struct Response {
|
||||||
pub xmr: monero::Amount,
|
pub xmr: Option<monero::Amount>,
|
||||||
|
pub error: Option<Error>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, thiserror::Error, Serialize, Deserialize)]
|
||||||
|
pub enum Error {
|
||||||
|
#[error(
|
||||||
|
"This seller currently does not accept incoming swap requests, please try again later"
|
||||||
|
)]
|
||||||
|
MaintenanceMode,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructs a new instance of the `spot-price` behaviour to be used by Alice.
|
/// Constructs a new instance of the `spot-price` behaviour to be used by Alice.
|
||||||
|
@ -42,6 +42,7 @@ pub struct EventLoop<RS> {
|
|||||||
max_buy: bitcoin::Amount,
|
max_buy: bitcoin::Amount,
|
||||||
|
|
||||||
swap_sender: mpsc::Sender<Swap>,
|
swap_sender: mpsc::Sender<Swap>,
|
||||||
|
resume_only: bool,
|
||||||
|
|
||||||
/// Stores incoming [`EncryptedSignature`]s per swap.
|
/// Stores incoming [`EncryptedSignature`]s per swap.
|
||||||
recv_encrypted_signature: HashMap<Uuid, bmrng::RequestSender<bitcoin::EncryptedSignature, ()>>,
|
recv_encrypted_signature: HashMap<Uuid, bmrng::RequestSender<bitcoin::EncryptedSignature, ()>>,
|
||||||
@ -62,6 +63,7 @@ impl<LR> EventLoop<LR>
|
|||||||
where
|
where
|
||||||
LR: LatestRate,
|
LR: LatestRate,
|
||||||
{
|
{
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
swarm: Swarm<Behaviour>,
|
swarm: Swarm<Behaviour>,
|
||||||
env_config: Config,
|
env_config: Config,
|
||||||
@ -70,6 +72,7 @@ where
|
|||||||
db: Arc<Database>,
|
db: Arc<Database>,
|
||||||
latest_rate: LR,
|
latest_rate: LR,
|
||||||
max_buy: bitcoin::Amount,
|
max_buy: bitcoin::Amount,
|
||||||
|
resume_only: bool,
|
||||||
) -> Result<(Self, mpsc::Receiver<Swap>)> {
|
) -> Result<(Self, mpsc::Receiver<Swap>)> {
|
||||||
let swap_channel = MpscChannels::default();
|
let swap_channel = MpscChannels::default();
|
||||||
|
|
||||||
@ -81,6 +84,7 @@ where
|
|||||||
db,
|
db,
|
||||||
latest_rate,
|
latest_rate,
|
||||||
swap_sender: swap_channel.sender,
|
swap_sender: swap_channel.sender,
|
||||||
|
resume_only,
|
||||||
max_buy,
|
max_buy,
|
||||||
recv_encrypted_signature: Default::default(),
|
recv_encrypted_signature: Default::default(),
|
||||||
inflight_encrypted_signatures: Default::default(),
|
inflight_encrypted_signatures: Default::default(),
|
||||||
@ -144,6 +148,20 @@ where
|
|||||||
swarm_event = self.swarm.next_event() => {
|
swarm_event = self.swarm.next_event() => {
|
||||||
match swarm_event {
|
match swarm_event {
|
||||||
SwarmEvent::Behaviour(OutEvent::SpotPriceRequested { request, channel, peer }) => {
|
SwarmEvent::Behaviour(OutEvent::SpotPriceRequested { request, channel, peer }) => {
|
||||||
|
if self.resume_only {
|
||||||
|
tracing::warn!(%peer, "Ignoring spot price request from {} because ASB started in resume-only mode", peer);
|
||||||
|
|
||||||
|
match self.swarm.behaviour_mut().spot_price.send_response(channel, spot_price::Response { xmr: None, error: Some(spot_price::Error::MaintenanceMode) }) {
|
||||||
|
Ok(_) => {},
|
||||||
|
Err(_) => {
|
||||||
|
tracing::debug!(%peer, "Failed to respond with error to spot price request");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
let btc = request.btc;
|
let btc = request.btc;
|
||||||
let xmr = match self.handle_spot_price_request(btc, self.monero_wallet.clone()).await {
|
let xmr = match self.handle_spot_price_request(btc, self.monero_wallet.clone()).await {
|
||||||
Ok(xmr) => xmr,
|
Ok(xmr) => xmr,
|
||||||
@ -153,7 +171,7 @@ where
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
match self.swarm.behaviour_mut().spot_price.send_response(channel, spot_price::Response { xmr }) {
|
match self.swarm.behaviour_mut().spot_price.send_response(channel, spot_price::Response { xmr: Some(xmr), error: None }) {
|
||||||
Ok(_) => {},
|
Ok(_) => {},
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
// if we can't respond, the peer probably just disconnected so it is not a huge deal, only log this on debug
|
// if we can't respond, the peer probably just disconnected so it is not a huge deal, only log this on debug
|
||||||
|
@ -3,7 +3,7 @@ use crate::network::quote::BidQuote;
|
|||||||
use crate::network::{encrypted_signature, spot_price};
|
use crate::network::{encrypted_signature, spot_price};
|
||||||
use crate::protocol::bob::{Behaviour, OutEvent, State0, State2};
|
use crate::protocol::bob::{Behaviour, OutEvent, State0, State2};
|
||||||
use crate::{bitcoin, monero};
|
use crate::{bitcoin, monero};
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{bail, Context, Result};
|
||||||
use futures::future::{BoxFuture, OptionFuture};
|
use futures::future::{BoxFuture, OptionFuture};
|
||||||
use futures::{FutureExt, StreamExt};
|
use futures::{FutureExt, StreamExt};
|
||||||
use libp2p::request_response::{RequestId, ResponseChannel};
|
use libp2p::request_response::{RequestId, ResponseChannel};
|
||||||
@ -261,11 +261,22 @@ impl EventLoopHandle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn request_spot_price(&mut self, btc: bitcoin::Amount) -> Result<monero::Amount> {
|
pub async fn request_spot_price(&mut self, btc: bitcoin::Amount) -> Result<monero::Amount> {
|
||||||
Ok(self
|
let response = self
|
||||||
.spot_price
|
.spot_price
|
||||||
.send_receive(spot_price::Request { btc })
|
.send_receive(spot_price::Request { btc })
|
||||||
.await?
|
.await?;
|
||||||
.xmr)
|
|
||||||
|
match (response.xmr, response.error) {
|
||||||
|
(Some(xmr), None) => Ok(xmr),
|
||||||
|
(_, Some(error)) => {
|
||||||
|
bail!(error);
|
||||||
|
}
|
||||||
|
(None, None) => {
|
||||||
|
bail!(
|
||||||
|
"Unexpected response for spot-price request, neither price nor error received"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn request_quote(&mut self) -> Result<BidQuote> {
|
pub async fn request_quote(&mut self) -> Result<BidQuote> {
|
||||||
|
@ -234,6 +234,7 @@ fn start_alice(
|
|||||||
db,
|
db,
|
||||||
FixedRate::default(),
|
FixedRate::default(),
|
||||||
bitcoin::Amount::ONE_BTC,
|
bitcoin::Amount::ONE_BTC,
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user