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