cumulus_pallet_aura_ext/
lib.rs1#![cfg_attr(not(feature = "std"), no_std)]
35
36use frame_support::traits::ExecuteBlock;
37use sp_application_crypto::RuntimeAppPublic;
38use sp_consensus_aura::{
39 digests::{find_pre_digest, take_seal},
40 Slot,
41};
42use sp_runtime::traits::{Block as BlockT, Header as HeaderT, LazyBlock};
43
44pub mod consensus_hook;
45pub mod migration;
46pub mod signature_verifier;
47#[cfg(test)]
48mod test;
49
50pub use consensus_hook::FixedVelocityConsensusHook;
51pub use signature_verifier::AuraSchedulingVerifier;
52
53type Aura<T> = pallet_aura::Pallet<T>;
54
55pub use pallet::*;
56
57#[frame_support::pallet]
58pub mod pallet {
59 use super::*;
60 use frame_support::pallet_prelude::*;
61 use frame_system::pallet_prelude::*;
62
63 #[pallet::config]
65 pub trait Config: pallet_aura::Config + frame_system::Config {}
66
67 #[pallet::pallet]
68 #[pallet::storage_version(migration::STORAGE_VERSION)]
69 pub struct Pallet<T>(_);
70
71 #[pallet::hooks]
72 impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
73 fn on_finalize(_: BlockNumberFor<T>) {
74 Authorities::<T>::put(pallet_aura::Authorities::<T>::get());
76 }
77
78 fn on_initialize(_: BlockNumberFor<T>) -> Weight {
79 Authorities::<T>::get();
81
82 T::DbWeight::get().reads_writes(1, 0)
83 }
84 }
85
86 #[pallet::storage]
92 pub(crate) type Authorities<T: Config> = StorageValue<
93 _,
94 BoundedVec<T::AuthorityId, <T as pallet_aura::Config>::MaxAuthorities>,
95 ValueQuery,
96 >;
97
98 #[pallet::storage]
103 pub(crate) type RelaySlotInfo<T: Config> = StorageValue<_, (Slot, u32), OptionQuery>;
104
105 #[pallet::genesis_config]
106 #[derive(frame_support::DefaultNoBound)]
107 pub struct GenesisConfig<T: Config> {
108 #[serde(skip)]
109 pub _config: core::marker::PhantomData<T>,
110 }
111
112 #[pallet::genesis_build]
113 impl<T: Config> BuildGenesisConfig for GenesisConfig<T> {
114 fn build(&self) {
115 let authorities = pallet_aura::Authorities::<T>::get();
116 Authorities::<T>::put(authorities);
117 }
118 }
119}
120
121pub struct BlockExecutor<T, I>(core::marker::PhantomData<(T, I)>);
126
127impl<Block, T, I> ExecuteBlock<Block> for BlockExecutor<T, I>
128where
129 Block: BlockT,
130 T: Config,
131 I: ExecuteBlock<Block>,
132{
133 fn verify_and_remove_seal(block: &mut <Block as BlockT>::LazyBlock) {
134 let header = block.header_mut();
135 let authorities = Authorities::<T>::get();
138
139 let (_, seal) =
140 take_seal::<<T::AuthorityId as RuntimeAppPublic>::Signature>(header.digest_mut())
141 .unwrap_or_else(|e| panic!("Invalid AuRa seal: {e:?}"));
142
143 let slot = find_pre_digest(header.digest())
144 .unwrap_or_else(|e| panic!("Invalid AuRa pre-digest: {e:?}"));
145
146 let author = Aura::<T>::slot_author_index(slot).expect("Could not find AuRa author index!");
147
148 let pre_hash = header.hash();
149
150 if !authorities
151 .get(author as usize)
152 .unwrap_or_else(|| {
153 panic!("Invalid AuRa author index {} for authorities: {:?}", author, authorities)
154 })
155 .verify(&pre_hash, &seal)
156 {
157 panic!("Invalid AuRa seal");
158 }
159 }
160
161 fn execute_verified_block(block: Block::LazyBlock) {
162 I::execute_verified_block(block);
163 }
164}