// Copyright 2017 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 . use std::fmt; use primitives::{validator, parachain}; use serde::de::DeserializeOwned; use serializer; use error::{ErrorKind, Result}; use parachains::{ParachainCode, ParaChain1}; /// A dummy validator implementation. #[derive(Debug)] pub struct Validator { codes: Vec>, } impl Validator { /// Create a new validator. pub fn new() -> Self { Validator { codes: vec![ Box::new(ParaChain1) as Box ], } } } impl Validator { pub fn validate( &self, code: &[u8], consolidated_ingress: &[(u64, Vec)], balance_downloads: &[validator::BalanceDownload], block_data: ¶chain::BlockData, previous_head_data: ¶chain::HeadData, ) -> Result { ensure!(code.len() == 1, ErrorKind::InvalidCode(format!("The code should be a single byte."))); match self.codes.get(code[0] as usize) { Some(code) => code.check(consolidated_ingress, balance_downloads, block_data, previous_head_data), None => bail!(ErrorKind::InvalidCode(format!("Unknown parachain code."))), } } } /// Simplified parachain code verification trait Code: fmt::Debug { /// Given parachain candidate block data returns it's validity /// and possible generated egress posts. fn check( &self, consolidated_ingress: &[(u64, Vec)], balance_downloads: &[validator::BalanceDownload], block_data: ¶chain::BlockData, previous_head_data: ¶chain::HeadData, ) -> Result; } impl Code for T where M: DeserializeOwned, B: DeserializeOwned, R: Into, T: ParachainCode, { fn check( &self, consolidated_ingress: &[(u64, Vec)], balance_downloads: &[validator::BalanceDownload], block_data: ¶chain::BlockData, previous_head_data: ¶chain::HeadData, ) -> Result { let messages = consolidated_ingress.iter() .map(|&(ref block, ref vec)| Ok((*block, vec.iter() .map(|msg| serializer::from_slice(&msg.0).map_err(Into::into)) .collect::>>()? ))) .collect::>>()?; let downloads = balance_downloads.iter() .map(|download| serializer::from_slice(&download.0).map_err(Into::into)) .collect::>>()?; let block_data = serializer::from_slice(&block_data.0)?; let head_data = serializer::from_slice(&previous_head_data.0)?; Ok(self.check(messages, downloads, block_data, head_data)?.into()) } }