@@ -33,7 +33,7 @@ use sp_consensus_grandpa::{AuthorityId, AuthoritySignature};
33
33
use sp_core:: H256 ;
34
34
use sp_runtime:: traits:: { One , Zero } ;
35
35
use std:: collections:: { BTreeMap , BTreeSet } ;
36
- use subxt:: { config:: Header , Config , OnlineClient } ;
36
+ use subxt:: { config:: Header , rpc_params , Config , OnlineClient } ;
37
37
38
38
/// Head data for parachain
39
39
#[ derive( Decode , Encode ) ]
@@ -180,6 +180,7 @@ where
180
180
u32 : From < <T :: Header as Header >:: Number > ,
181
181
<T :: Header as Header >:: Number : finality_grandpa:: BlockNumberOps + One ,
182
182
{
183
+ let max_height = previous_finalized_height + self . options . max_block_range ;
183
184
let finalized_hash = self . client . rpc ( ) . finalized_head ( ) . await ?;
184
185
let finalized_header = self
185
186
. client
@@ -188,16 +189,35 @@ where
188
189
. await ?
189
190
. ok_or_else ( || anyhow ! ( "Header not found for hash {finalized_hash:#?}" ) ) ?;
190
191
let finalized_number = u32:: from ( finalized_header. number ( ) ) ;
191
-
192
192
log:: trace!(
193
193
"Finalized block number for {}: {finalized_number}" ,
194
194
self . options. state_machine
195
195
) ;
196
196
197
- let target_block_number = std:: cmp:: min (
198
- previous_finalized_height + self . options . max_block_range ,
199
- finalized_number,
200
- ) ;
197
+ if max_height > finalized_number {
198
+ let encoded = self
199
+ . client
200
+ . rpc ( )
201
+ . request :: < Option < JustificationNotification > > (
202
+ "grandpa_proveFinality" ,
203
+ rpc_params ! [ finalized_number] ,
204
+ )
205
+ . await ?
206
+ . ok_or_else ( || anyhow ! ( "No justification found for block: {:?}" , finalized_number) ) ?
207
+ . 0 ;
208
+
209
+ let mut finality_proof = FinalityProof :: < DefaultHeader > :: decode ( & mut & encoded[ ..] ) ?;
210
+ let justification =
211
+ GrandpaJustification :: < T :: Header > :: decode ( & mut & finality_proof. justification [ ..] ) ?;
212
+ finality_proof. block = justification. commit . target_hash ;
213
+ finality_proof. unknown_headers = self
214
+ . query_headers ( previous_finalized_height, justification. commit . target_number )
215
+ . await ?;
216
+
217
+ return Ok ( finality_proof) ;
218
+ }
219
+
220
+ let target_block_number = max_height;
201
221
log:: trace!(
202
222
"Target block number for {}: {target_block_number}" ,
203
223
self . options. state_machine
@@ -234,9 +254,11 @@ where
234
254
"Found set rotation for {} at block number {height:?}" ,
235
255
self . options. state_machine
236
256
) ;
237
- target_block_hash = hash;
238
- // stop here
239
- break ;
257
+ if height != previous_finalized_height {
258
+ target_block_hash = hash;
259
+ // stop here
260
+ break ;
261
+ }
240
262
} else {
241
263
// check block justifications
242
264
let grandpa_justification = self
@@ -308,6 +330,47 @@ where
308
330
Ok ( finality_proof)
309
331
}
310
332
333
+ /// Query a range of headers from the chain
334
+ ///
335
+ /// # Arguments
336
+ ///
337
+ /// * `start` - The starting block height
338
+ /// * `end` - The ending block height (inclusive)
339
+ ///
340
+ /// # Returns
341
+ ///
342
+ /// A vector of decoded headers within the specified range
343
+ ///
344
+ /// # Errors
345
+ ///
346
+ /// Returns an error if any block hash or header cannot be retrieved
347
+ pub async fn query_headers (
348
+ & self ,
349
+ start : u32 ,
350
+ end : u32 ,
351
+ ) -> Result < Vec < DefaultHeader > , anyhow:: Error > {
352
+ let mut headers = Vec :: new ( ) ;
353
+ let pb = ProgressBar :: new ( ( start - end) as u64 ) ;
354
+ for height in start..=end {
355
+ let hash = self
356
+ . client
357
+ . rpc ( )
358
+ . block_hash ( Some ( height. into ( ) ) )
359
+ . await ?
360
+ . ok_or_else ( || anyhow ! ( "Failed to fetch block has for height {height}" ) ) ?;
361
+ let header = self
362
+ . client
363
+ . rpc ( )
364
+ . header ( Some ( hash) )
365
+ . await ?
366
+ . ok_or_else ( || anyhow ! ( "Header with hash: {hash:?} not found!" ) ) ?;
367
+ headers. push ( DefaultHeader :: decode ( & mut header. encode ( ) . as_ref ( ) ) ?) ;
368
+ pb. inc ( 1 ) ;
369
+ }
370
+ pb. finish_and_clear ( ) ;
371
+ Ok ( headers)
372
+ }
373
+
311
374
/// Returns the proof for parachain headers finalized by the provided finality proof
312
375
pub async fn query_finalized_parachain_headers_with_proof (
313
376
& self ,
0 commit comments