pub struct RfqManager {
active_rfqs: DashMap<Uuid, RfqRecord>,
qp_cache: Arc<QuoteProviderCache>,
qp_sessions: Arc<dyn QpSessionRegistry>,
rfq_sender: Sender<RfqExecuteRequest>,
db: Option<Arc<dyn RfqWriter>>,
config: RfqConfig,
}Expand description
Manages RFQ lifecycle: creation, QP fan-out, quote collection, acceptance.
Fields§
§active_rfqs: DashMap<Uuid, RfqRecord>§qp_cache: Arc<QuoteProviderCache>§qp_sessions: Arc<dyn QpSessionRegistry>§rfq_sender: Sender<RfqExecuteRequest>§db: Option<Arc<dyn RfqWriter>>§config: RfqConfigImplementations§
Source§impl RfqManager
impl RfqManager
pub fn new( qp_cache: Arc<QuoteProviderCache>, qp_sessions: Arc<dyn QpSessionRegistry>, rfq_sender: Sender<RfqExecuteRequest>, config: RfqConfig, ) -> Self
pub fn min_improvement_tick(&self) -> Decimal
Sourcefn persist_status(&self, rfq_id: &Uuid, status: RfqStatus)
fn persist_status(&self, rfq_id: &Uuid, status: RfqStatus)
Persist an RFQ status change to the rfq_records table. Non-fatal on
failure — logs a warning and keeps going so in-memory state
transitions stay responsive even if the DB hiccups. Callers MUST NOT
hold a DashMap lock (e.g. get_mut guard or alter_all closure) while
invoking this; drop the entry first.
Sourcepub fn set_db(&mut self, handler: Arc<dyn RfqWriter>)
pub fn set_db(&mut self, handler: Arc<dyn RfqWriter>)
Set the persistence writer for RFQ records and quotes.
Sourcepub async fn submit_rfq(
&self,
rfq_id: Uuid,
taker_wallet: WalletAddress,
taker_signer: WalletAddress,
legs: Vec<RfqLeg>,
legs_hash: [u8; 32],
taker_signature: String,
taker_nonce: u64,
auto_accept_limit: Option<Decimal>,
) -> Result<RfqRecord, String>
pub async fn submit_rfq( &self, rfq_id: Uuid, taker_wallet: WalletAddress, taker_signer: WalletAddress, legs: Vec<RfqLeg>, legs_hash: [u8; 32], taker_signature: String, taker_nonce: u64, auto_accept_limit: Option<Decimal>, ) -> Result<RfqRecord, String>
Submit a new RFQ from a taker.
pub async fn submit_rpi_auction( &self, request: SubmitRpiAuction, ) -> Result<RfqRecord, String>
Sourcepub fn handle_qp_response(
&self,
rfq_id: Uuid,
quote: QpQuote,
) -> Result<HandleQpResponseResult, String>
pub fn handle_qp_response( &self, rfq_id: Uuid, quote: QpQuote, ) -> Result<HandleQpResponseResult, String>
Handle a firm quote response from a QP.
No margin check here. Quotes are short-lived and non-binding until
accepted, so margin state can change between quote time and acceptance
(new fills, deposits, other RFQs landing). The authoritative SPAN
margin check on both taker and QP runs in plan_rfq_execution at
accept time, which cannot be skipped. Adding a check here would add
engine load on every incoming quote for a result that’s immediately
stale.
pub fn record_qp_invalid_response(&self, rfq_id: Uuid, qp_wallet: WalletAddress)
Sourcepub async fn accept_quote(
&self,
rfq_id: Uuid,
quote_id: Uuid,
taker_wallet: WalletAddress,
taker_signature: String,
taker_signer: WalletAddress,
taker_nonce: u64,
) -> Result<RfqExecuteResult, String>
pub async fn accept_quote( &self, rfq_id: Uuid, quote_id: Uuid, taker_wallet: WalletAddress, taker_signature: String, taker_signer: WalletAddress, taker_nonce: u64, ) -> Result<RfqExecuteResult, String>
Accept a quote. Uses get_mut() for atomic state transition (prevents double-accept). DashMap::get_mut() holds an exclusive shard lock for the key, so the read-check-write within the block is atomic with respect to other accesses to the same key.
Sourcepub async fn auto_accept_quote(
&self,
rfq_id: Uuid,
quote_id: Uuid,
taker_signature: String,
) -> Result<RfqExecuteResult, String>
pub async fn auto_accept_quote( &self, rfq_id: Uuid, quote_id: Uuid, taker_signature: String, ) -> Result<RfqExecuteResult, String>
Execute an auto-accepted RFQ quote. Called from a spawned task after
handle_qp_response returns AutoExecuted. The taker already
authorized execution via the SubmitAutoExecuteRfq EIP-712
signature, so no separate accept signature is needed.
pub fn record_qp_decline(&self, rfq_id: Uuid, qp_wallet: WalletAddress)
pub async fn wait_for_rpi_auction_close( &self, rfq_id: Uuid, ) -> Result<RfqRecord, String>
pub fn rpi_candidate_quote_ids( &self, rfq_id: &Uuid, ) -> Result<Vec<Uuid>, String>
pub async fn execute_rpi_quote( &self, rfq_id: Uuid, quote_id: Uuid, taker_signature: String, ) -> Result<RfqExecuteResult, String>
pub fn mark_rpi_fallback_to_book(&self, rfq_id: &Uuid)
Sourcepub fn get_history(&self, wallet: &WalletAddress) -> Vec<RfqRecord>
pub fn get_history(&self, wallet: &WalletAddress) -> Vec<RfqRecord>
Get RFQ history for a wallet.
Sourcepub fn start_cleanup_task(self: &Arc<Self>, shutdown: Receiver<()>)
pub fn start_cleanup_task(self: &Arc<Self>, shutdown: Receiver<()>)
Start a background cleanup task that expires stale RFQs.
Sourcefn cleanup_expired(&self)
fn cleanup_expired(&self)
Expire stale RFQs and evict old terminal records.
Auto Trait Implementations§
impl Freeze for RfqManager
impl !RefUnwindSafe for RfqManager
impl Send for RfqManager
impl Sync for RfqManager
impl Unpin for RfqManager
impl UnsafeUnpin for RfqManager
impl !UnwindSafe for RfqManager
Blanket Implementations§
§impl<T> AggregateExpressionMethods for T
impl<T> AggregateExpressionMethods for T
§fn aggregate_distinct(self) -> Self::Outputwhere
Self: DistinctDsl,
fn aggregate_distinct(self) -> Self::Outputwhere
Self: DistinctDsl,
DISTINCT modifier for aggregate functions Read more§fn aggregate_all(self) -> Self::Outputwhere
Self: AllDsl,
fn aggregate_all(self) -> Self::Outputwhere
Self: AllDsl,
ALL modifier for aggregate functions Read more§fn aggregate_filter<P>(self, f: P) -> Self::Outputwhere
P: AsExpression<Bool>,
Self: FilterDsl<<P as AsExpression<Bool>>::Expression>,
fn aggregate_filter<P>(self, f: P) -> Self::Outputwhere
P: AsExpression<Bool>,
Self: FilterDsl<<P as AsExpression<Bool>>::Expression>,
§fn aggregate_order<O>(self, o: O) -> Self::Outputwhere
Self: OrderAggregateDsl<O>,
fn aggregate_order<O>(self, o: O) -> Self::Outputwhere
Self: OrderAggregateDsl<O>,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Conv for T
impl<T> Conv for T
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.§impl<T> DowncastSend for T
impl<T> DowncastSend for T
§impl<T> DowncastSync for T
impl<T> DowncastSync for T
§impl<T> FmtForward for T
impl<T> FmtForward for T
§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.§fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
§impl<T> FutureExt for T
impl<T> FutureExt for T
§fn with_context(self, otel_cx: Context) -> WithContext<Self>
fn with_context(self, otel_cx: Context) -> WithContext<Self>
§fn with_current_context(self) -> WithContext<Self>
fn with_current_context(self) -> WithContext<Self>
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more§impl<T> IntoSql for T
impl<T> IntoSql for T
§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read more§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read more§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
§impl<T> Tap for T
impl<T> Tap for T
§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read more§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read more§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read more§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read more§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read more§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read more§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.