2016-02-05 13:40:41 +01:00
|
|
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
|
|
|
// This file is part of Parity.
|
|
|
|
|
|
|
|
// Parity 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 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. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
2016-07-28 20:32:20 +02:00
|
|
|
//! Consensus engine specification and basic implementations.
|
|
|
|
|
|
|
|
mod null_engine;
|
2016-07-30 23:42:31 +02:00
|
|
|
mod instant_seal;
|
2016-07-28 20:32:20 +02:00
|
|
|
mod basic_authority;
|
2016-08-23 12:58:40 +02:00
|
|
|
mod tendermint;
|
2016-08-22 13:19:23 +02:00
|
|
|
mod signed_vote;
|
2016-08-23 12:58:40 +02:00
|
|
|
mod propose_collect;
|
2016-07-28 20:32:20 +02:00
|
|
|
|
|
|
|
pub use self::null_engine::NullEngine;
|
2016-07-30 23:42:31 +02:00
|
|
|
pub use self::instant_seal::InstantSeal;
|
2016-07-28 20:32:20 +02:00
|
|
|
pub use self::basic_authority::BasicAuthority;
|
2016-08-23 12:58:40 +02:00
|
|
|
pub use self::tendermint::Tendermint;
|
2016-08-24 15:55:47 +02:00
|
|
|
pub use self::signed_vote::SignedVote;
|
|
|
|
pub use self::propose_collect::ProposeCollect;
|
2016-05-16 18:16:56 +02:00
|
|
|
|
2016-08-23 17:19:23 +02:00
|
|
|
use common::{HashMap, SemanticVersion, Header, EnvInfo, Address, Builtin, BTreeMap, U256, Bytes, SignedTransaction, Error, UntrustedRlp};
|
2016-06-20 00:10:34 +02:00
|
|
|
use account_provider::AccountProvider;
|
2016-01-26 19:18:22 +01:00
|
|
|
use block::ExecutedBlock;
|
2016-04-09 19:20:35 +02:00
|
|
|
use spec::CommonParams;
|
2016-05-19 00:44:49 +02:00
|
|
|
use evm::Schedule;
|
2015-12-20 13:16:12 +01:00
|
|
|
|
2016-08-24 15:55:47 +02:00
|
|
|
/// Voting errors.
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum EngineError {
|
|
|
|
/// Voter is not in the voters set.
|
|
|
|
UnauthorisedVoter,
|
|
|
|
/// Message pertaining incorrect consensus step.
|
|
|
|
WrongStep,
|
|
|
|
/// Message pertaining unknown consensus step.
|
|
|
|
UnknownStep,
|
|
|
|
/// Message was not expected.
|
|
|
|
UnexpectedMessage
|
|
|
|
}
|
|
|
|
|
2015-12-20 13:16:12 +01:00
|
|
|
/// A consensus mechanism for the chain. Generally either proof-of-work or proof-of-stake-based.
|
|
|
|
/// Provides hooks into each of the major parts of block import.
|
2016-01-11 11:51:31 +01:00
|
|
|
pub trait Engine : Sync + Send {
|
2015-12-20 13:16:12 +01:00
|
|
|
/// The name of this engine.
|
|
|
|
fn name(&self) -> &str;
|
2016-04-09 19:20:35 +02:00
|
|
|
/// The version of this engine. Should be of the form
|
2015-12-20 16:12:53 +01:00
|
|
|
fn version(&self) -> SemanticVersion { SemanticVersion::new(0, 0, 0) }
|
2015-12-20 13:16:12 +01:00
|
|
|
|
|
|
|
/// The number of additional header fields required for this engine.
|
2016-01-10 14:05:39 +01:00
|
|
|
fn seal_fields(&self) -> usize { 0 }
|
2015-12-20 13:16:12 +01:00
|
|
|
|
|
|
|
/// Additional engine-specific information for the user/developer concerning `header`.
|
|
|
|
fn extra_info(&self, _header: &Header) -> HashMap<String, String> { HashMap::new() }
|
|
|
|
|
2016-08-17 19:25:02 +02:00
|
|
|
/// Additional information.
|
|
|
|
fn additional_params(&self) -> HashMap<String, String> { HashMap::new() }
|
|
|
|
|
2015-12-20 16:12:53 +01:00
|
|
|
/// Get the general parameters of the chain.
|
2016-04-09 19:20:35 +02:00
|
|
|
fn params(&self) -> &CommonParams;
|
2015-12-20 16:12:53 +01:00
|
|
|
|
2015-12-23 12:56:38 +01:00
|
|
|
/// Get the EVM schedule for the given `env_info`.
|
2016-01-11 16:28:30 +01:00
|
|
|
fn schedule(&self, env_info: &EnvInfo) -> Schedule;
|
2015-12-20 16:12:53 +01:00
|
|
|
|
2016-04-09 19:20:35 +02:00
|
|
|
/// Builtin-contracts we would like to see in the chain.
|
|
|
|
/// (In principle these are just hints for the engine since that has the last word on them.)
|
|
|
|
fn builtins(&self) -> &BTreeMap<Address, Builtin>;
|
|
|
|
|
2015-12-21 18:40:48 +01:00
|
|
|
/// Some intrinsic operation parameters; by default they take their value from the `spec()`'s `engine_params`.
|
2016-04-09 19:20:35 +02:00
|
|
|
fn maximum_extra_data_size(&self) -> usize { self.params().maximum_extra_data_size }
|
2016-02-02 23:43:29 +01:00
|
|
|
/// Maximum number of uncles a block is allowed to declare.
|
2016-01-10 14:05:39 +01:00
|
|
|
fn maximum_uncle_count(&self) -> usize { 2 }
|
2016-03-02 19:38:00 +01:00
|
|
|
/// The number of generations back that uncles can be.
|
|
|
|
fn maximum_uncle_age(&self) -> usize { 6 }
|
2016-02-02 23:43:29 +01:00
|
|
|
/// The nonce with which accounts begin.
|
2016-04-09 19:20:35 +02:00
|
|
|
fn account_start_nonce(&self) -> U256 { self.params().account_start_nonce }
|
2015-12-21 18:40:48 +01:00
|
|
|
|
2016-02-02 23:43:29 +01:00
|
|
|
/// Block transformation functions, before the transactions.
|
2016-01-26 19:18:22 +01:00
|
|
|
fn on_new_block(&self, _block: &mut ExecutedBlock) {}
|
2016-02-02 23:43:29 +01:00
|
|
|
/// Block transformation functions, after the transactions.
|
2016-01-26 19:18:22 +01:00
|
|
|
fn on_close_block(&self, _block: &mut ExecutedBlock) {}
|
2015-12-21 18:40:48 +01:00
|
|
|
|
2016-05-03 17:23:53 +02:00
|
|
|
/// Attempt to seal the block internally.
|
|
|
|
///
|
|
|
|
/// If `Some` is returned, then you get a valid seal.
|
|
|
|
///
|
|
|
|
/// This operation is synchronous and may (quite reasonably) not be available, in which None will
|
|
|
|
/// be returned.
|
|
|
|
fn generate_seal(&self, _block: &ExecutedBlock, _accounts: Option<&AccountProvider>) -> Option<Vec<Bytes>> { None }
|
|
|
|
|
2016-04-09 19:20:35 +02:00
|
|
|
/// Phase 1 quick block verification. Only does checks that are cheap. `block` (the header's full block)
|
2016-01-11 13:51:58 +01:00
|
|
|
/// may be provided for additional checks. Returns either a null `Ok` or a general error detailing the problem with import.
|
2016-01-10 19:47:32 +01:00
|
|
|
fn verify_block_basic(&self, _header: &Header, _block: Option<&[u8]>) -> Result<(), Error> { Ok(()) }
|
2016-01-11 13:51:58 +01:00
|
|
|
|
2016-04-09 19:20:35 +02:00
|
|
|
/// Phase 2 verification. Perform costly checks such as transaction signatures. `block` (the header's full block)
|
2016-01-11 13:51:58 +01:00
|
|
|
/// may be provided for additional checks. Returns either a null `Ok` or a general error detailing the problem with import.
|
2016-01-10 19:47:32 +01:00
|
|
|
fn verify_block_unordered(&self, _header: &Header, _block: Option<&[u8]>) -> Result<(), Error> { Ok(()) }
|
2016-01-11 13:51:58 +01:00
|
|
|
|
2016-04-09 19:20:35 +02:00
|
|
|
/// Phase 3 verification. Check block information against parent and uncles. `block` (the header's full block)
|
2016-01-11 13:51:58 +01:00
|
|
|
/// may be provided for additional checks. Returns either a null `Ok` or a general error detailing the problem with import.
|
2016-01-14 19:03:48 +01:00
|
|
|
fn verify_block_family(&self, _header: &Header, _parent: &Header, _block: Option<&[u8]>) -> Result<(), Error> { Ok(()) }
|
2015-12-20 16:12:53 +01:00
|
|
|
|
2015-12-20 13:16:12 +01:00
|
|
|
/// Additional verification for transactions in blocks.
|
2015-12-20 16:12:53 +01:00
|
|
|
// TODO: Add flags for which bits of the transaction to check.
|
2015-12-23 12:56:38 +01:00
|
|
|
// TODO: consider including State in the params.
|
2016-02-04 23:48:29 +01:00
|
|
|
fn verify_transaction_basic(&self, _t: &SignedTransaction, _header: &Header) -> Result<(), Error> { Ok(()) }
|
2016-02-02 23:43:29 +01:00
|
|
|
/// Verify a particular transaction is valid.
|
2016-02-04 17:23:53 +01:00
|
|
|
fn verify_transaction(&self, _t: &SignedTransaction, _header: &Header) -> Result<(), Error> { Ok(()) }
|
2015-12-20 13:16:12 +01:00
|
|
|
|
2016-03-01 17:23:44 +01:00
|
|
|
/// Verify the seal of a block. This is an auxilliary method that actually just calls other `verify_` methods
|
|
|
|
/// to get the job done. By default it must pass `verify_basic` and `verify_block_unordered`. If more or fewer
|
|
|
|
/// methods are needed for an Engine, this may be overridden.
|
|
|
|
fn verify_block_seal(&self, header: &Header) -> Result<(), Error> {
|
|
|
|
self.verify_block_basic(header, None).and_then(|_| self.verify_block_unordered(header, None))
|
|
|
|
}
|
|
|
|
|
2016-03-02 00:34:38 +01:00
|
|
|
/// Don't forget to call Super::populate_from_parent when subclassing & overriding.
|
2015-12-23 12:56:38 +01:00
|
|
|
// TODO: consider including State in the params.
|
2016-06-23 14:29:16 +02:00
|
|
|
fn populate_from_parent(&self, header: &mut Header, parent: &Header, _gas_floor_target: U256, _gas_ceil_target: U256) {
|
2016-03-02 00:34:38 +01:00
|
|
|
header.difficulty = parent.difficulty;
|
|
|
|
header.gas_limit = parent.gas_limit;
|
2016-03-02 00:52:18 +01:00
|
|
|
header.note_dirty();
|
2016-03-02 00:34:38 +01:00
|
|
|
}
|
2015-12-20 13:16:12 +01:00
|
|
|
|
2016-08-19 17:18:30 +02:00
|
|
|
/// Handle any potential consensus messages;
|
|
|
|
/// updating consensus state and potentially issuing a new one.
|
2016-08-25 19:22:10 +02:00
|
|
|
fn handle_message(&self, _sender: Address, _message: UntrustedRlp) -> Result<Bytes, Error> { Err(EngineError::UnexpectedMessage.into()) }
|
2016-08-19 17:18:30 +02:00
|
|
|
|
2016-01-07 23:55:14 +01:00
|
|
|
// TODO: builtin contract routing - to do this properly, it will require removing the built-in configuration-reading logic
|
2015-12-21 18:40:48 +01:00
|
|
|
// from Spec into here and removing the Spec::builtins field.
|
2016-02-02 23:43:29 +01:00
|
|
|
/// Determine whether a particular address is a builtin contract.
|
2016-04-09 19:20:35 +02:00
|
|
|
fn is_builtin(&self, a: &Address) -> bool { self.builtins().contains_key(a) }
|
2016-02-02 23:43:29 +01:00
|
|
|
/// Determine the code execution cost of the builtin contract with address `a`.
|
|
|
|
/// Panics if `is_builtin(a)` is not true.
|
2016-04-09 19:20:35 +02:00
|
|
|
fn cost_of_builtin(&self, a: &Address, input: &[u8]) -> U256 { self.builtins().get(a).unwrap().cost(input.len()) }
|
2016-02-02 23:43:29 +01:00
|
|
|
/// Execution the builtin contract `a` on `input` and return `output`.
|
|
|
|
/// Panics if `is_builtin(a)` is not true.
|
2016-04-09 19:20:35 +02:00
|
|
|
fn execute_builtin(&self, a: &Address, input: &[u8], output: &mut [u8]) { self.builtins().get(a).unwrap().execute(input, output); }
|
2015-12-23 12:56:38 +01:00
|
|
|
|
|
|
|
// TODO: sealing stuff - though might want to leave this for later.
|
2015-12-20 13:16:12 +01:00
|
|
|
}
|