mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-06 03:17:25 +00:00
15a83079ba
* refactor out validation hosts to pool struct * make web-wasm compatible * typo * remove now-unused static hosts
117 lines
3.7 KiB
Rust
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(())
|
|
}
|