Remove dependency on error_chain (#277)

* Convert validation error

* Convert wasm_executor error

* Convert block evaluation error

* Convert collation errors and the compilation

* Remove error-chain dep from service

* Remove unused Result type

* Remove unused error variants

* Remove redundant intos

* Add missing comments

* Update validation/src/collation.rs

Co-Authored-By: thiolliere <gui.thiolliere@gmail.com>

* Fix new error variant
This commit is contained in:
Andrew Jones
2019-06-05 09:25:08 +01:00
committed by Bastian Köcher
parent 0634e90031
commit bdc1502411
10 changed files with 202 additions and 194 deletions
+2 -3
View File
@@ -2365,7 +2365,7 @@ dependencies = [
name = "polkadot-parachain" name = "polkadot-parachain"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "derive_more 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec 3.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-codec-derive 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec-derive 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2441,7 +2441,6 @@ dependencies = [
name = "polkadot-service" name = "polkadot-service"
version = "0.5.0" version = "0.5.0"
dependencies = [ dependencies = [
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2481,7 +2480,7 @@ dependencies = [
name = "polkadot-validation" name = "polkadot-validation"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "derive_more 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"exit-future 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "exit-future 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+2 -2
View File
@@ -8,7 +8,7 @@ description = "Types and utilities for creating and working with parachains"
parity-codec = { version = "3.5", default-features = false } parity-codec = { version = "3.5", default-features = false }
parity-codec-derive = { version = "3.3", default-features = false } parity-codec-derive = { version = "3.3", default-features = false }
wasmi = { version = "0.4.3", optional = true } wasmi = { version = "0.4.3", optional = true }
error-chain = { version = "0.12", optional = true } derive_more = { version = "0.14", optional = true }
serde = { version = "1.0", default-features = false } serde = { version = "1.0", default-features = false }
serde_derive = { version = "1.0", optional = true } serde_derive = { version = "1.0", optional = true }
@@ -18,4 +18,4 @@ tiny-keccak = "1.4"
[features] [features]
default = ["std"] default = ["std"]
wasm-api = [] wasm-api = []
std = ["parity-codec/std", "wasmi", "error-chain", "serde_derive", "serde/std"] std = ["parity-codec/std", "wasmi", "derive_more", "serde_derive", "serde/std"]
-4
View File
@@ -57,10 +57,6 @@ extern crate core;
#[cfg(feature = "std")] #[cfg(feature = "std")]
extern crate wasmi; extern crate wasmi;
#[cfg(feature = "std")]
#[macro_use]
extern crate error_chain;
#[cfg(feature = "std")] #[cfg(feature = "std")]
extern crate serde; extern crate serde;
+28 -23
View File
@@ -37,22 +37,27 @@ mod ids {
pub const POST_UPWARDS_MESSAGE: usize = 2; pub const POST_UPWARDS_MESSAGE: usize = 2;
} }
error_chain! { /// Error type for the wasm executor
types { Error, ErrorKind, ResultExt; } #[derive(Debug, derive_more::Display, derive_more::From)]
foreign_links { pub enum Error {
Wasm(WasmError); /// Wasm error
Externalities(ExternalitiesError); Wasm(WasmError),
} /// Externalities error
errors { Externalities(ExternalitiesError),
/// Call data too big. WASM32 only has a 32-bit address space. /// Call data too big. WASM32 only has a 32-bit address space.
ParamsTooLarge(len: usize) { #[display(fmt = "Validation parameters took up {} bytes, max allowed by WASM is {}", _0, i32::max_value())]
description("Validation parameters took up too much space to execute in WASM"), ParamsTooLarge(usize),
display("Validation parameters took up {} bytes, max allowed by WASM is {}", len, i32::max_value()), /// Bad return data or type.
} #[display(fmt = "Validation function returned invalid data.")]
/// Bad return data or type. BadReturn,
BadReturn { }
description("Validation function returned invalid data."),
display("Validation function returned invalid data."), impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Error::Wasm(ref err) => Some(err),
Error::Externalities(ref err) => Some(err),
_ => None,
} }
} }
} }
@@ -284,7 +289,7 @@ pub fn validate_candidate<E: Externalities>(
// hard limit from WASM. // hard limit from WASM.
if encoded_call_data.len() > i32::max_value() as usize { if encoded_call_data.len() > i32::max_value() as usize {
bail!(ErrorKind::ParamsTooLarge(encoded_call_data.len())); return Err(Error::ParamsTooLarge(encoded_call_data.len()));
} }
// allocate sufficient amount of wasm pages to fit encoded call data. // allocate sufficient amount of wasm pages to fit encoded call data.
@@ -308,7 +313,7 @@ pub fn validate_candidate<E: Externalities>(
.map_err(|e| -> Error { .map_err(|e| -> Error {
e.as_host_error() e.as_host_error()
.and_then(|he| he.downcast_ref::<ExternalitiesError>()) .and_then(|he| he.downcast_ref::<ExternalitiesError>())
.map(|ee| ErrorKind::Externalities(ee.clone()).into()) .map(|ee| Error::Externalities(ee.clone()))
.unwrap_or_else(move || e.into()) .unwrap_or_else(move || e.into())
})?; })?;
@@ -321,24 +326,24 @@ pub fn validate_candidate<E: Externalities>(
let len_offset = len_offset as usize; let len_offset = len_offset as usize;
let len = u32::decode(&mut &len_bytes[..]) let len = u32::decode(&mut &len_bytes[..])
.ok_or_else(|| ErrorKind::BadReturn)? as usize; .ok_or_else(|| Error::BadReturn)? as usize;
let return_offset = if len > len_offset { let return_offset = if len > len_offset {
bail!(ErrorKind::BadReturn); return Err(Error::BadReturn);
} else { } else {
len_offset - len len_offset - len
}; };
memory.with_direct_access(|mem| { memory.with_direct_access(|mem| {
if mem.len() < return_offset + len { if mem.len() < return_offset + len {
return Err(ErrorKind::BadReturn.into()); return Err(Error::BadReturn);
} }
ValidationResult::decode(&mut &mem[return_offset..][..len]) ValidationResult::decode(&mut &mem[return_offset..][..len])
.ok_or_else(|| ErrorKind::BadReturn) .ok_or_else(|| Error::BadReturn)
.map_err(Into::into) .map_err(Into::into)
}) })
} }
_ => bail!(ErrorKind::BadReturn), _ => return Err(Error::BadReturn),
} }
} }
-1
View File
@@ -6,7 +6,6 @@ edition = "2018"
[dependencies] [dependencies]
parking_lot = "0.7.1" parking_lot = "0.7.1"
error-chain = "0.12"
lazy_static = "1.0" lazy_static = "1.0"
log = "0.4.6" log = "0.4.6"
slog = "^2" slog = "^2"
+1 -1
View File
@@ -8,7 +8,7 @@ edition = "2018"
futures = "0.1.17" futures = "0.1.17"
parking_lot = "0.7.1" parking_lot = "0.7.1"
tokio = "0.1.7" tokio = "0.1.7"
error-chain = "0.12" derive_more = "0.14.0"
log = "0.4.6" log = "0.4.6"
exit-future = "0.1" exit-future = "0.1"
parity-codec = "3.1" parity-codec = "3.1"
+79 -80
View File
@@ -27,10 +27,8 @@ use polkadot_primitives::{Block, Hash, BlockId, parachain::CollatorId, parachain
}}; }};
use runtime_primitives::traits::ProvideRuntimeApi; use runtime_primitives::traits::ProvideRuntimeApi;
use parachain::{wasm_executor::{self, ExternalitiesError}, MessageRef, UpwardMessageRef}; use parachain::{wasm_executor::{self, ExternalitiesError}, MessageRef, UpwardMessageRef};
use error_chain::bail;
use futures::prelude::*; use futures::prelude::*;
use error_chain::*;
use log::debug; use log::debug;
/// Encapsulates connections to collators and allows collation on any parachain. /// Encapsulates connections to collators and allows collation on any parachain.
@@ -136,62 +134,47 @@ impl<C: Collators, P: ProvideRuntimeApi> Future for CollationFetch<C, P>
} }
// Errors that can occur when validating a parachain. // Errors that can occur when validating a parachain.
error_chain! { #[derive(Debug, derive_more::Display, derive_more::From)]
types { Error, ErrorKind, ResultExt; } pub enum Error {
/// Client error
Client(client::error::Error),
/// Wasm validation error
WasmValidation(wasm_executor::Error),
/// Collated for inactive parachain
#[display(fmt = "Collated for inactive parachain: {:?}", _0)]
InactiveParachain(ParaId),
/// Unexpected egress root
#[display(fmt = "Got unexpected egress root to {:?}. (expected: {:?}, got {:?})", id, expected, got)]
EgressRootMismatch { id: ParaId, expected: Hash, got: Hash },
/// Unexpected ingress root
#[display(fmt = "Got unexpected ingress root to {:?}. (expected: {:?}, got {:?})", id, expected, got)]
IngressRootMismatch { id: ParaId, expected: Hash, got: Hash },
/// Ingress from wrong chain
#[display(fmt = "Got ingress from wrong chain. (expected: {:?}, got {:?})", expected, got)]
IngressChainMismatch { expected: ParaId, got: ParaId },
/// Ingress canonicality mismatch
#[display(fmt = "Got data for {} roots, expected {}", expected, got)]
IngressCanonicalityMismatch { expected: usize, got: usize },
/// Missing or extra egress root
#[display(fmt = "Missing or extra egress root. (expected: {:?}, got {:?})", expected, got)]
MissingEgressRoot { expected: Option<ParaId>, got: Option<ParaId>, },
/// Parachain validation produced wrong head data
#[display(fmt = "Parachain validation produced wrong head data (expected: {:?}, got {:?})", expected, got)]
WrongHeadData { expected: Vec<u8>, got: Vec<u8> },
/// Block data is too big
#[display(fmt = "Block data is too big (maximum allowed size: {}, actual size: {})", size, max_size)]
BlockDataTooBig { size: u64, max_size: u64 },
/// Parachain validation produced wrong relay-chain messages
#[display(fmt = "Parachain validation produced wrong relay-chain messages (expected: {:?}, got {:?})", expected, got)]
UpwardMessagesInvalid { expected: Vec<UpwardMessage>, got: Vec<UpwardMessage> },
}
foreign_links { impl std::error::Error for Error {
Client(::client::error::Error); fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
} match self {
Error::Client(ref err) => Some(err),
links { Error::WasmValidation(ref err) => Some(err),
WasmValidation(wasm_executor::Error, wasm_executor::ErrorKind); _ => None,
}
errors {
InactiveParachain(id: ParaId) {
description("Collated for inactive parachain"),
display("Collated for inactive parachain: {:?}", id),
}
EgressRootMismatch(id: ParaId, expected: Hash, got: Hash) {
description("Got unexpected egress root."),
display(
"Got unexpected egress root to {:?}. (expected: {:?}, got {:?})",
id, expected, got
),
}
IngressRootMismatch(id: ParaId, expected: Hash, got: Hash) {
description("Got unexpected ingress root."),
display(
"Got unexpected ingress root to {:?}. (expected: {:?}, got {:?})",
id, expected, got
),
}
IngressChainMismatch(expected: ParaId, got: ParaId) {
description("Got ingress from wrong chain"),
display(
"Got ingress from wrong chain. (expected: {:?}, got {:?})",
expected, got
),
}
IngressCanonicalityMismatch(expected: usize, got: usize) {
description("Ingress canonicality mismatch."),
display("Got data for {} roots, expected {}", got, expected),
}
MissingEgressRoot(expected: Option<ParaId>, got: Option<ParaId>) {
description("Missing or extra egress root."),
display("Missing or extra egress root. (expected: {:?}, got {:?})", expected, got),
}
WrongHeadData(expected: Vec<u8>, got: Vec<u8>) {
description("Parachain validation produced wrong head data."),
display("Parachain validation produced wrong head data (expected: {:?}, got {:?})", expected, got),
}
BlockDataTooBig(size: u64, max_size: u64) {
description("Block data is too big."),
display("Block data is too big (maximum allowed size: {}, actual size: {})", max_size, size),
}
UpwardMessagesInvalid(expected: Vec<UpwardMessage>, got: Vec<UpwardMessage>) {
description("Parachain validation produced wrong relay-chain messages."),
display("Parachain validation produced wrong relay-chain messages (expected: {:?}, got {:?})", expected, got),
} }
} }
} }
@@ -240,11 +223,17 @@ fn check_extrinsic(
let mut expected_egress_roots = expected_egress_roots.iter(); let mut expected_egress_roots = expected_egress_roots.iter();
while let Some(batch_target) = messages_iter.peek().map(|o| o.target) { while let Some(batch_target) = messages_iter.peek().map(|o| o.target) {
let expected_root = match expected_egress_roots.next() { let expected_root = match expected_egress_roots.next() {
None => return Err(ErrorKind::MissingEgressRoot(Some(batch_target), None).into()), None => return Err(Error::MissingEgressRoot {
expected: Some(batch_target),
got: None
}),
Some(&(id, ref root)) => if id == batch_target { Some(&(id, ref root)) => if id == batch_target {
root root
} else { } else {
return Err(ErrorKind::MissingEgressRoot(Some(batch_target), Some(id)).into()); return Err(Error::MissingEgressRoot{
expected: Some(batch_target),
got: Some(id)
});
} }
}; };
@@ -258,17 +247,17 @@ fn check_extrinsic(
let computed_root = message_queue_root(messages_to); let computed_root = message_queue_root(messages_to);
if &computed_root != expected_root { if &computed_root != expected_root {
return Err(ErrorKind::EgressRootMismatch( return Err(Error::EgressRootMismatch {
batch_target, id: batch_target,
expected_root.clone(), expected: expected_root.clone(),
computed_root, got: computed_root,
).into()); });
} }
} }
// also check that there are no more additional expected roots. // also check that there are no more additional expected roots.
if let Some((next_target, _)) = expected_egress_roots.next() { if let Some((next_target, _)) = expected_egress_roots.next() {
return Err(ErrorKind::MissingEgressRoot(None, Some(*next_target)).into()); return Err(Error::MissingEgressRoot { expected: None, got: Some(*next_target) });
} }
} }
@@ -320,10 +309,10 @@ impl Externalities {
candidate: &CandidateReceipt, candidate: &CandidateReceipt,
) -> Result<Extrinsic, Error> { ) -> Result<Extrinsic, Error> {
if &self.upward != &candidate.upward_messages { if &self.upward != &candidate.upward_messages {
bail!(ErrorKind::UpwardMessagesInvalid( return Err(Error::UpwardMessagesInvalid {
candidate.upward_messages.clone(), expected: candidate.upward_messages.clone(),
self.upward.clone(), got: self.upward.clone(),
)); });
} }
check_extrinsic( check_extrinsic(
@@ -339,18 +328,28 @@ pub fn validate_incoming(
ingress: &ConsolidatedIngress, ingress: &ConsolidatedIngress,
) -> Result<(), Error> { ) -> Result<(), Error> {
if roots.0.len() != ingress.0.len() { if roots.0.len() != ingress.0.len() {
bail!(ErrorKind::IngressCanonicalityMismatch(roots.0.len(), ingress.0.len())); return Err(Error::IngressCanonicalityMismatch {
expected: roots.0.len(),
got: ingress.0.len()
});
} }
let all_iter = roots.0.iter().zip(&ingress.0); let all_iter = roots.0.iter().zip(&ingress.0);
for ((expected_id, root), (got_id, messages)) in all_iter { for ((expected_id, root), (got_id, messages)) in all_iter {
if expected_id != got_id { if expected_id != got_id {
bail!(ErrorKind::IngressChainMismatch(*expected_id, *got_id)); return Err(Error::IngressChainMismatch {
expected: *expected_id,
got: *got_id
});
} }
let got_root = message_queue_root(messages.iter().map(|msg| &msg.0[..])); let got_root = message_queue_root(messages.iter().map(|msg| &msg.0[..]));
if &got_root != root { if &got_root != root {
bail!(ErrorKind::IngressRootMismatch(*expected_id, *root, got_root)); return Err(Error::IngressRootMismatch{
id: *expected_id,
expected: *root,
got: got_root
});
} }
} }
@@ -375,20 +374,20 @@ pub fn validate_collation<P>(
if let Some(max_size) = max_block_data_size { if let Some(max_size) = max_block_data_size {
let block_data_size = collation.pov.block_data.0.len() as u64; let block_data_size = collation.pov.block_data.0.len() as u64;
if block_data_size > max_size { if block_data_size > max_size {
return Err(ErrorKind::BlockDataTooBig(block_data_size, max_size).into()); return Err(Error::BlockDataTooBig { size: block_data_size, max_size });
} }
} }
let api = client.runtime_api(); let api = client.runtime_api();
let para_id = collation.receipt.parachain_index; let para_id = collation.receipt.parachain_index;
let validation_code = api.parachain_code(relay_parent, para_id)? let validation_code = api.parachain_code(relay_parent, para_id)?
.ok_or_else(|| ErrorKind::InactiveParachain(para_id))?; .ok_or_else(|| Error::InactiveParachain(para_id))?;
let chain_head = api.parachain_head(relay_parent, para_id)? let chain_head = api.parachain_head(relay_parent, para_id)?
.ok_or_else(|| ErrorKind::InactiveParachain(para_id))?; .ok_or_else(|| Error::InactiveParachain(para_id))?;
let roots = api.ingress(relay_parent, para_id)? let roots = api.ingress(relay_parent, para_id)?
.ok_or_else(|| ErrorKind::InactiveParachain(para_id))?; .ok_or_else(|| Error::InactiveParachain(para_id))?;
validate_incoming(&roots, &collation.pov.ingress)?; validate_incoming(&roots, &collation.pov.ingress)?;
let params = ValidationParams { let params = ValidationParams {
@@ -415,10 +414,10 @@ pub fn validate_collation<P>(
if result.head_data == collation.receipt.head_data.0 { if result.head_data == collation.receipt.head_data.0 {
ext.final_checks(&collation.receipt) ext.final_checks(&collation.receipt)
} else { } else {
Err(ErrorKind::WrongHeadData( Err(Error::WrongHeadData {
collation.receipt.head_data.0.clone(), expected: collation.receipt.head_data.0.clone(),
result.head_data got: result.head_data
).into()) })
} }
} }
Err(e) => Err(e.into()) Err(e) => Err(e.into())
+36 -30
View File
@@ -18,38 +18,44 @@
use runtime_primitives::RuntimeString; use runtime_primitives::RuntimeString;
use primitives::ed25519::Public as AuthorityId; use primitives::ed25519::Public as AuthorityId;
use error_chain::*;
error_chain! { /// Error type for validation
foreign_links { #[derive(Debug, derive_more::Display, derive_more::From)]
Client(::client::error::Error); pub enum Error {
Consensus(::consensus::error::Error); /// Client error
} Client(client::error::Error),
/// Consensus error
Consensus(consensus::error::Error),
#[display(fmt = "Invalid duty roster length: expected {}, got {}", expected, got)]
InvalidDutyRosterLength {
/// Expected roster length
expected: usize,
/// Actual roster length
got: usize,
},
/// Local account not a validator at this block
#[display(fmt = "Local account ID ({:?}) not a validator at this block.", _0)]
NotValidator(AuthorityId),
/// Unexpected error checking inherents
#[display(fmt = "Unexpected error while checking inherents: {}", _0)]
InherentError(RuntimeString),
/// Proposer destroyed before finishing proposing or evaluating
#[display(fmt = "Proposer destroyed before finishing proposing or evaluating")]
PrematureDestruction,
/// Timer failed
#[display(fmt = "Timer failed: {}", _0)]
Timer(tokio::timer::Error),
/// Unable to dispatch agreement future
#[display(fmt = "Unable to dispatch agreement future: {:?}", _0)]
Executor(futures::future::ExecuteErrorKind),
}
errors { impl std::error::Error for Error {
InvalidDutyRosterLength(expected: usize, got: usize) { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
description("Duty Roster had invalid length"), match self {
display("Invalid duty roster length: expected {}, got {}", expected, got), Error::Client(ref err) => Some(err),
} Error::Consensus(ref err) => Some(err),
NotValidator(id: AuthorityId) { _ => None,
description("Local account ID not a validator at this block."),
display("Local account ID ({:?}) not a validator at this block.", id),
}
InherentError(reason: RuntimeString) {
description("Unexpected error while checking inherents"),
display("Unexpected error while checking inherents: {}", reason),
}
PrematureDestruction {
description("Proposer destroyed before finishing proposing or evaluating"),
display("Proposer destroyed before finishing proposing or evaluating"),
}
Timer(e: ::tokio::timer::Error) {
description("Failed to register or resolve async timer."),
display("Timer failed: {}", e),
}
Executor(e: ::futures::future::ExecuteErrorKind) {
description("Unable to dispatch agreement future"),
display("Unable to dispatch agreement future: {:?}", e),
} }
} }
} }
+41 -39
View File
@@ -21,44 +21,40 @@ use super::MAX_TRANSACTIONS_SIZE;
use parity_codec::Encode; use parity_codec::Encode;
use polkadot_primitives::{Block, Hash, BlockNumber}; use polkadot_primitives::{Block, Hash, BlockNumber};
use polkadot_primitives::parachain::Id as ParaId; use polkadot_primitives::parachain::Id as ParaId;
use error_chain::*;
error_chain! { /// Result type alias for block evaluation
foreign_links { pub type Result<T> = std::result::Result<T, Error>;
Client(::client::error::Error);
}
errors { /// Error type for block evaluation
ProposalNotForPolkadot { #[derive(Debug, derive_more::Display, derive_more::From)]
description("Proposal provided not a Polkadot block."), pub enum Error {
display("Proposal provided not a Polkadot block."), /// Client error
} Client(client::error::Error),
TooManyCandidates(expected: usize, got: usize) { /// Too many parachain candidates in proposal
description("Proposal included more candidates than is possible."), #[display(fmt = "Proposal included {} candidates for {} parachains", expected, got)]
display("Proposal included {} candidates for {} parachains", got, expected), TooManyCandidates { expected: usize, got: usize },
} /// Proposal included unregistered parachain
ParachainOutOfOrder { #[display(fmt = "Proposal included unregistered parachain {:?}", _0)]
description("Proposal included parachains out of order."), UnknownParachain(ParaId),
display("Proposal included parachains out of order."), /// Proposal had wrong parent hash
} #[display(fmt = "Proposal had wrong parent hash. Expected {:?}, got {:?}", expected, got)]
UnknownParachain(id: ParaId) { WrongParentHash { expected: Hash, got: Hash },
description("Proposal included unregistered parachain."), /// Proposal had wrong number
display("Proposal included unregistered parachain {:?}", id), #[display(fmt = "Proposal had wrong number. Expected {:?}, got {:?}", expected, got)]
} WrongNumber { expected: BlockNumber, got: BlockNumber },
WrongParentHash(expected: Hash, got: Hash) { /// Proposal exceeded the maximum size
description("Proposal had wrong parent hash."), #[display(
display("Proposal had wrong parent hash. Expected {:?}, got {:?}", expected, got), fmt = "Proposal exceeded the maximum size of {} by {} bytes.",
} MAX_TRANSACTIONS_SIZE, MAX_TRANSACTIONS_SIZE.saturating_sub(*_0)
WrongNumber(expected: BlockNumber, got: BlockNumber) { )]
description("Proposal had wrong number."), ProposalTooLarge(usize),
display("Proposal had wrong number. Expected {:?}, got {:?}", expected, got), }
}
ProposalTooLarge(size: usize) { impl std::error::Error for Error {
description("Proposal exceeded the maximum size."), fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
display( match self {
"Proposal exceeded the maximum size of {} by {} bytes.", Error::Client(ref err) => Some(err),
MAX_TRANSACTIONS_SIZE, MAX_TRANSACTIONS_SIZE.saturating_sub(*size) _ => None,
),
} }
} }
} }
@@ -77,15 +73,21 @@ pub fn evaluate_initial(
}); });
if transactions_size > MAX_TRANSACTIONS_SIZE { if transactions_size > MAX_TRANSACTIONS_SIZE {
bail!(ErrorKind::ProposalTooLarge(transactions_size)) return Err(Error::ProposalTooLarge(transactions_size))
} }
if proposal.header.parent_hash != *parent_hash { if proposal.header.parent_hash != *parent_hash {
bail!(ErrorKind::WrongParentHash(*parent_hash, proposal.header.parent_hash)); return Err(Error::WrongParentHash {
expected: *parent_hash,
got: proposal.header.parent_hash
});
} }
if proposal.header.number != parent_number + 1 { if proposal.header.number != parent_number + 1 {
bail!(ErrorKind::WrongNumber(parent_number + 1, proposal.header.number)); return Err(Error::WrongNumber {
expected: parent_number + 1,
got: proposal.header.number
});
} }
Ok(()) Ok(())
+13 -11
View File
@@ -62,14 +62,13 @@ use dynamic_inclusion::DynamicInclusion;
use inherents::InherentData; use inherents::InherentData;
use runtime_aura::timestamp::TimestampInherentData; use runtime_aura::timestamp::TimestampInherentData;
use log::{info, debug, warn, trace}; use log::{info, debug, warn, trace};
use error_chain::bail;
use ed25519::Public as AuthorityId; use ed25519::Public as AuthorityId;
pub use self::collation::{ pub use self::collation::{
validate_collation, validate_incoming, message_queue_root, egress_roots, Collators, validate_collation, validate_incoming, message_queue_root, egress_roots, Collators,
}; };
pub use self::error::{ErrorKind, Error}; pub use self::error::Error;
pub use self::shared_table::{ pub use self::shared_table::{
SharedTable, ParachainWork, PrimedParachainWork, Validated, Statement, SignedStatement, SharedTable, ParachainWork, PrimedParachainWork, Validated, Statement, SignedStatement,
GenericStatement, GenericStatement,
@@ -188,7 +187,10 @@ pub fn make_group_info(
local_id: AuthorityId, local_id: AuthorityId,
) -> Result<(HashMap<ParaId, GroupInfo>, LocalDuty), Error> { ) -> Result<(HashMap<ParaId, GroupInfo>, LocalDuty), Error> {
if roster.validator_duty.len() != authorities.len() { if roster.validator_duty.len() != authorities.len() {
bail!(ErrorKind::InvalidDutyRosterLength(authorities.len(), roster.validator_duty.len())) return Err(Error::InvalidDutyRosterLength {
expected: authorities.len(),
got: roster.validator_duty.len()
});
} }
let mut local_validation = None; let mut local_validation = None;
@@ -223,7 +225,7 @@ pub fn make_group_info(
Ok((map, local_duty)) Ok((map, local_duty))
} }
None => bail!(ErrorKind::NotValidator(local_id)), None => return Err(Error::NotValidator(local_id)),
} }
} }
@@ -594,7 +596,7 @@ impl<C, TxApi> consensus::Proposer<Block> for Proposer<C, TxApi> where
let believed_timestamp = match inherent_data.timestamp_inherent_data() { let believed_timestamp = match inherent_data.timestamp_inherent_data() {
Ok(timestamp) => timestamp, Ok(timestamp) => timestamp,
Err(e) => return Either::B(future::err(ErrorKind::InherentError(e).into())), Err(e) => return Either::B(future::err(Error::InherentError(e))),
}; };
// set up delay until next allowed timestamp. // set up delay until next allowed timestamp.
@@ -649,26 +651,26 @@ struct ProposalTiming {
impl ProposalTiming { impl ProposalTiming {
// whether it's time to attempt a proposal. // whether it's time to attempt a proposal.
// shouldn't be called outside of the context of a task. // shouldn't be called outside of the context of a task.
fn poll(&mut self, included: usize) -> Poll<(), ErrorKind> { fn poll(&mut self, included: usize) -> Poll<(), Error> {
// first drain from the interval so when the minimum delay is up // first drain from the interval so when the minimum delay is up
// we don't have any notifications built up. // we don't have any notifications built up.
// //
// this interval is just meant to produce periodic task wakeups // this interval is just meant to produce periodic task wakeups
// that lead to the `dynamic_inclusion` getting updated as necessary. // that lead to the `dynamic_inclusion` getting updated as necessary.
while let Async::Ready(x) = self.attempt_propose.poll().map_err(ErrorKind::Timer)? { while let Async::Ready(x) = self.attempt_propose.poll().map_err(Error::Timer)? {
x.expect("timer still alive; intervals never end; qed"); x.expect("timer still alive; intervals never end; qed");
} }
// wait until the minimum time has passed. // wait until the minimum time has passed.
if let Some(mut minimum) = self.minimum.take() { if let Some(mut minimum) = self.minimum.take() {
if let Async::NotReady = minimum.poll().map_err(ErrorKind::Timer)? { if let Async::NotReady = minimum.poll().map_err(Error::Timer)? {
self.minimum = Some(minimum); self.minimum = Some(minimum);
return Ok(Async::NotReady); return Ok(Async::NotReady);
} }
} }
if included == self.last_included { if included == self.last_included {
return self.enough_candidates.poll().map_err(ErrorKind::Timer); return self.enough_candidates.poll().map_err(Error::Timer);
} }
// the amount of includable candidates has changed. schedule a wakeup // the amount of includable candidates has changed. schedule a wakeup
@@ -677,7 +679,7 @@ impl ProposalTiming {
Some(instant) => { Some(instant) => {
self.last_included = included; self.last_included = included;
self.enough_candidates.reset(instant); self.enough_candidates.reset(instant);
self.enough_candidates.poll().map_err(ErrorKind::Timer) self.enough_candidates.poll().map_err(Error::Timer)
} }
None => Ok(Async::Ready(())), None => Ok(Async::Ready(())),
} }
@@ -712,7 +714,7 @@ impl<C, TxApi> CreateProposal<C, TxApi> where
let mut inherent_data = self.inherent_data let mut inherent_data = self.inherent_data
.take() .take()
.expect("CreateProposal is not polled after finishing; qed"); .expect("CreateProposal is not polled after finishing; qed");
inherent_data.put_data(polkadot_runtime::PARACHAIN_INHERENT_IDENTIFIER, &candidates).map_err(ErrorKind::InherentError)?; inherent_data.put_data(polkadot_runtime::PARACHAIN_INHERENT_IDENTIFIER, &candidates).map_err(Error::InherentError)?;
let runtime_api = self.client.runtime_api(); let runtime_api = self.client.runtime_api();