Skip to main content

bark/exit/models/
states.rs

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	/// Returns a copy of this origin reflecting the given confirmation state, preserving the
81	/// origin kind where it makes sense. A `Wallet` origin keeps its kind (we still know it's
82	/// ours) and updates its `confirmed_in`; mempool/block origins become `Block` once confirmed
83	/// and `Mempool` otherwise.
84	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}