@@ -156,10 +156,10 @@ impl<Block: BlockT + DeserializeOwned> Blockchain<Block> {
156156 storage. genesis_hash = hash;
157157 }
158158
159- // Update leaves for non-genesis blocks
160- if storage . blocks . len ( ) > 1 {
161- storage . leaves . import ( hash , number , * header . parent_hash ( ) ) ;
162- }
159+ // Update leaves for all blocks including genesis.
160+ // For genesis when forking, the parent_hash points to the previous block on the remote chain.
161+ // That parent won't be in our leaf set, so this effectively adds genesis as a new leaf.
162+ storage . leaves . import ( hash , number , * header . parent_hash ( ) ) ;
163163
164164 // Finalize block only if explicitly requested via new_state
165165 if let NewBlockState :: Final = new_state {
@@ -266,25 +266,43 @@ impl<Block: BlockT + DeserializeOwned> HeaderBackend<Block> for Blockchain<Block
266266
267267 // If not found in local storage, fetch from RPC client
268268 let header = if let Some ( rpc) = self . rpc ( ) {
269- rpc. block ( Some ( hash) ) . ok ( ) . flatten ( ) . map ( |full| {
270- let block = full. block . clone ( ) ;
271- self . storage
272- . write ( )
273- . blocks
274- . insert ( hash, StoredBlock :: Full ( block. clone ( ) , full. justifications ) ) ;
275- block. header ( ) . clone ( )
276- } )
269+ match rpc. block ( Some ( hash) ) {
270+ Ok ( Some ( full) ) => {
271+ let block = full. block . clone ( ) ;
272+ self . storage
273+ . write ( )
274+ . blocks
275+ . insert ( hash, StoredBlock :: Full ( block. clone ( ) , full. justifications ) ) ;
276+ Some ( block. header ( ) . clone ( ) )
277+ }
278+ Ok ( None ) => {
279+ // Block not found on remote chain - this is expected for locally-built blocks
280+ tracing:: debug!(
281+ target: LAZY_LOADING_LOG_TARGET ,
282+ "Block {:?} not found in local storage or remote RPC" ,
283+ hash
284+ ) ;
285+ None
286+ }
287+ Err ( e) => {
288+ tracing:: warn!(
289+ target: LAZY_LOADING_LOG_TARGET ,
290+ "Failed to fetch block {:?} from RPC: {}" ,
291+ hash,
292+ e
293+ ) ;
294+ None
295+ }
296+ }
277297 } else {
278- None
279- } ;
280-
281- if header. is_none ( ) {
282- tracing:: warn!(
298+ // No RPC configured - block simply doesn't exist locally
299+ tracing:: debug!(
283300 target: LAZY_LOADING_LOG_TARGET ,
284- "Expected block {:x ?} to exist. " ,
285- & hash
301+ "Block {: ?} not found in local storage (no RPC configured) " ,
302+ hash
286303 ) ;
287- }
304+ None
305+ } ;
288306
289307 Ok ( header)
290308 }
@@ -418,19 +436,34 @@ impl<Block: BlockT + DeserializeOwned> sp_blockchain::Backend<Block> for Blockch
418436 Ok ( leaves)
419437 }
420438
421- fn children ( & self , _parent_hash : Block :: Hash ) -> sp_blockchain:: Result < Vec < Block :: Hash > > {
422- unimplemented ! ( "Not supported by the `lazy-loading` backend." )
439+ fn children ( & self , parent_hash : Block :: Hash ) -> sp_blockchain:: Result < Vec < Block :: Hash > > {
440+ // Find all blocks whose parent_hash matches the given hash
441+ let storage = self . storage . read ( ) ;
442+ let children: Vec < Block :: Hash > = storage
443+ . blocks
444+ . iter ( )
445+ . filter_map ( |( hash, block) | {
446+ if * block. header ( ) . parent_hash ( ) == parent_hash {
447+ Some ( * hash)
448+ } else {
449+ None
450+ }
451+ } )
452+ . collect ( ) ;
453+ Ok ( children)
423454 }
424455
425456 fn indexed_transaction ( & self , _hash : Block :: Hash ) -> sp_blockchain:: Result < Option < Vec < u8 > > > {
426- unimplemented ! ( "Not supported by the `lazy-loading` backend." )
457+ // Indexed transactions are not supported in the lazy-loading backend
458+ Ok ( None )
427459 }
428460
429461 fn block_indexed_body (
430462 & self ,
431463 _hash : Block :: Hash ,
432464 ) -> sp_blockchain:: Result < Option < Vec < Vec < u8 > > > > {
433- unimplemented ! ( "Not supported by the `lazy-loading` backend." )
465+ // Indexed block bodies are not supported in the lazy-loading backend
466+ Ok ( None )
434467 }
435468}
436469
0 commit comments