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#[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 pub vtxo_id: VtxoId,
142 pub state: ExitState,
144 pub error: Option<ExitError>,
146}
147
148#[derive(Debug, Clone, PartialEq, Eq)]
149pub struct ExitTransactionStatus {
150 pub vtxo_id: VtxoId,
152 pub state: ExitState,
154 pub history: Option<Vec<ExitState>>,
156 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}