-
Notifications
You must be signed in to change notification settings - Fork 379
aura-ext: check slot in consensus hook and remove all CheckInherents
logic
#2658
Changes from all commits
9751951
3bf8776
10b9a81
68eb7e1
1dcf3f0
bc8e7bb
2a10bdf
76065bd
f1cbacd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,28 +19,51 @@ | |
//! | ||
//! The velocity `V` refers to the rate of block processing by the relay chain. | ||
|
||
use super::pallet; | ||
use super::{pallet, Aura}; | ||
use cumulus_pallet_parachain_system::{ | ||
consensus_hook::{ConsensusHook, UnincludedSegmentCapacity}, | ||
relay_state_snapshot::RelayChainStateProof, | ||
}; | ||
use frame_support::pallet_prelude::*; | ||
use sp_consensus_aura::{Slot, SlotDuration}; | ||
use sp_std::{marker::PhantomData, num::NonZeroU32}; | ||
|
||
const MILLIS_PER_SECOND: u64 = 1000; | ||
|
||
/// A consensus hook for a fixed block processing velocity and unincluded segment capacity. | ||
pub struct FixedVelocityConsensusHook<T, const V: u32, const C: u32>(PhantomData<T>); | ||
/// | ||
/// Relay chain slot duration must be provided in seconds. | ||
pub struct FixedVelocityConsensusHook< | ||
T, | ||
const RELAY_CHAIN_SLOT_DURATION: u32, | ||
const V: u32, | ||
const C: u32, | ||
>(PhantomData<T>); | ||
|
||
impl<T: pallet::Config, const V: u32, const C: u32> ConsensusHook | ||
for FixedVelocityConsensusHook<T, V, C> | ||
impl<T: pallet::Config, const RELAY_CHAIN_SLOT_DURATION: u32, const V: u32, const C: u32> | ||
ConsensusHook for FixedVelocityConsensusHook<T, RELAY_CHAIN_SLOT_DURATION, V, C> | ||
where | ||
<T as pallet_timestamp::Config>::Moment: Into<u64>, | ||
{ | ||
// Validates the number of authored blocks within the slot with respect to the `V + 1` limit. | ||
fn on_state_proof(_state_proof: &RelayChainStateProof) -> (Weight, UnincludedSegmentCapacity) { | ||
fn on_state_proof(state_proof: &RelayChainStateProof) -> (Weight, UnincludedSegmentCapacity) { | ||
// Ensure velocity is non-zero. | ||
let velocity = V.max(1); | ||
let relay_chain_slot = state_proof.read_slot().expect("failed to read relay chain slot"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What happens here if the collator isn't up to date with the latest relay block? I think a "slot number mismatch" would occur. Right now it seems that collation is still triggered by new incoming relay blocks, so the scenario I described won't occur. But my understanding is that we will want to unteather these. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe the state proof comes from the relay parent the para is building on top of. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's right - the parachain has no information about what the latest relay-parent is, other than what the collator gives it. But validators will only accept blocks with recent relay-parents. |
||
|
||
let authored = pallet::Pallet::<T>::slot_info() | ||
.map(|(_slot, authored)| authored) | ||
let (slot, authored) = pallet::Pallet::<T>::slot_info() | ||
.expect("slot info is inserted on block initialization"); | ||
Comment on lines
+54
to
55
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @rphmeier There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would guess that it's most likely the case that blocks built in tests don't contain the pre-runtime digest which sets the slot in |
||
|
||
// Convert relay chain timestamp. | ||
let relay_chain_timestamp = u64::from(RELAY_CHAIN_SLOT_DURATION) | ||
.saturating_mul(*relay_chain_slot) | ||
.saturating_mul(MILLIS_PER_SECOND); | ||
let para_slot_duration = SlotDuration::from_millis(Aura::<T>::slot_duration().into()); | ||
let para_slot_from_relay = | ||
Slot::from_timestamp(relay_chain_timestamp.into(), para_slot_duration); | ||
|
||
// Perform checks. | ||
assert_eq!(slot, para_slot_from_relay, "slot number mismatch"); | ||
if authored > velocity + 1 { | ||
panic!("authored blocks limit is reached for the slot") | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aura::slot_duration
returnsT::Moment
with a definitionAnd
SlotDuration
cannot be built out of it.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are workarounds - what have you tried?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couldn't come up with any other way. Ideally, I would expect
Aura::slot_duration
to returnSlotDuration
.As you can see from the type definition, it's not convertible to any numeric primitive, so we have to enforce it in boundary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's reasonable to enforce it in the boundary as long as that aligns with the instantiations that are typically used in runtime declarations. Seems like a good solution to me.