mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 15:11:03 +00:00
Make BlockImport and Verifier async (#8472)
* Make grandpa work * Introduce `SharedData` * Add test and fix bugs * Switch to `SharedData` * Make grandpa tests working * More Babe work * Make it async * Fix fix * Use `async_trait` in sc-consensus-slots This makes the code a little bit easier to read and also expresses that there can always only be one call at a time to `on_slot`. * Make grandpa tests compile * More Babe tests work * Fix network test * Start fixing service test * Finish service-test * Fix sc-consensus-aura * Fix fix fix * More fixes * Make everything compile *yeah* * Fix build when we have Rust 1.51 * Update client/consensus/common/src/shared_data.rs Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> * Update client/consensus/common/src/shared_data.rs Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> * Update client/consensus/common/src/shared_data.rs Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> * Update client/consensus/common/src/shared_data.rs Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> * Update client/consensus/common/src/shared_data.rs Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> * Update client/consensus/babe/src/tests.rs Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> * Update client/consensus/babe/src/tests.rs Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> * Fix warning Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com>
This commit is contained in:
@@ -47,6 +47,7 @@ use rand_chacha::{
|
||||
};
|
||||
use sc_keystore::LocalKeystore;
|
||||
use sp_application_crypto::key_types::BABE;
|
||||
use futures::executor::block_on;
|
||||
|
||||
type Item = DigestItem<Hash>;
|
||||
|
||||
@@ -67,6 +68,9 @@ enum Stage {
|
||||
|
||||
type Mutator = Arc<dyn Fn(&mut TestHeader, Stage) + Send + Sync>;
|
||||
|
||||
type BabeBlockImport =
|
||||
PanickingBlockImport<crate::BabeBlockImport<TestBlock, TestClient, Arc<TestClient>>>;
|
||||
|
||||
#[derive(Clone)]
|
||||
struct DummyFactory {
|
||||
client: Arc<TestClient>,
|
||||
@@ -134,7 +138,7 @@ impl DummyProposer {
|
||||
|
||||
// figure out if we should add a consensus digest, since the test runtime
|
||||
// doesn't.
|
||||
let epoch_changes = self.factory.epoch_changes.lock();
|
||||
let epoch_changes = self.factory.epoch_changes.shared_data();
|
||||
let epoch = epoch_changes.epoch_data_for_child_of(
|
||||
descendent_query(&*self.factory.client),
|
||||
&self.parent_hash,
|
||||
@@ -188,30 +192,37 @@ thread_local! {
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct PanickingBlockImport<B>(B);
|
||||
pub struct PanickingBlockImport<B>(B);
|
||||
|
||||
impl<B: BlockImport<TestBlock>> BlockImport<TestBlock> for PanickingBlockImport<B> {
|
||||
#[async_trait::async_trait]
|
||||
impl<B: BlockImport<TestBlock>> BlockImport<TestBlock> for PanickingBlockImport<B>
|
||||
where
|
||||
B::Transaction: Send,
|
||||
B: Send,
|
||||
{
|
||||
type Error = B::Error;
|
||||
type Transaction = B::Transaction;
|
||||
|
||||
fn import_block(
|
||||
async fn import_block(
|
||||
&mut self,
|
||||
block: BlockImportParams<TestBlock, Self::Transaction>,
|
||||
new_cache: HashMap<CacheKeyId, Vec<u8>>,
|
||||
) -> Result<ImportResult, Self::Error> {
|
||||
Ok(self.0.import_block(block, new_cache).expect("importing block failed"))
|
||||
Ok(self.0.import_block(block, new_cache).await.expect("importing block failed"))
|
||||
}
|
||||
|
||||
fn check_block(
|
||||
async fn check_block(
|
||||
&mut self,
|
||||
block: BlockCheckParams<TestBlock>,
|
||||
) -> Result<ImportResult, Self::Error> {
|
||||
Ok(self.0.check_block(block).expect("checking block failed"))
|
||||
Ok(self.0.check_block(block).await.expect("checking block failed"))
|
||||
}
|
||||
}
|
||||
|
||||
type BabePeer = Peer<Option<PeerData>, BabeBlockImport>;
|
||||
|
||||
pub struct BabeTestNet {
|
||||
peers: Vec<Peer<Option<PeerData>>>,
|
||||
peers: Vec<BabePeer>,
|
||||
}
|
||||
|
||||
type TestHeader = <TestBlock as BlockT>::Header;
|
||||
@@ -227,11 +238,12 @@ pub struct TestVerifier {
|
||||
mutator: Mutator,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl Verifier<TestBlock> for TestVerifier {
|
||||
/// Verify the given data and return the BlockImportParams and an optional
|
||||
/// new set of validators to import. If not, err with an Error-Message
|
||||
/// presented to the User in the logs.
|
||||
fn verify(
|
||||
async fn verify(
|
||||
&mut self,
|
||||
origin: BlockOrigin,
|
||||
mut header: TestHeader,
|
||||
@@ -240,7 +252,7 @@ impl Verifier<TestBlock> for TestVerifier {
|
||||
) -> Result<(BlockImportParams<TestBlock, ()>, Option<Vec<(CacheKeyId, Vec<u8>)>>), String> {
|
||||
// apply post-sealing mutations (i.e. stripping seal, if desired).
|
||||
(self.mutator)(&mut header, Stage::PostSeal);
|
||||
self.inner.verify(origin, header, justifications, body)
|
||||
self.inner.verify(dbg!(origin), header, justifications, body).await
|
||||
}
|
||||
}
|
||||
|
||||
@@ -255,6 +267,7 @@ pub struct PeerData {
|
||||
impl TestNetFactory for BabeTestNet {
|
||||
type Verifier = TestVerifier;
|
||||
type PeerData = Option<PeerData>;
|
||||
type BlockImport = BabeBlockImport;
|
||||
|
||||
/// Create new test network with peers and given config.
|
||||
fn from_config(_config: &ProtocolConfig) -> Self {
|
||||
@@ -264,9 +277,9 @@ impl TestNetFactory for BabeTestNet {
|
||||
}
|
||||
}
|
||||
|
||||
fn make_block_import<Transaction>(&self, client: PeersClient)
|
||||
fn make_block_import(&self, client: PeersClient)
|
||||
-> (
|
||||
BlockImportAdapter<Transaction>,
|
||||
BlockImportAdapter<Self::BlockImport>,
|
||||
Option<BoxJustificationImport<Block>>,
|
||||
Option<PeerData>,
|
||||
)
|
||||
@@ -287,7 +300,7 @@ impl TestNetFactory for BabeTestNet {
|
||||
Some(Box::new(block_import.clone()) as BoxBlockImport<_, _>)
|
||||
);
|
||||
(
|
||||
BlockImportAdapter::new_full(block_import),
|
||||
BlockImportAdapter::new(block_import),
|
||||
None,
|
||||
Some(PeerData { link, inherent_data_providers, block_import: data_block_import }),
|
||||
)
|
||||
@@ -326,17 +339,17 @@ impl TestNetFactory for BabeTestNet {
|
||||
}
|
||||
}
|
||||
|
||||
fn peer(&mut self, i: usize) -> &mut Peer<Self::PeerData> {
|
||||
fn peer(&mut self, i: usize) -> &mut BabePeer {
|
||||
trace!(target: "babe", "Retrieving a peer");
|
||||
&mut self.peers[i]
|
||||
}
|
||||
|
||||
fn peers(&self) -> &Vec<Peer<Self::PeerData>> {
|
||||
fn peers(&self) -> &Vec<BabePeer> {
|
||||
trace!(target: "babe", "Retrieving peers");
|
||||
&self.peers
|
||||
}
|
||||
|
||||
fn mut_peers<F: FnOnce(&mut Vec<Peer<Self::PeerData>>)>(
|
||||
fn mut_peers<F: FnOnce(&mut Vec<BabePeer>)>(
|
||||
&mut self,
|
||||
closure: F,
|
||||
) {
|
||||
@@ -436,7 +449,7 @@ fn run_one_test(
|
||||
telemetry: None,
|
||||
}).expect("Starts babe"));
|
||||
}
|
||||
futures::executor::block_on(future::select(
|
||||
block_on(future::select(
|
||||
futures::future::poll_fn(move |cx| {
|
||||
let mut net = net.lock();
|
||||
net.poll(cx);
|
||||
@@ -567,7 +580,7 @@ fn can_author_block() {
|
||||
}
|
||||
|
||||
// Propose and import a new BABE block on top of the given parent.
|
||||
fn propose_and_import_block<Transaction>(
|
||||
fn propose_and_import_block<Transaction: Send + 'static>(
|
||||
parent: &TestHeader,
|
||||
slot: Option<Slot>,
|
||||
proposer_factory: &mut DummyFactory,
|
||||
@@ -595,7 +608,7 @@ fn propose_and_import_block<Transaction>(
|
||||
|
||||
let mut block = futures::executor::block_on(proposer.propose_with(pre_digest)).unwrap().block;
|
||||
|
||||
let epoch_descriptor = proposer_factory.epoch_changes.lock().epoch_descriptor_for_child_of(
|
||||
let epoch_descriptor = proposer_factory.epoch_changes.shared_data().epoch_descriptor_for_child_of(
|
||||
descendent_query(&*proposer_factory.client),
|
||||
&parent_hash,
|
||||
*parent.number(),
|
||||
@@ -623,10 +636,10 @@ fn propose_and_import_block<Transaction>(
|
||||
import.body = Some(block.extrinsics);
|
||||
import.intermediates.insert(
|
||||
Cow::from(INTERMEDIATE_KEY),
|
||||
Box::new(BabeIntermediate::<TestBlock> { epoch_descriptor }) as Box<dyn Any>,
|
||||
Box::new(BabeIntermediate::<TestBlock> { epoch_descriptor }) as Box<_>,
|
||||
);
|
||||
import.fork_choice = Some(ForkChoiceStrategy::LongestChain);
|
||||
let import_result = block_import.import_block(import, Default::default()).unwrap();
|
||||
let import_result = block_on(block_import.import_block(import, Default::default())).unwrap();
|
||||
|
||||
match import_result {
|
||||
ImportResult::Imported(_) => {},
|
||||
@@ -664,7 +677,7 @@ fn importing_block_one_sets_genesis_epoch() {
|
||||
|
||||
let genesis_epoch = Epoch::genesis(&data.link.config, 999.into());
|
||||
|
||||
let epoch_changes = data.link.epoch_changes.lock();
|
||||
let epoch_changes = data.link.epoch_changes.shared_data();
|
||||
let epoch_for_second_block = epoch_changes.epoch_data_for_child_of(
|
||||
descendent_query(&*client),
|
||||
&block_hash,
|
||||
@@ -739,13 +752,13 @@ fn importing_epoch_change_block_prunes_tree() {
|
||||
|
||||
// We should be tracking a total of 9 epochs in the fork tree
|
||||
assert_eq!(
|
||||
epoch_changes.lock().tree().iter().count(),
|
||||
epoch_changes.shared_data().tree().iter().count(),
|
||||
9,
|
||||
);
|
||||
|
||||
// And only one root
|
||||
assert_eq!(
|
||||
epoch_changes.lock().tree().roots().count(),
|
||||
epoch_changes.shared_data().tree().roots().count(),
|
||||
1,
|
||||
);
|
||||
|
||||
@@ -756,16 +769,16 @@ fn importing_epoch_change_block_prunes_tree() {
|
||||
|
||||
// at this point no hashes from the first fork must exist on the tree
|
||||
assert!(
|
||||
!epoch_changes.lock().tree().iter().map(|(h, _, _)| h).any(|h| fork_1.contains(h)),
|
||||
!epoch_changes.shared_data().tree().iter().map(|(h, _, _)| h).any(|h| fork_1.contains(h)),
|
||||
);
|
||||
|
||||
// but the epoch changes from the other forks must still exist
|
||||
assert!(
|
||||
epoch_changes.lock().tree().iter().map(|(h, _, _)| h).any(|h| fork_2.contains(h))
|
||||
epoch_changes.shared_data().tree().iter().map(|(h, _, _)| h).any(|h| fork_2.contains(h))
|
||||
);
|
||||
|
||||
assert!(
|
||||
epoch_changes.lock().tree().iter().map(|(h, _, _)| h).any(|h| fork_3.contains(h)),
|
||||
epoch_changes.shared_data().tree().iter().map(|(h, _, _)| h).any(|h| fork_3.contains(h)),
|
||||
);
|
||||
|
||||
// finalizing block #25 from the canon chain should prune out the second fork
|
||||
@@ -774,12 +787,12 @@ fn importing_epoch_change_block_prunes_tree() {
|
||||
|
||||
// at this point no hashes from the second fork must exist on the tree
|
||||
assert!(
|
||||
!epoch_changes.lock().tree().iter().map(|(h, _, _)| h).any(|h| fork_2.contains(h)),
|
||||
!epoch_changes.shared_data().tree().iter().map(|(h, _, _)| h).any(|h| fork_2.contains(h)),
|
||||
);
|
||||
|
||||
// while epoch changes from the last fork should still exist
|
||||
assert!(
|
||||
epoch_changes.lock().tree().iter().map(|(h, _, _)| h).any(|h| fork_3.contains(h)),
|
||||
epoch_changes.shared_data().tree().iter().map(|(h, _, _)| h).any(|h| fork_3.contains(h)),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user