WIP - outline the quote protocol refactoring
Similar to the spot price protocol changes. Missing: - Move the actual logic from ASB event loop to the added quote protocol. - Add a separate task that periodically updates the balance for spot price and quote!quote-protocol-refactor
parent
593d5be77b
commit
de642e542f
@ -0,0 +1,153 @@
|
||||
use libp2p::{NetworkBehaviour, PeerId};
|
||||
use crate::network::quote::{BidQuote, BidQuoteProtocol};
|
||||
use crate::protocol::alice::event_loop::LatestRate;
|
||||
use std::collections::VecDeque;
|
||||
use libp2p::request_response::{RequestResponseConfig, ProtocolSupport, ResponseChannel};
|
||||
use crate::network::json_pull_codec::JsonPullCodec;
|
||||
use crate::monero;
|
||||
use std::task::{Context, Poll};
|
||||
use libp2p::swarm::{PollParameters, NetworkBehaviourAction, NetworkBehaviourEventProcess};
|
||||
use crate::protocol::alice;
|
||||
use crate::network::quote;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum OutEvent {
|
||||
QuoteSent {
|
||||
peer: PeerId,
|
||||
quote: BidQuote
|
||||
},
|
||||
Error {
|
||||
peer: PeerId,
|
||||
error: Error,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum Error {
|
||||
#[error("ASB is running in resume-only mode")]
|
||||
FailedToCreateQuote,
|
||||
#[error("Balance is {xmr_balance} which is insufficient to fulfill max buy of {max_buy} at price {price}")]
|
||||
InsufficientFunds {
|
||||
max_buy: bitcoin::Amount,
|
||||
price: bitcoin::Amount,
|
||||
xmr_balance: monero::Amount
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(NetworkBehaviour)]
|
||||
#[behaviour(out_event = "OutEvent", poll_method = "poll", event_process = true)]
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct Behaviour<LR>
|
||||
where
|
||||
LR: LatestRate + Send + 'static,
|
||||
{
|
||||
behaviour: quote::Behaviour,
|
||||
|
||||
#[behaviour(ignore)]
|
||||
events: VecDeque<OutEvent>,
|
||||
|
||||
#[behaviour(ignore)]
|
||||
balance: monero::Amount,
|
||||
#[behaviour(ignore)]
|
||||
lock_fee: monero::Amount,
|
||||
#[behaviour(ignore)]
|
||||
max_buy: bitcoin::Amount,
|
||||
#[behaviour(ignore)]
|
||||
latest_rate: LR,
|
||||
#[behaviour(ignore)]
|
||||
resume_only: bool,
|
||||
}
|
||||
|
||||
/// Behaviour that handles quotes
|
||||
/// All the logic how to react to a quote request is contained here, events
|
||||
/// reporting the successful handling of a quote request or a failure are
|
||||
/// bubbled up to the parent behaviour.
|
||||
impl<LR> Behaviour<LR>
|
||||
where
|
||||
LR: LatestRate + Send + 'static,
|
||||
{
|
||||
pub fn new(
|
||||
balance: monero::Amount,
|
||||
lock_fee: monero::Amount,
|
||||
max_buy: bitcoin::Amount,
|
||||
latest_rate: LR,
|
||||
resume_only: bool,
|
||||
) -> Self {
|
||||
Self {
|
||||
behaviour: quote::Behaviour::new(
|
||||
JsonPullCodec::default(),
|
||||
vec![(BidQuoteProtocol, ProtocolSupport::Inbound)],
|
||||
RequestResponseConfig::default(),
|
||||
),
|
||||
events: Default::default(),
|
||||
balance,
|
||||
lock_fee,
|
||||
max_buy,
|
||||
latest_rate,
|
||||
resume_only,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_balance(&mut self, balance: monero::Amount) {
|
||||
self.balance = balance;
|
||||
}
|
||||
|
||||
fn decline(
|
||||
&mut self,
|
||||
peer: PeerId,
|
||||
channel: ResponseChannel<quote::Response>,
|
||||
error: Error,
|
||||
) {
|
||||
if self
|
||||
.behaviour
|
||||
.send_response(
|
||||
channel,
|
||||
quote::Response::Error,
|
||||
)
|
||||
.is_err()
|
||||
{
|
||||
tracing::debug!(%peer, "Unable to send error response for quote request");
|
||||
}
|
||||
|
||||
self.events.push_back(OutEvent::Error { peer, error });
|
||||
}
|
||||
|
||||
fn poll<BIE>(
|
||||
&mut self,
|
||||
_cx: &mut Context<'_>,
|
||||
_params: &mut impl PollParameters,
|
||||
) -> Poll<NetworkBehaviourAction<BIE, OutEvent>> {
|
||||
if let Some(event) = self.events.pop_front() {
|
||||
return Poll::Ready(NetworkBehaviourAction::GenerateEvent(event));
|
||||
}
|
||||
|
||||
// We trust in libp2p to poll us.
|
||||
Poll::Pending
|
||||
}
|
||||
}
|
||||
|
||||
impl<LR> NetworkBehaviourEventProcess<quote::OutEvent> for Behaviour<LR>
|
||||
where
|
||||
LR: LatestRate + Send + 'static,
|
||||
{
|
||||
fn inject_event(&mut self, event: quote::OutEvent) {
|
||||
|
||||
// TODO: Move the quote from the event loop into here
|
||||
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<OutEvent> for alice::OutEvent {
|
||||
fn from(event: OutEvent) -> Self {
|
||||
match event {
|
||||
OutEvent::QuoteSent { peer, quote } => {
|
||||
Self::QuoteSent { peer, quote }
|
||||
}
|
||||
OutEvent::Error { peer, error } => Self::QuoteError { peer, error },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// TODO: Add tests similar to spot price
|
Loading…
Reference in New Issue