simulator_api/reroute_report/record.rs
1//! The source-agnostic input both reports consume — one row of a reroute population,
2//! whether it arrived as a websocket notification or a session-DB row. Adapters own the
3//! mapping; nothing here does I/O.
4
5use solana_address::Address;
6
7use crate::route_plan::RoutePlan;
8
9/// Whether the swap fixes the input amount (`ExactIn`) or the output amount (`ExactOut`).
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub enum SwapMode {
12 ExactIn,
13 ExactOut,
14}
15
16impl SwapMode {
17 pub const fn as_str(self) -> &'static str {
18 match self {
19 Self::ExactIn => "ExactIn",
20 Self::ExactOut => "ExactOut",
21 }
22 }
23
24 /// Anything unrecognized reads as `ExactIn`, the overwhelming default in every source.
25 pub fn parse(raw: &str) -> Self {
26 match raw == Self::ExactOut.as_str() {
27 true => Self::ExactOut,
28 false => Self::ExactIn,
29 }
30 }
31}
32
33/// One re-quoted swap. The three plans share one shape ([`RoutePlan`]); a side that was not
34/// recorded is `None`, never an empty plan.
35#[derive(Debug, Clone)]
36pub struct LegRecord {
37 pub original_signature: String,
38 pub input_mint: Address,
39 pub output_mint: Address,
40 /// In the input token for ExactIn, the output token for ExactOut.
41 pub amount: u64,
42 pub swap_mode: SwapMode,
43 /// The replacement never landed — a reverted simulation or a not-ok execution. Neither
44 /// report column counts it as flow, but pricing still reads the original's side.
45 pub failed: bool,
46 /// The original failed on L1, so its route events are not flow any venue served.
47 pub original_failed: bool,
48 /// What the replacement actually produced; `None` when unattributable.
49 pub realized_output_amount: Option<u64>,
50 /// What the historical original produced. `None` when it cannot be attributed to this
51 /// record alone — a multi-swap transaction's total is nobody's single leg.
52 pub original_realized_output_amount: Option<u64>,
53 /// The route the replacement was quoted over.
54 pub route_plan: Option<RoutePlan>,
55 /// The route the original actually took on L1.
56 pub original_route_plan: Option<RoutePlan>,
57 /// What the replacement's own simulation moved, hop by hop — the fill to compare
58 /// `original_route_plan` against.
59 pub realized_route_plan: Option<RoutePlan>,
60}