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

Return babe configuration information in the babe api epoch functions #8072

Merged
26 commits merged into from
Mar 10, 2021
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
120fc30
Make changes
expenses Feb 17, 2021
4cbac3e
Add serialize/deserialize, copy babe epoch config defaults from node …
expenses Feb 17, 2021
cb22034
Fix line widths and turn default features off for serde
expenses Feb 17, 2021
a85fdcd
Remove ser/deser from Epoch, fix node-cli
expenses Feb 17, 2021
2617aaf
Merge remote-tracking branch 'origin/master' into ashley-standalone-e…
expenses Feb 18, 2021
b1b589f
Merge remote-tracking branch 'origin/master' into ashley-standalone-e…
expenses Feb 22, 2021
11826f0
Apply suggestions
expenses Feb 22, 2021
f16980a
Merge remote-tracking branch 'origin/master' into ashley-standalone-e…
expenses Feb 22, 2021
6c920d6
Add comment to BABE_GENESIS_EPOCH_CONFIG in bin
expenses Feb 23, 2021
099673a
Apply suggestions
expenses Feb 24, 2021
f5d3b18
Add a sketchy migration function
expenses Feb 24, 2021
44ad4ff
Add a migration test
expenses Feb 24, 2021
8d9cecb
Check for PendingEpochConfigChange as well
expenses Feb 24, 2021
a339dfe
Make epoch_config in node-cli
expenses Feb 25, 2021
fed698d
Move updating EpochConfig out of the if
expenses Feb 25, 2021
e1e3e16
Merge remote-tracking branch 'origin/master' into ashley-standalone-e…
expenses Feb 25, 2021
5834911
Fix executor tests
expenses Feb 25, 2021
a06fb96
Calculate weight for add_epoch_configurations
expenses Mar 1, 2021
7fd659f
Fix babe test
expenses Mar 1, 2021
4bd651f
Merge remote-tracking branch 'origin/master' into ashley-standalone-e…
expenses Mar 1, 2021
bdfe039
Apply suggestions from code review
expenses Mar 3, 2021
74fbbb4
Add more asserts to tests, remove unused changes to primitives/slots
expenses Mar 3, 2021
8b9a2af
Merge remote-tracking branch 'origin/master' into ashley-standalone-e…
expenses Mar 3, 2021
a49a87f
Allow setting the migration pallet prefix
expenses Mar 9, 2021
cec8f99
Merge remote-tracking branch 'origin/master' into ashley-standalone-e…
expenses Mar 9, 2021
35ff1cf
Rename to BabePalletPrefix
expenses Mar 9, 2021
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.

1 change: 1 addition & 0 deletions bin/node/cli/src/chain_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@ pub fn testnet_genesis(
},
pallet_babe: BabeConfig {
authorities: vec![],
epoch_config: Some(node_runtime::BABE_GENESIS_EPOCH_CONFIG),
},
pallet_im_online: ImOnlineConfig {
keys: vec![],
Expand Down
11 changes: 9 additions & 2 deletions bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,13 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
transaction_version: 2,
};

/// The BABE epoch configuration at genesis.
pub const BABE_GENESIS_EPOCH_CONFIG: sp_consensus_babe::BabeEpochConfiguration =
sp_consensus_babe::BabeEpochConfiguration {
c: PRIMARY_PROBABILITY,
allowed_slots: sp_consensus_babe::AllowedSlots::PrimaryAndSecondaryPlainSlots
};

/// Native version.
#[cfg(any(feature = "std", test))]
pub fn native_version() -> NativeVersion {
Expand Down Expand Up @@ -1272,10 +1279,10 @@ impl_runtime_apis! {
sp_consensus_babe::BabeGenesisConfiguration {
slot_duration: Babe::slot_duration(),
epoch_length: EpochDuration::get(),
c: PRIMARY_PROBABILITY,
c: BABE_GENESIS_EPOCH_CONFIG.c,
genesis_authorities: Babe::authorities(),
randomness: Babe::randomness(),
allowed_slots: sp_consensus_babe::AllowedSlots::PrimaryAndSecondaryPlainSlots,
allowed_slots: BABE_GENESIS_EPOCH_CONFIG.allowed_slots,
}
}

Expand Down
7 changes: 5 additions & 2 deletions bin/node/testing/src/genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use sp_keyring::{Ed25519Keyring, Sr25519Keyring};
use node_runtime::{
GenesisConfig, BalancesConfig, SessionConfig, StakingConfig, SystemConfig,
GrandpaConfig, IndicesConfig, ContractsConfig, SocietyConfig, wasm_binary_unwrap,
AccountId, StakerStatus,
AccountId, StakerStatus, BabeConfig, BABE_GENESIS_EPOCH_CONFIG,
};
use node_runtime::constants::currency::*;
use sp_core::ChangesTrieConfiguration;
Expand Down Expand Up @@ -100,7 +100,10 @@ pub fn config_endowed(
pallet_contracts: ContractsConfig {
current_schedule: Default::default(),
},
pallet_babe: Default::default(),
pallet_babe: BabeConfig {
authorities: vec![],
epoch_config: Some(BABE_GENESIS_EPOCH_CONFIG),
},
pallet_grandpa: GrandpaConfig {
authorities: vec![],
},
Expand Down
1 change: 1 addition & 0 deletions client/consensus/babe/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,7 @@ async fn answer_requests<B: BlockT, C>(
duration: viable_epoch.as_ref().duration,
authorities: viable_epoch.as_ref().authorities.clone(),
randomness: viable_epoch.as_ref().randomness,
config: viable_epoch.as_ref().config.clone(),
})
};

Expand Down
81 changes: 74 additions & 7 deletions frame/babe/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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"));
})
}
}

Expand Down Expand Up @@ -326,7 +338,7 @@ decl_module! {
config: NextConfigDescriptor,
) {
ensure_root(origin)?;
NextEpochConfig::put(config);
PendingEpochConfigChange::put(config);
}
}
}
Expand Down Expand Up @@ -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));
}
}

Expand All @@ -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"),
}
}

Expand All @@ -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")
}),
}
}

Expand Down Expand Up @@ -835,3 +859,46 @@ fn compute_randomness(

sp_io::hashing::blake2_256(&s)
}

pub mod migrations {
use super::*;
use frame_support::pallet_prelude::{ValueQuery, StorageValue};

pub trait HasPalletPrefix: Config {
expenses marked this conversation as resolved.
Show resolved Hide resolved
fn pallet_prefix() -> &'static str;
}

struct __OldNextEpochConfig<T>(sp_std::marker::PhantomData<T>);
impl<T: HasPalletPrefix> 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
>;

pub fn add_epoch_configuration<T: HasPalletPrefix>(
expenses marked this conversation as resolved.
Show resolved Hide resolved
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)
}
}
91 changes: 85 additions & 6 deletions frame/babe/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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] = [
Expand Down Expand Up @@ -231,22 +231,45 @@ 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();

progress_to_block(4);
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());
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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::HasPalletPrefix for Test {
fn pallet_prefix() -> &'static str {
"BabeApi"
}
}

new_test_ext(1).execute_with(|| {
let next_config_descriptor = NextConfigDescriptor::V1 {
c: (3, 4),
allowed_slots: AllowedSlots::PrimarySlots
};

put_storage_value(
b"BabeApi",
b"NextEpochConfig",
&[],
Some(next_config_descriptor.clone())
);

assert!(get_storage_value::<Option<NextConfigDescriptor>>(
b"BabeApi",
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"BabeApi",
b"NextEpochConfig",
&[],
).is_none());

assert_eq!(EpochConfig::get(), Some(current_epoch));
assert_eq!(PendingEpochConfigChange::get(), Some(next_config_descriptor));
});
}
2 changes: 2 additions & 0 deletions primitives/consensus/babe/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ sp-inherents = { version = "3.0.0", default-features = false, path = "../../inhe
sp-keystore = { version = "0.9.0", default-features = false, path = "../../keystore", optional = true }
sp-runtime = { version = "3.0.0", default-features = false, path = "../../runtime" }
sp-timestamp = { version = "3.0.0", default-features = false, path = "../../timestamp" }
serde = { version = "1.0.123", features = ["derive"], optional = true }

[features]
default = ["std"]
Expand All @@ -43,4 +44,5 @@ std = [
"sp-keystore",
"sp-runtime/std",
"sp-timestamp/std",
"serde",
]
6 changes: 6 additions & 0 deletions primitives/consensus/babe/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ pub use sp_consensus_vrf::schnorrkel::{

use codec::{Decode, Encode};
#[cfg(feature = "std")]
use serde::{Serialize, Deserialize};
#[cfg(feature = "std")]
use sp_keystore::vrf::{VRFTranscriptData, VRFTranscriptValue};
use sp_runtime::{traits::Header, ConsensusEngineId, RuntimeDebug};
use sp_std::vec::Vec;
Expand Down Expand Up @@ -216,6 +218,7 @@ pub struct BabeGenesisConfiguration {

/// Types of allowed slots.
#[derive(Clone, Copy, PartialEq, Eq, Encode, Decode, RuntimeDebug)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub enum AllowedSlots {
/// Only allow primary slots.
PrimarySlots,
Expand Down Expand Up @@ -248,6 +251,7 @@ impl sp_consensus::SlotData for BabeGenesisConfiguration {

/// Configuration data used by the BABE consensus engine.
#[derive(Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct BabeEpochConfiguration {
/// A constant value that is used in the threshold calculation formula.
/// Expressed as a rational where the first member of the tuple is the
Expand Down Expand Up @@ -362,6 +366,8 @@ pub struct Epoch {
pub authorities: Vec<(AuthorityId, BabeAuthorityWeight)>,
/// Randomness for this epoch.
pub randomness: [u8; VRF_OUTPUT_LENGTH],
/// Configuration of the epoch.
pub config: BabeEpochConfiguration,
}

sp_api::decl_runtime_apis! {
Expand Down