openethereum/ethcore/src/engines/mod.rs

298 lines
12 KiB
Rust
Raw Normal View History

// Copyright 2015-2017 Parity Technologies (UK) Ltd.
2016-02-05 13:40:41 +01:00
// 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/>.
//! Consensus engine specification and basic implementations.
2016-09-08 12:12:24 +02:00
mod authority_round;
mod basic_authority;
2017-04-18 14:19:10 +02:00
mod epoch_verifier;
mod instant_seal;
mod null_engine;
mod signer;
2016-08-23 12:58:40 +02:00
mod tendermint;
mod transition;
mod validator_set;
mod vote_collector;
2016-09-08 12:12:24 +02:00
pub use self::authority_round::AuthorityRound;
pub use self::basic_authority::BasicAuthority;
2017-04-18 14:19:10 +02:00
pub use self::epoch_verifier::EpochVerifier;
pub use self::instant_seal::InstantSeal;
pub use self::null_engine::NullEngine;
2016-08-23 12:58:40 +02:00
pub use self::tendermint::Tendermint;
2016-05-16 18:16:56 +02:00
use std::sync::Weak;
2017-04-11 17:07:04 +02:00
use account_provider::AccountProvider;
use block::ExecutedBlock;
use builtin::Builtin;
2017-04-11 17:07:04 +02:00
use client::Client;
use env_info::EnvInfo;
use error::Error;
use evm::Schedule;
use header::{Header, BlockNumber};
use receipt::Receipt;
2017-04-19 20:31:53 +02:00
use snapshot::SnapshotComponents;
use spec::CommonParams;
use transaction::{UnverifiedTransaction, SignedTransaction};
2017-04-11 17:07:04 +02:00
use ethkey::Signature;
use util::*;
2016-08-24 15:55:47 +02:00
/// Voting errors.
#[derive(Debug)]
pub enum EngineError {
2016-11-29 13:51:27 +01:00
/// Signature does not belong to an authority.
2016-12-08 12:03:34 +01:00
NotAuthorized(Address),
2016-11-29 13:51:27 +01:00
/// The same author issued different votes at the same step.
2016-12-08 12:03:34 +01:00
DoubleVote(Address),
2016-11-29 13:51:27 +01:00
/// The received block is from an incorrect proposer.
2016-12-08 12:03:34 +01:00
NotProposer(Mismatch<Address>),
2016-08-24 15:55:47 +02:00
/// Message was not expected.
2016-08-26 19:27:50 +02:00
UnexpectedMessage,
2016-12-02 14:32:00 +01:00
/// Seal field has an unexpected size.
BadSealFieldSize(OutOfBounds<usize>),
2017-04-12 18:55:38 +02:00
/// Validation proof insufficient.
InsufficientProof(String),
2016-11-29 13:51:27 +01:00
}
impl fmt::Display for EngineError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::EngineError::*;
let msg = match *self {
DoubleVote(ref address) => format!("Author {} issued too many blocks.", address),
NotProposer(ref mis) => format!("Author is not a current proposer: {}", mis),
NotAuthorized(ref address) => format!("Signer {} is not authorized.", address),
UnexpectedMessage => "This Engine should not be fed messages.".into(),
2016-12-02 14:32:00 +01:00
BadSealFieldSize(ref oob) => format!("Seal field has an unexpected length: {}", oob),
2017-04-12 18:55:38 +02:00
InsufficientProof(ref msg) => format!("Insufficient validation proof: {}", msg),
2016-11-29 13:51:27 +01:00
};
f.write_fmt(format_args!("Engine error ({})", msg))
}
2016-08-24 15:55:47 +02:00
}
2016-12-08 12:03:34 +01:00
/// Seal type.
#[derive(Debug, PartialEq, Eq)]
pub enum Seal {
/// Proposal seal; should be broadcasted, but not inserted into blockchain.
Proposal(Vec<Bytes>),
/// Regular block seal; should be part of the blockchain.
Regular(Vec<Bytes>),
/// Engine does generate seal for this block right now.
None,
}
2017-04-11 17:07:04 +02:00
/// Type alias for a function we can make calls through synchronously.
2017-04-19 14:58:19 +02:00
pub type Call<'a> = Fn(Address, Bytes) -> Result<Bytes, String> + 'a;
2017-04-11 17:07:04 +02:00
2017-04-18 14:19:10 +02:00
/// Results of a query of whether an epoch change occurred at the given block.
#[derive(Debug, Clone, PartialEq)]
pub enum EpochChange {
2017-04-12 14:41:19 +02:00
/// Cannot determine until more data is passed.
Unsure(Unsure),
2017-04-18 14:19:10 +02:00
/// No epoch change.
2017-04-12 14:41:19 +02:00
No,
2017-04-19 14:58:19 +02:00
/// Validation proof required, and the new epoch number and expected proof.
Yes(u64, Bytes),
2017-04-12 14:41:19 +02:00
}
2017-04-18 14:19:10 +02:00
/// More data required to determine if an epoch change occurred at a given block.
#[derive(Debug, Clone, Copy, PartialEq)]
2017-04-12 14:41:19 +02:00
pub enum Unsure {
/// Needs the body.
NeedsBody,
/// Needs the receipts.
NeedsReceipts,
/// Needs both body and receipts.
NeedsBoth,
}
/// 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 {
/// The name of this engine.
fn name(&self) -> &str;
/// 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) }
/// The number of additional header fields required for this engine.
2016-01-10 14:05:39 +01:00
fn seal_fields(&self) -> usize { 0 }
/// Additional engine-specific information for the user/developer concerning `header`.
fn extra_info(&self, _header: &Header) -> BTreeMap<String, String> { BTreeMap::new() }
/// 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.
fn params(&self) -> &CommonParams;
2015-12-20 16:12:53 +01:00
/// Get the EVM schedule for the given `block_number`.
fn schedule(&self, block_number: BlockNumber) -> Schedule;
2015-12-20 16:12:53 +01: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>;
/// Some intrinsic operation parameters; by default they take their value from the `spec()`'s `engine_params`.
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 }
/// 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.
fn account_start_nonce(&self) -> U256 { self.params().account_start_nonce }
2016-02-02 23:43:29 +01:00
/// Block transformation functions, before the transactions.
fn on_new_block(&self, _block: &mut ExecutedBlock) {}
2016-02-02 23:43:29 +01:00
/// Block transformation functions, after the transactions.
fn on_close_block(&self, _block: &mut ExecutedBlock) {}
2017-02-20 16:35:53 +01:00
/// None means that it requires external input (e.g. PoW) to seal a block.
/// Some(true) means the engine is currently prime for seal generation (i.e. node is the current validator).
/// Some(false) means that the node might seal internally but is not qualified now.
fn seals_internally(&self) -> Option<bool> { None }
/// 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.
2016-12-08 12:03:34 +01:00
fn generate_seal(&self, _block: &ExecutedBlock) -> Seal { Seal::None }
/// 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.
fn verify_block_basic(&self, _header: &Header, _block: Option<&[u8]>) -> Result<(), Error> { Ok(()) }
2016-01-11 13:51:58 +01: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.
fn verify_block_unordered(&self, _header: &Header, _block: Option<&[u8]>) -> Result<(), Error> { Ok(()) }
2016-01-11 13:51:58 +01: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
/// Phase 4 verification. Verify block header against potentially external data.
fn verify_block_external(&self, _header: &Header, _block: Option<&[u8]>) -> Result<(), Error> { Ok(()) }
/// 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.
fn verify_transaction_basic(&self, t: &UnverifiedTransaction, _header: &Header) -> Result<(), Error> {
t.verify_basic(true, Some(self.params().network_id), true)?;
Ok(())
}
2016-02-02 23:43:29 +01:00
/// Verify a particular transaction is valid.
fn verify_transaction(&self, t: UnverifiedTransaction, _header: &Header) -> Result<SignedTransaction, Error> {
SignedTransaction::new(t)
}
/// The network ID that transactions should be signed with.
fn signing_network_id(&self, _env_info: &EnvInfo) -> Option<u64> {
Some(self.params().chain_id)
}
/// 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.
2017-04-12 14:41:19 +02:00
fn verify_block_seal(&self, header: &Header) -> Result<(), Error> {
self.verify_block_basic(header, None).and_then(|_| self.verify_block_unordered(header, None))
}
2017-04-18 14:19:10 +02:00
/// Generate epoch change proof.
2017-04-11 17:07:04 +02:00
///
2017-04-18 14:19:10 +02:00
/// This will be used to generate proofs of epoch change as well as verify them.
2017-04-12 18:55:38 +02:00
/// Must be called on blocks that have already passed basic verification.
///
2017-04-18 14:19:10 +02:00
/// Return the "epoch proof" generated.
/// This must be usable to generate a `EpochVerifier` for verifying all blocks
/// from the supplied header up to the next one where proof is required.
///
/// For example, for PoA chains the proof will be a validator set,
2017-04-18 14:19:10 +02:00
/// and the corresponding `EpochVerifier` can be used to correctly validate
/// all blocks produced under that `ValidatorSet`
2017-04-18 14:19:10 +02:00
fn epoch_proof(&self, _header: &Header, _caller: &Call)
-> Result<Vec<u8>, Error>
{
2017-04-12 18:55:38 +02:00
Ok(Vec::new())
2017-04-12 14:41:19 +02:00
}
2017-04-18 14:19:10 +02:00
/// Whether an epoch change occurred at the given header.
/// Should not interact with state.
fn is_epoch_end(&self, _header: &Header, _block: Option<&[u8]>, _receipts: Option<&[Receipt]>)
-> EpochChange
2017-04-12 14:41:19 +02:00
{
2017-04-18 14:19:10 +02:00
EpochChange::No
2017-04-11 17:07:04 +02:00
}
2017-04-18 14:19:10 +02:00
/// Create an epoch verifier from validation proof.
///
2017-04-18 14:19:10 +02:00
/// The proof should be one generated by `epoch_proof`.
/// See docs of `epoch_proof` for description.
fn epoch_verifier(&self, _header: &Header, _proof: &[u8]) -> Result<Box<EpochVerifier>, Error> {
Ok(Box::new(self::epoch_verifier::NoOp))
}
/// Populate a header's fields based on its parent's header.
/// Usually implements the chain scoring rule based on weight.
/// The gas floor target must not be lower than the engine's minimum gas limit.
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) {
header.set_difficulty(parent.difficulty().clone());
header.set_gas_limit(parent.gas_limit().clone());
2016-03-02 00:34:38 +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-12-11 12:32:01 +01:00
fn handle_message(&self, _message: &[u8]) -> Result<(), Error> { Err(EngineError::UnexpectedMessage.into()) }
2016-08-19 17:18:30 +02:00
/// Attempt to get a handle to a built-in contract.
/// Only returns references to activated built-ins.
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
// from Spec into here and removing the Spec::builtins field.
fn builtin(&self, a: &Address, block_number: ::header::BlockNumber) -> Option<&Builtin> {
self.builtins()
.get(a)
.and_then(|b| if b.is_active(block_number) { Some(b) } else { None })
}
2015-12-23 12:56:38 +01:00
2016-12-08 12:03:34 +01:00
/// Find out if the block is a proposal block and should not be inserted into the DB.
/// Takes a header of a fully verified block.
fn is_proposal(&self, _verified_header: &Header) -> bool { false }
2016-12-05 18:08:16 +01:00
/// Register an account which signs consensus messages.
fn set_signer(&self, _account_provider: Arc<AccountProvider>, _address: Address, _password: String) {}
2016-12-05 18:08:16 +01:00
/// Sign using the EngineSigner, to be used for consensus tx signing.
fn sign(&self, _hash: H256) -> Result<Signature, Error> { unimplemented!() }
/// Add Client which can be used for sealing, querying the state and sending messages.
fn register_client(&self, _client: Weak<Client>) {}
2016-12-06 19:23:15 +01:00
/// Trigger next step of the consensus engine.
fn step(&self) {}
/// Stops any services that the may hold the Engine and makes it safe to drop.
fn stop(&self) {}
2017-04-19 20:31:53 +02:00
/// Create a factory for building snapshot chunks and restoring from them.
/// Returning `None` indicates that this engine doesn't support snapshot creation.
fn snapshot_components(&self) -> Option<Box<SnapshotComponents>> {
None
}
}