2018-06-04 10:19:50 +02:00
// Copyright 2015-2018 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/>.
2016-07-28 20:32:20 +02:00
//! Consensus engine specification and basic implementations.
2016-09-08 12:12:24 +02:00
mod authority_round ;
2017-04-13 20:24:21 +02:00
mod basic_authority ;
mod instant_seal ;
mod null_engine ;
mod signer ;
2016-08-23 12:58:40 +02:00
mod tendermint ;
2017-04-13 20:24:21 +02:00
mod transition ;
2017-01-10 12:23:59 +01:00
mod validator_set ;
2017-04-13 20:24:21 +02:00
mod vote_collector ;
2016-07-28 20:32:20 +02:00
2018-05-07 12:57:03 +02:00
pub mod block_reward ;
2017-06-28 13:17:36 +02:00
pub mod epoch ;
2016-09-08 12:12:24 +02:00
pub use self ::authority_round ::AuthorityRound ;
2017-04-13 20:24:21 +02:00
pub use self ::basic_authority ::BasicAuthority ;
2017-06-28 13:17:36 +02:00
pub use self ::epoch ::{ EpochVerifier , Transition as EpochTransition } ;
2017-04-13 20:24:21 +02:00
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
2017-07-29 21:56:42 +02:00
use std ::sync ::{ Weak , Arc } ;
2017-07-29 17:12:07 +02:00
use std ::collections ::{ BTreeMap , HashMap } ;
2018-04-19 11:52:54 +02:00
use std ::{ fmt , error } ;
2017-04-11 17:07:04 +02:00
2017-06-28 13:17:36 +02:00
use self ::epoch ::PendingTransition ;
2016-06-20 00:10:34 +02:00
use account_provider ::AccountProvider ;
2016-10-24 18:35:25 +02:00
use builtin ::Builtin ;
2018-09-25 12:39:27 +02:00
use vm ::{ EnvInfo , Schedule , CreateContractAddress , CallType , ActionValue } ;
2017-04-19 14:30:00 +02:00
use error ::Error ;
use header ::{ Header , BlockNumber } ;
2017-04-19 20:31:53 +02:00
use snapshot ::SnapshotComponents ;
2017-04-19 20:43:24 +02:00
use spec ::CommonParams ;
2018-04-13 17:34:27 +02:00
use transaction ::{ self , UnverifiedTransaction , SignedTransaction } ;
2017-04-11 17:07:04 +02:00
2018-06-22 15:09:15 +02:00
use ethkey ::{ Password , Signature } ;
2018-05-16 08:58:01 +02:00
use parity_machine ::{ Machine , LocalizedMachine as Localized , TotalScoredHeader } ;
2018-01-10 13:35:18 +01:00
use ethereum_types ::{ H256 , U256 , Address } ;
2017-09-05 12:14:03 +02:00
use unexpected ::{ Mismatch , OutOfBounds } ;
2017-09-06 20:47:45 +02:00
use bytes ::Bytes ;
2018-05-16 08:58:01 +02:00
use types ::ancestry_action ::AncestryAction ;
2015-12-20 13:16:12 +01:00
2018-04-20 12:32:00 +02:00
/// Default EIP-210 contract code.
2017-09-15 21:07:54 +02:00
/// As defined in https://github.com/ethereum/EIPs/pull/210
pub const DEFAULT_BLOCKHASH_CONTRACT : & 'static str = " 73fffffffffffffffffffffffffffffffffffffffe33141561006a5760014303600035610100820755610100810715156100455760003561010061010083050761010001555b6201000081071515610064576000356101006201000083050761020001555b5061013e565b4360003512151561008457600060405260206040f361013d565b61010060003543031315156100a857610100600035075460605260206060f361013c565b6101006000350715156100c55762010000600035430313156100c8565b60005b156100ea576101006101006000350507610100015460805260206080f361013b565b620100006000350715156101095763010000006000354303131561010c565b60005b1561012f57610100620100006000350507610200015460a052602060a0f361013a565b600060c052602060c0f35b5b5b5b5b " ;
2017-05-30 11:52:33 +02:00
2018-05-16 08:58:01 +02:00
/// Fork choice.
#[ derive(Debug, PartialEq, Eq) ]
pub enum ForkChoice {
/// Choose the new block.
New ,
/// Choose the current best block.
Old ,
}
2016-08-24 15:55:47 +02:00
/// Voting errors.
#[ derive(Debug) ]
pub enum EngineError {
2017-06-12 11:54:34 +02:00
/// Signature or author field 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 ) ,
2017-06-28 13:17:36 +02:00
/// Failed system call.
FailedSystemCall ( String ) ,
2017-09-26 14:19:08 +02:00
/// Malformed consensus message.
MalformedMessage ( String ) ,
2017-06-28 13:17:36 +02:00
/// Requires client ref, but none registered.
RequiresClient ,
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 ) ,
2017-06-28 13:17:36 +02:00
FailedSystemCall ( ref msg ) = > format! ( " Failed to make system call: {} " , msg ) ,
2017-09-26 14:19:08 +02:00
MalformedMessage ( ref msg ) = > format! ( " Received malformed consensus message: {} " , msg ) ,
2017-06-28 13:17:36 +02:00
RequiresClient = > format! ( " Call requires client but none registered " ) ,
2016-11-29 13:51:27 +01:00
} ;
f . write_fmt ( format_args! ( " Engine error ( {} ) " , msg ) )
}
2016-08-24 15:55:47 +02:00
}
2018-04-19 11:52:54 +02:00
impl error ::Error for EngineError {
fn description ( & self ) -> & str {
" Engine error "
}
}
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 ,
}
2018-04-20 12:32:00 +02:00
/// A system-calling closure. Enacts calls on a block's state from the system address.
pub type SystemCall < ' a > = FnMut ( Address , Vec < u8 > ) -> Result < Vec < u8 > , String > + ' a ;
2018-08-29 17:17:18 +02:00
/// A system-calling closure. Enacts calls on a block's state with code either from an on-chain contract, or hard-coded EVM or WASM (if enabled on-chain) codes.
pub type SystemOrCodeCall < ' a > = FnMut ( SystemOrCodeCallKind , Vec < u8 > ) -> Result < Vec < u8 > , String > + ' a ;
/// Kind of SystemOrCodeCall, this is either an on-chain address, or code.
#[ derive(PartialEq, Debug, Clone) ]
pub enum SystemOrCodeCallKind {
/// On-chain address.
Address ( Address ) ,
/// Hard-coded code.
Code ( Arc < Vec < u8 > > , H256 ) ,
}
/// Default SystemOrCodeCall implementation.
pub fn default_system_or_code_call < ' a > ( machine : & ' a ::machine ::EthereumMachine , block : & ' a mut ::block ::ExecutedBlock ) -> impl FnMut ( SystemOrCodeCallKind , Vec < u8 > ) -> Result < Vec < u8 > , String > + ' a {
move | to , data | {
let result = match to {
SystemOrCodeCallKind ::Address ( address ) = > {
machine . execute_as_system (
block ,
address ,
U256 ::max_value ( ) ,
Some ( data ) ,
)
} ,
SystemOrCodeCallKind ::Code ( code , code_hash ) = > {
machine . execute_code_as_system (
block ,
None ,
Some ( code ) ,
Some ( code_hash ) ,
2018-09-25 12:39:27 +02:00
Some ( ActionValue ::Apparent ( U256 ::zero ( ) ) ) ,
2018-08-29 17:17:18 +02:00
U256 ::max_value ( ) ,
Some ( data ) ,
2018-09-25 12:39:27 +02:00
Some ( CallType ::StaticCall ) ,
2018-08-29 17:17:18 +02:00
)
} ,
} ;
result . map_err ( | e | format! ( " {} " , e ) )
}
}
2017-06-28 13:17:36 +02:00
/// Type alias for a function we can get headers by hash through.
2017-09-26 14:19:08 +02:00
pub type Headers < ' a , H > = Fn ( H256 ) -> Option < H > + ' a ;
2017-06-28 13:17:36 +02:00
/// Type alias for a function we can query pending transitions by block hash through.
pub type PendingTransitionStore < ' a > = Fn ( H256 ) -> Option < PendingTransition > + ' a ;
2017-09-05 17:54:05 +02:00
/// Proof dependent on state.
2017-09-26 14:19:08 +02:00
pub trait StateDependentProof < M : Machine > : Send + Sync {
2017-09-05 17:54:05 +02:00
/// Generate a proof, given the state.
2017-09-26 14:19:08 +02:00
// TODO: make this into an &M::StateContext
fn generate_proof < ' a > ( & self , state : & < M as Localized < ' a > > ::StateContext ) -> Result < Vec < u8 > , String > ;
2017-09-05 17:54:05 +02:00
/// Check a proof generated elsewhere (potentially by a peer).
// `engine` needed to check state proofs, while really this should
// just be state machine params.
2017-09-26 14:19:08 +02:00
fn check_proof ( & self , machine : & M , proof : & [ u8 ] ) -> Result < ( ) , String > ;
2017-09-05 17:54:05 +02:00
}
2017-06-28 13:17:36 +02:00
/// Proof generated on epoch change.
2017-09-26 14:19:08 +02:00
pub enum Proof < M : Machine > {
2017-09-05 17:54:05 +02:00
/// Known proof (extracted from signal)
2017-06-28 13:17:36 +02:00
Known ( Vec < u8 > ) ,
2017-09-05 17:54:05 +02:00
/// State dependent proof.
2017-09-26 14:19:08 +02:00
WithState ( Arc < StateDependentProof < M > > ) ,
2017-06-28 13:17:36 +02:00
}
/// Generated epoch verifier.
2017-09-26 14:19:08 +02:00
pub enum ConstructedVerifier < ' a , M : Machine > {
2017-06-28 13:17:36 +02:00
/// Fully trusted verifier.
2017-09-26 14:19:08 +02:00
Trusted ( Box < EpochVerifier < M > > ) ,
2017-06-28 13:17:36 +02:00
/// Verifier unconfirmed. Check whether given finality proof finalizes given hash
/// under previous epoch.
2017-09-26 14:19:08 +02:00
Unconfirmed ( Box < EpochVerifier < M > > , & ' a [ u8 ] , H256 ) ,
2017-06-28 13:17:36 +02:00
/// Error constructing verifier.
Err ( Error ) ,
}
2017-09-26 14:19:08 +02:00
impl < ' a , M : Machine > ConstructedVerifier < ' a , M > {
2017-06-28 13:17:36 +02:00
/// Convert to a result, indicating that any necessary confirmation has been done
/// already.
2017-09-26 14:19:08 +02:00
pub fn known_confirmed ( self ) -> Result < Box < EpochVerifier < M > > , Error > {
2017-06-28 13:17:36 +02:00
match self {
ConstructedVerifier ::Trusted ( v ) | ConstructedVerifier ::Unconfirmed ( v , _ , _ ) = > Ok ( v ) ,
ConstructedVerifier ::Err ( e ) = > Err ( e ) ,
}
}
}
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.
2017-09-26 14:19:08 +02:00
pub enum EpochChange < M : Machine > {
2017-04-12 14:41:19 +02:00
/// Cannot determine until more data is passed.
2017-09-26 14:19:08 +02:00
Unsure ( M ::AuxiliaryRequest ) ,
2017-04-18 14:19:10 +02:00
/// No epoch change.
2017-04-12 14:41:19 +02:00
No ,
2017-06-28 13:17:36 +02:00
/// The epoch will change, with proof.
2017-09-26 14:19:08 +02:00
Yes ( Proof < M > ) ,
2017-04-12 14:41:19 +02:00
}
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.
2017-09-26 14:19:08 +02:00
pub trait Engine < M : Machine > : Sync + Send {
2015-12-20 13:16:12 +01:00
/// The name of this engine.
fn name ( & self ) -> & str ;
2017-09-26 14:19:08 +02:00
/// Get access to the underlying state machine.
// TODO: decouple.
fn machine ( & self ) -> & M ;
2015-12-20 13:16:12 +01:00
/// The number of additional header fields required for this engine.
2018-02-15 01:39:29 +01:00
fn seal_fields ( & self , _header : & M ::Header ) -> usize { 0 }
2015-12-20 13:16:12 +01:00
/// Additional engine-specific information for the user/developer concerning `header`.
2017-09-26 14:19:08 +02:00
fn extra_info ( & self , _header : & M ::Header ) -> BTreeMap < String , String > { BTreeMap ::new ( ) }
2015-12-20 13:16:12 +01:00
2016-02-02 23:43:29 +01:00
/// Maximum number of uncles a block is allowed to declare.
2017-12-05 15:57:45 +01:00
fn maximum_uncle_count ( & self , _block : BlockNumber ) -> usize { 0 }
2016-03-02 19:38:00 +01:00
/// The number of generations back that uncles can be.
fn maximum_uncle_age ( & self ) -> usize { 6 }
2015-12-21 18:40:48 +01:00
2016-02-02 23:43:29 +01:00
/// Block transformation functions, before the transactions.
2017-06-28 13:17:36 +02:00
/// `epoch_begin` set to true if this block kicks off an epoch.
fn on_new_block (
& self ,
2017-09-26 14:19:08 +02:00
_block : & mut M ::LiveBlock ,
2017-06-28 13:17:36 +02:00
_epoch_begin : bool ,
2018-05-16 08:58:01 +02:00
_ancestry : & mut Iterator < Item = M ::ExtendedHeader > ,
2017-09-26 14:19:08 +02:00
) -> Result < ( ) , M ::Error > {
Ok ( ( ) )
2017-05-30 11:52:33 +02:00
}
2016-02-02 23:43:29 +01:00
/// Block transformation functions, after the transactions.
2017-09-26 14:19:08 +02:00
fn on_close_block ( & self , _block : & mut M ::LiveBlock ) -> Result < ( ) , M ::Error > {
2017-08-10 12:36:29 +02:00
Ok ( ( ) )
2017-05-30 11:52:33 +02:00
}
2015-12-21 18:40:48 +01:00
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 }
2017-09-26 14:19:08 +02: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.
2017-09-26 14:19:08 +02:00
///
/// It is fine to require access to state or a full client for this function, since
/// light clients do not generate seals.
2017-12-07 12:17:11 +01:00
fn generate_seal ( & self , _block : & M ::LiveBlock , _parent : & M ::Header ) -> Seal { Seal ::None }
2015-12-20 16:12:53 +01:00
2017-09-26 14:19:08 +02:00
/// Verify a locally-generated seal of a header.
///
/// If this engine seals internally,
/// no checks have to be done here, since all internally generated seals
/// should be valid.
///
/// Externally-generated seals (e.g. PoW) will need to be checked for validity.
///
/// It is fine to require access to state or a full client for this function, since
/// light clients do not generate seals.
fn verify_local_seal ( & self , header : & M ::Header ) -> Result < ( ) , M ::Error > ;
2017-04-13 20:24:21 +02:00
2017-09-26 14:19:08 +02:00
/// Phase 1 quick block verification. Only does checks that are cheap. Returns either a null `Ok` or a general error detailing the problem with import.
2018-09-06 04:37:41 +02:00
/// The verification module can optionally avoid checking the seal (`check_seal`), if seal verification is disabled this method won't be called.
2017-09-26 14:19:08 +02:00
fn verify_block_basic ( & self , _header : & M ::Header ) -> Result < ( ) , M ::Error > { Ok ( ( ) ) }
2017-01-13 09:51:36 +01:00
2017-09-26 14:19:08 +02:00
/// Phase 2 verification. Perform costly checks such as transaction signatures. Returns either a null `Ok` or a general error detailing the problem with import.
2018-09-06 04:37:41 +02:00
/// The verification module can optionally avoid checking the seal (`check_seal`), if seal verification is disabled this method won't be called.
2017-09-26 14:19:08 +02:00
fn verify_block_unordered ( & self , _header : & M ::Header ) -> Result < ( ) , M ::Error > { Ok ( ( ) ) }
2015-12-20 13:16:12 +01:00
2017-09-26 14:19:08 +02:00
/// Phase 3 verification. Check block information against parent. Returns either a null `Ok` or a general error detailing the problem with import.
2018-04-05 11:31:58 +02:00
fn verify_block_family ( & self , _header : & M ::Header , _parent : & M ::Header ) -> Result < ( ) , M ::Error > { Ok ( ( ) ) }
2016-11-03 22:22:25 +01:00
2017-09-26 14:19:08 +02:00
/// Phase 4 verification. Verify block header against potentially external data.
/// Should only be called when `register_client` has been called previously.
2018-04-05 11:31:58 +02:00
fn verify_block_external ( & self , _header : & M ::Header ) -> Result < ( ) , M ::Error > { Ok ( ( ) ) }
2016-03-01 17:23:44 +01:00
2017-06-28 13:17:36 +02:00
/// Genesis epoch data.
2017-09-26 14:19:08 +02:00
fn genesis_epoch_data < ' a > ( & self , _header : & M ::Header , _state : & < M as Localized < ' a > > ::StateContext ) -> Result < Vec < u8 > , String > { Ok ( Vec ::new ( ) ) }
2017-04-12 14:41:19 +02:00
2017-06-28 13:17:36 +02:00
/// Whether an epoch change is signalled at the given header but will require finality.
/// If a change can be enacted immediately then return `No` from this function but
/// `Yes` from `is_epoch_end`.
2017-05-17 12:41:33 +02:00
///
2017-09-26 14:19:08 +02:00
/// If auxiliary data of the block is required, return an auxiliary request and the function will be
2017-05-17 12:41:33 +02:00
/// called again with them.
/// Return `Yes` or `No` when the answer is definitively known.
///
2017-04-18 14:19:10 +02:00
/// Should not interact with state.
2017-09-26 14:19:08 +02:00
fn signals_epoch_end < ' a > ( & self , _header : & M ::Header , _aux : < M as Localized < ' a > > ::AuxiliaryData )
-> EpochChange < M >
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-06-28 13:17:36 +02:00
/// Whether a block is the end of an epoch.
///
/// This either means that an immediate transition occurs or a block signalling transition
/// has reached finality. The `Headers` given are not guaranteed to return any blocks
/// from any epoch other than the current.
2017-04-13 20:24:21 +02:00
///
2017-06-28 13:17:36 +02:00
/// Return optional transition proof.
fn is_epoch_end (
& self ,
2017-09-26 14:19:08 +02:00
_chain_head : & M ::Header ,
_chain : & Headers < M ::Header > ,
2017-06-28 13:17:36 +02:00
_transition_store : & PendingTransitionStore ,
) -> Option < Vec < u8 > > {
None
}
/// Create an epoch verifier from validation proof and a flag indicating
/// whether finality is required.
2017-09-26 14:19:08 +02:00
fn epoch_verifier < ' a > ( & self , _header : & M ::Header , _proof : & ' a [ u8 ] ) -> ConstructedVerifier < ' a , M > {
2017-06-28 13:17:36 +02:00
ConstructedVerifier ::Trusted ( Box ::new ( self ::epoch ::NoOp ) )
2017-04-13 20:24:21 +02:00
}
2016-12-11 12:50:48 +01:00
/// Populate a header's fields based on its parent's header.
2017-01-23 15:27:11 +01:00
/// Usually implements the chain scoring rule based on weight.
2017-09-26 14:19:08 +02:00
fn populate_from_parent ( & self , _header : & mut M ::Header , _parent : & M ::Header ) { }
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.
2017-09-26 14:19:08 +02:00
fn handle_message ( & self , _message : & [ u8 ] ) -> Result < ( ) , EngineError > { Err ( EngineError ::UnexpectedMessage ) }
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.
2017-09-26 14:19:08 +02:00
fn is_proposal ( & self , _verified_header : & M ::Header ) -> bool { false }
2016-12-08 12:03:34 +01:00
2016-12-05 18:08:16 +01:00
/// Register an account which signs consensus messages.
2018-06-22 15:09:15 +02:00
fn set_signer ( & self , _account_provider : Arc < AccountProvider > , _address : Address , _password : Password ) { }
2016-12-05 18:08:16 +01:00
2017-01-24 10:03:58 +01:00
/// Sign using the EngineSigner, to be used for consensus tx signing.
2018-04-05 11:31:58 +02:00
fn sign ( & self , _hash : H256 ) -> Result < Signature , M ::Error > { unimplemented! ( ) }
2017-01-24 10:03:58 +01:00
2017-09-26 14:19:08 +02:00
/// Add Client which can be used for sealing, potentially querying the state and sending messages.
fn register_client ( & self , _client : Weak < M ::EngineClient > ) { }
2016-11-16 11:29:54 +01:00
2016-12-06 19:23:15 +01:00
/// Trigger next step of the consensus engine.
fn step ( & self ) { }
2017-01-10 12:23:59 +01:00
/// 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
}
2017-05-05 16:00:40 +02:00
2017-05-10 17:12:00 +02:00
/// Whether this engine supports warp sync.
fn supports_warp ( & self ) -> bool {
self . snapshot_components ( ) . is_some ( )
}
2018-04-05 10:11:21 +02:00
/// Return a new open block header timestamp based on the parent timestamp.
fn open_block_header_timestamp ( & self , parent_timestamp : u64 ) -> u64 {
use std ::{ time , cmp } ;
let now = time ::SystemTime ::now ( ) . duration_since ( time ::UNIX_EPOCH ) . unwrap_or_default ( ) ;
cmp ::max ( now . as_secs ( ) as u64 , parent_timestamp + 1 )
}
/// Check whether the parent timestamp is valid.
fn is_timestamp_valid ( & self , header_timestamp : u64 , parent_timestamp : u64 ) -> bool {
header_timestamp > parent_timestamp
}
2018-05-16 08:58:01 +02:00
/// Gather all ancestry actions. Called at the last stage when a block is committed. The Engine must guarantee that
/// the ancestry exists.
fn ancestry_actions ( & self , _block : & M ::LiveBlock , _ancestry : & mut Iterator < Item = M ::ExtendedHeader > ) -> Vec < AncestryAction > {
Vec ::new ( )
}
/// Check whether the given new block is the best block, after finalization check.
fn fork_choice ( & self , new : & M ::ExtendedHeader , best : & M ::ExtendedHeader ) -> ForkChoice ;
}
/// Check whether a given block is the best block based on the default total difficulty rule.
pub fn total_difficulty_fork_choice < T : TotalScoredHeader > ( new : & T , best : & T ) -> ForkChoice where < T as TotalScoredHeader > ::Value : Ord {
if new . total_score ( ) > best . total_score ( ) {
ForkChoice ::New
} else {
ForkChoice ::Old
}
2017-09-26 14:19:08 +02:00
}
2017-05-10 17:12:00 +02:00
2017-09-26 14:19:08 +02:00
/// Common type alias for an engine coupled with an Ethereum-like state machine.
// TODO: make this a _trait_ alias when those exist.
// fortunately the effect is largely the same since engines are mostly used
// via trait objects.
pub trait EthEngine : Engine < ::machine ::EthereumMachine > {
/// Get the general parameters of the chain.
fn params ( & self ) -> & CommonParams {
self . machine ( ) . params ( )
}
/// Get the EVM schedule for the given block number.
fn schedule ( & self , block_number : BlockNumber ) -> Schedule {
self . machine ( ) . schedule ( block_number )
}
/// Builtin-contracts for the chain..
fn builtins ( & self ) -> & BTreeMap < Address , Builtin > {
self . machine ( ) . builtins ( )
}
/// Attempt to get a handle to a built-in contract.
/// Only returns references to activated built-ins.
fn builtin ( & self , a : & Address , block_number : BlockNumber ) -> Option < & Builtin > {
self . machine ( ) . builtin ( a , block_number )
}
/// Some intrinsic operation parameters; by default they take their value from the `spec()`'s `engine_params`.
fn maximum_extra_data_size ( & self ) -> usize {
self . machine ( ) . maximum_extra_data_size ( )
}
/// The nonce with which accounts begin at given block.
2017-12-05 15:57:45 +01:00
fn account_start_nonce ( & self , block : BlockNumber ) -> U256 {
2017-09-26 14:19:08 +02:00
self . machine ( ) . account_start_nonce ( block )
}
/// The network ID that transactions should be signed with.
fn signing_chain_id ( & self , env_info : & EnvInfo ) -> Option < u64 > {
self . machine ( ) . signing_chain_id ( env_info )
2017-07-10 17:42:10 +02:00
}
2017-05-05 16:00:40 +02:00
/// Returns new contract address generation scheme at given block number.
fn create_address_scheme ( & self , number : BlockNumber ) -> CreateContractAddress {
2017-09-26 14:19:08 +02:00
self . machine ( ) . create_address_scheme ( number )
}
/// Verify a particular transaction is valid.
2018-04-13 17:34:27 +02:00
///
/// Unordered verification doesn't rely on the transaction execution order,
/// i.e. it should only verify stuff that doesn't assume any previous transactions
/// has already been verified and executed.
///
/// NOTE This function consumes an `UnverifiedTransaction` and produces `SignedTransaction`
/// which implies that a heavy check of the signature is performed here.
fn verify_transaction_unordered ( & self , t : UnverifiedTransaction , header : & Header ) -> Result < SignedTransaction , transaction ::Error > {
2017-09-26 14:19:08 +02:00
self . machine ( ) . verify_transaction_unordered ( t , header )
}
2018-04-13 17:34:27 +02:00
/// Perform basic/cheap transaction verification.
///
/// This should include all cheap checks that can be done before
/// actually checking the signature, like chain-replay protection.
///
/// NOTE This is done before the signature is recovered so avoid
/// doing any state-touching checks that might be expensive.
///
/// TODO: Add flags for which bits of the transaction to check.
/// TODO: consider including State in the params.
fn verify_transaction_basic ( & self , t : & UnverifiedTransaction , header : & Header ) -> Result < ( ) , transaction ::Error > {
2017-09-26 14:19:08 +02:00
self . machine ( ) . verify_transaction_basic ( t , header )
}
2017-10-05 15:34:30 +02:00
/// Additional information.
fn additional_params ( & self ) -> HashMap < String , String > {
self . machine ( ) . additional_params ( )
}
2018-04-27 15:02:45 +02:00
/// Performs pre-validation of RLP decoded transaction before other processing
fn decode_transaction ( & self , transaction : & [ u8 ] ) -> Result < UnverifiedTransaction , transaction ::Error > {
self . machine ( ) . decode_transaction ( transaction )
}
2015-12-20 13:16:12 +01:00
}
2017-05-30 11:52:33 +02:00
2017-09-26 14:19:08 +02:00
// convenience wrappers for existing functions.
impl < T > EthEngine for T where T : Engine < ::machine ::EthereumMachine > { }