1use std::collections::HashSet;
2use std::fmt;
3
4use bitcoin::{Amount, FeeRate, Txid};
5
6use bitcoin_ext::BlockHeight;
7use crate::primitives::BlockRef;
8
9#[cfg(feature = "utoipa")]
10use utoipa::ToSchema;
11
12#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)]
13#[cfg_attr(feature = "utoipa", derive(ToSchema))]
14pub struct ExitTx {
15 #[cfg_attr(feature = "utoipa", schema(value_type = String))]
16 pub txid: Txid,
17 pub status: ExitTxStatus,
18}
19
20#[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)]
21#[cfg_attr(feature = "utoipa", derive(ToSchema))]
22#[serde(tag = "type", rename_all = "kebab-case")]
23pub enum ExitTxStatus {
24 #[default]
25 VerifyInputs,
26 AwaitingInputConfirmation {
27 #[cfg_attr(feature = "utoipa", schema(value_type = Vec<String>))]
28 txids: HashSet<Txid>
29 },
30 NeedsSignedPackage,
31 NeedsReplacementPackage {
32 #[serde(rename = "min_fee_rate_sat_per_kvb", with = "crate::serde_utils::fee_rate_sat_per_kvb")]
33 #[cfg_attr(feature = "utoipa", schema(value_type = u64))]
34 min_fee_rate: FeeRate,
35 #[deprecated(note = "use min_fee_rate_sat_per_kvb instead")]
36 #[cfg_attr(feature = "utoipa", schema(value_type = u64))]
37 min_fee_rate_kwu: u64,
38 #[cfg_attr(feature = "utoipa", schema(value_type = u64))]
39 min_fee: Amount,
40 },
41 NeedsBroadcasting {
42 #[cfg_attr(feature = "utoipa", schema(value_type = String))]
43 child_txid: Txid,
44 origin: ExitTxOrigin,
45 },
46 BroadcastWithCpfp {
47 #[cfg_attr(feature = "utoipa", schema(value_type = String))]
48 child_txid: Txid,
49 origin: ExitTxOrigin,
50 },
51 Confirmed {
52 #[cfg_attr(feature = "utoipa", schema(value_type = String))]
53 child_txid: Txid,
54 block: BlockRef,
55 origin: ExitTxOrigin,
56 },
57}
58
59impl fmt::Display for ExitTxStatus {
60 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61 fmt::Debug::fmt(self, f)
62 }
63}
64
65impl From<bark::exit::ExitTxStatus> for ExitTxStatus {
66 fn from(v: bark::exit::ExitTxStatus) -> Self {
67 match v {
68 bark::exit::ExitTxStatus::VerifyInputs => {
69 ExitTxStatus::VerifyInputs
70 },
71 bark::exit::ExitTxStatus::AwaitingInputConfirmation { txids } => {
72 ExitTxStatus::AwaitingInputConfirmation { txids }
73 },
74 bark::exit::ExitTxStatus::NeedsSignedPackage => {
75 ExitTxStatus::NeedsSignedPackage
76 },
77 bark::exit::ExitTxStatus::NeedsReplacementPackage { min_fee_rate, min_fee } => {
78 let min_fee_rate_kwu = min_fee_rate.to_sat_per_kwu();
79 ExitTxStatus::NeedsReplacementPackage { min_fee_rate, min_fee, min_fee_rate_kwu }
80 },
81 bark::exit::ExitTxStatus::NeedsBroadcasting { child_txid, origin } => {
82 ExitTxStatus::NeedsBroadcasting { child_txid, origin: origin.into() }
83 },
84 bark::exit::ExitTxStatus::BroadcastWithCpfp { child_txid, origin } => {
85 ExitTxStatus::BroadcastWithCpfp { child_txid, origin: origin.into() }
86 },
87 bark::exit::ExitTxStatus::Confirmed { child_txid, block, origin } => {
88 ExitTxStatus::Confirmed { child_txid, block: block.into(), origin: origin.into() }
89 },
90 }
91 }
92}
93
94#[derive(Clone, Copy, Debug, Eq, PartialEq, Deserialize, Serialize)]
95#[cfg_attr(feature = "utoipa", derive(ToSchema))]
96#[serde(tag = "type", rename_all = "kebab-case")]
97pub enum ExitTxOrigin {
98 Wallet {
99 confirmed_in: Option<BlockRef>
100 },
101 Mempool {
102 #[serde(rename = "fee_rate_sat_per_kvb", with = "crate::serde_utils::fee_rate_sat_per_kvb")]
104 #[cfg_attr(feature = "utoipa", schema(value_type = u64))]
105 fee_rate: FeeRate,
106 #[deprecated(note = "use fee_rate_sat_per_kvb instead")]
107 #[cfg_attr(feature = "utoipa", schema(value_type = u64))]
108 #[serde(rename = "fee_rate")]
109 fee_rate_kwu: u64,
110 #[cfg_attr(feature = "utoipa", schema(value_type = u64))]
112 total_fee: Amount,
113 },
114 Block {
115 confirmed_in: BlockRef
116 },
117}
118
119impl fmt::Display for ExitTxOrigin {
120 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
121 fmt::Debug::fmt(self, f)
122 }
123}
124
125impl From<bark::exit::ExitTxOrigin> for ExitTxOrigin {
126 fn from(v: bark::exit::ExitTxOrigin) -> Self {
127 match v {
128 bark::exit::ExitTxOrigin::Wallet { confirmed_in } => {
129 ExitTxOrigin::Wallet { confirmed_in: confirmed_in.map(Into::into) }
130 },
131 bark::exit::ExitTxOrigin::Mempool { fee_rate, total_fee } => {
132 let fee_rate_kwu = fee_rate.to_sat_per_kwu();
133 ExitTxOrigin::Mempool { fee_rate, total_fee, fee_rate_kwu }
134 },
135 bark::exit::ExitTxOrigin::Block { confirmed_in } => {
136 ExitTxOrigin::Block { confirmed_in: confirmed_in.into() }
137 },
138 }
139 }
140}
141
142#[derive(Clone, Copy, Debug, Eq, PartialEq, Deserialize, Serialize)]
143#[cfg_attr(feature = "utoipa", derive(ToSchema))]
144pub struct ExitStartState {
145 pub tip_height: BlockHeight,
146}
147
148#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)]
149#[cfg_attr(feature = "utoipa", derive(ToSchema))]
150pub struct ExitProcessingState {
151 pub tip_height: BlockHeight,
152 pub transactions: Vec<ExitTx>,
153}
154
155#[derive(Clone, Copy, Debug, Eq, PartialEq, Deserialize, Serialize)]
156#[cfg_attr(feature = "utoipa", derive(ToSchema))]
157pub struct ExitAwaitingDeltaState {
158 pub tip_height: BlockHeight,
159 pub confirmed_block: BlockRef,
160 pub claimable_height: BlockHeight,
161}
162
163#[derive(Clone, Copy, Debug, Eq, PartialEq, Deserialize, Serialize)]
164#[cfg_attr(feature = "utoipa", derive(ToSchema))]
165pub struct ExitClaimableState {
166 pub tip_height: BlockHeight,
167 pub claimable_since: BlockRef,
168 pub last_scanned_block: Option<BlockRef>,
169}
170
171#[derive(Clone, Copy, Debug, Eq, PartialEq, Deserialize, Serialize)]
172#[cfg_attr(feature = "utoipa", derive(ToSchema))]
173pub struct ExitClaimInProgressState {
174 pub tip_height: BlockHeight,
175 pub claimable_since: BlockRef,
176 #[cfg_attr(feature = "utoipa", schema(value_type = String))]
177 pub claim_txid: Txid,
178}
179
180#[derive(Clone, Copy, Debug, Eq, PartialEq, Deserialize, Serialize)]
181#[cfg_attr(feature = "utoipa", derive(ToSchema))]
182pub struct ExitClaimedState {
183 pub tip_height: BlockHeight,
184 #[cfg_attr(feature = "utoipa", schema(value_type = String))]
185 pub txid: Txid,
186 pub block: BlockRef,
187}