Files
pezkuwi-subxt/polkadot/validation/src/collation.rs
T
Robert Habermeier 15a83079ba refactor out validation hosts to pool struct (#972)
* refactor out validation hosts to pool struct

* make web-wasm compatible

* typo

* remove now-unused static hosts
2020-04-04 15:15:54 -04:00

117 lines
3.7 KiB
Rust

// Copyright 2017-2020 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Polkadot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
//! Validator-side view of collation.
//!
//! This module contains type definitions, a trait for a batch of collators, and a trait for
//! attempting to fetch a collation repeatedly until a valid one is obtained.
use std::sync::Arc;
use polkadot_primitives::{
BlakeTwo256, Block, Hash, HashT,
parachain::{
CollatorId, ParachainHost, Id as ParaId, Collation, ErasureChunk, CollationInfo,
},
};
use polkadot_erasure_coding as erasure;
use sp_api::ProvideRuntimeApi;
use futures::prelude::*;
use log::debug;
/// Encapsulates connections to collators and allows collation on any parachain.
///
/// This is expected to be a lightweight, shared type like an `Arc`.
pub trait Collators: Clone {
/// Errors when producing collations.
type Error: std::fmt::Debug;
/// A full collation.
type Collation: Future<Output=Result<Collation, Self::Error>>;
/// Collate on a specific parachain, building on a given relay chain parent hash.
///
/// The returned collation should be checked for basic validity in the signature
/// and will be checked for state-transition validity by the consumer of this trait.
///
/// This does not have to guarantee local availability, as a valid collation
/// will be passed to the `TableRouter` instance.
///
/// The returned future may be prematurely concluded if the `relay_parent` goes
/// out of date.
fn collate(&self, parachain: ParaId, relay_parent: Hash) -> Self::Collation;
/// Note a bad collator. TODO: take proof (https://github.com/paritytech/polkadot/issues/217)
fn note_bad_collator(&self, collator: CollatorId);
}
/// A future which resolves when a collation is available.
pub async fn collation_fetch<C: Collators, P>(
validation_pool: Option<crate::pipeline::ValidationPool>,
parachain: ParaId,
relay_parent: Hash,
collators: C,
client: Arc<P>,
max_block_data_size: Option<u64>,
n_validators: usize,
) -> Result<(CollationInfo, crate::pipeline::FullOutput), C::Error>
where
P::Api: ParachainHost<Block, Error = sp_blockchain::Error>,
C: Collators + Unpin,
P: ProvideRuntimeApi<Block>,
<C as Collators>::Collation: Unpin,
{
loop {
let collation = collators.collate(parachain, relay_parent).await?;
let Collation { info, pov } = collation;
let res = crate::pipeline::full_output_validation_with_api(
validation_pool.as_ref(),
&*client,
&info,
&pov,
&relay_parent,
max_block_data_size,
n_validators,
);
match res {
Ok(full_output) => {
return Ok((info, full_output))
}
Err(e) => {
debug!("Failed to validate parachain due to API error: {}", e);
// just continue if we got a bad collation or failed to validate
collators.note_bad_collator(info.collator)
}
}
}
}
/// Validate an erasure chunk against an expected root.
pub fn validate_chunk(
root: &Hash,
chunk: &ErasureChunk,
) -> Result<(), ()> {
let expected = erasure::branch_hash(root, &chunk.proof, chunk.index as usize).map_err(|_| ())?;
let got = BlakeTwo256::hash(&chunk.chunk);
if expected != got {
return Err(())
}
Ok(())
}