referrerpolicy=no-referrer-when-downgrade

sc_consensus_manual_seal/consensus/
aura.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
5
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// You should have received a copy of the GNU General Public License
17// along with this program. If not, see <https://www.gnu.org/licenses/>.
18
19//! Aura consensus data provider, This allows manual seal author blocks that are valid for
20//! runtimes that expect the aura-specific digests.
21
22use crate::{ConsensusDataProvider, Error};
23use sc_client_api::{AuxStore, UsageProvider};
24use sc_consensus::BlockImportParams;
25use sp_api::{ProvideRuntimeApi, StorageProof};
26use sp_consensus_aura::{
27	digests::CompatibleDigestItem,
28	sr25519::{AuthorityId, AuthoritySignature},
29	AuraApi, Slot, SlotDuration,
30};
31use sp_inherents::InherentData;
32use sp_runtime::{traits::Block as BlockT, Digest, DigestItem};
33use sp_timestamp::TimestampInherentData;
34use std::{marker::PhantomData, sync::Arc};
35
36/// Consensus data provider for Aura. This allows to use manual-seal driven nodes to author valid
37/// AURA blocks. It will inspect incoming [`InherentData`] and look for included timestamps. Based
38/// on these timestamps, the [`AuraConsensusDataProvider`] will emit fitting digest items.
39pub struct AuraConsensusDataProvider<B> {
40	// slot duration
41	slot_duration: SlotDuration,
42	// phantom data for required generics
43	_phantom: PhantomData<B>,
44}
45
46impl<B> AuraConsensusDataProvider<B>
47where
48	B: BlockT,
49{
50	/// Creates a new instance of the [`AuraConsensusDataProvider`], requires that `client`
51	/// implements [`sp_consensus_aura::AuraApi`]
52	pub fn new<C>(client: Arc<C>) -> Self
53	where
54		C: AuxStore + ProvideRuntimeApi<B> + UsageProvider<B>,
55		C::Api: AuraApi<B, AuthorityId>,
56	{
57		let slot_duration = sc_consensus_aura::slot_duration(&*client)
58			.expect("slot_duration is always present; qed.");
59
60		Self { slot_duration, _phantom: PhantomData }
61	}
62
63	/// Creates a new instance of the [`AuraConsensusDataProvider`]
64	pub fn new_with_slot_duration(slot_duration: SlotDuration) -> Self {
65		Self { slot_duration, _phantom: PhantomData }
66	}
67}
68
69impl<B> ConsensusDataProvider<B> for AuraConsensusDataProvider<B>
70where
71	B: BlockT,
72{
73	fn create_digest(
74		&self,
75		_parent: &B::Header,
76		inherents: &InherentData,
77	) -> Result<Digest, Error> {
78		let timestamp =
79			inherents.timestamp_inherent_data()?.expect("Timestamp is always present; qed");
80
81		// we always calculate the new slot number based on the current time-stamp and the slot
82		// duration.
83		let digest_item = <DigestItem as CompatibleDigestItem<AuthoritySignature>>::aura_pre_digest(
84			Slot::from_timestamp(timestamp, self.slot_duration),
85		);
86
87		Ok(Digest { logs: vec![digest_item] })
88	}
89
90	fn append_block_import(
91		&self,
92		_parent: &B::Header,
93		_params: &mut BlockImportParams<B>,
94		_inherents: &InherentData,
95		_proof: StorageProof,
96	) -> Result<(), Error> {
97		Ok(())
98	}
99}