Skip to main content

bark/exit/models/
mod.rs

1
2mod error;
3mod package;
4mod states;
5
6pub use self::package::{
7	ChildTransactionInfo, ExitCpfpRequest, ExitTransactionPackage, FeeInfo, RbfRequirement,
8	TransactionInfo,
9};
10pub use self::error::ExitError;
11pub use self::states::{
12	ExitTx, ExitTxStatus, ExitTxOrigin, ExitStartState, ExitProcessingState, ExitAwaitingDeltaState,
13	ExitClaimableState, ExitClaimInProgressState, ExitClaimedState,
14};
15
16use ark::VtxoId;
17use bitcoin::Txid;
18
19use bitcoin_ext::{BlockDelta, BlockHeight, BlockRef, TxStatus};
20
21/// A utility type to wrap ExitState children so they can be easily serialized. This also helps with
22/// debugging a lot!
23#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
24#[serde(tag = "type", rename_all = "kebab-case")]
25pub enum ExitState {
26	Start(ExitStartState),
27	Processing(ExitProcessingState),
28	AwaitingDelta(ExitAwaitingDeltaState),
29	Claimable(ExitClaimableState),
30	ClaimInProgress(ExitClaimInProgressState),
31	Claimed(ExitClaimedState),
32}
33
34impl ExitState {
35	pub fn new_start(tip: BlockHeight) -> Self {
36		ExitState::Start(ExitStartState { tip_height: tip })
37	}
38
39	pub fn new_processing<T: IntoIterator<Item = Txid>>(tip: BlockHeight, txids: T) -> Self {
40		ExitState::Processing(ExitProcessingState {
41			tip_height: tip,
42			transactions: txids.into_iter()
43				.map(|id| ExitTx {
44					txid: id,
45					status: ExitTxStatus::VerifyInputs,
46				})
47				.collect::<Vec<_>>(),
48		})
49	}
50
51	pub fn new_processing_from_transactions(tip: BlockHeight, transactions: Vec<ExitTx>) -> Self {
52		ExitState::Processing(ExitProcessingState {
53			tip_height: tip,
54			transactions,
55		})
56	}
57
58	pub fn new_awaiting_delta(
59		tip: BlockHeight,
60		confirmed_block: BlockRef,
61		wait_delta: BlockDelta
62	) -> Self {
63		debug_assert_ne!(wait_delta, 0, "wait delta must be non-zero");
64		let claimable_height = confirmed_block.height + wait_delta as BlockHeight;
65		ExitState::AwaitingDelta(ExitAwaitingDeltaState {
66			tip_height: tip,
67			confirmed_block,
68			claimable_height,
69		})
70	}
71
72	pub fn new_claimable(
73		tip: BlockHeight,
74		claimable_since: BlockRef,
75		last_scanned_block: Option<BlockRef>
76	) -> Self {
77		ExitState::Claimable(ExitClaimableState {
78			tip_height: tip,
79			claimable_since,
80			last_scanned_block,
81		})
82	}
83
84	pub fn new_claim_in_progress(
85		tip: BlockHeight,
86		claimable_since: BlockRef,
87		claim_txid: Txid
88	) -> Self {
89		ExitState::ClaimInProgress(ExitClaimInProgressState {
90			tip_height: tip,
91			claimable_since,
92			claim_txid,
93		})
94	}
95
96	pub fn new_claimed(tip: BlockHeight, txid: Txid, block: BlockRef) -> Self {
97		ExitState::Claimed(ExitClaimedState {
98			tip_height: tip,
99			txid,
100			block,
101		})
102	}
103
104	pub fn is_pending(&self) -> bool {
105		match self {
106			ExitState::Start(_) => true,
107			ExitState::Processing(_) => true,
108			ExitState::AwaitingDelta(_) => true,
109			_ => false,
110		}
111	}
112
113	pub fn requires_confirmations(&self) -> bool {
114		match self {
115			ExitState::Processing(s) => {
116				s.transactions.iter().any(|s| match s.status {
117					ExitTxStatus::AwaitingInputConfirmation { .. } => true,
118					ExitTxStatus::AwaitingConfirmation { .. } => true,
119					_ => false,
120				})
121			},
122			ExitState::AwaitingDelta(_) => true,
123			ExitState::ClaimInProgress(_) => true,
124			_ => false,
125		}
126	}
127
128	pub fn claimable_height(&self) -> Option<BlockHeight> {
129		match self {
130			ExitState::AwaitingDelta(s) => Some(s.claimable_height),
131			ExitState::Claimable(s) => Some(s.claimable_since.height),
132			ExitState::ClaimInProgress(s) => Some(s.claimable_since.height),
133			_ => None,
134		}
135	}
136}
137
138#[derive(Debug, Clone, PartialEq, Eq)]
139pub struct ExitProgressStatus {
140	/// The ID of the VTXO that is being unilaterally exited
141	pub vtxo_id: VtxoId,
142	/// The current state of the exit transaction
143	pub state: ExitState,
144	/// Any error that occurred during the exit process
145	pub error: Option<ExitError>,
146}
147
148#[derive(Debug, Clone, PartialEq, Eq)]
149pub struct ExitTransactionStatus {
150	/// The ID of the VTXO that is being unilaterally exited
151	pub vtxo_id: VtxoId,
152	/// The current state of the exit transaction
153	pub state: ExitState,
154	/// The history of each state the exit transaction has gone through
155	pub history: Option<Vec<ExitState>>,
156	/// Each exit transaction package required for the unilateral exit
157	pub transactions: Vec<ExitTransactionPackage>,
158}
159
160#[derive(Clone, Copy, Debug,  Eq, PartialEq)]
161pub struct ExitChildStatus {
162	pub txid: Txid,
163	pub status: TxStatus,
164	pub origin: ExitTxOrigin,
165	pub fee_info: Option<FeeInfo>,
166}