Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit c08e1db

Browse files
committed
Aura: Adds some compatibility mode to support old chains
In #9132 we changed the way how we get the authorities from the runtime. Before this mentioned pr we would call `initialize_block` before calling the authorities runtime function. The problem with this was that when you have a block X that would switch the authority set, it would already be signed by an authority of the new set. This was wrong, as a block should only be signed by the current authority set. As this change is a hard fork, this pr brings back the possibility for users that have a chain running with this old logic to upgrade. They will need to use: ``` CompatibilityMode::UseInitializeBlock { until: some_block_in_the_future } ``` Using this compatibility mode will make the node behave like the old nodes, aka calling `initialize_block` before doing the actual runtime call to `authorities`. Then when the given `until` block is being build/imported the node switches to the new behaviour of not calling `initialize_block` before. This is a hard fork, so the `until` block should be chosen wisely as a point where all nodes in the network have upgraded.
1 parent fd00b14 commit c08e1db

File tree

4 files changed

+143
-58
lines changed

4 files changed

+143
-58
lines changed

client/consensus/aura/src/import_queue.rs

Lines changed: 42 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818

1919
//! Module implementing the logic for verifying and importing AuRa blocks.
2020
21-
use crate::{aura_err, authorities, find_pre_digest, slot_author, AuthorityId, Error};
21+
use crate::{
22+
aura_err, authorities, find_pre_digest, slot_author, AuthorityId, CompatibilityMode, Error,
23+
};
2224
use codec::{Codec, Decode, Encode};
2325
use log::{debug, info, trace};
2426
use prometheus_endpoint::Registry;
@@ -31,21 +33,15 @@ use sc_consensus_slots::{check_equivocation, CheckedHeader, InherentDataProvider
3133
use sc_telemetry::{telemetry, TelemetryHandle, CONSENSUS_DEBUG, CONSENSUS_TRACE};
3234
use sp_api::{ApiExt, ProvideRuntimeApi};
3335
use sp_block_builder::BlockBuilder as BlockBuilderApi;
34-
use sp_blockchain::{
35-
well_known_cache_keys::{self, Id as CacheKeyId},
36-
HeaderBackend,
37-
};
36+
use sp_blockchain::{well_known_cache_keys::Id as CacheKeyId, HeaderBackend};
3837
use sp_consensus::Error as ConsensusError;
39-
use sp_consensus_aura::{
40-
digests::CompatibleDigestItem, inherents::AuraInherentData, AuraApi, ConsensusLog,
41-
AURA_ENGINE_ID,
42-
};
38+
use sp_consensus_aura::{digests::CompatibleDigestItem, inherents::AuraInherentData, AuraApi};
4339
use sp_consensus_slots::Slot;
4440
use sp_core::{crypto::Pair, ExecutionContext};
4541
use sp_inherents::{CreateInherentDataProviders, InherentDataProvider as _};
4642
use sp_runtime::{
47-
generic::{BlockId, OpaqueDigestItemId},
48-
traits::{Block as BlockT, Header},
43+
generic::BlockId,
44+
traits::{Block as BlockT, Header, NumberFor},
4945
DigestItem,
5046
};
5147
use std::{fmt::Debug, hash::Hash, marker::PhantomData, sync::Arc};
@@ -109,32 +105,35 @@ where
109105
}
110106

111107
/// A verifier for Aura blocks.
112-
pub struct AuraVerifier<C, P, CIDP> {
108+
pub struct AuraVerifier<C, P, CIDP, N> {
113109
client: Arc<C>,
114110
phantom: PhantomData<P>,
115111
create_inherent_data_providers: CIDP,
116112
check_for_equivocation: CheckForEquivocation,
117113
telemetry: Option<TelemetryHandle>,
114+
compatibility_mode: CompatibilityMode<N>,
118115
}
119116

120-
impl<C, P, CIDP> AuraVerifier<C, P, CIDP> {
117+
impl<C, P, CIDP, N> AuraVerifier<C, P, CIDP, N> {
121118
pub(crate) fn new(
122119
client: Arc<C>,
123120
create_inherent_data_providers: CIDP,
124121
check_for_equivocation: CheckForEquivocation,
125122
telemetry: Option<TelemetryHandle>,
123+
compatibility_mode: CompatibilityMode<N>,
126124
) -> Self {
127125
Self {
128126
client,
129127
create_inherent_data_providers,
130128
check_for_equivocation,
131129
telemetry,
130+
compatibility_mode,
132131
phantom: PhantomData,
133132
}
134133
}
135134
}
136135

137-
impl<C, P, CIDP> AuraVerifier<C, P, CIDP>
136+
impl<C, P, CIDP, N> AuraVerifier<C, P, CIDP, N>
138137
where
139138
P: Send + Sync + 'static,
140139
CIDP: Send,
@@ -172,9 +171,9 @@ where
172171
}
173172

174173
#[async_trait::async_trait]
175-
impl<B: BlockT, C, P, CIDP> Verifier<B> for AuraVerifier<C, P, CIDP>
174+
impl<B: BlockT, C, P, CIDP> Verifier<B> for AuraVerifier<C, P, CIDP, NumberFor<B>>
176175
where
177-
C: ProvideRuntimeApi<B> + Send + Sync + sc_client_api::backend::AuxStore + BlockOf,
176+
C: ProvideRuntimeApi<B> + Send + Sync + sc_client_api::backend::AuxStore,
178177
C::Api: BlockBuilderApi<B> + AuraApi<B, AuthorityId<P>> + ApiExt<B>,
179178
P: Pair + Send + Sync + 'static,
180179
P::Public: Send + Sync + Hash + Eq + Clone + Decode + Encode + Debug + 'static,
@@ -188,8 +187,13 @@ where
188187
) -> Result<(BlockImportParams<B, ()>, Option<Vec<(CacheKeyId, Vec<u8>)>>), String> {
189188
let hash = block.header.hash();
190189
let parent_hash = *block.header.parent_hash();
191-
let authorities = authorities(self.client.as_ref(), &BlockId::Hash(parent_hash))
192-
.map_err(|e| format!("Could not fetch authorities at {:?}: {}", parent_hash, e))?;
190+
let authorities = authorities(
191+
self.client.as_ref(),
192+
parent_hash,
193+
*block.header.number(),
194+
&self.compatibility_mode,
195+
)
196+
.map_err(|e| format!("Could not fetch authorities at {:?}: {}", parent_hash, e))?;
193197

194198
let create_inherent_data_providers = self
195199
.create_inherent_data_providers
@@ -259,28 +263,12 @@ where
259263
"pre_header" => ?pre_header,
260264
);
261265

262-
// Look for an authorities-change log.
263-
let maybe_keys = pre_header
264-
.digest()
265-
.logs()
266-
.iter()
267-
.filter_map(|l| {
268-
l.try_to::<ConsensusLog<AuthorityId<P>>>(OpaqueDigestItemId::Consensus(
269-
&AURA_ENGINE_ID,
270-
))
271-
})
272-
.find_map(|l| match l {
273-
ConsensusLog::AuthoritiesChange(a) =>
274-
Some(vec![(well_known_cache_keys::AUTHORITIES, a.encode())]),
275-
_ => None,
276-
});
277-
278266
block.header = pre_header;
279267
block.post_digests.push(seal);
280268
block.fork_choice = Some(ForkChoiceStrategy::LongestChain);
281269
block.post_hash = Some(hash);
282270

283-
Ok((block, maybe_keys))
271+
Ok((block, None))
284272
},
285273
CheckedHeader::Deferred(a, b) => {
286274
debug!(target: "aura", "Checking {:?} failed; {:?}, {:?}.", hash, a, b);
@@ -323,7 +311,7 @@ impl Default for CheckForEquivocation {
323311
}
324312

325313
/// Parameters of [`import_queue`].
326-
pub struct ImportQueueParams<'a, Block, I, C, S, CIDP> {
314+
pub struct ImportQueueParams<'a, Block: BlockT, I, C, S, CIDP> {
327315
/// The block import to use.
328316
pub block_import: I,
329317
/// The justification import.
@@ -340,6 +328,10 @@ pub struct ImportQueueParams<'a, Block, I, C, S, CIDP> {
340328
pub check_for_equivocation: CheckForEquivocation,
341329
/// Telemetry instance used to report telemetry metrics.
342330
pub telemetry: Option<TelemetryHandle>,
331+
/// Compatibility mode that should be used.
332+
///
333+
/// If in doubt, use `Default::default()`.
334+
pub compatibility_mode: CompatibilityMode<NumberFor<Block>>,
343335
}
344336

345337
/// Start an import queue for the Aura consensus algorithm.
@@ -353,6 +345,7 @@ pub fn import_queue<P, Block, I, C, S, CIDP>(
353345
registry,
354346
check_for_equivocation,
355347
telemetry,
348+
compatibility_mode,
356349
}: ImportQueueParams<Block, I, C, S, CIDP>,
357350
) -> Result<DefaultImportQueue<Block, C>, sp_consensus::Error>
358351
where
@@ -377,18 +370,19 @@ where
377370
CIDP: CreateInherentDataProviders<Block, ()> + Sync + Send + 'static,
378371
CIDP::InherentDataProviders: InherentDataProviderExt + Send + Sync,
379372
{
380-
let verifier = build_verifier::<P, _, _>(BuildVerifierParams {
373+
let verifier = build_verifier::<P, _, _, _>(BuildVerifierParams {
381374
client,
382375
create_inherent_data_providers,
383376
check_for_equivocation,
384377
telemetry,
378+
compatibility_mode,
385379
});
386380

387381
Ok(BasicQueue::new(verifier, Box::new(block_import), justification_import, spawner, registry))
388382
}
389383

390384
/// Parameters of [`build_verifier`].
391-
pub struct BuildVerifierParams<C, CIDP> {
385+
pub struct BuildVerifierParams<C, CIDP, N> {
392386
/// The client to interact with the chain.
393387
pub client: Arc<C>,
394388
/// Something that can create the inherent data providers.
@@ -397,21 +391,27 @@ pub struct BuildVerifierParams<C, CIDP> {
397391
pub check_for_equivocation: CheckForEquivocation,
398392
/// Telemetry instance used to report telemetry metrics.
399393
pub telemetry: Option<TelemetryHandle>,
394+
/// Compatibility mode that should be used.
395+
///
396+
/// If in doubt, use `Default::default()`.
397+
pub compatibility_mode: CompatibilityMode<N>,
400398
}
401399

402400
/// Build the [`AuraVerifier`]
403-
pub fn build_verifier<P, C, CIDP>(
401+
pub fn build_verifier<P, C, CIDP, N>(
404402
BuildVerifierParams {
405403
client,
406404
create_inherent_data_providers,
407405
check_for_equivocation,
408406
telemetry,
409-
}: BuildVerifierParams<C, CIDP>,
410-
) -> AuraVerifier<C, P, CIDP> {
411-
AuraVerifier::<_, P, _>::new(
407+
compatibility_mode,
408+
}: BuildVerifierParams<C, CIDP, N>,
409+
) -> AuraVerifier<C, P, CIDP, N> {
410+
AuraVerifier::<_, P, _, _>::new(
412411
client,
413412
create_inherent_data_providers,
414413
check_for_equivocation,
415414
telemetry,
415+
compatibility_mode,
416416
)
417417
}

0 commit comments

Comments
 (0)