1use std::collections::HashSet;
2use std::fmt;
3
4use bitcoin::Txid;
5
6use bitcoin_ext::{BlockHeight, BlockRef};
7
8use crate::exit::models::ExitState;
9
10#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
11pub struct ExitTx {
12 pub txid: Txid,
13 pub status: ExitTxStatus,
14}
15
16#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
17#[serde(tag = "type", rename_all = "kebab-case")]
18pub enum ExitTxStatus {
19 #[default]
20 VerifyInputs,
21 AwaitingInputConfirmation {
22 txids: HashSet<Txid>
23 },
24 AwaitingCpfpBroadcast,
25 AwaitingConfirmation {
26 child_txid: Txid,
27 origin: ExitTxOrigin,
28 },
29 Confirmed {
30 child_txid: Txid,
31 block: BlockRef,
32 origin: ExitTxOrigin,
33 },
34}
35
36impl ExitTxStatus {
37 pub fn child_txid(&self) -> Option<&Txid> {
38 match self {
39 ExitTxStatus::AwaitingConfirmation { child_txid, .. } => Some(child_txid),
40 ExitTxStatus::Confirmed { child_txid, .. } => Some(child_txid),
41 _ => None,
42 }
43 }
44
45 pub fn confirmed_in(&self) -> Option<&BlockRef> {
46 match self {
47 ExitTxStatus::Confirmed { block, .. } => Some(block),
48 _ => None,
49 }
50 }
51}
52
53impl fmt::Display for ExitTxStatus {
54 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55 fmt::Debug::fmt(self, f)
56 }
57}
58
59#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize)]
60#[serde(tag = "type", rename_all = "kebab-case")]
61pub enum ExitTxOrigin {
62 Wallet {
63 confirmed_in: Option<BlockRef>
64 },
65 Mempool,
66 Block {
67 confirmed_in: BlockRef
68 },
69}
70
71impl ExitTxOrigin {
72 pub fn confirmed_in(&self) -> Option<BlockRef> {
73 match self {
74 ExitTxOrigin::Wallet { confirmed_in } => *confirmed_in,
75 ExitTxOrigin::Mempool => None,
76 ExitTxOrigin::Block { confirmed_in } => Some(*confirmed_in),
77 }
78 }
79
80 pub fn with_confirmed_in(self, confirmed_in: Option<BlockRef>) -> ExitTxOrigin {
85 match (self, confirmed_in) {
86 (ExitTxOrigin::Wallet { .. }, _) => ExitTxOrigin::Wallet { confirmed_in },
87 (_, Some(confirmed_in)) => ExitTxOrigin::Block { confirmed_in },
88 (_, None) => ExitTxOrigin::Mempool,
89 }
90 }
91}
92
93impl fmt::Display for ExitTxOrigin {
94 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
95 fmt::Debug::fmt(self, f)
96 }
97}
98
99#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize)]
100pub struct ExitStartState {
101 pub tip_height: BlockHeight,
102}
103
104#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
105pub struct ExitProcessingState {
106 pub tip_height: BlockHeight,
107 pub transactions: Vec<ExitTx>,
108}
109
110#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize)]
111pub struct ExitAwaitingDeltaState {
112 pub tip_height: BlockHeight,
113 pub confirmed_block: BlockRef,
114 pub claimable_height: BlockHeight,
115}
116
117#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize)]
118pub struct ExitClaimableState {
119 pub tip_height: BlockHeight,
120 pub claimable_since: BlockRef,
121 pub last_scanned_block: Option<BlockRef>,
122}
123
124#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize)]
125pub struct ExitClaimInProgressState {
126 pub tip_height: BlockHeight,
127 pub claimable_since: BlockRef,
128 pub claim_txid: Txid,
129}
130
131#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize)]
132pub struct ExitClaimedState {
133 pub tip_height: BlockHeight,
134 pub txid: Txid,
135 pub block: BlockRef,
136}
137
138impl Into<ExitState> for ExitStartState {
139 fn into(self) -> ExitState {
140 ExitState::Start(self)
141 }
142}
143
144impl Into<ExitState> for ExitProcessingState {
145 fn into(self) -> ExitState {
146 ExitState::Processing(self)
147 }
148}
149
150impl Into<ExitState> for ExitAwaitingDeltaState {
151 fn into(self) -> ExitState {
152 ExitState::AwaitingDelta(self)
153 }
154}
155
156impl Into<ExitState> for ExitClaimableState {
157 fn into(self) -> ExitState {
158 ExitState::Claimable(self)
159 }
160}
161
162impl Into<ExitState> for ExitClaimInProgressState {
163 fn into(self) -> ExitState {
164 ExitState::ClaimInProgress(self)
165 }
166}
167
168impl Into<ExitState> for ExitClaimedState {
169 fn into(self) -> ExitState {
170 ExitState::Claimed(self)
171 }
172}