Files
pezkuwi-subxt/substrate/demo/consensus/src/evaluation.rs
T
Arkadiy Paronyan fea750511e Bring substrate-demo up to date (#658)
* Updating substrate-demo

* Consenus fixes

* Reverted toolchain change

* Adjusted timeout formula

* Simplfied proposal creation

* Fixed tests

* Fixed a few small issues

* 2017->2018

* Style

* More style

* Renamed demo executable to substrate

* Style

* Fixed compilation after merge

* Style
2018-09-10 17:54:32 +02:00

97 lines
3.1 KiB
Rust

// Copyright 2018 Parity Technologies (UK) Ltd.
// This file is part of Substrate Demo.
// Substrate Demo 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.
// Substrate Demo 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 Substrate Demo. If not, see <http://www.gnu.org/licenses/>.
//! Block evaluation and evaluation errors.
use super::MAX_TRANSACTIONS_SIZE;
use codec::{Decode, Encode};
use demo_runtime::{Block as GenericBlock, CheckedBlock};
use demo_primitives::{Block, Hash, BlockNumber, Timestamp};
error_chain! {
links {
Api(::demo_api::Error, ::demo_api::ErrorKind);
}
errors {
BadProposalFormat {
description("Proposal provided not a block."),
display("Proposal provided not a block."),
}
TimestampInFuture {
description("Proposal had timestamp too far in the future."),
display("Proposal had timestamp too far in the future."),
}
WrongParentHash(expected: Hash, got: Hash) {
description("Proposal had wrong parent hash."),
display("Proposal had wrong parent hash. Expected {:?}, got {:?}", expected, got),
}
WrongNumber(expected: BlockNumber, got: BlockNumber) {
description("Proposal had wrong number."),
display("Proposal had wrong number. Expected {:?}, got {:?}", expected, got),
}
ProposalTooLarge(size: usize) {
description("Proposal exceeded the maximum size."),
display(
"Proposal exceeded the maximum size of {} by {} bytes.",
MAX_TRANSACTIONS_SIZE, size.saturating_sub(MAX_TRANSACTIONS_SIZE)
),
}
}
}
/// Attempt to evaluate a substrate block as a demo block, returning error
/// upon any initial validity checks failing.
pub fn evaluate_initial(
proposal: &Block,
now: Timestamp,
parent_hash: &Hash,
parent_number: BlockNumber,
) -> Result<CheckedBlock> {
const MAX_TIMESTAMP_DRIFT: Timestamp = 60;
let encoded = Encode::encode(proposal);
let proposal = GenericBlock::decode(&mut &encoded[..])
.and_then(|b| CheckedBlock::new(b).ok())
.ok_or_else(|| ErrorKind::BadProposalFormat)?;
let transactions_size = proposal.extrinsics.iter().fold(0, |a, tx| {
a + Encode::encode(tx).len()
});
if transactions_size > MAX_TRANSACTIONS_SIZE {
bail!(ErrorKind::ProposalTooLarge(transactions_size))
}
if proposal.header.parent_hash != *parent_hash {
bail!(ErrorKind::WrongParentHash(*parent_hash, proposal.header.parent_hash));
}
if proposal.header.number != parent_number + 1 {
bail!(ErrorKind::WrongNumber(parent_number + 1, proposal.header.number));
}
let block_timestamp = proposal.timestamp();
// lenient maximum -- small drifts will just be delayed using a timer.
if block_timestamp > now + MAX_TIMESTAMP_DRIFT {
bail!(ErrorKind::TimestampInFuture)
}
Ok(proposal)
}