Skip to content

Commit

Permalink
A0-3307: Introduce verifiable requests (#1494)
Browse files Browse the repository at this point in the history
# Description

Introduce verifiable requests. For backwards compatibility reasons they
cannot be fully enforced yet, that will require a separate update.

## Type of change

- New feature (non-breaking change which adds functionality)

# Checklist:

<!-- delete when not applicable to your PR -->

- I have added tests
- I have made corresponding changes to the existing documentation
- I have created new documentation
  • Loading branch information
timorleph authored Nov 20, 2023
1 parent 4d1708c commit fdcc4f8
Show file tree
Hide file tree
Showing 12 changed files with 644 additions and 316 deletions.
17 changes: 9 additions & 8 deletions finality-aleph/src/data_io/data_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ where
B: BlockT<Hash = BlockHash>,
B::Header: HeaderT<Number = BlockNumber> + UnverifiedHeader + Header<Unverified = B::Header>,
C: HeaderBackend<B> + BlockchainEvents<B> + Send + Sync + 'static,
RB: RequestBlocks + 'static,
RB: RequestBlocks<B::Header>,
Message: AlephNetworkMessage<B::Header>
+ std::fmt::Debug
+ Send
Expand Down Expand Up @@ -186,7 +186,7 @@ where
B: BlockT<Hash = BlockHash>,
B::Header: HeaderT<Number = BlockNumber> + UnverifiedHeader + Header<Unverified = B::Header>,
C: HeaderBackend<B> + BlockchainEvents<B> + Send + Sync + 'static,
RB: RequestBlocks + 'static,
RB: RequestBlocks<B::Header>,
Message: AlephNetworkMessage<B::Header>
+ std::fmt::Debug
+ Send
Expand Down Expand Up @@ -307,11 +307,12 @@ where
_ => continue,
};

let block = proposal.top_block();
if !self.chain_info_provider.is_block_imported(&block) {
debug!(target: "aleph-data-store", "Requesting a block {:?} after it has been missing for {:?} secs.", block, time_waiting.as_secs());
if let Err(e) = self.block_requester.request_block(block.clone()) {
warn!(target: "aleph-data-store", "Error requesting block {:?}, {}.", block, e);
let header = proposal.top_block_header();
let block_id = proposal.top_block();
if !self.chain_info_provider.is_block_imported(&block_id) {
debug!(target: "aleph-data-store", "Requesting a block {:?} after it has been missing for {:?} secs.", block_id, time_waiting.as_secs());
if let Err(e) = self.block_requester.request_block(header) {
warn!(target: "aleph-data-store", "Error requesting block {:?}, {}.", block_id, e);
}
continue;
}
Expand Down Expand Up @@ -667,7 +668,7 @@ where
B: BlockT<Hash = BlockHash>,
B::Header: HeaderT<Number = BlockNumber> + UnverifiedHeader + Header<Unverified = B::Header>,
C: HeaderBackend<B> + BlockchainEvents<B> + Send + Sync + 'static,
RB: RequestBlocks + 'static,
RB: RequestBlocks<B::Header>,
Message: AlephNetworkMessage<B::Header>
+ std::fmt::Debug
+ Send
Expand Down
8 changes: 4 additions & 4 deletions finality-aleph/src/data_io/legacy/data_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ use crate::{
Network as DataNetwork,
},
party::manager::Runnable,
sync::RequestBlocks,
sync::LegacyRequestBlocks,
BlockId, SessionBoundaries,
};

Expand Down Expand Up @@ -152,7 +152,7 @@ where
B: BlockT<Hash = BlockHash>,
B::Header: HeaderT<Number = BlockNumber>,
C: HeaderBackend<B> + BlockchainEvents<B> + Send + Sync + 'static,
RB: RequestBlocks + 'static,
RB: LegacyRequestBlocks,
Message: AlephNetworkMessage
+ std::fmt::Debug
+ Send
Expand Down Expand Up @@ -185,7 +185,7 @@ where
B: BlockT<Hash = BlockHash>,
B::Header: HeaderT<Number = BlockNumber>,
C: HeaderBackend<B> + BlockchainEvents<B> + Send + Sync + 'static,
RB: RequestBlocks + 'static,
RB: LegacyRequestBlocks,
Message: AlephNetworkMessage
+ std::fmt::Debug
+ Send
Expand Down Expand Up @@ -642,7 +642,7 @@ where
B: BlockT<Hash = BlockHash>,
B::Header: HeaderT<Number = BlockNumber>,
C: HeaderBackend<B> + BlockchainEvents<B> + Send + Sync + 'static,
RB: RequestBlocks + 'static,
RB: LegacyRequestBlocks,
Message: AlephNetworkMessage
+ std::fmt::Debug
+ Send
Expand Down
8 changes: 4 additions & 4 deletions finality-aleph/src/party/manager/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ pub use task::{Handle, Runnable, Task, TaskCommon};

use crate::{
abft::{CURRENT_VERSION, LEGACY_VERSION},
sync::RequestBlocks,
sync::{LegacyRequestBlocks, RequestBlocks},
};

#[cfg(feature = "only_legacy")]
Expand Down Expand Up @@ -102,7 +102,7 @@ where
C: crate::ClientForAleph<B, BE> + Send + Sync + 'static,
BE: Backend<B> + 'static,
SC: SelectChain<B> + 'static,
RB: RequestBlocks,
RB: RequestBlocks<B::Header> + LegacyRequestBlocks,
SM: SessionManager<VersionedNetworkData<B::Header>> + 'static,
JS: JustificationSubmissions<Justification> + Send + Sync + Clone,
V: HeaderVerifier<B::Header>,
Expand Down Expand Up @@ -130,7 +130,7 @@ where
C::Api: crate::aleph_primitives::AlephSessionApi<B>,
BE: Backend<B> + 'static,
SC: SelectChain<B> + 'static,
RB: RequestBlocks,
RB: RequestBlocks<B::Header> + LegacyRequestBlocks,
SM: SessionManager<VersionedNetworkData<B::Header>>,
JS: JustificationSubmissions<Justification> + Send + Sync + Clone + 'static,
V: HeaderVerifier<B::Header>,
Expand Down Expand Up @@ -426,7 +426,7 @@ where
C::Api: crate::aleph_primitives::AlephSessionApi<B>,
BE: Backend<B> + 'static,
SC: SelectChain<B> + 'static,
RB: RequestBlocks,
RB: RequestBlocks<B::Header> + LegacyRequestBlocks,
SM: SessionManager<VersionedNetworkData<B::Header>>,
JS: JustificationSubmissions<Justification> + Send + Sync + Clone + 'static,
V: HeaderVerifier<B::Header>,
Expand Down
76 changes: 60 additions & 16 deletions finality-aleph/src/sync/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ use static_assertions::const_assert;

use crate::{
aleph_primitives::MAX_BLOCK_SIZE,
block::{Block, Justification, UnverifiedHeader, UnverifiedHeaderFor, UnverifiedJustification},
block::{
Block, Header, Justification, UnverifiedHeader, UnverifiedHeaderFor,
UnverifiedJustification,
},
network::GossipNetwork,
sync::{PeerId, LOG_TARGET},
BlockId, Version,
Expand Down Expand Up @@ -114,10 +117,27 @@ impl<J: Justification> RequestV1<J> {
}
}

// TODO(A0-3494): Only needed because old requests did not have headers, afterwards we will have headers always.
#[derive(Clone, Debug, Encode, Decode)]
pub enum MaybeHeader<UH: UnverifiedHeader> {
Header(UH),
Id(BlockId),
}

impl<UH: UnverifiedHeader> MaybeHeader<UH> {
pub fn id(&self) -> BlockId {
use MaybeHeader::*;
match self {
Header(header) => header.id(),
Id(id) => id.clone(),
}
}
}

/// Request content, current version.
#[derive(Clone, Debug, Encode, Decode)]
pub struct Request<J: Justification> {
target_id: BlockId,
target: MaybeHeader<UnverifiedHeaderFor<J>>,
branch_knowledge: BranchKnowledge,
state: State<J>,
}
Expand All @@ -130,7 +150,7 @@ impl<J: Justification> From<RequestV1<J>> for Request<J> {
state,
} = other;
Request {
target_id,
target: MaybeHeader::Id(target_id),
branch_knowledge,
state: state.into(),
}
Expand All @@ -140,10 +160,14 @@ impl<J: Justification> From<RequestV1<J>> for Request<J> {
impl<J: Justification> From<Request<J>> for RequestV1<J> {
fn from(other: Request<J>) -> Self {
let Request {
target_id,
target,
branch_knowledge,
state,
} = other;
let target_id = match target {
MaybeHeader::Header(header) => header.id(),
MaybeHeader::Id(id) => id,
};
RequestV1 {
target_id,
branch_knowledge,
Expand All @@ -153,9 +177,13 @@ impl<J: Justification> From<Request<J>> for RequestV1<J> {
}

impl<J: Justification> Request<J> {
pub fn new(target_id: BlockId, branch_knowledge: BranchKnowledge, state: State<J>) -> Self {
pub fn new(
target: MaybeHeader<UnverifiedHeaderFor<J>>,
branch_knowledge: BranchKnowledge,
state: State<J>,
) -> Self {
Self {
target_id,
target,
branch_knowledge,
state,
}
Expand All @@ -166,38 +194,54 @@ impl<J: Justification> Request<J> {
pub fn state(&self) -> &State<J> {
&self.state
}
pub fn target_id(&self) -> &BlockId {
&self.target_id
pub fn target(&self) -> &MaybeHeader<UnverifiedHeaderFor<J>> {
&self.target
}
pub fn branch_knowledge(&self) -> &BranchKnowledge {
&self.branch_knowledge
}
}

/// Data that can be used to generate a request given our state.
pub struct PreRequest<I: PeerId> {
id: BlockId,
pub struct PreRequest<UH: UnverifiedHeader, I: PeerId> {
header: MaybeHeader<UH>,
branch_knowledge: BranchKnowledge,
know_most: HashSet<I>,
}

impl<I: PeerId> PreRequest<I> {
pub fn new(id: BlockId, branch_knowledge: BranchKnowledge, know_most: HashSet<I>) -> Self {
impl<UH: UnverifiedHeader, I: PeerId> PreRequest<UH, I> {
pub fn new_headerless(
id: BlockId,
branch_knowledge: BranchKnowledge,
know_most: HashSet<I>,
) -> Self {
PreRequest {
header: MaybeHeader::Id(id),
branch_knowledge,
know_most,
}
}

pub fn new(header: UH, branch_knowledge: BranchKnowledge, know_most: HashSet<I>) -> Self {
PreRequest {
id,
header: MaybeHeader::Header(header),
branch_knowledge,
know_most,
}
}

/// Convert to a request and recipients given a state.
pub fn with_state<J: Justification>(self, state: State<J>) -> (Request<J>, HashSet<I>) {
pub fn with_state<J>(self, state: State<J>) -> (Request<J>, HashSet<I>)
where
J: Justification,
J::Header: Header<Unverified = UH>,
{
let PreRequest {
id,
header,
branch_knowledge,
know_most,
} = self;
(Request::new(id, branch_knowledge, state), know_most)
(Request::new(header, branch_knowledge, state), know_most)
}
}

Expand Down
Loading

0 comments on commit fdcc4f8

Please sign in to comment.