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 all commits
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.

1 change: 1 addition & 0 deletions bin/node/cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ browser-utils = { path = "../../../utils/browser", optional = true }
[dev-dependencies]
sc-keystore = { version = "2.0.0", path = "../../../client/keystore" }
sc-consensus-babe = { version = "0.8", features = ["test-helpers"], path = "../../../client/consensus/babe" }
sc-consensus-epochs = { version = "0.8", path = "../../../client/consensus/epochs" }
sc-service-test = { version = "2.0.0", path = "../../../client/service/test" }
futures = "0.3.1"
tempfile = "3.1.0"
Expand Down
28 changes: 24 additions & 4 deletions bin/node/cli/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,8 +371,11 @@ pub fn new_light(config: NodeConfiguration)

#[cfg(test)]
mod tests {
use std::sync::Arc;
use sc_consensus_babe::CompatibleDigestItem;
use std::{sync::Arc, collections::HashMap, borrow::Cow, any::Any};
use sc_consensus_babe::{
CompatibleDigestItem, BabeIntermediate, INTERMEDIATE_KEY
};
use sc_consensus_epochs::descendent_query;
use sp_consensus::{
Environment, Proposer, BlockImportParams, BlockOrigin, ForkChoiceStrategy, BlockImport,
RecordProof,
Expand All @@ -384,7 +387,7 @@ mod tests {
use sp_core::{crypto::Pair as CryptoPair, H256};
use sp_runtime::{
generic::{BlockId, Era, Digest, SignedPayload},
traits::Block as BlockT,
traits::{Block as BlockT, Header as HeaderT},
traits::Verify,
OpaqueExtrinsic,
};
Expand Down Expand Up @@ -499,11 +502,21 @@ mod tests {

let parent_id = BlockId::number(service.client().chain_info().best_number);
let parent_header = service.client().header(&parent_id).unwrap().unwrap();
let parent_hash = parent_header.hash();
let parent_number = *parent_header.number();
let mut proposer_factory = sc_basic_authorship::ProposerFactory {
client: service.client(),
transaction_pool: service.transaction_pool(),
};

let epoch = babe_link.epoch_changes().lock().epoch_for_child_of(
descendent_query(&*service.client()),
&parent_hash,
parent_number,
slot_num,
|slot| babe_link.config().genesis_epoch(slot)
).unwrap().unwrap();

let mut digest = Digest::<H256>::default();

// even though there's only one authority some slots might be empty,
Expand Down Expand Up @@ -555,7 +568,14 @@ mod tests {
storage_changes: None,
finalized: false,
auxiliary: Vec::new(),
intermediates: Default::default(),
intermediates: {
let mut intermediates = HashMap::new();
intermediates.insert(
Cow::from(INTERMEDIATE_KEY),
Box::new(BabeIntermediate { epoch }) as Box<dyn Any>,
);
intermediates
},
fork_choice: Some(ForkChoiceStrategy::LongestChain),
allow_missing_state: false,
import_existing: false,
Expand Down
3 changes: 2 additions & 1 deletion client/consensus/aura/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,8 +274,9 @@ impl<B, C, E, I, P, Error, SO> sc_consensus_slots::SimpleSlotWorker<B> for AuraW
Vec<B::Extrinsic>,
StorageChanges<sp_api::TransactionFor<C, B>, B>,
Self::Claim,
Self::EpochData,
) -> sp_consensus::BlockImportParams<B, sp_api::TransactionFor<C, B>> + Send> {
Box::new(|header, header_hash, body, storage_changes, pair| {
Box::new(|header, header_hash, body, storage_changes, pair, _epoch| {
// sign the pre-sealed hash of the block and then
// add it to a digest item.
let signature = pair.sign(header_hash.as_ref());
Expand Down
84 changes: 57 additions & 27 deletions client/consensus/babe/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,10 @@ pub use sp_consensus_babe::{
digests::{PreDigest, CompatibleDigestItem, NextEpochDescriptor},
};
pub use sp_consensus::SyncOracle;
use std::{collections::HashMap, sync::Arc, u64, pin::Pin, time::{Instant, Duration}};
use std::{
collections::HashMap, sync::Arc, u64, pin::Pin, time::{Instant, Duration},
any::Any, borrow::Cow
};
use sp_consensus_babe;
use sp_consensus::{ImportResult, CanAuthorWith};
use sp_consensus::import_queue::{
Expand Down Expand Up @@ -103,7 +106,9 @@ use log::{warn, debug, info, trace};
use sc_consensus_slots::{
SlotWorker, SlotInfo, SlotCompatible, StorageChanges, CheckedHeader, check_equivocation,
};
use sc_consensus_epochs::{descendent_query, SharedEpochChanges, EpochChangesFor, Epoch as EpochT};
use sc_consensus_epochs::{
descendent_query, ViableEpoch, SharedEpochChanges, EpochChangesFor, Epoch as EpochT
};
use sp_blockchain::{
Result as ClientResult, Error as ClientError,
HeaderBackend, ProvideCache, HeaderMetadata
Expand Down Expand Up @@ -196,10 +201,6 @@ enum Error<B: BlockT> {
FetchParentHeader(sp_blockchain::Error),
#[display(fmt = "Expected epoch change to happen at {:?}, s{}", _0, _1)]
ExpectedEpochChange(B::Hash, u64),
#[display(fmt = "Could not look up epoch: {:?}", _0)]
CouldNotLookUpEpoch(Box<fork_tree::Error<sp_blockchain::Error>>),
#[display(fmt = "Block {} is not valid under any epoch.", _0)]
BlockNotValid(B::Hash),
#[display(fmt = "Unexpected epoch change")]
UnexpectedEpochChange,
#[display(fmt = "Parent block of {} has no associated weight", _0)]
Expand Down Expand Up @@ -231,6 +232,16 @@ macro_rules! babe_info {
};
}


/// Intermediate value passed to block importer.
pub struct BabeIntermediate {
/// The epoch data, if available.
pub epoch: ViableEpoch<Epoch>,
}

/// Intermediate key for Babe engine.
pub static INTERMEDIATE_KEY: &[u8] = b"babe1";

/// A slot duration. Create with `get_or_compute`.
// FIXME: Once Rust has higher-kinded types, the duplication between this
// and `super::babe::Config` can be eliminated.
Expand Down Expand Up @@ -394,7 +405,7 @@ impl<B, C, E, I, Error, SO> sc_consensus_slots::SimpleSlotWorker<B> for BabeWork
SO: SyncOracle + Send + Clone,
Error: std::error::Error + Send + From<ConsensusError> + From<I::Error> + 'static,
{
type EpochData = Epoch;
type EpochData = ViableEpoch<Epoch>;
type Claim = (PreDigest, AuthorityPair);
type SyncOracle = SO;
type CreateProposer = Pin<Box<
Expand Down Expand Up @@ -424,24 +435,23 @@ impl<B, C, E, I, Error, SO> sc_consensus_slots::SimpleSlotWorker<B> for BabeWork
|slot| self.config.genesis_epoch(slot)
)
.map_err(|e| ConsensusError::ChainLookup(format!("{:?}", e)))?
.map(|e| e.into_inner())
.ok_or(sp_consensus::Error::InvalidAuthoritiesSet)
}

fn authorities_len(&self, epoch_data: &Self::EpochData) -> usize {
epoch_data.authorities.len()
epoch_data.as_ref().authorities.len()
}

fn claim_slot(
&self,
_parent_header: &B::Header,
slot_number: SlotNumber,
epoch_data: &Epoch,
epoch_data: &ViableEpoch<Epoch>,
) -> Option<Self::Claim> {
debug!(target: "babe", "Attempting to claim slot {}", slot_number);
let s = authorship::claim_slot(
slot_number,
epoch_data,
epoch_data.as_ref(),
&*self.config,
&self.keystore,
);
Expand Down Expand Up @@ -469,8 +479,9 @@ impl<B, C, E, I, Error, SO> sc_consensus_slots::SimpleSlotWorker<B> for BabeWork
Vec<B::Extrinsic>,
StorageChanges<I::Transaction, B>,
Self::Claim,
Self::EpochData,
) -> sp_consensus::BlockImportParams<B, I::Transaction> + Send> {
Box::new(|header, header_hash, body, storage_changes, (_, pair)| {
Box::new(|header, header_hash, body, storage_changes, (_, pair), epoch| {
// sign the pre-sealed hash of the block and then
// add it to a digest item.
let signature = pair.sign(header_hash.as_ref());
Expand All @@ -485,7 +496,14 @@ impl<B, C, E, I, Error, SO> sc_consensus_slots::SimpleSlotWorker<B> for BabeWork
storage_changes: Some(storage_changes),
finalized: false,
auxiliary: Vec::new(), // block-weight is written in block import.
intermediates: Default::default(),
intermediates: {
let mut intermediates = HashMap::new();
intermediates.insert(
Cow::from(INTERMEDIATE_KEY),
Box::new(BabeIntermediate { epoch }) as Box<dyn Any>,
);
intermediates
},
fork_choice: None,
allow_missing_state: false,
import_existing: false,
Expand Down Expand Up @@ -634,6 +652,19 @@ pub struct BabeLink<Block: BlockT> {
epoch_changes: SharedEpochChanges<Block, Epoch>,
config: Config,
}

impl<Block: BlockT> BabeLink<Block> {
/// Get the epoch changes of this link.
pub fn epoch_changes(&self) -> &SharedEpochChanges<Block, Epoch> {
&self.epoch_changes
}

/// Get the config of this link.
pub fn config(&self) -> &Config {
&self.config
}
}

/// A verifier for Babe blocks.
pub struct BabeVerifier<B, E, Block: BlockT, RA, PRA> {
client: Arc<Client<B, E, Block, RA>>,
Expand Down Expand Up @@ -830,6 +861,14 @@ impl<B, E, Block, RA, PRA> Verifier<Block> for BabeVerifier<B, E, Block, RA, PRA
"babe.checked_and_importing";
"pre_header" => ?pre_header);

let mut intermediates = HashMap::new();
intermediates.insert(
Cow::from(INTERMEDIATE_KEY),
Box::new(BabeIntermediate {
epoch,
}) as Box<dyn Any>,
);

let block_import_params = BlockImportParams {
origin,
header: pre_header,
Expand All @@ -839,7 +878,7 @@ impl<B, E, Block, RA, PRA> Verifier<Block> for BabeVerifier<B, E, Block, RA, PRA
finalized: false,
justification,
auxiliary: Vec::new(),
intermediates: Default::default(),
intermediates,
fork_choice: None,
allow_missing_state: false,
import_existing: false,
Expand Down Expand Up @@ -997,20 +1036,11 @@ impl<B, E, Block, I, RA, PRA> BlockImport<Block> for BabeBlockImport<B, E, Block
))?
};

let epoch = epoch_changes.epoch_for_child_of(
descendent_query(&*self.client),
&parent_hash,
*parent_header.number(),
slot_number,
|slot| self.config.genesis_epoch(slot),
)
.map_err(|e: fork_tree::Error<sp_blockchain::Error>| ConsensusError::ChainLookup(
babe_err(Error::<Block>::CouldNotLookUpEpoch(Box::new(e))).into()
))?
.ok_or_else(|| ConsensusError::ClientImport(
babe_err(Error::<Block>::BlockNotValid(hash)).into()
))?;
let intermediate = block.take_intermediate::<BabeIntermediate>(
INTERMEDIATE_KEY
)?;

let epoch = intermediate.epoch;
let first_in_epoch = parent_slot < epoch.as_ref().start_slot;
(epoch, first_in_epoch, parent_weight)
};
Expand Down
19 changes: 18 additions & 1 deletion client/consensus/babe/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -565,8 +565,18 @@ fn propose_and_import_block<Transaction>(
],
};

let parent_hash = parent.hash();

let mut block = futures::executor::block_on(proposer.propose_with(pre_digest)).unwrap().block;

let epoch = proposer_factory.epoch_changes.lock().epoch_for_child_of(
descendent_query(&*proposer_factory.client),
&parent_hash,
*parent.number(),
slot_number,
|slot| proposer_factory.config.genesis_epoch(slot)
).unwrap().unwrap();

let seal = {
// sign the pre-sealed hash of the block and then
// add it to a digest item.
Expand All @@ -593,7 +603,14 @@ fn propose_and_import_block<Transaction>(
storage_changes: None,
finalized: false,
auxiliary: Vec::new(),
intermediates: Default::default(),
intermediates: {
let mut intermediates = HashMap::new();
intermediates.insert(
Cow::from(INTERMEDIATE_KEY),
Box::new(BabeIntermediate { epoch }) as Box<dyn Any>,
);
intermediates
},
fork_choice: Some(ForkChoiceStrategy::LongestChain),
allow_missing_state: false,
import_existing: false,
Expand Down
4 changes: 3 additions & 1 deletion client/consensus/slots/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ pub trait SimpleSlotWorker<B: BlockT> {
type Claim: Send + 'static;

/// Epoch data necessary for authoring.
type EpochData;
type EpochData: Send + 'static;

/// The logging target to use when logging messages.
fn logging_target(&self) -> &'static str;
Expand Down Expand Up @@ -119,6 +119,7 @@ pub trait SimpleSlotWorker<B: BlockT> {
Vec<B::Extrinsic>,
StorageChanges<<Self::BlockImport as BlockImport<B>>::Transaction, B>,
Self::Claim,
Self::EpochData,
) -> sp_consensus::BlockImportParams<
B,
<Self::BlockImport as BlockImport<B>>::Transaction
Expand Down Expand Up @@ -280,6 +281,7 @@ pub trait SimpleSlotWorker<B: BlockT> {
body,
proposal.storage_changes,
claim,
epoch_data,
);

info!(
Expand Down