referrerpolicy=no-referrer-when-downgrade

sc_service/client/
block_rules.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
5
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// You should have received a copy of the GNU General Public License
17// along with this program. If not, see <https://www.gnu.org/licenses/>.
18
19//! Client fixed chain specification rules
20
21use std::collections::{HashMap, HashSet};
22
23use sp_runtime::traits::{Block as BlockT, NumberFor};
24
25use sc_client_api::{BadBlocks, ForkBlocks};
26
27/// Chain specification rules lookup result.
28pub enum LookupResult<B: BlockT> {
29	/// Specification rules do not contain any special rules about this block
30	NotSpecial,
31	/// The block is known to be bad and should not be imported
32	KnownBad,
33	/// There is a specified canonical block hash for the given height
34	Expected(B::Hash),
35}
36
37/// Chain-specific block filtering rules.
38///
39/// This holds known bad blocks and known good forks, and
40/// is usually part of the chain spec.
41pub struct BlockRules<B: BlockT> {
42	bad: HashSet<B::Hash>,
43	forks: HashMap<NumberFor<B>, B::Hash>,
44}
45
46impl<B: BlockT> BlockRules<B> {
47	/// New block rules with provided black and white lists.
48	pub fn new(fork_blocks: ForkBlocks<B>, bad_blocks: BadBlocks<B>) -> Self {
49		Self {
50			bad: bad_blocks.unwrap_or_default(),
51			forks: fork_blocks.unwrap_or_default().into_iter().collect(),
52		}
53	}
54
55	/// Mark a new block as bad.
56	pub fn mark_bad(&mut self, hash: B::Hash) {
57		self.bad.insert(hash);
58	}
59
60	/// Check if there's any rule affecting the given block.
61	pub fn lookup(&self, number: NumberFor<B>, hash: &B::Hash) -> LookupResult<B> {
62		if let Some(hash_for_height) = self.forks.get(&number) {
63			if hash_for_height != hash {
64				return LookupResult::Expected(*hash_for_height)
65			}
66		}
67
68		if self.bad.contains(hash) {
69			return LookupResult::KnownBad
70		}
71
72		LookupResult::NotSpecial
73	}
74}