1- use bdk_core:: { CheckPoint , ToBlockHash , ToBlockTime , WithMtp } ;
1+ use bdk_core:: { CheckPoint , MissingBlocks , ToBlockHash , ToBlockTime , WithMtp } ;
22use bdk_testenv:: { block_id, hash} ;
33use bitcoin:: hashes:: Hash ;
44use bitcoin:: BlockHash ;
@@ -86,19 +86,19 @@ fn test_median_time_past_with_timestamps() {
8686 let cp = CheckPoint :: from_blocks ( blocks) . expect ( "must construct valid chain" ) ;
8787
8888 // Height 11: 11 previous blocks (11..=1), pseudo-median at index 6 = 1060
89- assert_eq ! ( cp. compute_mtp( ) , Some ( 1060 ) ) ;
89+ assert_eq ! ( cp. compute_mtp( ) , Ok ( 1060 ) ) ;
9090
9191 // Height 10: 11 previous blocks (10..=0), pseudo-median at index 5 = 1050
92- assert_eq ! ( cp. get( 10 ) . unwrap( ) . compute_mtp( ) , Some ( 1050 ) ) ;
92+ assert_eq ! ( cp. get( 10 ) . unwrap( ) . compute_mtp( ) , Ok ( 1050 ) ) ;
9393
9494 // Height 5: 6 previous blocks (5..=0), pseudo-median at index 3 = 1030
95- assert_eq ! ( cp. get( 5 ) . unwrap( ) . compute_mtp( ) , Some ( 1030 ) ) ;
95+ assert_eq ! ( cp. get( 5 ) . unwrap( ) . compute_mtp( ) , Ok ( 1030 ) ) ;
9696
9797 // Height 3: 4 previous blocks (3..=0), pseudo-median at index 2 = 1020
98- assert_eq ! ( cp. get( 3 ) . unwrap( ) . compute_mtp( ) , Some ( 1020 ) ) ;
98+ assert_eq ! ( cp. get( 3 ) . unwrap( ) . compute_mtp( ) , Ok ( 1020 ) ) ;
9999
100100 // Height 0: 1 block at index 0 = 1000
101- assert_eq ! ( cp. get( 0 ) . unwrap( ) . compute_mtp( ) , Some ( 1000 ) ) ;
101+ assert_eq ! ( cp. get( 0 ) . unwrap( ) . compute_mtp( ) , Ok ( 1000 ) ) ;
102102}
103103
104104#[ test]
@@ -113,23 +113,28 @@ fn test_previous_median_time_past_edge_cases() {
113113 // At height 10: next_mtp uses all 11 blocks (0-10)
114114 // Times: [1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800, 1900, 2000]
115115 // Median at index 5 = 1500
116- assert_eq ! ( cp. compute_mtp( ) , Some ( 1500 ) ) ;
116+ assert_eq ! ( cp. compute_mtp( ) , Ok ( 1500 ) ) ;
117117
118118 // At height 9: mtp uses blocks 0-9 (10 blocks)
119119 // Times: [1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800, 1900]
120120 // Median at index 5 = 1400
121- assert_eq ! ( cp. get( 9 ) . unwrap( ) . compute_mtp( ) , Some ( 1500 ) ) ;
121+ assert_eq ! ( cp. get( 9 ) . unwrap( ) . compute_mtp( ) , Ok ( 1500 ) ) ;
122122
123- // Test sparse chain where next_mtp returns None due to missing blocks
123+ // Test sparse chain where compute_mtp reports the missing heights
124124 let sparse = vec ! [
125125 ( 0 , BlockWithTime ( 0 , 1000 ) ) ,
126126 ( 5 , BlockWithTime ( 5 , 1050 ) ) ,
127127 ( 10 , BlockWithTime ( 10 , 1100 ) ) ,
128128 ] ;
129129 let sparse_cp = CheckPoint :: from_blocks ( sparse) . expect ( "must construct valid chain" ) ;
130130
131- // At height 10: next_mtp needs blocks 0-10 but many are missing
132- assert_eq ! ( sparse_cp. compute_mtp( ) , None ) ;
131+ // At height 10: window is 0..=10; only 0, 5, 10 are present.
132+ assert_eq ! (
133+ sparse_cp. compute_mtp( ) ,
134+ Err ( MissingBlocks {
135+ heights: vec![ 1 , 2 , 3 , 4 , 6 , 7 , 8 , 9 ] ,
136+ } )
137+ ) ;
133138}
134139
135140#[ test]
@@ -155,18 +160,18 @@ fn test_mtp_with_non_monotonic_times() {
155160 // Height 10:
156161 // mtp uses blocks 0-10: sorted
157162 // [1000,1100,1200,1300,1400,1500,1600,1700,1800,1900,2000] Median at index 5 = 1500
158- assert_eq ! ( cp. get( 10 ) . unwrap( ) . compute_mtp( ) , Some ( 1500 ) ) ;
163+ assert_eq ! ( cp. get( 10 ) . unwrap( ) . compute_mtp( ) , Ok ( 1500 ) ) ;
159164
160165 // Height 11:
161166 // mtp uses blocks 1-11: sorted
162167 // [1000,1100,1200,1300,1400,1600,1650,1700,1800,1900,2000] Median at index 5 = 1600
163- assert_eq ! ( cp. compute_mtp( ) , Some ( 1600 ) ) ;
168+ assert_eq ! ( cp. compute_mtp( ) , Ok ( 1600 ) ) ;
164169
165170 // Test with smaller chain to verify sorting at different heights
166171 let cp3 = cp. get ( 3 ) . unwrap ( ) ;
167172 // Height 3: timestamps [1100, 1800, 1200, 1500] -> sorted [1100, 1200, 1500, 1800]
168173 // Pseudo-median at index 2 = 1500
169- assert_eq ! ( cp3. compute_mtp( ) , Some ( 1500 ) ) ;
174+ assert_eq ! ( cp3. compute_mtp( ) , Ok ( 1500 ) ) ;
170175}
171176
172177#[ test]
@@ -182,9 +187,20 @@ fn test_mtp_sparse_chain() {
182187
183188 let cp = CheckPoint :: from_blocks ( blocks) . expect ( "must construct valid chain" ) ;
184189
185- // All heights should return None due to missing sequential blocks
186- assert_eq ! ( cp. compute_mtp( ) , None ) ;
187- assert_eq ! ( cp. get( 11 ) . unwrap( ) . compute_mtp( ) , None ) ;
190+ // Tip is at height 15, window is 5..=15; present in window: 7, 11, 15.
191+ assert_eq ! (
192+ cp. compute_mtp( ) ,
193+ Err ( MissingBlocks {
194+ heights: vec![ 5 , 6 , 8 , 9 , 10 , 12 , 13 , 14 ] ,
195+ } )
196+ ) ;
197+ // At height 11 the window is 1..=11; present in window: 3, 7, 11.
198+ assert_eq ! (
199+ cp. get( 11 ) . unwrap( ) . compute_mtp( ) ,
200+ Err ( MissingBlocks {
201+ heights: vec![ 1 , 2 , 4 , 5 , 6 , 8 , 9 , 10 ] ,
202+ } )
203+ ) ;
188204}
189205
190206#[ test]
0 commit comments