@@ -92,8 +92,8 @@ use retain_mut::RetainMut;
9292use schnorrkel:: SignatureError ;
9393
9494use sc_client_api:: {
95- backend:: AuxStore , AuxDataOperations , BlockchainEvents , FinalityNotification , PreCommitActions ,
96- ProvideUncles , UsageProvider ,
95+ backend:: AuxStore , AuxDataOperations , Backend as BackendT , BlockchainEvents ,
96+ FinalityNotification , PreCommitActions , ProvideUncles , UsageProvider ,
9797} ;
9898use sc_consensus:: {
9999 block_import:: {
@@ -113,7 +113,9 @@ use sc_telemetry::{telemetry, TelemetryHandle, CONSENSUS_DEBUG, CONSENSUS_TRACE}
113113use sp_api:: { ApiExt , ProvideRuntimeApi } ;
114114use sp_application_crypto:: AppKey ;
115115use sp_block_builder:: BlockBuilder as BlockBuilderApi ;
116- use sp_blockchain:: { Error as ClientError , HeaderBackend , HeaderMetadata , Result as ClientResult } ;
116+ use sp_blockchain:: {
117+ Backend as _, Error as ClientError , HeaderBackend , HeaderMetadata , Result as ClientResult ,
118+ } ;
117119use sp_consensus:: {
118120 BlockOrigin , CacheKeyId , CanAuthorWith , Environment , Error as ConsensusError , Proposer ,
119121 SelectChain ,
@@ -1830,3 +1832,74 @@ where
18301832
18311833 Ok ( BasicQueue :: new ( verifier, Box :: new ( block_import) , justification_import, spawner, registry) )
18321834}
1835+
1836+ /// Reverts aux data.
1837+ pub fn revert < Block , Client , Backend > (
1838+ client : Arc < Client > ,
1839+ backend : Arc < Backend > ,
1840+ blocks : NumberFor < Block > ,
1841+ ) -> ClientResult < ( ) >
1842+ where
1843+ Block : BlockT ,
1844+ Client : AuxStore
1845+ + HeaderMetadata < Block , Error = sp_blockchain:: Error >
1846+ + HeaderBackend < Block >
1847+ + ProvideRuntimeApi < Block >
1848+ + UsageProvider < Block > ,
1849+ Client :: Api : BabeApi < Block > ,
1850+ Backend : BackendT < Block > ,
1851+ {
1852+ let best_number = client. info ( ) . best_number ;
1853+ let finalized = client. info ( ) . finalized_number ;
1854+ let revertible = blocks. min ( best_number - finalized) ;
1855+
1856+ let number = best_number - revertible;
1857+ let hash = client
1858+ . block_hash_from_id ( & BlockId :: Number ( number) ) ?
1859+ . ok_or ( ClientError :: Backend ( format ! (
1860+ "Unexpected hash lookup failure for block number: {}" ,
1861+ number
1862+ ) ) ) ?;
1863+
1864+ // Revert epoch changes tree.
1865+
1866+ let config = Config :: get ( & * client) ?;
1867+ let epoch_changes =
1868+ aux_schema:: load_epoch_changes :: < Block , Client > ( & * client, config. genesis_config ( ) ) ?;
1869+ let mut epoch_changes = epoch_changes. shared_data ( ) ;
1870+
1871+ if number == Zero :: zero ( ) {
1872+ // Special case, no epoch changes data were present on genesis.
1873+ * epoch_changes = EpochChangesFor :: < Block , Epoch > :: default ( ) ;
1874+ } else {
1875+ epoch_changes. revert ( descendent_query ( & * client) , hash, number) ;
1876+ }
1877+
1878+ // Remove block weights added after the revert point.
1879+
1880+ let mut weight_keys = HashSet :: with_capacity ( revertible. saturated_into ( ) ) ;
1881+ let leaves = backend. blockchain ( ) . leaves ( ) ?. into_iter ( ) . filter ( |& leaf| {
1882+ sp_blockchain:: tree_route ( & * client, hash, leaf)
1883+ . map ( |route| route. retracted ( ) . is_empty ( ) )
1884+ . unwrap_or_default ( )
1885+ } ) ;
1886+ for leaf in leaves {
1887+ let mut hash = leaf;
1888+ // Insert parent after parent until we don't hit an already processed
1889+ // branch or we reach a direct child of the rollback point.
1890+ while weight_keys. insert ( aux_schema:: block_weight_key ( hash) ) {
1891+ let meta = client. header_metadata ( hash) ?;
1892+ if meta. number <= number + One :: one ( ) {
1893+ // We've reached a child of the revert point, stop here.
1894+ break
1895+ }
1896+ hash = client. header_metadata ( hash) ?. parent ;
1897+ }
1898+ }
1899+ let weight_keys: Vec < _ > = weight_keys. iter ( ) . map ( |val| val. as_slice ( ) ) . collect ( ) ;
1900+
1901+ // Write epoch changes and remove weights in one shot.
1902+ aux_schema:: write_epoch_changes :: < Block , _ , _ > ( & epoch_changes, |values| {
1903+ client. insert_aux ( values, weight_keys. iter ( ) )
1904+ } )
1905+ }
0 commit comments