@@ -1519,7 +1519,7 @@ impl<E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>> HotColdDB<E, Hot, Cold>
1519
1519
?state_root,
1520
1520
slot = %state. slot( ) ,
1521
1521
storage_strategy = ?self . hot_storage_strategy( state. slot( ) ) ?,
1522
- diff_base_state_root = ? summary. diff_base_state_root ,
1522
+ diff_base_state = % summary. diff_base_state ,
1523
1523
previous_state_root = ?summary. previous_state_root,
1524
1524
"Storing hot state summary and diffs"
1525
1525
) ;
@@ -1656,7 +1656,7 @@ impl<E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>> HotColdDB<E, Hot, Cold>
1656
1656
// FIXME(tree-states): Add cache of hot hdiff buffers
1657
1657
let Some ( HotStateSummary {
1658
1658
slot,
1659
- diff_base_state_root ,
1659
+ diff_base_state ,
1660
1660
..
1661
1661
} ) = self . load_hot_state_summary ( & state_root) ?
1662
1662
else {
@@ -1665,7 +1665,7 @@ impl<E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>> HotColdDB<E, Hot, Cold>
1665
1665
. into_iter ( )
1666
1666
. map ( |( state_root, summary) | ( state_root, summary. slot ) )
1667
1667
. collect :: < Vec < ( Hash256 , Slot ) > > ( ) ;
1668
- existing_summaries. sort_by ( |a , b| a . 1 . cmp ( & b . 1 ) ) ;
1668
+ existing_summaries. sort_by_key ( | ( _ , slot ) | * slot ) ;
1669
1669
// Hot summaries should never be missing, dump the current list of summaries to ease debug
1670
1670
// TODO(hdiff): this log is for debug and can include a very long list of roots,
1671
1671
// thousands in non-finality.
@@ -1695,7 +1695,7 @@ impl<E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>> HotColdDB<E, Hot, Cold>
1695
1695
Ok ( buffer)
1696
1696
}
1697
1697
StorageStrategy :: DiffFrom ( from_slot) => {
1698
- let from_state_root = diff_base_state_root . get_root ( from_slot) ?;
1698
+ let from_state_root = diff_base_state . get_root ( from_slot) ?;
1699
1699
let mut buffer = self . load_hot_hdiff_buffer ( from_state_root) . map_err ( |e| {
1700
1700
Error :: LoadingHotHdiffBufferError (
1701
1701
format ! ( "load hdiff DiffFrom {from_slot} {state_root}" ) ,
@@ -1708,7 +1708,7 @@ impl<E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>> HotColdDB<E, Hot, Cold>
1708
1708
Ok ( buffer)
1709
1709
}
1710
1710
StorageStrategy :: ReplayFrom ( from_slot) => {
1711
- let from_state_root = diff_base_state_root . get_root ( from_slot) ?;
1711
+ let from_state_root = diff_base_state . get_root ( from_slot) ?;
1712
1712
self . load_hot_hdiff_buffer ( from_state_root) . map_err ( |e| {
1713
1713
Error :: LoadingHotHdiffBufferError (
1714
1714
format ! ( "load hdiff ReplayFrom {from_slot} {state_root}" ) ,
@@ -1750,7 +1750,7 @@ impl<E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>> HotColdDB<E, Hot, Cold>
1750
1750
if let Some ( HotStateSummary {
1751
1751
slot,
1752
1752
latest_block_root,
1753
- diff_base_state_root ,
1753
+ diff_base_state ,
1754
1754
..
1755
1755
} ) = self . load_hot_state_summary ( state_root) ?
1756
1756
{
@@ -1774,7 +1774,7 @@ impl<E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>> HotColdDB<E, Hot, Cold>
1774
1774
state
1775
1775
}
1776
1776
StorageStrategy :: ReplayFrom ( from_slot) => {
1777
- let from_state_root = diff_base_state_root . get_root ( from_slot) ?;
1777
+ let from_state_root = diff_base_state . get_root ( from_slot) ?;
1778
1778
1779
1779
let ( mut base_state, _) = self
1780
1780
. load_hot_state ( & from_state_root, update_cache)
@@ -3558,14 +3558,20 @@ fn get_ancestor_state_root<'a, E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>
3558
3558
Ordering :: Greater => { } // keep going
3559
3559
}
3560
3560
3561
- // Jump to an older state summary that is ancestor of `state_root`
3562
- if target_slot <= state_summary. diff_base_state_root . slot {
3563
- // As an optimization use the HDiff state root to jump states faster
3564
- state_root = state_summary. diff_base_state_root . state_root ;
3565
- } else {
3566
- // Else jump slot by slot
3567
- state_root = state_summary. previous_state_root ;
3561
+ // Jump to an older state summary that is an ancestor of `state_root`
3562
+ if let OptionalDiffBaseState :: BaseState ( DiffBaseState {
3563
+ slot,
3564
+ state_root : diff_base_state_root,
3565
+ } ) = state_summary. diff_base_state
3566
+ {
3567
+ if target_slot <= slot {
3568
+ // As an optimization use the HDiff state root to jump states faster
3569
+ state_root = diff_base_state_root;
3570
+ }
3571
+ continue ;
3568
3572
}
3573
+ // Else jump slot by slot
3574
+ state_root = state_summary. previous_state_root ;
3569
3575
}
3570
3576
}
3571
3577
@@ -3577,45 +3583,72 @@ pub struct HotStateSummary {
3577
3583
pub slot : Slot ,
3578
3584
pub latest_block_root : Hash256 ,
3579
3585
pub latest_block_slot : Slot ,
3580
- // FIXME(tree-states): consider not storing the storage strategy and storing a state root instead
3581
- pub diff_base_state_root : DiffBaseStateRoot ,
3582
- // FIXME(tree-states): should add this as part of this migration
3586
+ pub diff_base_state : OptionalDiffBaseState ,
3583
3587
pub previous_state_root : Hash256 ,
3584
3588
}
3585
3589
3586
- /// Cache for a single state root associated with a slot
3590
+ /// Information about the state that a hot state is diffed from or replays blocks from, if any.
3591
+ ///
3592
+ /// In the case of a snapshot, there is no diff base state, so this value will be
3593
+ /// `DiffBaseState::Snapshot`.
3587
3594
#[ derive( Debug , Clone , Copy , Encode , Decode ) ]
3588
- pub struct DiffBaseStateRoot {
3595
+ #[ ssz( enum_behaviour = "union" ) ]
3596
+ pub enum OptionalDiffBaseState {
3597
+ Snapshot ( Slot ) ,
3598
+ BaseState ( DiffBaseState ) ,
3599
+ }
3600
+
3601
+ #[ derive( Debug , Clone , Copy , Encode , Decode ) ]
3602
+ pub struct DiffBaseState {
3589
3603
slot : Slot ,
3590
3604
state_root : Hash256 ,
3591
3605
}
3592
3606
3593
- impl DiffBaseStateRoot {
3607
+ impl OptionalDiffBaseState {
3594
3608
pub fn new ( slot : Slot , state_root : Hash256 ) -> Self {
3595
- Self { slot, state_root }
3609
+ Self :: BaseState ( DiffBaseState { slot, state_root } )
3596
3610
}
3597
3611
3598
- pub fn zero ( ) -> Self {
3599
- Self {
3600
- slot : Slot :: new ( 0 ) ,
3601
- state_root : Hash256 :: ZERO ,
3612
+ pub fn get_root ( & self , slot : Slot ) -> Result < Hash256 , Error > {
3613
+ match * self {
3614
+ Self :: Snapshot ( stored_slot) => {
3615
+ if slot == stored_slot {
3616
+ Err ( Error :: SnapshotDiffBaseState { slot } )
3617
+ } else {
3618
+ Err ( Error :: MismatchedDiffBaseState {
3619
+ expected_slot : slot,
3620
+ stored_slot,
3621
+ } )
3622
+ }
3623
+ }
3624
+ Self :: BaseState ( DiffBaseState {
3625
+ slot : stored_slot,
3626
+ state_root,
3627
+ } ) => {
3628
+ if stored_slot == slot {
3629
+ Ok ( state_root)
3630
+ } else {
3631
+ Err ( Error :: MismatchedDiffBaseState {
3632
+ expected_slot : slot,
3633
+ stored_slot,
3634
+ } )
3635
+ }
3636
+ }
3602
3637
}
3603
3638
}
3639
+ }
3604
3640
3605
- pub fn get_root ( & self , slot : Slot ) -> Result < Hash256 , Error > {
3606
- if self . slot == slot {
3607
- Ok ( self . state_root )
3608
- } else {
3609
- Err ( Error :: MissmatchDiffBaseStateRoot {
3610
- expected_slot : slot,
3611
- stored_slot : self . slot ,
3612
- } )
3641
+ // Succint rendering of (slot, state_root) pair for "Storing hot state summary and diffs" log
3642
+ impl std:: fmt:: Display for OptionalDiffBaseState {
3643
+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
3644
+ match self {
3645
+ Self :: Snapshot ( slot) => write ! ( f, "{slot}/snapshot" ) ,
3646
+ Self :: BaseState ( base_state) => write ! ( f, "{base_state}" ) ,
3613
3647
}
3614
3648
}
3615
3649
}
3616
3650
3617
- // Succint rendering of (slot, state_root) pair for "Storing hot state summary and diffs" log
3618
- impl std:: fmt:: Display for DiffBaseStateRoot {
3651
+ impl std:: fmt:: Display for DiffBaseState {
3619
3652
fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
3620
3653
write ! ( f, "{}/{:?}" , self . slot, self . state_root)
3621
3654
}
@@ -3662,10 +3695,10 @@ impl HotStateSummary {
3662
3695
}
3663
3696
} ;
3664
3697
let diff_base_slot = storage_strategy. diff_base_slot ( ) ;
3665
- let diff_base_state_root = if let Some ( diff_base_slot) = diff_base_slot {
3666
- DiffBaseStateRoot :: new ( diff_base_slot, get_state_root ( diff_base_slot) ?)
3698
+ let diff_base_state = if let Some ( diff_base_slot) = diff_base_slot {
3699
+ OptionalDiffBaseState :: new ( diff_base_slot, get_state_root ( diff_base_slot) ?)
3667
3700
} else {
3668
- DiffBaseStateRoot :: zero ( )
3701
+ OptionalDiffBaseState :: Snapshot ( state . slot ( ) )
3669
3702
} ;
3670
3703
3671
3704
let previous_state_root = if state. slot ( ) == 0 {
@@ -3679,7 +3712,7 @@ impl HotStateSummary {
3679
3712
slot : state. slot ( ) ,
3680
3713
latest_block_root,
3681
3714
latest_block_slot : state. latest_block_header ( ) . slot ,
3682
- diff_base_state_root ,
3715
+ diff_base_state ,
3683
3716
previous_state_root,
3684
3717
} )
3685
3718
}
0 commit comments