@@ -218,27 +218,51 @@ impl From<BeaconStateHash> for Hash256 {
218218 map_beacon_state_base_fields( ) ,
219219 map_beacon_state_base_tree_list_fields( mutable, fallible, groups( tree_lists) ) ,
220220 ) ,
221+ bimappings( bimap_beacon_state_base_tree_list_fields(
222+ other_type = "BeaconStateBase" ,
223+ self_mutable,
224+ fallible,
225+ groups( tree_lists)
226+ ) ) ,
221227 num_fields( all( ) ) ,
222228 ) ) ,
223229 Altair ( metastruct(
224230 mappings(
225231 map_beacon_state_altair_fields( ) ,
226232 map_beacon_state_altair_tree_list_fields( mutable, fallible, groups( tree_lists) ) ,
227233 ) ,
234+ bimappings( bimap_beacon_state_altair_tree_list_fields(
235+ other_type = "BeaconStateAltair" ,
236+ self_mutable,
237+ fallible,
238+ groups( tree_lists)
239+ ) ) ,
228240 num_fields( all( ) ) ,
229241 ) ) ,
230242 Merge ( metastruct(
231243 mappings(
232244 map_beacon_state_bellatrix_fields( ) ,
233245 map_beacon_state_bellatrix_tree_list_fields( mutable, fallible, groups( tree_lists) ) ,
234246 ) ,
247+ bimappings( bimap_beacon_state_merge_tree_list_fields(
248+ other_type = "BeaconStateMerge" ,
249+ self_mutable,
250+ fallible,
251+ groups( tree_lists)
252+ ) ) ,
235253 num_fields( all( ) ) ,
236254 ) ) ,
237255 Capella ( metastruct(
238256 mappings(
239257 map_beacon_state_capella_fields( ) ,
240258 map_beacon_state_capella_tree_list_fields( mutable, fallible, groups( tree_lists) ) ,
241259 ) ,
260+ bimappings( bimap_beacon_state_capella_tree_list_fields(
261+ other_type = "BeaconStateCapella" ,
262+ self_mutable,
263+ fallible,
264+ groups( tree_lists)
265+ ) ) ,
242266 num_fields( all( ) ) ,
243267 ) ) ,
244268 ) ,
@@ -287,6 +311,8 @@ where
287311 #[ metastruct( exclude_from( tree_lists) ) ]
288312 pub eth1_data : Eth1Data ,
289313 #[ test_random( default ) ]
314+ // FIXME(sproul): excluded due to `rebase_on` issue
315+ #[ metastruct( exclude_from( tree_lists) ) ]
290316 pub eth1_data_votes : VList < Eth1Data , T :: SlotsPerEth1VotingPeriod > ,
291317 #[ superstruct( getter( copy) ) ]
292318 #[ metastruct( exclude_from( tree_lists) ) ]
@@ -1739,6 +1765,101 @@ impl<T: EthSpec> BeaconState<T> {
17391765 } ;
17401766 Ok ( sync_committee)
17411767 }
1768+
1769+ // FIXME(sproul): missing eth1 data votes, they would need a ResetListDiff
1770+ #[ allow( clippy:: integer_arithmetic) ]
1771+ pub fn rebase_on ( & mut self , base : & Self , spec : & ChainSpec ) -> Result < ( ) , Error > {
1772+ // Required for macros (which use type-hints internally).
1773+ type GenericValidator = Validator ;
1774+
1775+ match ( & mut * self , base) {
1776+ ( Self :: Base ( self_inner) , Self :: Base ( base_inner) ) => {
1777+ bimap_beacon_state_base_tree_list_fields ! (
1778+ self_inner,
1779+ base_inner,
1780+ |_, self_field, base_field| { self_field. rebase_on( base_field) }
1781+ ) ;
1782+ }
1783+ ( Self :: Altair ( self_inner) , Self :: Altair ( base_inner) ) => {
1784+ bimap_beacon_state_altair_tree_list_fields ! (
1785+ self_inner,
1786+ base_inner,
1787+ |_, self_field, base_field| { self_field. rebase_on( base_field) }
1788+ ) ;
1789+ }
1790+ ( Self :: Merge ( self_inner) , Self :: Merge ( base_inner) ) => {
1791+ bimap_beacon_state_merge_tree_list_fields ! (
1792+ self_inner,
1793+ base_inner,
1794+ |_, self_field, base_field| { self_field. rebase_on( base_field) }
1795+ ) ;
1796+ }
1797+ ( Self :: Capella ( self_inner) , Self :: Capella ( base_inner) ) => {
1798+ bimap_beacon_state_capella_tree_list_fields ! (
1799+ self_inner,
1800+ base_inner,
1801+ |_, self_field, base_field| { self_field. rebase_on( base_field) }
1802+ ) ;
1803+ }
1804+ // Do not rebase across forks, this should be OK for most situations.
1805+ _ => { }
1806+ }
1807+
1808+ // Use sync committees from `base` if they are equal.
1809+ if let Ok ( current_sync_committee) = self . current_sync_committee_mut ( ) {
1810+ if let Ok ( base_sync_committee) = base. current_sync_committee ( ) {
1811+ if current_sync_committee == base_sync_committee {
1812+ * current_sync_committee = base_sync_committee. clone ( ) ;
1813+ }
1814+ }
1815+ }
1816+ if let Ok ( next_sync_committee) = self . next_sync_committee_mut ( ) {
1817+ if let Ok ( base_sync_committee) = base. next_sync_committee ( ) {
1818+ if next_sync_committee == base_sync_committee {
1819+ * next_sync_committee = base_sync_committee. clone ( ) ;
1820+ }
1821+ }
1822+ }
1823+
1824+ // Rebase caches like the committee caches and the pubkey cache, which are expensive to
1825+ // rebuild and likely to be re-usable from the base state.
1826+ self . rebase_caches_on ( base, spec) ?;
1827+
1828+ Ok ( ( ) )
1829+ }
1830+
1831+ pub fn rebase_caches_on ( & mut self , base : & Self , spec : & ChainSpec ) -> Result < ( ) , Error > {
1832+ // Use pubkey cache from `base` if it contains superior information (likely if our cache is
1833+ // uninitialized).
1834+ let num_validators = self . validators ( ) . len ( ) ;
1835+ let pubkey_cache = self . pubkey_cache_mut ( ) ;
1836+ let base_pubkey_cache = base. pubkey_cache ( ) ;
1837+ if pubkey_cache. len ( ) < base_pubkey_cache. len ( ) && pubkey_cache. len ( ) < num_validators {
1838+ * pubkey_cache = base_pubkey_cache. clone ( ) ;
1839+ }
1840+
1841+ // Use committee caches from `base` if they are relevant.
1842+ let epochs = [
1843+ self . previous_epoch ( ) ,
1844+ self . current_epoch ( ) ,
1845+ self . next_epoch ( ) ?,
1846+ ] ;
1847+ for ( index, epoch) in epochs. into_iter ( ) . enumerate ( ) {
1848+ if let Ok ( base_relative_epoch) = RelativeEpoch :: from_epoch ( base. current_epoch ( ) , epoch)
1849+ {
1850+ * self . committee_cache_at_index_mut ( index) ? =
1851+ base. committee_cache ( base_relative_epoch) ?. clone ( ) ;
1852+
1853+ // Ensure total active balance cache remains built whenever current committee
1854+ // cache is built.
1855+ if epoch == self . current_epoch ( ) {
1856+ self . build_total_active_balance_cache ( spec) ?;
1857+ }
1858+ }
1859+ }
1860+
1861+ Ok ( ( ) )
1862+ }
17421863}
17431864
17441865impl < T : EthSpec , GenericValidator : ValidatorTrait > BeaconState < T , GenericValidator > {
@@ -1790,6 +1911,7 @@ impl<T: EthSpec, GenericValidator: ValidatorTrait> BeaconState<T, GenericValidat
17901911 map_beacon_state_capella_tree_list_fields ! ( inner, |_, x| { x. apply_updates( ) } )
17911912 }
17921913 }
1914+ self . eth1_data_votes_mut ( ) . apply_updates ( ) ?;
17931915 Ok ( ( ) )
17941916 }
17951917
0 commit comments