cumulus_pallet_aura_ext/
lib.rs1#![cfg_attr(not(feature = "std"), no_std)]
36
37use frame_support::traits::{ExecuteBlock, FindAuthor};
38use sp_application_crypto::RuntimeAppPublic;
39use sp_consensus_aura::{digests::CompatibleDigestItem, Slot};
40use sp_runtime::traits::{Block as BlockT, Header as HeaderT};
41
42pub mod consensus_hook;
43pub mod migration;
44mod test;
45
46pub use consensus_hook::FixedVelocityConsensusHook;
47
48type Aura<T> = pallet_aura::Pallet<T>;
49
50pub use pallet::*;
51
52#[frame_support::pallet]
53pub mod pallet {
54 use super::*;
55 use frame_support::pallet_prelude::*;
56 use frame_system::pallet_prelude::*;
57
58 #[pallet::config]
60 pub trait Config: pallet_aura::Config + frame_system::Config {}
61
62 #[pallet::pallet]
63 #[pallet::storage_version(migration::STORAGE_VERSION)]
64 pub struct Pallet<T>(_);
65
66 #[pallet::hooks]
67 impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
68 fn on_finalize(_: BlockNumberFor<T>) {
69 Authorities::<T>::put(pallet_aura::Authorities::<T>::get());
71 }
72
73 fn on_initialize(_: BlockNumberFor<T>) -> Weight {
74 Authorities::<T>::get();
76
77 T::DbWeight::get().reads_writes(1, 0)
78 }
79 }
80
81 #[pallet::storage]
87 pub(crate) type Authorities<T: Config> = StorageValue<
88 _,
89 BoundedVec<T::AuthorityId, <T as pallet_aura::Config>::MaxAuthorities>,
90 ValueQuery,
91 >;
92
93 #[pallet::storage]
98 pub(crate) type RelaySlotInfo<T: Config> = StorageValue<_, (Slot, u32), OptionQuery>;
99
100 #[pallet::genesis_config]
101 #[derive(frame_support::DefaultNoBound)]
102 pub struct GenesisConfig<T: Config> {
103 #[serde(skip)]
104 pub _config: core::marker::PhantomData<T>,
105 }
106
107 #[pallet::genesis_build]
108 impl<T: Config> BuildGenesisConfig for GenesisConfig<T> {
109 fn build(&self) {
110 let authorities = pallet_aura::Authorities::<T>::get();
111 Authorities::<T>::put(authorities);
112 }
113 }
114}
115
116pub struct BlockExecutor<T, I>(core::marker::PhantomData<(T, I)>);
121
122impl<Block, T, I> ExecuteBlock<Block> for BlockExecutor<T, I>
123where
124 Block: BlockT,
125 T: Config,
126 I: ExecuteBlock<Block>,
127{
128 fn execute_block(block: Block) {
129 let (mut header, extrinsics) = block.deconstruct();
130 let authorities = Authorities::<T>::get();
133
134 let mut seal = None;
135 header.digest_mut().logs.retain(|s| {
136 let s =
137 CompatibleDigestItem::<<T::AuthorityId as RuntimeAppPublic>::Signature>::as_aura_seal(s);
138 match (s, seal.is_some()) {
139 (Some(_), true) => panic!("Found multiple AuRa seal digests"),
140 (None, _) => true,
141 (Some(s), false) => {
142 seal = Some(s);
143 false
144 },
145 }
146 });
147
148 let seal = seal.expect("Could not find an AuRa seal digest!");
149
150 let author = Aura::<T>::find_author(
151 header.digest().logs().iter().filter_map(|d| d.as_pre_runtime()),
152 )
153 .expect("Could not find AuRa author index!");
154
155 let pre_hash = header.hash();
156
157 if !authorities
158 .get(author as usize)
159 .unwrap_or_else(|| {
160 panic!("Invalid AuRa author index {} for authorities: {:?}", author, authorities)
161 })
162 .verify(&pre_hash, &seal)
163 {
164 panic!("Invalid AuRa seal");
165 }
166
167 I::execute_block(Block::new(header, extrinsics));
168 }
169}