Asynchronous-backing compatible Aura, not plugged in (#2573)

* rough draft of potential parent search

* get things compiling

* fmt

* add new function to all RelayChainInterface implementations

* fix compilation

* set slot and timestamp based on relay parent, prepare for find-parent

* skeleton of new aura logic

* fmt

* introduce a collator module in the Aura crate

* extract different implementations into own modules

* make interface more convenient

* docs and todos for lookahead

* refactor basic collator to use new collator utility

* some more refactoring

* finish most of the control flow for new aura

* introduce backend as parameter

* fix compilation

* fix a couple more TODOs

* add an `announce_block` function to collator service

* announce with barrier

* rename block announcement validator to be more specific

* fmt

* clean up unused import errors

* update references to BlockAnnounceValidator

* rename unstable_reimpl

* add AuraUnincludedSegmentApi

* finish rename

* integrate AuraUnincludedSegmentApi

* add a new block announcement validator for backwards compatibility

* add some naive equivocation defenses

* rustfmt

* clean up remaining TODO [now]s

* fmt

* try to fix inprocess-interface

* actually fix compilation

* ignored -> rejected rephrase

* fix test compilation

* fmt

* clippy
This commit is contained in:
asynchronous rob
2023-07-11 13:56:09 +02:00
committed by GitHub
parent cc5e0ae9ab
commit 406f92ad90
20 changed files with 1588 additions and 548 deletions
+63 -6
View File
@@ -17,7 +17,7 @@
//! Parachain specific networking
//!
//! Provides a custom block announcement implementation for parachains
//! that use the relay chain provided consensus. See [`BlockAnnounceValidator`]
//! that use the relay chain provided consensus. See [`RequireSecondedInBlockAnnounce`]
//! and [`WaitToAnnounce`] for more information about this implementation.
use sp_consensus::block_validation::{
@@ -185,8 +185,17 @@ impl TryFrom<&'_ CollationSecondedSignal> for BlockAnnounceData {
}
}
/// A type alias for the [`RequireSecondedInBlockAnnounce`] validator.
#[deprecated = "This has been renamed to RequireSecondedInBlockAnnounce"]
pub type BlockAnnounceValidator<Block, RCInterface> =
RequireSecondedInBlockAnnounce<Block, RCInterface>;
/// Parachain specific block announce validator.
///
/// This is not required when the collation mechanism itself is sybil-resistant, as it is a spam protection
/// mechanism used to prevent nodes from dealing with unbounded numbers of blocks. For sybil-resistant
/// collation mechanisms, this will only slow things down.
///
/// This block announce validator is required if the parachain is running
/// with the relay chain provided consensus to make sure each node only
/// imports a reasonable number of blocks per round. The relay chain provided
@@ -213,23 +222,23 @@ impl TryFrom<&'_ CollationSecondedSignal> for BlockAnnounceData {
/// it. However, if the announcement is for a block below the tip the announcement is accepted
/// as it probably comes from a node that is currently syncing the chain.
#[derive(Clone)]
pub struct BlockAnnounceValidator<Block, RCInterface> {
pub struct RequireSecondedInBlockAnnounce<Block, RCInterface> {
phantom: PhantomData<Block>,
relay_chain_interface: RCInterface,
para_id: ParaId,
}
impl<Block, RCInterface> BlockAnnounceValidator<Block, RCInterface>
impl<Block, RCInterface> RequireSecondedInBlockAnnounce<Block, RCInterface>
where
RCInterface: Clone,
{
/// Create a new [`BlockAnnounceValidator`].
/// Create a new [`RequireSecondedInBlockAnnounce`].
pub fn new(relay_chain_interface: RCInterface, para_id: ParaId) -> Self {
Self { phantom: Default::default(), relay_chain_interface, para_id }
}
}
impl<Block: BlockT, RCInterface> BlockAnnounceValidator<Block, RCInterface>
impl<Block: BlockT, RCInterface> RequireSecondedInBlockAnnounce<Block, RCInterface>
where
RCInterface: RelayChainInterface + Clone,
{
@@ -314,7 +323,7 @@ where
}
impl<Block: BlockT, RCInterface> BlockAnnounceValidatorT<Block>
for BlockAnnounceValidator<Block, RCInterface>
for RequireSecondedInBlockAnnounce<Block, RCInterface>
where
RCInterface: RelayChainInterface + Clone + 'static,
{
@@ -452,3 +461,51 @@ async fn wait_to_announce<Block: BlockT>(
);
}
}
/// A [`BlockAnnounceValidator`] which accepts all block announcements, as it assumes
/// sybil resistance is handled elsewhere.
#[derive(Debug, Clone)]
pub struct AssumeSybilResistance(bool);
impl AssumeSybilResistance {
/// Instantiate this block announcement validator while permissively allowing (but ignoring)
/// announcements which come tagged with seconded messages.
///
/// This is useful for backwards compatibility when upgrading nodes: old nodes will continue
/// to broadcast announcements with seconded messages, so these announcements shouldn't be rejected
/// and the peers not punished.
pub fn allow_seconded_messages() -> Self {
AssumeSybilResistance(true)
}
/// Instantiate this block announcement validator while rejecting announcements that come with
/// data.
pub fn reject_seconded_messages() -> Self {
AssumeSybilResistance(false)
}
}
impl<Block: BlockT> BlockAnnounceValidatorT<Block> for AssumeSybilResistance {
fn validate(
&mut self,
_header: &Block::Header,
data: &[u8],
) -> Pin<Box<dyn Future<Output = Result<Validation, BoxedError>> + Send>> {
let allow_seconded_messages = self.0;
let data = data.to_vec();
async move {
Ok(if data.is_empty() {
Validation::Success { is_new_best: false }
} else if !allow_seconded_messages {
Validation::Failure { disconnect: false }
} else {
match BlockAnnounceData::decode_all(&mut data.as_slice()) {
Ok(_) => Validation::Success { is_new_best: false },
Err(_) => Validation::Failure { disconnect: true },
}
})
}
.boxed()
}
}
+5 -3
View File
@@ -255,11 +255,13 @@ impl RelayChainInterface for DummyRelayChainInterface {
}
}
fn make_validator_and_api(
) -> (BlockAnnounceValidator<Block, Arc<DummyRelayChainInterface>>, Arc<DummyRelayChainInterface>) {
fn make_validator_and_api() -> (
RequireSecondedInBlockAnnounce<Block, Arc<DummyRelayChainInterface>>,
Arc<DummyRelayChainInterface>,
) {
let relay_chain_interface = Arc::new(DummyRelayChainInterface::new());
(
BlockAnnounceValidator::new(relay_chain_interface.clone(), ParaId::from(56)),
RequireSecondedInBlockAnnounce::new(relay_chain_interface.clone(), ParaId::from(56)),
relay_chain_interface,
)
}