Grandpa revert procedure (#11162)

* Grandpa revert procedure

* Trigger ci pipeline

* Test rename

* Update client/finality-grandpa/src/authorities.rs

Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com>
This commit is contained in:
Davide Galassi
2022-04-06 16:23:57 +02:00
committed by GitHub
parent 845e37609b
commit 2bdebbcb00
7 changed files with 224 additions and 12 deletions
+48 -1
View File
@@ -63,6 +63,7 @@ use parking_lot::RwLock;
use prometheus_endpoint::{PrometheusError, Registry};
use sc_client_api::{
backend::{AuxStore, Backend},
utils::is_descendent_of,
BlockchainEvents, CallExecutor, ExecutionStrategy, ExecutorProvider, Finalizer, LockImportRun,
StorageProvider, TransactionFor,
};
@@ -71,7 +72,7 @@ use sc_telemetry::{telemetry, TelemetryHandle, CONSENSUS_DEBUG, CONSENSUS_INFO};
use sc_utils::mpsc::{tracing_unbounded, TracingUnboundedReceiver};
use sp_api::ProvideRuntimeApi;
use sp_application_crypto::AppKey;
use sp_blockchain::{Error as ClientError, HeaderBackend, HeaderMetadata};
use sp_blockchain::{Error as ClientError, HeaderBackend, HeaderMetadata, Result as ClientResult};
use sp_consensus::SelectChain;
use sp_core::crypto::ByteArray;
use sp_keystore::{SyncCryptoStore, SyncCryptoStorePtr};
@@ -1162,3 +1163,49 @@ fn local_authority_id(
.map(|(p, _)| p.clone())
})
}
/// Reverts protocol aux data to at most the last finalized block.
/// In particular, standard and forced authority set changes announced after the
/// revert point are removed.
pub fn revert<Block, Client>(client: Arc<Client>, blocks: NumberFor<Block>) -> ClientResult<()>
where
Block: BlockT,
Client: AuxStore
+ HeaderMetadata<Block, Error = sp_blockchain::Error>
+ HeaderBackend<Block>
+ ProvideRuntimeApi<Block>,
{
let best_number = client.info().best_number;
let finalized = client.info().finalized_number;
let revertible = blocks.min(best_number - finalized);
let number = best_number - revertible;
let hash = client
.block_hash_from_id(&BlockId::Number(number))?
.ok_or(ClientError::Backend(format!(
"Unexpected hash lookup failure for block number: {}",
number
)))?;
let info = client.info();
let persistent_data: PersistentData<Block> =
aux_schema::load_persistent(&*client, info.genesis_hash, Zero::zero(), || unreachable!())?;
let shared_authority_set = persistent_data.authority_set;
let mut authority_set = shared_authority_set.inner();
let is_descendent_of = is_descendent_of(&*client, None);
authority_set.revert(hash, number, &is_descendent_of);
// The following has the side effect to properly reset the current voter state.
let (set_id, set_ref) = authority_set.current();
let new_set = Some(NewAuthoritySet {
canon_hash: info.finalized_hash,
canon_number: info.finalized_number,
set_id,
authorities: set_ref.to_vec(),
});
aux_schema::update_authority_set::<Block, _, _>(&authority_set, new_set.as_ref(), |values| {
client.insert_aux(values, None)
})
}