@@ -158,7 +158,7 @@ pub struct Chain {
158
158
pow_verifier : fn ( & BlockHeader ) -> Result < ( ) , pow:: Error > ,
159
159
denylist : Arc < RwLock < Vec < Hash > > > ,
160
160
archive_mode : bool ,
161
- genesis : BlockHeader ,
161
+ genesis : Block ,
162
162
}
163
163
164
164
impl Chain {
@@ -184,7 +184,7 @@ impl Chain {
184
184
None ,
185
185
) ?;
186
186
187
- setup_head ( & genesis, & store, & mut header_pmmr, & mut txhashset) ?;
187
+ setup_head ( & genesis, & store, & mut header_pmmr, & mut txhashset, false ) ?;
188
188
189
189
// Initialize the output_pos index based on UTXO set
190
190
// and NRD kernel_pos index based recent kernel history.
@@ -207,7 +207,7 @@ impl Chain {
207
207
pow_verifier,
208
208
denylist : Arc :: new ( RwLock :: new ( vec ! [ ] ) ) ,
209
209
archive_mode,
210
- genesis : genesis. header ,
210
+ genesis : genesis,
211
211
} ;
212
212
213
213
chain. log_heads ( ) ?;
@@ -269,6 +269,33 @@ impl Chain {
269
269
Ok ( ( ) )
270
270
}
271
271
272
+ /// wipes the chain head down to genesis, without attempting to rewind
273
+ /// Used upon PIBD failure, where we want to keep the header chain but
274
+ /// restart the output PMMRs from scratch
275
+ pub fn reset_chain_head_to_genesis ( & self ) -> Result < ( ) , Error > {
276
+ let mut header_pmmr = self . header_pmmr . write ( ) ;
277
+ let mut txhashset = self . txhashset . write ( ) ;
278
+ let batch = self . store . batch ( ) ?;
279
+
280
+ // Change head back to genesis
281
+ {
282
+ let head = Tip :: from_header ( & self . genesis . header ) ;
283
+ batch. save_body_head ( & head) ?;
284
+ batch. commit ( ) ?;
285
+ }
286
+
287
+ // Reinit
288
+ setup_head (
289
+ & self . genesis ,
290
+ & self . store ,
291
+ & mut header_pmmr,
292
+ & mut txhashset,
293
+ true ,
294
+ ) ?;
295
+
296
+ Ok ( ( ) )
297
+ }
298
+
272
299
/// Reset prune lists (when PIBD resets and rolls back the
273
300
/// entire chain, the prune list needs to be manually wiped
274
301
/// as it's currently not included as part of rewind)
@@ -309,7 +336,7 @@ impl Chain {
309
336
310
337
/// return genesis header
311
338
pub fn genesis ( & self ) -> BlockHeader {
312
- self . genesis . clone ( )
339
+ self . genesis . header . clone ( )
313
340
}
314
341
315
342
/// Shared store instance.
@@ -703,7 +730,7 @@ impl Chain {
703
730
txhashset:: extending_readonly ( & mut header_pmmr, & mut txhashset, |ext, batch| {
704
731
self . rewind_and_apply_fork ( & header, ext, batch) ?;
705
732
ext. extension . validate (
706
- & self . genesis ,
733
+ & self . genesis . header ,
707
734
fast_validation,
708
735
& NoStatus ,
709
736
None ,
@@ -943,7 +970,7 @@ impl Chain {
943
970
self . txhashset ( ) ,
944
971
self . header_pmmr . clone ( ) ,
945
972
header. clone ( ) ,
946
- self . genesis . clone ( ) ,
973
+ self . genesis . header . clone ( ) ,
947
974
self . store . clone ( ) ,
948
975
) )
949
976
}
@@ -1125,7 +1152,13 @@ impl Chain {
1125
1152
1126
1153
let header_pmmr = self . header_pmmr . read ( ) ;
1127
1154
let batch = self . store . batch ( ) ?;
1128
- txhashset. verify_kernel_pos_index ( & self . genesis , & header_pmmr, & batch, None , None ) ?;
1155
+ txhashset. verify_kernel_pos_index (
1156
+ & self . genesis . header ,
1157
+ & header_pmmr,
1158
+ & batch,
1159
+ None ,
1160
+ None ,
1161
+ ) ?;
1129
1162
}
1130
1163
1131
1164
// all good, prepare a new batch and update all the required records
@@ -1143,8 +1176,15 @@ impl Chain {
1143
1176
1144
1177
// Validate the extension, generating the utxo_sum and kernel_sum.
1145
1178
// Full validation, including rangeproofs and kernel signature verification.
1146
- let ( utxo_sum, kernel_sum) =
1147
- extension. validate ( & self . genesis , false , status, None , None , & header, None ) ?;
1179
+ let ( utxo_sum, kernel_sum) = extension. validate (
1180
+ & self . genesis . header ,
1181
+ false ,
1182
+ status,
1183
+ None ,
1184
+ None ,
1185
+ & header,
1186
+ None ,
1187
+ ) ?;
1148
1188
1149
1189
// Save the block_sums (utxo_sum, kernel_sum) to the db for use later.
1150
1190
batch. save_block_sums (
@@ -1231,7 +1271,7 @@ impl Chain {
1231
1271
1232
1272
let tail = match batch. tail ( ) {
1233
1273
Ok ( tail) => tail,
1234
- Err ( _) => Tip :: from_header ( & self . genesis ) ,
1274
+ Err ( _) => Tip :: from_header ( & self . genesis . header ) ,
1235
1275
} ;
1236
1276
1237
1277
let mut cutoff = head. height . saturating_sub ( horizon) ;
@@ -1643,6 +1683,7 @@ fn setup_head(
1643
1683
store : & store:: ChainStore ,
1644
1684
header_pmmr : & mut txhashset:: PMMRHandle < BlockHeader > ,
1645
1685
txhashset : & mut txhashset:: TxHashSet ,
1686
+ resetting_pibd : bool ,
1646
1687
) -> Result < ( ) , Error > {
1647
1688
let mut batch = store. batch ( ) ?;
1648
1689
@@ -1689,7 +1730,7 @@ fn setup_head(
1689
1730
let head = batch. get_block_header ( & head. last_block_h ) ?;
1690
1731
let pibd_tip = store. pibd_head ( ) ?;
1691
1732
let pibd_head = batch. get_block_header ( & pibd_tip. last_block_h ) ?;
1692
- if pibd_head. height > head. height {
1733
+ if pibd_head. height > head. height && !resetting_pibd {
1693
1734
pibd_in_progress = true ;
1694
1735
pibd_head
1695
1736
} else {
0 commit comments