@@ -323,14 +323,15 @@ where
323323 & mut self ,
324324 block : & BlockWithSenders ,
325325 total_difficulty : U256 ,
326+ ancestor : Option < & HashMap < B256 , Header > > ,
326327 ) -> Result < BscExecuteOutput , BlockExecutionError > {
327328 // 1. get parent header and snapshot
328- let parent = & ( self . get_header_by_hash ( block. parent_hash ) ?) ;
329+ let parent = & ( self . get_header_by_hash ( block. parent_hash , ancestor ) ?) ;
329330 let snapshot_reader = SnapshotReader :: new ( self . provider . clone ( ) , self . parlia . clone ( ) ) ;
330- let snap = & ( snapshot_reader. snapshot ( parent, None ) ?) ;
331+ let snap = & ( snapshot_reader. snapshot ( parent, ancestor ) ?) ;
331332
332333 // 2. prepare state on new block
333- self . on_new_block ( & block. header , parent, snap) ?;
334+ self . on_new_block ( & block. header , parent, ancestor , snap) ?;
334335
335336 // 3. get data from contracts before execute transactions
336337 let post_execution_input =
@@ -353,6 +354,7 @@ where
353354 self . post_execution (
354355 block,
355356 parent,
357+ ancestor,
356358 snap,
357359 post_execution_input,
358360 & mut system_txs,
@@ -370,6 +372,7 @@ where
370372
371373 pub ( crate ) fn get_justified_header (
372374 & self ,
375+ ancestor : Option < & HashMap < B256 , Header > > ,
373376 snap : & Snapshot ,
374377 ) -> Result < Header , BlockExecutionError > {
375378 if snap. vote_data . source_hash == B256 :: ZERO && snap. vote_data . target_hash == B256 :: ZERO {
@@ -382,16 +385,23 @@ where
382385 } ) ;
383386 }
384387
385- self . get_header_by_hash ( snap. vote_data . target_hash )
388+ self . get_header_by_hash ( snap. vote_data . target_hash , ancestor )
386389 }
387390
388391 pub ( crate ) fn get_header_by_hash (
389392 & self ,
390393 block_hash : B256 ,
394+ ancestor : Option < & HashMap < B256 , Header > > ,
391395 ) -> Result < Header , BlockExecutionError > {
392- self . provider
393- . header ( & block_hash)
394- . map_err ( |err| BscBlockExecutionError :: ProviderInnerError { error : err. into ( ) } ) ?
396+ ancestor
397+ . and_then ( |m| m. get ( & block_hash) . cloned ( ) )
398+ . or_else ( || {
399+ self . provider
400+ . header ( & block_hash)
401+ . map_err ( |err| BscBlockExecutionError :: ProviderInnerError { error : err. into ( ) } )
402+ . ok ( )
403+ . flatten ( )
404+ } )
395405 . ok_or_else ( || BscBlockExecutionError :: UnknownHeader { block_hash } . into ( ) )
396406 }
397407
@@ -670,7 +680,7 @@ where
670680 DB : Database < Error : Into < ProviderError > + std:: fmt:: Display > ,
671681 P : ParliaProvider ,
672682{
673- type Input < ' a > = BlockExecutionInput < ' a , BlockWithSenders > ;
683+ type Input < ' a > = BlockExecutionInput < ' a , BlockWithSenders , Header > ;
674684 type Output = BlockExecutionOutput < Receipt > ;
675685 type Error = BlockExecutionError ;
676686
@@ -682,9 +692,9 @@ where
682692 ///
683693 /// State changes are committed to the database.
684694 fn execute ( mut self , input : Self :: Input < ' _ > ) -> Result < Self :: Output , Self :: Error > {
685- let BlockExecutionInput { block, total_difficulty } = input;
695+ let BlockExecutionInput { block, total_difficulty, ancestor_headers } = input;
686696 let BscExecuteOutput { receipts, gas_used, snapshot } =
687- self . execute_and_verify ( block, total_difficulty) ?;
697+ self . execute_and_verify ( block, total_difficulty, ancestor_headers ) ?;
688698
689699 // NOTE: we need to merge keep the reverts for the bundle retention
690700 self . state . merge_transitions ( BundleRetention :: Reverts ) ;
@@ -726,15 +736,15 @@ where
726736 DB : Database < Error : Into < ProviderError > + std:: fmt:: Display > ,
727737 P : ParliaProvider ,
728738{
729- type Input < ' a > = BlockExecutionInput < ' a , BlockWithSenders > ;
739+ type Input < ' a > = BlockExecutionInput < ' a , BlockWithSenders , Header > ;
730740 type Output = ExecutionOutcome ;
731741 type Error = BlockExecutionError ;
732742
733743 fn execute_and_verify_one ( & mut self , input : Self :: Input < ' _ > ) -> Result < ( ) , Self :: Error > {
734- let BlockExecutionInput { block, total_difficulty } = input;
744+ let BlockExecutionInput { block, total_difficulty, .. } = input;
735745 let execute_start = Instant :: now ( ) ;
736746 let BscExecuteOutput { receipts, gas_used : _, snapshot } =
737- self . executor . execute_and_verify ( block, total_difficulty) ?;
747+ self . executor . execute_and_verify ( block, total_difficulty, None ) ?;
738748 self . stats . execution_duration += execute_start. elapsed ( ) ;
739749
740750 validate_block_post_execution ( block, self . executor . chain_spec ( ) , & receipts) ?;
@@ -806,7 +816,7 @@ where
806816 pub fn snapshot (
807817 & self ,
808818 header : & Header ,
809- parent : Option < & Header > ,
819+ ancestor : Option < & HashMap < B256 , Header > > ,
810820 ) -> Result < Snapshot , BlockExecutionError > {
811821 let mut cache = RECENT_SNAPS . write ( ) ;
812822
@@ -853,14 +863,14 @@ where
853863
854864 // No snapshot for this header, gather the header and move backward
855865 skip_headers. push ( header. clone ( ) ) ;
856- if let Some ( parent) = parent {
857- block_number = parent. number ;
858- block_hash = header. parent_hash ;
859- header = parent. clone ( ) ;
860- } else if let Ok ( h) = self . get_header_by_hash ( header. parent_hash ) {
866+ if let Ok ( h) = self . get_header_by_hash ( header. parent_hash , ancestor) {
861867 block_number = h. number ;
862868 block_hash = header. parent_hash ;
863869 header = h;
870+ } else {
871+ return Err (
872+ BscBlockExecutionError :: UnknownHeader { block_hash : header. parent_hash } . into ( )
873+ )
864874 }
865875 }
866876
@@ -880,7 +890,7 @@ where
880890 {
881891 // change validator set
882892 let checkpoint_header =
883- self . find_ancient_header ( header, snap. miner_history_check_len ( ) ) ?;
893+ self . find_ancient_header ( header, ancestor , snap. miner_history_check_len ( ) ) ?;
884894
885895 let validators_info = self
886896 . parlia
@@ -924,21 +934,32 @@ where
924934 Ok ( snap)
925935 }
926936
927- fn get_header_by_hash ( & self , block_hash : B256 ) -> Result < Header , BlockExecutionError > {
928- self . provider
929- . header ( & block_hash)
930- . map_err ( |err| BscBlockExecutionError :: ProviderInnerError { error : err. into ( ) } ) ?
937+ fn get_header_by_hash (
938+ & self ,
939+ block_hash : B256 ,
940+ ancestor : Option < & HashMap < B256 , Header > > ,
941+ ) -> Result < Header , BlockExecutionError > {
942+ ancestor
943+ . and_then ( |m| m. get ( & block_hash) . cloned ( ) )
944+ . or_else ( || {
945+ self . provider
946+ . header ( & block_hash)
947+ . map_err ( |err| BscBlockExecutionError :: ProviderInnerError { error : err. into ( ) } )
948+ . ok ( )
949+ . flatten ( )
950+ } )
931951 . ok_or_else ( || BscBlockExecutionError :: UnknownHeader { block_hash } . into ( ) )
932952 }
933953
934954 fn find_ancient_header (
935955 & self ,
936956 header : & Header ,
957+ ancestor : Option < & HashMap < B256 , Header > > ,
937958 count : u64 ,
938959 ) -> Result < Header , BlockExecutionError > {
939960 let mut result = header. clone ( ) ;
940961 for _ in 0 ..count {
941- result = self . get_header_by_hash ( result. parent_hash ) ?;
962+ result = self . get_header_by_hash ( result. parent_hash , ancestor ) ?;
942963 }
943964 Ok ( result)
944965 }
0 commit comments