mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 01:11:10 +00:00
Return babe configuration information in the babe api epoch functions (#8072)
* Make changes * Add serialize/deserialize, copy babe epoch config defaults from node runtime * Fix line widths and turn default features off for serde * Remove ser/deser from Epoch, fix node-cli * Apply suggestions * Add comment to BABE_GENESIS_EPOCH_CONFIG in bin * Apply suggestions * Add a sketchy migration function * Add a migration test * Check for PendingEpochConfigChange as well * Make epoch_config in node-cli * Move updating EpochConfig out of the if * Fix executor tests * Calculate weight for add_epoch_configurations * Fix babe test * Apply suggestions from code review Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> * Add more asserts to tests, remove unused changes to primitives/slots * Allow setting the migration pallet prefix * Rename to BabePalletPrefix Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com>
This commit is contained in:
@@ -42,7 +42,8 @@ use sp_timestamp::OnTimestampSet;
|
||||
|
||||
use sp_consensus_babe::{
|
||||
digests::{NextConfigDescriptor, NextEpochDescriptor, PreDigest},
|
||||
BabeAuthorityWeight, ConsensusLog, Epoch, EquivocationProof, Slot, BABE_ENGINE_ID,
|
||||
BabeAuthorityWeight, BabeEpochConfiguration, ConsensusLog, Epoch,
|
||||
EquivocationProof, Slot, BABE_ENGINE_ID,
|
||||
};
|
||||
use sp_consensus_vrf::schnorrkel;
|
||||
|
||||
@@ -187,8 +188,8 @@ decl_storage! {
|
||||
// variable to its underlying value.
|
||||
pub Randomness get(fn randomness): schnorrkel::Randomness;
|
||||
|
||||
/// Next epoch configuration, if changed.
|
||||
NextEpochConfig: Option<NextConfigDescriptor>;
|
||||
/// Pending epoch configuration change that will be applied when the next epoch is enacted.
|
||||
PendingEpochConfigChange: Option<NextConfigDescriptor>;
|
||||
|
||||
/// Next epoch randomness.
|
||||
NextRandomness: schnorrkel::Randomness;
|
||||
@@ -225,10 +226,21 @@ decl_storage! {
|
||||
/// on block finalization. Querying this storage entry outside of block
|
||||
/// execution context should always yield zero.
|
||||
Lateness get(fn lateness): T::BlockNumber;
|
||||
|
||||
/// The configuration for the current epoch. Should never be `None` as it is initialized in genesis.
|
||||
EpochConfig: Option<BabeEpochConfiguration>;
|
||||
|
||||
/// The configuration for the next epoch, `None` if the config will not change
|
||||
/// (you can fallback to `EpochConfig` instead in that case).
|
||||
NextEpochConfig: Option<BabeEpochConfiguration>;
|
||||
}
|
||||
add_extra_genesis {
|
||||
config(authorities): Vec<(AuthorityId, BabeAuthorityWeight)>;
|
||||
build(|config| Module::<T>::initialize_authorities(&config.authorities))
|
||||
config(epoch_config): Option<BabeEpochConfiguration>;
|
||||
build(|config| {
|
||||
Module::<T>::initialize_authorities(&config.authorities);
|
||||
EpochConfig::put(config.epoch_config.clone().expect("epoch_config must not be None"));
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -326,7 +338,7 @@ decl_module! {
|
||||
config: NextConfigDescriptor,
|
||||
) {
|
||||
ensure_root(origin)?;
|
||||
NextEpochConfig::put(config);
|
||||
PendingEpochConfigChange::put(config);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -490,8 +502,16 @@ impl<T: Config> Module<T> {
|
||||
};
|
||||
Self::deposit_consensus(ConsensusLog::NextEpochData(next_epoch));
|
||||
|
||||
if let Some(next_config) = NextEpochConfig::take() {
|
||||
Self::deposit_consensus(ConsensusLog::NextConfigData(next_config));
|
||||
if let Some(next_config) = NextEpochConfig::get() {
|
||||
EpochConfig::put(next_config);
|
||||
}
|
||||
|
||||
if let Some(pending_epoch_config_change) = PendingEpochConfigChange::take() {
|
||||
let next_epoch_config: BabeEpochConfiguration =
|
||||
pending_epoch_config_change.clone().into();
|
||||
NextEpochConfig::put(next_epoch_config);
|
||||
|
||||
Self::deposit_consensus(ConsensusLog::NextConfigData(pending_epoch_config_change));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -510,6 +530,7 @@ impl<T: Config> Module<T> {
|
||||
duration: T::EpochDuration::get(),
|
||||
authorities: Self::authorities(),
|
||||
randomness: Self::randomness(),
|
||||
config: EpochConfig::get().expect("EpochConfig is initialized in genesis; we never `take` or `kill` it; qed"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -527,6 +548,9 @@ impl<T: Config> Module<T> {
|
||||
duration: T::EpochDuration::get(),
|
||||
authorities: NextAuthorities::get(),
|
||||
randomness: NextRandomness::get(),
|
||||
config: NextEpochConfig::get().unwrap_or_else(|| {
|
||||
EpochConfig::get().expect("EpochConfig is initialized in genesis; we never `take` or `kill` it; qed")
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -835,3 +859,49 @@ fn compute_randomness(
|
||||
|
||||
sp_io::hashing::blake2_256(&s)
|
||||
}
|
||||
|
||||
pub mod migrations {
|
||||
use super::*;
|
||||
use frame_support::pallet_prelude::{ValueQuery, StorageValue};
|
||||
|
||||
/// Something that can return the storage prefix of the `Babe` pallet.
|
||||
pub trait BabePalletPrefix: Config {
|
||||
fn pallet_prefix() -> &'static str;
|
||||
}
|
||||
|
||||
struct __OldNextEpochConfig<T>(sp_std::marker::PhantomData<T>);
|
||||
impl<T: BabePalletPrefix> frame_support::traits::StorageInstance for __OldNextEpochConfig<T> {
|
||||
fn pallet_prefix() -> &'static str { T::pallet_prefix() }
|
||||
const STORAGE_PREFIX: &'static str = "NextEpochConfig";
|
||||
}
|
||||
|
||||
type OldNextEpochConfig<T> = StorageValue<
|
||||
__OldNextEpochConfig<T>, Option<NextConfigDescriptor>, ValueQuery
|
||||
>;
|
||||
|
||||
/// A storage migration that adds the current epoch configuration for Babe
|
||||
/// to storage.
|
||||
pub fn add_epoch_configuration<T: BabePalletPrefix>(
|
||||
epoch_config: BabeEpochConfiguration,
|
||||
) -> Weight {
|
||||
let mut writes = 0;
|
||||
let mut reads = 0;
|
||||
|
||||
if let Some(pending_change) = OldNextEpochConfig::<T>::get() {
|
||||
PendingEpochConfigChange::put(pending_change);
|
||||
|
||||
writes += 1;
|
||||
}
|
||||
|
||||
reads += 1;
|
||||
|
||||
OldNextEpochConfig::<T>::kill();
|
||||
|
||||
EpochConfig::put(epoch_config.clone());
|
||||
NextEpochConfig::put(epoch_config);
|
||||
|
||||
writes += 3;
|
||||
|
||||
T::DbWeight::get().writes(writes) + T::DbWeight::get().reads(reads)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ use frame_support::{
|
||||
};
|
||||
use mock::*;
|
||||
use pallet_session::ShouldEndSession;
|
||||
use sp_consensus_babe::{AllowedSlots, Slot};
|
||||
use sp_consensus_babe::{AllowedSlots, Slot, BabeEpochConfiguration};
|
||||
use sp_core::crypto::Pair;
|
||||
|
||||
const EMPTY_RANDOMNESS: [u8; 32] = [
|
||||
@@ -231,11 +231,31 @@ fn can_enact_next_config() {
|
||||
assert_eq!(Babe::epoch_index(), 0);
|
||||
go_to_block(2, 7);
|
||||
|
||||
let current_config = BabeEpochConfiguration {
|
||||
c: (0, 4),
|
||||
allowed_slots: sp_consensus_babe::AllowedSlots::PrimarySlots,
|
||||
};
|
||||
|
||||
let next_config = BabeEpochConfiguration {
|
||||
c: (1, 4),
|
||||
allowed_slots: sp_consensus_babe::AllowedSlots::PrimarySlots,
|
||||
};
|
||||
|
||||
let next_next_config = BabeEpochConfiguration {
|
||||
c: (2, 4),
|
||||
allowed_slots: sp_consensus_babe::AllowedSlots::PrimarySlots,
|
||||
};
|
||||
|
||||
EpochConfig::put(current_config);
|
||||
NextEpochConfig::put(next_config.clone());
|
||||
|
||||
assert_eq!(NextEpochConfig::get(), Some(next_config.clone()));
|
||||
|
||||
Babe::plan_config_change(
|
||||
Origin::root(),
|
||||
NextConfigDescriptor::V1 {
|
||||
c: (1, 4),
|
||||
allowed_slots: AllowedSlots::PrimarySlots,
|
||||
c: next_next_config.c,
|
||||
allowed_slots: next_next_config.allowed_slots,
|
||||
},
|
||||
).unwrap();
|
||||
|
||||
@@ -243,10 +263,13 @@ fn can_enact_next_config() {
|
||||
Babe::on_finalize(9);
|
||||
let header = System::finalize();
|
||||
|
||||
assert_eq!(EpochConfig::get(), Some(next_config));
|
||||
assert_eq!(NextEpochConfig::get(), Some(next_next_config.clone()));
|
||||
|
||||
let consensus_log = sp_consensus_babe::ConsensusLog::NextConfigData(
|
||||
sp_consensus_babe::digests::NextConfigDescriptor::V1 {
|
||||
c: (1, 4),
|
||||
allowed_slots: AllowedSlots::PrimarySlots,
|
||||
NextConfigDescriptor::V1 {
|
||||
c: next_next_config.c,
|
||||
allowed_slots: next_next_config.allowed_slots,
|
||||
}
|
||||
);
|
||||
let consensus_digest = DigestItem::Consensus(BABE_ENGINE_ID, consensus_log.encode());
|
||||
@@ -291,6 +314,11 @@ fn only_root_can_enact_config_change() {
|
||||
#[test]
|
||||
fn can_fetch_current_and_next_epoch_data() {
|
||||
new_test_ext(5).execute_with(|| {
|
||||
EpochConfig::put(BabeEpochConfiguration {
|
||||
c: (1, 4),
|
||||
allowed_slots: sp_consensus_babe::AllowedSlots::PrimarySlots,
|
||||
});
|
||||
|
||||
// genesis authorities should be used for the first and second epoch
|
||||
assert_eq!(
|
||||
Babe::current_epoch().authorities,
|
||||
@@ -809,3 +837,54 @@ fn valid_equivocation_reports_dont_pay_fees() {
|
||||
assert_eq!(post_info.pays_fee, Pays::Yes);
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn add_epoch_configurations_migration_works() {
|
||||
use frame_support::storage::migration::{
|
||||
put_storage_value, get_storage_value,
|
||||
};
|
||||
|
||||
impl crate::migrations::BabePalletPrefix for Test {
|
||||
fn pallet_prefix() -> &'static str {
|
||||
"Babe"
|
||||
}
|
||||
}
|
||||
|
||||
new_test_ext(1).execute_with(|| {
|
||||
let next_config_descriptor = NextConfigDescriptor::V1 {
|
||||
c: (3, 4),
|
||||
allowed_slots: AllowedSlots::PrimarySlots
|
||||
};
|
||||
|
||||
put_storage_value(
|
||||
b"Babe",
|
||||
b"NextEpochConfig",
|
||||
&[],
|
||||
Some(next_config_descriptor.clone())
|
||||
);
|
||||
|
||||
assert!(get_storage_value::<Option<NextConfigDescriptor>>(
|
||||
b"Babe",
|
||||
b"NextEpochConfig",
|
||||
&[],
|
||||
).is_some());
|
||||
|
||||
let current_epoch = BabeEpochConfiguration {
|
||||
c: (1, 4),
|
||||
allowed_slots: sp_consensus_babe::AllowedSlots::PrimarySlots,
|
||||
};
|
||||
|
||||
crate::migrations::add_epoch_configuration::<Test>(
|
||||
current_epoch.clone()
|
||||
);
|
||||
|
||||
assert!(get_storage_value::<Option<NextConfigDescriptor>>(
|
||||
b"Babe",
|
||||
b"NextEpochConfig",
|
||||
&[],
|
||||
).is_none());
|
||||
|
||||
assert_eq!(EpochConfig::get(), Some(current_epoch));
|
||||
assert_eq!(PendingEpochConfigChange::get(), Some(next_config_descriptor));
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user