evaluation.rs 3.01 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 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 <http://www.gnu.org/licenses/>.

//! Polkadot block evaluation and evaluation errors.

use super::MAX_TRANSACTIONS_SIZE;

21
use codec::Encode;
Gav Wood's avatar
Gav Wood committed
22
use polkadot_primitives::{Block, Hash, BlockNumber};
23
24
25
26
use polkadot_primitives::parachain::Id as ParaId;

error_chain! {
	links {
27
		Client(::client::error::Error, ::client::error::ErrorKind);
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
	}

	errors {
		ProposalNotForPolkadot {
			description("Proposal provided not a Polkadot block."),
			display("Proposal provided not a Polkadot block."),
		}
		TooManyCandidates(expected: usize, got: usize) {
			description("Proposal included more candidates than is possible."),
			display("Proposal included {} candidates for {} parachains", got, expected),
		}
		ParachainOutOfOrder {
			description("Proposal included parachains out of order."),
			display("Proposal included parachains out of order."),
		}
		UnknownParachain(id: ParaId) {
			description("Proposal included unregistered parachain."),
			display("Proposal included unregistered parachain {:?}", id),
		}
Gav Wood's avatar
Gav Wood committed
47
		WrongParentHash(expected: Hash, got: Hash) {
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
			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, MAX_TRANSACTIONS_SIZE.saturating_sub(*size)
			),
		}
	}
}

/// Attempt to evaluate a substrate block as a polkadot block, returning error
/// upon any initial validity checks failing.
pub fn evaluate_initial(
Gav Wood's avatar
Gav Wood committed
68
	proposal: &Block,
Gav Wood's avatar
Gav Wood committed
69
	_now: u64,
Gav Wood's avatar
Gav Wood committed
70
	parent_hash: &Hash,
71
	parent_number: BlockNumber,
72
73
	_active_parachains: &[ParaId],
) -> Result<()> {
74
	let transactions_size = proposal.extrinsics.iter().fold(0, |a, tx| {
Arkadiy Paronyan's avatar
Arkadiy Paronyan committed
75
		a + Encode::encode(tx).len()
76
77
78
79
80
81
82
83
84
85
86
87
88
89
	});

	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));
	}

90
	Ok(())
91
}