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

aura-ext: limit the number of authored blocks per slot #2551

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

44 changes: 44 additions & 0 deletions pallets/aura-ext/src/consensus_hook.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright 2023 Parity Technologies (UK) Ltd.
// This file is part of Cumulus.

// Cumulus is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Cumulus is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Cumulus. If not, see <http://www.gnu.org/licenses/>.

//! The definition of a [`FixedVelocityConsensusHook`] for consensus logic to manage
//! block velocity.
//!
//! The velocity `V` refers to the rate of block processing by the relay chain.

use super::pallet;
use frame_support::pallet_prelude::*;
use sp_std::marker::PhantomData;

/// A consensus hook for a fixed block processing velocity.
slumber marked this conversation as resolved.
Show resolved Hide resolved
pub struct FixedVelocityConsensusHook<T, const V: u32, const C: u32>(PhantomData<T>);

impl<T: pallet::Config, const V: u32, const C: u32> FixedVelocityConsensusHook<T, V, C> {
/// Validates the number of authored blocks within the slot with respect to the `V + 1` limit.
pub fn validate_slot() -> Weight {
slumber marked this conversation as resolved.
Show resolved Hide resolved
// Ensure velocity is non-zero.
let velocity = V.max(1);

let authored = pallet::Pallet::<T>::slot_info()
.map(|(_slot, authored)| authored)
.expect("slot info is inserted on block initialization");
if authored > velocity + 1 {
panic!("authored blocks limit is reached for the slot")
}

T::DbWeight::get().reads(1)
}
}
25 changes: 24 additions & 1 deletion pallets/aura-ext/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,12 @@

use frame_support::traits::{ExecuteBlock, FindAuthor};
use sp_application_crypto::RuntimeAppPublic;
use sp_consensus_aura::digests::CompatibleDigestItem;
use sp_consensus_aura::{digests::CompatibleDigestItem, Slot};
use sp_runtime::traits::{Block as BlockT, Header as HeaderT};

pub mod consensus_hook;
pub use consensus_hook::FixedVelocityConsensusHook;

type Aura<T> = pallet_aura::Pallet<T>;

pub use pallet::*;
Expand Down Expand Up @@ -68,6 +71,19 @@ pub mod pallet {
// Fetch the authorities once to get them into the storage proof of the PoV.
Authorities::<T>::get();

let new_slot = Aura::<T>::current_slot();

let (new_slot, authored) = match SlotInfo::<T>::get() {
slumber marked this conversation as resolved.
Show resolved Hide resolved
Some((slot, authored)) if slot == new_slot => (slot, authored + 1),
Some((slot, _)) if slot < new_slot => (new_slot, 1),
Some(..) => {
panic!("slot moved backwards")
},
None => (new_slot, 1),
};

SlotInfo::<T>::put((new_slot, authored));

T::DbWeight::get().reads_writes(2, 1)
}
}
Expand All @@ -84,6 +100,13 @@ pub mod pallet {
ValueQuery,
>;

/// Current slot paired with a number of authored blocks.
///
/// Updated on each block initialization.
#[pallet::storage]
#[pallet::getter(fn slot_info)]
pub(crate) type SlotInfo<T: Config> = StorageValue<_, (Slot, u32), OptionQuery>;

#[pallet::genesis_config]
#[derive(Default)]
pub struct GenesisConfig;
Expand Down
2 changes: 2 additions & 0 deletions pallets/parachain-system/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ xcm = { git = "https://github.com/paritytech/polkadot", default-features = false
cumulus-pallet-parachain-system-proc-macro = { path = "proc-macro", default-features = false }
cumulus-primitives-core = { path = "../../primitives/core", default-features = false }
cumulus-primitives-parachain-inherent = { path = "../../primitives/parachain-inherent", default-features = false }
cumulus-pallet-aura-ext = { path = "../aura-ext", default-features = false }
slumber marked this conversation as resolved.
Show resolved Hide resolved

[dev-dependencies]
assert_matches = "1.5"
Expand All @@ -60,6 +61,7 @@ std = [
"cumulus-pallet-parachain-system-proc-macro/std",
"cumulus-primitives-core/std",
"cumulus-primitives-parachain-inherent/std",
"cumulus-pallet-aura-ext/std",
"frame-support/std",
"frame-system/std",
"sp-core/std",
Expand Down
14 changes: 14 additions & 0 deletions pallets/parachain-system/src/consensus_hook.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
use super::relay_state_snapshot::RelayChainStateProof;
use sp_std::num::NonZeroU32;

use cumulus_pallet_aura_ext::{consensus_hook as aura_consensus_hook, pallet as pallet_aura_ext};

/// The possible capacity of the unincluded segment.
#[derive(Clone)]
pub struct UnincludedSegmentCapacity(UnincludedSegmentCapacityInner);
Expand Down Expand Up @@ -100,3 +102,15 @@ impl<const N: u32> ConsensusHook for FixedCapacityUnincludedSegment<N> {
///
/// This is a simple type alias around a fixed-capacity unincluded segment with a size of 1.
pub type RequireParentIncluded = FixedCapacityUnincludedSegment<1>;

impl<T: pallet_aura_ext::Config, const V: u32, const C: u32> ConsensusHook
for aura_consensus_hook::FixedVelocityConsensusHook<T, V, C>
{
fn on_state_proof(_state_proof: &RelayChainStateProof) -> UnincludedSegmentCapacity {
Self::validate_slot();
slumber marked this conversation as resolved.
Show resolved Hide resolved

NonZeroU32::new(sp_std::cmp::max(C, 1))
.expect("1 is the minimum value and non-zero; qed")
.into()
}
}