Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
9062f94
value ranges in consensus cache
svyatonik Aug 2, 2019
ce451c3
skip values in cache
svyatonik Aug 2, 2019
2efc6a4
read epoch0 + epoch1 data from genesis in babe
svyatonik Aug 2, 2019
d9d75bc
sync authorities + session validators at genesis
svyatonik Aug 4, 2019
aa491d0
removed some debug printlns
svyatonik Aug 4, 2019
de097ee
fixed cache encoding
svyatonik Aug 5, 2019
4bbebde
Revert "skip values in cache"
svyatonik Aug 5, 2019
2897a83
Revert "value ranges in consensus cache"
svyatonik Aug 5, 2019
2c72a87
get rid of cache::AUTHORITIES in Babe
svyatonik Aug 5, 2019
1c7b2cd
cleaning up
svyatonik Aug 5, 2019
cb2851f
cleaning up
svyatonik Aug 5, 2019
e5c7bd8
update spec version
svyatonik Aug 5, 2019
a838e9b
lost changes
svyatonik Aug 5, 2019
200a638
fixed tests
svyatonik Aug 5, 2019
3c420ff
Merge branch 'master' into fix_flaming_fir_light_sync
svyatonik Aug 5, 2019
c4c6788
Update node/runtime/src/lib.rs
svyatonik Aug 6, 2019
04f73d5
Merge branch 'master' into fix_flaming_fir_light_sync
svyatonik Aug 6, 2019
f30f0fb
fix once-per-block condition
svyatonik Aug 6, 2019
773982b
fix standalone babe + temp_storage in BuildGenesis
svyatonik Aug 6, 2019
c922fad
fix benhes compilation
svyatonik Aug 6, 2019
69fe38a
fixed comment
svyatonik Aug 6, 2019
b5e223e
Merge branch 'master' into fix_flaming_fir_light_sync
svyatonik Aug 8, 2019
54fd261
Merge branch 'master' into fix_flaming_fir_light_sync
svyatonik Aug 12, 2019
5991212
re-added light nodes to integration tests
svyatonik Aug 12, 2019
d24bb0b
Merge branch 'master' into fix_flaming_fir_light_sync
Demi-Marie Aug 14, 2019
51b79fc
finalize_with_ancestors from extra_requests
svyatonik Aug 14, 2019
651d8ad
Merge branch 'fix_flaming_fir_light_sync' of https://github.com/parit…
svyatonik Aug 14, 2019
8f106ae
post-merge fix
svyatonik Aug 14, 2019
b4dd1bd
aaand removed debug code
svyatonik Aug 14, 2019
d593290
(another one)
svyatonik Aug 14, 2019
a7adc1c
fix warn in logs (do not call ForkTree::finalize twice for the same b…
svyatonik Aug 14, 2019
707b288
sync digest.next_authorities with actual next authorities
svyatonik Aug 14, 2019
f1d0e41
more docs
svyatonik Aug 15, 2019
515587c
Merge branch 'master' into fix_flaming_fir_light_sync
svyatonik Aug 15, 2019
b328acb
reverting all commits affecting storage
svyatonik Aug 16, 2019
4786ea7
Merge branch 'master' into fix_flaming_fir_light_sync
svyatonik Aug 16, 2019
e33fd0f
also remove keys from babe trait
svyatonik Aug 16, 2019
e7644e4
fixed warnings
svyatonik Aug 16, 2019
f70bbcc
Merge branch 'master' into fix_flaming_fir_light_sync
svyatonik Aug 16, 2019
89447ee
post-merge fixes
svyatonik Aug 16, 2019
320534d
reverted some redundant changes
svyatonik Aug 16, 2019
5bf8db9
reverted more changes
svyatonik Aug 16, 2019
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
Prev Previous commit
Next Next commit
sync authorities + session validators at genesis
  • Loading branch information
svyatonik committed Aug 4, 2019
commit d9d75bc8e4696b810685760daef952b315f14c57
24 changes: 9 additions & 15 deletions core/consensus/babe/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,10 +255,8 @@ impl<Hash, H, B, C, E, I, Error, SO> SlotWorker<B> for BabeWorker<C, E, I, SO> w
let (timestamp, slot_number, slot_duration) =
(slot_info.timestamp, slot_info.number, slot_info.duration);

// we assume that the SlotWorker only works in environment that has no consensus cache (on full nodes)
// => we always expect a regular epoch entry here
let regular_epoch = epoch(client.as_ref(), &BlockId::Hash(chain_head.hash()))
.and_then(|epoch| epoch.into_regular().ok_or(consensus_common::Error::InvalidAuthoritiesSet));
let regular_epoch = epoch_from_runtime(client.as_ref(), &BlockId::Hash(chain_head.hash()))
.ok_or(consensus_common::Error::InvalidAuthoritiesSet);

let epoch = match regular_epoch {
Ok(epoch) => epoch,
Expand Down Expand Up @@ -322,7 +320,7 @@ impl<Hash, H, B, C, E, I, Error, SO> SlotWorker<B> for BabeWorker<C, E, I, SO> w
return Box::pin(future::ready(Ok(())))
}
};

println!("=== Babe.OnSlot: {}", slot_number);
let inherent_digest = BabePreDigest {
vrf_proof,
vrf_output: inout.to_output(),
Expand Down Expand Up @@ -1078,7 +1076,7 @@ impl<B, E, Block, I, RA, PRA> BlockImport<Block> for BabeBlockImport<B, E, Block
&is_descendent_of,
&|epoch| epoch.start_slot <= slot_number,
).map_err(|e| ConsensusError::from(ConsensusError::ClientImport(e.to_string())))?;

println!("=== Babe.ImportBlock.slot={} enacted_epoch={:?}", slot_number, enacted_epoch);
let check_roots = || -> Result<bool, ConsensusError> {
// this can only happen when the chain starts, since there's no
// epoch change at genesis. afterwards every time we expect an epoch
Expand Down Expand Up @@ -1139,31 +1137,27 @@ impl<B, E, Block, I, RA, PRA> BlockImport<Block> for BabeBlockImport<B, E, Block
enacted_epoch.encode(),
);

// we really could ignore epoch0 here, because the change epoch0 -> epoch1 doesn't emit any digest
// => we'll never reach this code
let current_epoch = epoch(&*self.api, &BlockId::Hash(parent_hash))?;
let authorities_changed = match current_epoch {
MaybeSpanEpoch::Genesis(_, epoch1) => epoch1.authorities != enacted_epoch.authorities,
MaybeSpanEpoch::Regular(epoch) => epoch.authorities != enacted_epoch.authorities,
};
let current_epoch = epoch_from_runtime(&*self.api, &BlockId::Hash(parent_hash))
.ok_or(consensus_common::Error::InvalidAuthoritiesSet)?;

// if the authorities have changed then we populate the
// `AUTHORITIES` key with the enacted epoch, so that the inner
// `ImportBlock` can process it (`EPOCH` is specific to BABE).
// e.g. in the case of GRANDPA it would require a justification
// for the block, expecting that the authorities actually
// changed.
if authorities_changed {
if current_epoch.authorities != enacted_epoch.authorities {
new_cache.insert(
well_known_cache_keys::AUTHORITIES,
enacted_epoch.encode(),
enacted_epoch.authorities.encode(),
);
}
}

old_epoch_changes = Some(epoch_changes.clone());

// track the epoch change in the fork tree
println!("=== Babe.ImportBlock.ImportNextEpoch: {:?}", next_epoch);
epoch_changes.import(
hash,
number,
Expand Down
2 changes: 1 addition & 1 deletion core/consensus/slots/src/slots.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ impl<SC: SlotCompatible + Unpin> Stream for Slots<SC> {
// never yield the same slot twice.
if slot_num > self.last_slot {
self.last_slot = slot_num;

println!("=== slot_ready: {}", slot_num);
break Poll::Ready(Some(Ok(SlotInfo {
number: slot_num,
duration: self.slot_duration,
Expand Down
3 changes: 3 additions & 0 deletions core/primitives/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ pub mod well_known_keys {
/// Current extrinsic index (u32) is stored under this key.
pub const EXTRINSIC_INDEX: &'static [u8] = b":extrinsic_index";

/// Mutated initial (genesis) validators list from the session module.
pub const MUTATED_SESSION_VALIDATORS_KEYS: &'static [u8] = b":mutated_session_validators_keys";

/// Changes trie configuration is stored under this key.
pub const CHANGES_TRIE_CONFIG: &'static [u8] = b":changes_trie";

Expand Down
2 changes: 1 addition & 1 deletion node/runtime/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ pub mod time {

pub const SLOT_DURATION: Moment = 1650;

pub const EPOCH_DURATION_IN_BLOCKS: Moment = 10 * MINUTES;
pub const EPOCH_DURATION_IN_BLOCKS: Moment = 1 * MINUTES;
pub const EPOCH_DURATION_IN_SLOTS: Moment = {
const SLOT_FILL_RATE: f64 = MILLISECS_PER_BLOCK as f64 / SLOT_DURATION as f64;

Expand Down
3 changes: 2 additions & 1 deletion node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ parameter_types! {
impl babe::Trait for Runtime {
type EpochDuration = EpochDuration;
type ExpectedBlockTime = ExpectedBlockTime;
type Keys = SessionKeys;
}

impl indices::Trait for Runtime {
Expand Down Expand Up @@ -400,13 +401,13 @@ construct_runtime!(
UncheckedExtrinsic = UncheckedExtrinsic
{
System: system::{Module, Call, Storage, Config, Event},
Babe: babe::{Module, Call, Storage, Config, Inherent(Timestamp)},
Timestamp: timestamp::{Module, Call, Storage, Inherent},
Authorship: authorship::{Module, Call, Storage},
Indices: indices,
Balances: balances,
Staking: staking::{default, OfflineWorker},
Session: session::{Module, Call, Storage, Event, Config<T>},
Babe: babe::{Module, Call, Storage, Config, Inherent(Timestamp)},
Democracy: democracy::{Module, Call, Storage, Config, Event<T>},
Council: collective::<Instance1>::{Module, Call, Storage, Origin<T>, Event<T>, Config<T>},
TechnicalCommittee: collective::<Instance2>::{Module, Call, Storage, Origin<T>, Event<T>, Config<T>},
Expand Down
3 changes: 2 additions & 1 deletion srml/babe/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ timestamp = { package = "srml-timestamp", path = "../timestamp", default-feature
session = { package = "srml-session", path = "../session", default-features = false }
babe-primitives = { package = "substrate-consensus-babe-primitives", path = "../../core/consensus/babe/primitives", default-features = false }
runtime_io = { package = "sr-io", path = "../../core/sr-io", default-features = false }
primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false }

[dev-dependencies]
lazy_static = "1.3.0"
parking_lot = "0.8.0"
primitives = { package = "substrate-primitives", path = "../../core/primitives" }

[features]
default = ["std"]
Expand All @@ -39,4 +39,5 @@ std = [
"session/std",
"runtime_io/std",
"staking/std",
"primitives/std",
]
65 changes: 60 additions & 5 deletions srml/babe/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,13 @@
pub use timestamp;

use rstd::{result, prelude::*};
use srml_support::{decl_storage, decl_module, StorageValue, traits::FindAuthor, traits::Get};
use srml_support::{decl_storage, decl_module, StorageValue, traits::FindAuthor, traits::Get, Parameter};
use timestamp::{OnTimestampSet};
use primitives::storage::well_known_keys;
use sr_primitives::{generic::DigestItem, ConsensusEngineId};
use sr_primitives::traits::{IsMember, SaturatedConversion, Saturating, RandomnessBeacon, Convert};
use sr_primitives::traits::{
IsMember, SaturatedConversion, Saturating, RandomnessBeacon, Convert, OpaqueKeys, Member, TypedKey,
};
#[cfg(feature = "std")]
use timestamp::TimestampInherentData;
use parity_codec::{Encode, Decode};
Expand Down Expand Up @@ -110,6 +113,9 @@ impl ProvideInherentData for InherentDataProvider {
pub trait Trait: timestamp::Trait {
type EpochDuration: Get<u64>;
type ExpectedBlockTime: Get<Self::Moment>;

/// The keys. Used when BABE is used with session module to decode inital validators set of session module.
type Keys: OpaqueKeys + Member + Parameter;
}

/// The length of the BABE randomness
Expand All @@ -121,7 +127,7 @@ decl_storage! {
pub EpochIndex get(epoch_index): u64;

/// Current epoch authorities.
pub Authorities get(authorities) config(): Vec<(AuthorityId, BabeWeight)>;
pub Authorities get(authorities): Vec<(AuthorityId, BabeWeight)>;

/// Slot at which the current epoch started. It is possible that no
/// block was authored at the given slot and the epoch change was
Expand Down Expand Up @@ -152,6 +158,52 @@ decl_storage! {
/// Randomness under construction.
UnderConstruction: [u8; 32 /* VRF_OUTPUT_LENGTH */];
}
add_extra_genesis {
config(authorities): Vec<(AuthorityId, BabeWeight)>;
build(|
storage: &mut sr_primitives::StorageOverlay,
_: &mut sr_primitives::ChildrenStorageOverlay,
config: &GenesisConfig,
| {
runtime_io::with_storage(storage, || {
let mut authorities = config.authorities.clone();

// if session module is here AND it has mutated initial validators list, then we want to sync
// it with our authorities list
let session_validators_keys: Vec<(T::AccountId, T::Keys)> = srml_support::storage::unhashed::get_raw(
well_known_keys::MUTATED_SESSION_VALIDATORS_KEYS,
).and_then(|v| Decode::decode(&mut &v[..]))
.expect("unable to decode initial session validators keys");

// we expect that the validators set passed received from session will have the same set or subset
// of authorities passed to the BABE module

assert!(
session_validators_keys.len() <= authorities.len(),
"Trying to select unknown BABE authorities for genesis block",
);

let session_validators_keys_len = session_validators_keys.len();
for (idx, session_validator_keys) in session_validators_keys.into_iter().enumerate() {
let session_validator_key = session_validator_keys.1.get(AuthorityId::KEY_TYPE)
.expect("TODO");
let authority_position = authorities.iter().position(|(a, _)| *a == session_validator_key);
match authority_position {
Some(position) if position == idx => (),
Some(position) if position < idx => panic!(
"Trying to select duplicate BABE authority for genesis block",
),
Some(position) => authorities.swap(position, idx),
None => panic!("Trying to select unknown BABE authority for genesis block"),
}
}

authorities.truncate(session_validators_keys_len);

Authorities::put(authorities);
});
});
}
}

decl_module! {
Expand All @@ -170,6 +222,7 @@ decl_module! {

/// Initialization
fn on_initialize() {
println!("=== Babe.OnInitialize");
for digest in Self::get_inherent_digests()
.logs
.iter()
Expand All @@ -183,7 +236,7 @@ decl_module! {
if EpochStartSlot::get() == 0 {
EpochStartSlot::put(digest.slot_number);
}

println!("=== Babe.OnInitialize: {}", digest.slot_number);
CurrentSlot::put(digest.slot_number);
Self::deposit_vrf_output(&digest.vrf_output);

Expand Down Expand Up @@ -226,6 +279,7 @@ impl<T: Trait> IsMember<AuthorityId> for Module<T> {
impl<T: Trait> session::ShouldEndSession<T::BlockNumber> for Module<T> {
fn should_end_session(_: T::BlockNumber) -> bool {
let diff = CurrentSlot::get().saturating_sub(EpochStartSlot::get());
println!("=== Babe.should_end_session: {} - {} = {} >= {}", CurrentSlot::get(), EpochStartSlot::get(), diff, T::EpochDuration::get());
diff >= T::EpochDuration::get()
}
}
Expand Down Expand Up @@ -276,6 +330,7 @@ impl<T: Trait + staking::Trait> session::OneSessionHandler<T::AccountId> for Mod
fn on_new_session<'a, I: 'a>(_changed: bool, validators: I, queued_validators: I)
where I: Iterator<Item=(&'a T::AccountId, AuthorityId)>
{
println!("=== Session.OnNewSession");
use staking::BalanceOf;
let to_votes = |b: BalanceOf<T>| {
<T::CurrencyToVote as Convert<BalanceOf<T>, u64>>::convert(b)
Expand Down Expand Up @@ -336,7 +391,7 @@ impl<T: Trait + staking::Trait> session::OneSessionHandler<T::AccountId> for Mod
authorities: next_authorities,
randomness: next_randomness,
};

println!("=== Session.NextEpochData: {:?}", next);
Self::deposit_consensus(ConsensusLog::NextEpochData(next))
}

Expand Down
4 changes: 3 additions & 1 deletion srml/session/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ serde = { version = "1.0", optional = true }
safe-mix = { version = "1.0", default-features = false}
parity-codec = { version = "4.1.1", default-features = false, features = ["derive"] }
rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false }
primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false }
sr-primitives = { path = "../../core/sr-primitives", default-features = false }
srml-support = { path = "../support", default-features = false }
system = { package = "srml-system", path = "../system", default-features = false }
Expand All @@ -31,5 +32,6 @@ std = [
"srml-support/std",
"sr-primitives/std",
"timestamp/std",
"substrate-trie/std"
"substrate-trie/std",
"primitives/std",
]
26 changes: 22 additions & 4 deletions srml/session/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@
#![cfg_attr(not(feature = "std"), no_std)]

use rstd::{prelude::*, marker::PhantomData, ops::{Sub, Rem}};
use parity_codec::Decode;
use parity_codec::{Encode, Decode};
use primitives::storage::well_known_keys;
use sr_primitives::KeyTypeId;
use sr_primitives::weights::SimpleDispatchInfo;
use sr_primitives::traits::{Convert, Zero, Member, OpaqueKeys, TypedKey};
Expand Down Expand Up @@ -332,8 +333,11 @@ decl_storage! {
.expect("genesis config must not contain duplicates; qed");
}

let initial_validators = T::SelectInitialValidators::select_initial_validators()
.unwrap_or_else(|| config.keys.iter().map(|(ref v, _)| v.clone()).collect());
let initial_validators = T::SelectInitialValidators::select_initial_validators();
let (validators_selected, initial_validators) = match initial_validators {
Some(initial_validators) => (true, initial_validators),
None => (false, config.keys.iter().map(|(ref v, _)| v.clone()).collect()),
};

assert!(!initial_validators.is_empty(), "Empty validator set in genesis block!");

Expand All @@ -346,6 +350,20 @@ decl_storage! {
))
.collect();

// There are some other modules (BABE, for example) that are maintaining similar validators/authorities
// lists and may work standalone OR in conjunction with session module.
// When working in conjunction with session module, they tend to maintain the same list as the session
// module.
// But session module can mutate this list in genesis, using SelectInitialValidators.
// To notify other modules about this mutation (so they could use mutated list), let's write this
// mutated list into well-known-key.
if validators_selected {
srml_support::storage::unhashed::put_raw(
well_known_keys::MUTATED_SESSION_VALIDATORS_KEYS,
&queued_keys.encode(),
);
}

<Validators<T>>::put(initial_validators);
<QueuedKeys<T>>::put(queued_keys);
});
Expand Down Expand Up @@ -414,7 +432,7 @@ impl<T: Trait> Module<T> {
/// equivocation punishment after a fork.
pub fn rotate_session() {
let session_index = CurrentIndex::get();

println!("=== Session.RotateSession");
let changed = QueuedChanged::get();
let mut next_changed = Changed::take();

Expand Down