f59ed47b1b
* Aura: Report malice on sibling blocks from the same validator This was originally written by @vkomenda, then squashed for easier rebasing on master. Cleanup of `received_step_hashes` was moved to `verify_block_family`, since `on_prepare_block` does not exist on master, and a unit test was added. Original commit messages: added the map of received block header hashes do not return an error and remove older received block records optimised older record removal block hash comparison optimisation and the weak client ref fix SIBLING_MALICE_DETECTION_PERIOD constant review comments using step numbers instead of block numbers * Add docs; use map_or. * Update step hash record comment. Co-Authored-By: David <dvdplm@gmail.com> * Remove hash records after 2 rounds instead of 100 steps.
118 lines
3.4 KiB
Rust
118 lines
3.4 KiB
Rust
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
|
|
// This file is part of Parity Ethereum.
|
|
|
|
// Parity Ethereum 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.
|
|
|
|
// Parity Ethereum 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 Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
/// Used for Engine testing.
|
|
|
|
use std::str::FromStr;
|
|
use std::sync::Arc;
|
|
use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering};
|
|
|
|
use log::trace;
|
|
use parity_util_mem::MallocSizeOf;
|
|
use common_types::{
|
|
BlockNumber,
|
|
ids::BlockId,
|
|
header::Header,
|
|
errors::EthcoreError,
|
|
engines::machine::{Call, AuxiliaryData},
|
|
};
|
|
use ethereum_types::{H256, Address};
|
|
use machine::Machine;
|
|
use parity_bytes::Bytes;
|
|
|
|
use super::{ValidatorSet, SimpleList};
|
|
|
|
/// Set used for testing with a single validator.
|
|
#[derive(Clone, MallocSizeOf, Debug)]
|
|
pub struct TestSet {
|
|
validator: SimpleList,
|
|
#[ignore_malloc_size_of = "zero sized"]
|
|
last_malicious: Arc<AtomicUsize>,
|
|
#[ignore_malloc_size_of = "zero sized"]
|
|
last_benign: Arc<AtomicUsize>,
|
|
}
|
|
|
|
impl Default for TestSet {
|
|
fn default() -> Self {
|
|
TestSet::new(
|
|
Default::default(),
|
|
Default::default(),
|
|
vec![Address::from_str("7d577a597b2742b498cb5cf0c26cdcd726d39e6e").unwrap()]
|
|
)
|
|
}
|
|
}
|
|
|
|
impl TestSet {
|
|
pub fn new(last_malicious: Arc<AtomicUsize>, last_benign: Arc<AtomicUsize>, validators: Vec<Address>) -> Self {
|
|
TestSet {
|
|
validator: SimpleList::new(validators),
|
|
last_malicious,
|
|
last_benign,
|
|
}
|
|
}
|
|
|
|
pub fn from_validators(validators: Vec<Address>) -> Self {
|
|
TestSet::new(Default::default(), Default::default(), validators)
|
|
}
|
|
|
|
pub fn last_malicious(&self) -> usize {
|
|
self.last_malicious.load(AtomicOrdering::SeqCst)
|
|
}
|
|
|
|
pub fn last_benign(&self) -> usize {
|
|
self.last_benign.load(AtomicOrdering::SeqCst)
|
|
}
|
|
}
|
|
|
|
impl ValidatorSet for TestSet {
|
|
fn default_caller(&self, _block_id: BlockId) -> Box<Call> {
|
|
Box::new(|_, _| Err("Test set doesn't require calls.".into()))
|
|
}
|
|
|
|
fn is_epoch_end(&self, _first: bool, _chain_head: &Header) -> Option<Vec<u8>> { None }
|
|
|
|
fn signals_epoch_end(&self, _: bool, _: &Header, _: AuxiliaryData)
|
|
-> engine::EpochChange
|
|
{
|
|
engine::EpochChange::No
|
|
}
|
|
|
|
fn epoch_set(&self, _: bool, _: &Machine, _: BlockNumber, _: &[u8]) -> Result<(SimpleList, Option<H256>), EthcoreError> {
|
|
Ok((self.validator.clone(), None))
|
|
}
|
|
|
|
fn contains_with_caller(&self, bh: &H256, address: &Address, _: &Call) -> bool {
|
|
self.validator.contains(bh, address)
|
|
}
|
|
|
|
fn get_with_caller(&self, bh: &H256, nonce: usize, _: &Call) -> Address {
|
|
self.validator.get(bh, nonce)
|
|
}
|
|
|
|
fn count_with_caller(&self, _bh: &H256, _: &Call) -> usize {
|
|
1
|
|
}
|
|
|
|
fn report_malicious(&self, _validator: &Address, _set_block: BlockNumber, block: BlockNumber, _proof: Bytes) {
|
|
self.last_malicious.store(block as usize, AtomicOrdering::SeqCst)
|
|
}
|
|
|
|
fn report_benign(&self, _validator: &Address, _set_block: BlockNumber, block: BlockNumber) {
|
|
trace!(target: "engine", "test validator set recording benign misbehaviour");
|
|
self.last_benign.store(block as usize, AtomicOrdering::SeqCst)
|
|
}
|
|
}
|