kabu_types_events/
swap_compose.rs1use crate::Message;
2use crate::tx_compose::TxComposeData;
3use alloy_primitives::{Bytes, TxHash, U256};
4use alloy_rpc_types::TransactionRequest;
5use eyre::{Result, eyre};
6use kabu_types_blockchain::GethStateUpdateVec;
7use kabu_types_market::PoolId;
8use kabu_types_swap::Swap;
9use reth_ethereum_primitives::EthPrimitives;
10use reth_node_types::NodePrimitives;
11use revm::DatabaseRef;
12use std::ops::Deref;
13
14#[derive(Clone, Debug)]
15pub enum TxState<N: NodePrimitives = EthPrimitives> {
16 Stuffing(N::SignedTx),
17 SignatureRequired(Box<TransactionRequest>),
18 ReadyForBroadcast(Bytes),
19 ReadyForBroadcastStuffing(Bytes),
20}
21
22impl<N: NodePrimitives> TxState<N> {
23 pub fn rlp(&self) -> Result<Bytes> {
24 match self {
25 TxState::Stuffing(_t) => {
26 Err(eyre!("Encoding not yet implemented for NodePrimitives"))
28 }
29 TxState::ReadyForBroadcast(t) | TxState::ReadyForBroadcastStuffing(t) => Ok(t.clone()),
30 _ => Err(eyre!("NOT_READY_FOR_BROADCAST")),
31 }
32 }
33}
34
35#[derive(Clone, Debug)]
36pub enum SwapComposeMessage<DB, N: NodePrimitives = EthPrimitives> {
37 Prepare(SwapComposeData<DB, N>),
38 Estimate(SwapComposeData<DB, N>),
39 Ready(SwapComposeData<DB, N>),
40}
41
42impl<DB, N: NodePrimitives> Deref for SwapComposeMessage<DB, N> {
43 type Target = SwapComposeData<DB, N>;
44
45 fn deref(&self) -> &Self::Target {
46 self.data()
47 }
48}
49
50impl<DB, N: NodePrimitives> SwapComposeMessage<DB, N> {
51 pub fn data(&self) -> &SwapComposeData<DB, N> {
52 match self {
53 SwapComposeMessage::Prepare(x) | SwapComposeMessage::Estimate(x) | SwapComposeMessage::Ready(x) => x,
54 }
55 }
56}
57
58#[derive(Clone, Debug)]
59pub struct SwapComposeData<DB, N: NodePrimitives = EthPrimitives> {
60 pub tx_compose: TxComposeData<N>,
61 pub swap: Swap,
62 pub prestate: Option<DB>,
63 pub poststate: Option<DB>,
64 pub poststate_update: Option<GethStateUpdateVec>,
65 pub origin: Option<String>,
66 pub tips_pct: Option<u32>,
67 pub tips: Option<U256>,
68}
69
70impl<DB: Clone + 'static, N: NodePrimitives> SwapComposeData<DB, N> {
71 pub fn same_stuffing(&self, others_stuffing_txs_hashes: &[TxHash]) -> bool {
72 let tx_len = self.tx_compose.stuffing_txs_hashes.len();
73
74 if tx_len != others_stuffing_txs_hashes.len() {
75 false
76 } else if tx_len == 0 {
77 true
78 } else {
79 others_stuffing_txs_hashes.iter().all(|x| self.tx_compose.stuffing_txs_hashes.contains(x))
80 }
81 }
82
83 pub fn cross_pools(&self, others_pools: &[PoolId]) -> bool {
84 self.swap.get_pool_id_vec().iter().any(|x| others_pools.contains(x))
85 }
86
87 pub fn first_stuffing_hash(&self) -> TxHash {
88 self.tx_compose.stuffing_txs_hashes.first().map_or(TxHash::default(), |x| *x)
89 }
90
91 pub fn tips_gas_ratio(&self) -> U256 {
92 if self.tx_compose.gas == 0 { U256::ZERO } else { self.tips.unwrap_or_default() / U256::from(self.tx_compose.gas) }
93 }
94
95 pub fn profit_eth_gas_ratio(&self) -> U256 {
96 if self.tx_compose.gas == 0 { U256::ZERO } else { self.swap.arb_profit_eth() / U256::from(self.tx_compose.gas) }
97 }
98
99 pub fn gas_price(&self) -> u128 {
100 self.tx_compose.next_block_base_fee as u128 + self.tx_compose.priority_gas_fee as u128
101 }
102
103 pub fn gas_cost(&self) -> u128 {
104 self.tx_compose.gas as u128 * (self.tx_compose.next_block_base_fee as u128 + self.tx_compose.priority_gas_fee as u128)
105 }
106}
107
108impl<DB: DatabaseRef + Send + Sync + Clone + 'static, N: NodePrimitives> Default for SwapComposeData<DB, N> {
109 fn default() -> Self {
110 Self {
111 tx_compose: Default::default(),
112 swap: Swap::None,
113 prestate: None,
114 poststate: None,
115 poststate_update: None,
116 origin: None,
117 tips_pct: None,
118 tips: None,
119 }
120 }
121}
122
123pub type MessageSwapCompose<DB, N = EthPrimitives> = Message<SwapComposeMessage<DB, N>>;
124
125impl<DB, N: NodePrimitives> MessageSwapCompose<DB, N> {
126 pub fn prepare(data: SwapComposeData<DB, N>) -> Self {
127 Message::new(SwapComposeMessage::Prepare(data))
128 }
129
130 pub fn estimate(data: SwapComposeData<DB, N>) -> Self {
131 Message::new(SwapComposeMessage::Estimate(data))
132 }
133
134 pub fn ready(data: SwapComposeData<DB, N>) -> Self {
135 Message::new(SwapComposeMessage::Ready(data))
136 }
137}