1
1
use bitcoin:: { hashes:: Hash , BlockHash , OutPoint , TxOut , Txid } ;
2
2
3
- use crate :: { Anchor , AnchorFromBlockPosition , COINBASE_MATURITY } ;
3
+ use crate :: { Anchor , BlockTime , COINBASE_MATURITY } ;
4
4
5
5
/// Represents the observed position of some chain data.
6
- ///
7
- /// The generic `A` should be a [`Anchor`] implementation.
8
6
#[ derive( Debug , Clone , Copy , PartialEq , Eq , PartialOrd , Ord , core:: hash:: Hash ) ]
9
7
pub enum ChainPosition < A > {
10
- /// The chain data is seen as confirmed, and in anchored by `A `.
11
- Confirmed ( A ) ,
8
+ /// The chain data is seen as confirmed, and in anchored by `Anchor `.
9
+ Confirmed ( Anchor , A ) ,
12
10
/// The chain data is not confirmed and last seen in the mempool at this timestamp.
13
11
Unconfirmed ( u64 ) ,
14
12
}
15
13
16
14
impl < A > ChainPosition < A > {
17
15
/// Returns whether [`ChainPosition`] is confirmed or not.
18
16
pub fn is_confirmed ( & self ) -> bool {
19
- matches ! ( self , Self :: Confirmed ( _) )
17
+ matches ! ( self , Self :: Confirmed ( _, _ ) )
20
18
}
21
19
}
22
20
23
- impl < A : Clone > ChainPosition < & A > {
24
- /// Maps a [`ChainPosition<&A> `] into a [`ChainPosition<A> `] by cloning the contents.
21
+ impl < A : Clone > ChainPosition < A > {
22
+ /// Maps a [`ChainPosition`] into a [`ChainPosition`] by cloning the contents.
25
23
pub fn cloned ( self ) -> ChainPosition < A > {
26
24
match self {
27
- ChainPosition :: Confirmed ( a) => ChainPosition :: Confirmed ( a . clone ( ) ) ,
25
+ ChainPosition :: Confirmed ( anchor , a) => ChainPosition :: Confirmed ( anchor , a ) ,
28
26
ChainPosition :: Unconfirmed ( last_seen) => ChainPosition :: Unconfirmed ( last_seen) ,
29
27
}
30
28
}
31
29
}
32
30
33
- impl < A : Anchor > ChainPosition < A > {
34
- /// Determines the upper bound of the confirmation height.
35
- pub fn confirmation_height_upper_bound ( & self ) -> Option < u32 > {
36
- match self {
37
- ChainPosition :: Confirmed ( a) => Some ( a. confirmation_height_upper_bound ( ) ) ,
38
- ChainPosition :: Unconfirmed ( _) => None ,
39
- }
40
- }
41
- }
42
-
43
31
/// Block height and timestamp at which a transaction is confirmed.
44
32
#[ derive( Debug , Clone , PartialEq , Eq , Copy , PartialOrd , Ord , core:: hash:: Hash ) ]
45
33
#[ cfg_attr(
@@ -74,12 +62,12 @@ impl ConfirmationTime {
74
62
}
75
63
}
76
64
77
- impl From < ChainPosition < ConfirmationBlockTime > > for ConfirmationTime {
78
- fn from ( observed_as : ChainPosition < ConfirmationBlockTime > ) -> Self {
65
+ impl From < ChainPosition < BlockTime > > for ConfirmationTime {
66
+ fn from ( observed_as : ChainPosition < BlockTime > ) -> Self {
79
67
match observed_as {
80
- ChainPosition :: Confirmed ( a ) => Self :: Confirmed {
81
- height : a . block_id . height ,
82
- time : a . confirmation_time ,
68
+ ChainPosition :: Confirmed ( ( _txid , blockid ) , anchor_meta ) => Self :: Confirmed {
69
+ height : blockid . height ,
70
+ time : * anchor_meta . as_ref ( ) as u64 ,
83
71
} ,
84
72
ChainPosition :: Unconfirmed ( last_seen) => Self :: Unconfirmed { last_seen } ,
85
73
}
@@ -103,18 +91,6 @@ pub struct BlockId {
103
91
pub hash : BlockHash ,
104
92
}
105
93
106
- impl Anchor for BlockId {
107
- fn anchor_block ( & self ) -> Self {
108
- * self
109
- }
110
- }
111
-
112
- impl AnchorFromBlockPosition for BlockId {
113
- fn from_block_position ( _block : & bitcoin:: Block , block_id : BlockId , _tx_pos : usize ) -> Self {
114
- block_id
115
- }
116
- }
117
-
118
94
impl Default for BlockId {
119
95
fn default ( ) -> Self {
120
96
Self {
@@ -145,41 +121,6 @@ impl From<(&u32, &BlockHash)> for BlockId {
145
121
}
146
122
}
147
123
148
- /// An [`Anchor`] implementation that also records the exact confirmation time of the transaction.
149
- ///
150
- /// Refer to [`Anchor`] for more details.
151
- #[ derive( Debug , Default , Clone , PartialEq , Eq , Copy , PartialOrd , Ord , core:: hash:: Hash ) ]
152
- #[ cfg_attr(
153
- feature = "serde" ,
154
- derive( serde:: Deserialize , serde:: Serialize ) ,
155
- serde( crate = "serde_crate" )
156
- ) ]
157
- pub struct ConfirmationBlockTime {
158
- /// The anchor block.
159
- pub block_id : BlockId ,
160
- /// The confirmation time of the transaction being anchored.
161
- pub confirmation_time : u64 ,
162
- }
163
-
164
- impl Anchor for ConfirmationBlockTime {
165
- fn anchor_block ( & self ) -> BlockId {
166
- self . block_id
167
- }
168
-
169
- fn confirmation_height_upper_bound ( & self ) -> u32 {
170
- self . block_id . height
171
- }
172
- }
173
-
174
- impl AnchorFromBlockPosition for ConfirmationBlockTime {
175
- fn from_block_position ( block : & bitcoin:: Block , block_id : BlockId , _tx_pos : usize ) -> Self {
176
- Self {
177
- block_id,
178
- confirmation_time : block. header . time as _ ,
179
- }
180
- }
181
- }
182
-
183
124
/// A `TxOut` with as much data as we can retrieve about it
184
125
#[ derive( Debug , Clone , PartialEq , Eq , PartialOrd , Ord ) ]
185
126
pub struct FullTxOut < A > {
@@ -195,7 +136,7 @@ pub struct FullTxOut<A> {
195
136
pub is_on_coinbase : bool ,
196
137
}
197
138
198
- impl < A : Anchor > FullTxOut < A > {
139
+ impl < A > FullTxOut < A > {
199
140
/// Whether the `txout` is considered mature.
200
141
///
201
142
/// Depending on the implementation of [`confirmation_height_upper_bound`] in [`Anchor`], this
@@ -206,7 +147,7 @@ impl<A: Anchor> FullTxOut<A> {
206
147
pub fn is_mature ( & self , tip : u32 ) -> bool {
207
148
if self . is_on_coinbase {
208
149
let tx_height = match & self . chain_position {
209
- ChainPosition :: Confirmed ( anchor ) => anchor . confirmation_height_upper_bound ( ) ,
150
+ ChainPosition :: Confirmed ( ( _ , blockid ) , _ ) => blockid . height ,
210
151
ChainPosition :: Unconfirmed ( _) => {
211
152
debug_assert ! ( false , "coinbase tx can never be unconfirmed" ) ;
212
153
return false ;
@@ -236,16 +177,16 @@ impl<A: Anchor> FullTxOut<A> {
236
177
}
237
178
238
179
let confirmation_height = match & self . chain_position {
239
- ChainPosition :: Confirmed ( anchor ) => anchor . confirmation_height_upper_bound ( ) ,
180
+ ChainPosition :: Confirmed ( ( _ , blockid ) , _ ) => blockid . height ,
240
181
ChainPosition :: Unconfirmed ( _) => return false ,
241
182
} ;
242
183
if confirmation_height > tip {
243
184
return false ;
244
185
}
245
186
246
187
// if the spending tx is confirmed within tip height, the txout is no longer spendable
247
- if let Some ( ( ChainPosition :: Confirmed ( spending_anchor ) , _) ) = & self . spent_by {
248
- if spending_anchor . anchor_block ( ) . height <= tip {
188
+ if let Some ( ( ChainPosition :: Confirmed ( ( _ , spending_blockid ) , _ ) , _) ) = & self . spent_by {
189
+ if spending_blockid . height <= tip {
249
190
return false ;
250
191
}
251
192
}
@@ -257,25 +198,32 @@ impl<A: Anchor> FullTxOut<A> {
257
198
#[ cfg( test) ]
258
199
mod test {
259
200
use super :: * ;
201
+ use crate :: BlockTime ;
260
202
261
203
#[ test]
262
204
fn chain_position_ord ( ) {
263
- let unconf1 = ChainPosition :: < ConfirmationBlockTime > :: Unconfirmed ( 10 ) ;
264
- let unconf2 = ChainPosition :: < ConfirmationBlockTime > :: Unconfirmed ( 20 ) ;
265
- let conf1 = ChainPosition :: Confirmed ( ConfirmationBlockTime {
266
- confirmation_time : 20 ,
267
- block_id : BlockId {
268
- height : 9 ,
269
- ..Default :: default ( )
270
- } ,
271
- } ) ;
272
- let conf2 = ChainPosition :: Confirmed ( ConfirmationBlockTime {
273
- confirmation_time : 15 ,
274
- block_id : BlockId {
275
- height : 12 ,
276
- ..Default :: default ( )
277
- } ,
278
- } ) ;
205
+ let unconf1 = ChainPosition :: Unconfirmed ( 10 ) ;
206
+ let unconf2 = ChainPosition :: Unconfirmed ( 20 ) ;
207
+ let conf1 = ChainPosition :: Confirmed (
208
+ (
209
+ Txid :: all_zeros ( ) ,
210
+ BlockId {
211
+ height : 9 ,
212
+ ..Default :: default ( )
213
+ } ,
214
+ ) ,
215
+ BlockTime :: new ( 20 ) ,
216
+ ) ;
217
+ let conf2 = ChainPosition :: Confirmed (
218
+ (
219
+ Txid :: all_zeros ( ) ,
220
+ BlockId {
221
+ height : 12 ,
222
+ ..Default :: default ( )
223
+ } ,
224
+ ) ,
225
+ BlockTime :: new ( 15 ) ,
226
+ ) ;
279
227
280
228
assert ! ( unconf2 > unconf1, "higher last_seen means higher ord" ) ;
281
229
assert ! ( unconf1 > conf1, "unconfirmed is higher ord than confirmed" ) ;
0 commit comments