2020-09-22 14:53:52 +02:00
// Copyright 2015-2020 Parity Technologies (UK) Ltd.
// This file is part of OpenEthereum.
2016-02-05 13:40:41 +01:00
2020-09-22 14:53:52 +02:00
// OpenEthereum is free software: you can redistribute it and/or modify
2016-02-05 13:40:41 +01:00
// 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.
2020-09-22 14:53:52 +02:00
// OpenEthereum is distributed in the hope that it will be useful,
2016-02-05 13:40:41 +01:00
// 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
2020-09-22 14:53:52 +02:00
// along with OpenEthereum. If not, see <http://www.gnu.org/licenses/>.
2016-02-05 13:40:41 +01:00
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 ;
2019-03-26 23:31:52 +01:00
mod clique ;
2017-04-13 20:24:21 +02:00
mod instant_seal ;
mod null_engine ;
2017-01-10 12:23:59 +01:00
mod validator_set ;
2016-07-28 20:32:20 +02:00
2018-05-07 12:57:03 +02:00
pub mod block_reward ;
2019-02-07 14:34:24 +01:00
pub mod signer ;
2017-06-28 13:17:36 +02:00
2020-08-05 06:08:03 +02:00
pub use self ::{
authority_round ::AuthorityRound ,
basic_authority ::BasicAuthority ,
clique ::Clique ,
instant_seal ::{ InstantSeal , InstantSealParams } ,
null_engine ::NullEngine ,
signer ::EngineSigner ,
} ;
2016-05-16 18:16:56 +02:00
2019-01-04 14:05:46 +01:00
// TODO [ToDr] Remove re-export (#10130)
2020-08-05 06:08:03 +02:00
pub use types ::engines ::{
epoch ::{ self , Transition as EpochTransition } ,
ForkChoice ,
} ;
2019-01-04 14:05:46 +01:00
2020-08-05 06:08:03 +02:00
use std ::{
collections ::{ BTreeMap , HashMap } ,
error , fmt ,
sync ::{ Arc , Weak } ,
} ;
2017-04-11 17:07:04 +02:00
2016-10-24 18:35:25 +02:00
use builtin ::Builtin ;
2017-04-19 14:30:00 +02:00
use error ::Error ;
2017-04-19 20:31:53 +02:00
use snapshot ::SnapshotComponents ;
2017-04-19 20:43:24 +02:00
use spec ::CommonParams ;
2020-08-05 06:08:03 +02:00
use types ::{
header ::{ ExtendedHeader , Header } ,
transaction ::{ self , SignedTransaction , UnverifiedTransaction } ,
BlockNumber ,
} ;
use vm ::{ ActionValue , CallType , CreateContractAddress , EnvInfo , Schedule } ;
2017-04-11 17:07:04 +02:00
2020-08-05 06:08:03 +02:00
use block ::ExecutedBlock ;
2017-09-06 20:47:45 +02:00
use bytes ::Bytes ;
2020-08-05 06:08:03 +02:00
use ethereum_types ::{ Address , H256 , H64 , U256 } ;
use ethkey ::Signature ;
use machine ::{ self , AuxiliaryData , AuxiliaryRequest , Machine } ;
2018-05-16 08:58:01 +02:00
use types ::ancestry_action ::AncestryAction ;
2020-08-05 06:08:03 +02:00
use unexpected ::{ Mismatch , OutOfBounds } ;
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 " ;
2019-03-14 21:34:26 +01:00
/// The number of generations back that uncles can be.
pub const MAX_UNCLE_AGE : usize = 6 ;
2017-05-30 11:52:33 +02:00
2016-08-24 15:55:47 +02:00
/// Voting errors.
#[ derive(Debug) ]
pub enum EngineError {
2020-08-05 06:08:03 +02:00
/// Signature or author field does not belong to an authority.
NotAuthorized ( Address ) ,
/// The same author issued different votes at the same step.
DoubleVote ( Address ) ,
/// The received block is from an incorrect proposer.
NotProposer ( Mismatch < Address > ) ,
/// Message was not expected.
UnexpectedMessage ,
/// Seal field has an unexpected size.
BadSealFieldSize ( OutOfBounds < usize > ) ,
/// Validation proof insufficient.
InsufficientProof ( String ) ,
/// Failed system call.
FailedSystemCall ( String ) ,
/// Malformed consensus message.
MalformedMessage ( String ) ,
/// Requires client ref, but none registered.
RequiresClient ,
/// Invalid engine specification or implementation.
InvalidEngine ,
/// Requires signer ref, but none registered.
RequiresSigner ,
/// Checkpoint is missing
CliqueMissingCheckpoint ( H256 ) ,
/// Missing vanity data
CliqueMissingVanity ,
/// Missing signature
CliqueMissingSignature ,
/// Missing signers
CliqueCheckpointNoSigner ,
/// List of signers is invalid
CliqueCheckpointInvalidSigners ( usize ) ,
/// Wrong author on a checkpoint
CliqueWrongAuthorCheckpoint ( Mismatch < Address > ) ,
/// Wrong checkpoint authors recovered
CliqueFaultyRecoveredSigners ( Vec < String > ) ,
/// Invalid nonce (should contain vote)
CliqueInvalidNonce ( H64 ) ,
/// The signer signed a block to recently
CliqueTooRecentlySigned ( Address ) ,
/// Custom
Custom ( String ) ,
2016-11-29 13:51:27 +01:00
}
impl fmt ::Display for EngineError {
2020-08-05 06:08:03 +02:00
fn fmt ( & self , f : & mut fmt ::Formatter ) -> fmt ::Result {
use self ::EngineError ::* ;
let msg = match * self {
CliqueMissingCheckpoint ( ref hash ) = > format! ( " Missing checkpoint block: {} " , hash ) ,
CliqueMissingVanity = > format! ( " Extra data is missing vanity data " ) ,
CliqueMissingSignature = > format! ( " Extra data is missing signature " ) ,
CliqueCheckpointInvalidSigners ( len ) = > format! (
" Checkpoint block list was of length: {} of checkpoint but
it needs to be bigger than zero and a divisible by 20 " ,
len
) ,
CliqueCheckpointNoSigner = > format! ( " Checkpoint block list of signers was empty " ) ,
CliqueInvalidNonce ( ref mis ) = > format! (
" Unexpected nonce {} expected {} or {} " ,
mis ,
0_ u64 ,
u64 ::max_value ( )
) ,
CliqueWrongAuthorCheckpoint ( ref oob ) = > {
format! ( " Unexpected checkpoint author: {} " , oob )
}
CliqueFaultyRecoveredSigners ( ref mis ) = > format! ( " Faulty recovered signers {:?} " , mis ) ,
CliqueTooRecentlySigned ( ref address ) = > {
format! ( " The signer: {} has signed a block too recently " , address )
}
Custom ( ref s ) = > s . clone ( ) ,
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 ( ) ,
BadSealFieldSize ( ref oob ) = > format! ( " Seal field has an unexpected length: {} " , oob ) ,
InsufficientProof ( ref msg ) = > format! ( " Insufficient validation proof: {} " , msg ) ,
FailedSystemCall ( ref msg ) = > format! ( " Failed to make system call: {} " , msg ) ,
MalformedMessage ( ref msg ) = > format! ( " Received malformed consensus message: {} " , msg ) ,
RequiresClient = > format! ( " Call requires client but none registered " ) ,
RequiresSigner = > format! ( " Call requires signer but none registered " ) ,
InvalidEngine = > format! ( " Invalid engine specification or implementation " ) ,
} ;
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 {
2020-08-05 06:08:03 +02:00
fn description ( & self ) -> & str {
" Engine error "
}
2018-04-19 11:52:54 +02:00
}
2016-12-08 12:03:34 +01:00
/// Seal type.
#[ derive(Debug, PartialEq, Eq) ]
pub enum Seal {
2020-08-05 06:08:03 +02:00
/// 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 not generate seal for this block right now.
None ,
2016-12-08 12:03:34 +01:00
}
2018-04-20 12:32:00 +02:00
/// A system-calling closure. Enacts calls on a block's state from the system address.
2020-07-29 10:36:15 +02:00
pub type SystemCall < ' a > = dyn FnMut ( Address , Vec < u8 > ) -> Result < Vec < u8 > , String > + ' a ;
2018-04-20 12:32:00 +02:00
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.
2020-08-05 06:08:03 +02:00
pub type SystemOrCodeCall < ' a > =
2020-07-29 10:36:15 +02:00
dyn FnMut ( SystemOrCodeCallKind , Vec < u8 > ) -> Result < Vec < u8 > , String > + ' a ;
2018-08-29 17:17:18 +02:00
/// Kind of SystemOrCodeCall, this is either an on-chain address, or code.
#[ derive(PartialEq, Debug, Clone) ]
pub enum SystemOrCodeCallKind {
2020-08-05 06:08:03 +02:00
/// On-chain address.
Address ( Address ) ,
/// Hard-coded code.
Code ( Arc < Vec < u8 > > , H256 ) ,
2018-08-29 17:17:18 +02:00
}
/// Default SystemOrCodeCall implementation.
2020-08-05 06:08:03 +02:00
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 ) ,
Some ( ActionValue ::Apparent ( U256 ::zero ( ) ) ) ,
U256 ::max_value ( ) ,
Some ( data ) ,
Some ( CallType ::StaticCall ) ,
) ,
} ;
result . map_err ( | e | format! ( " {} " , e ) )
}
2018-08-29 17:17:18 +02:00
}
2017-06-28 13:17:36 +02:00
/// Type alias for a function we can get headers by hash through.
2020-07-29 10:36:15 +02:00
pub type Headers < ' a , H > = dyn 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.
2020-07-29 10:36:15 +02:00
pub type PendingTransitionStore < ' a > = dyn Fn ( H256 ) -> Option < epoch ::PendingTransition > + ' a ;
2017-06-28 13:17:36 +02:00
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 {
2020-08-05 06:08:03 +02:00
/// Generate a proof, given the state.
fn generate_proof < ' a > ( & self , state : & machine ::Call ) -> Result < Vec < u8 > , String > ;
/// Check a proof generated elsewhere (potentially by a peer).
// `engine` needed to check state proofs, while really this should
// just be state machine params.
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 > {
2020-08-05 06:08:03 +02:00
/// Known proof (extracted from signal)
Known ( Vec < u8 > ) ,
/// State dependent proof.
2020-07-29 10:36:15 +02:00
WithState ( Arc < dyn 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 > {
2020-08-05 06:08:03 +02:00
/// Fully trusted verifier.
2020-07-29 10:36:15 +02:00
Trusted ( Box < dyn EpochVerifier < M > > ) ,
2020-08-05 06:08:03 +02:00
/// Verifier unconfirmed. Check whether given finality proof finalizes given hash
/// under previous epoch.
2020-07-29 10:36:15 +02:00
Unconfirmed ( Box < dyn EpochVerifier < M > > , & ' a [ u8 ] , H256 ) ,
2020-08-05 06:08:03 +02:00
/// Error constructing verifier.
Err ( Error ) ,
2017-06-28 13:17:36 +02:00
}
2017-09-26 14:19:08 +02:00
impl < ' a , M : Machine > ConstructedVerifier < ' a , M > {
2020-08-05 06:08:03 +02:00
/// Convert to a result, indicating that any necessary confirmation has been done
/// already.
2020-07-29 10:36:15 +02:00
pub fn known_confirmed ( self ) -> Result < Box < dyn EpochVerifier < M > > , Error > {
2020-08-05 06:08:03 +02:00
match self {
ConstructedVerifier ::Trusted ( v ) | ConstructedVerifier ::Unconfirmed ( v , _ , _ ) = > Ok ( v ) ,
ConstructedVerifier ::Err ( e ) = > Err ( e ) ,
}
}
2017-06-28 13:17:36 +02:00
}
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 > {
2020-08-05 06:08:03 +02:00
/// Cannot determine until more data is passed.
Unsure ( AuxiliaryRequest ) ,
/// No epoch change.
No ,
/// The epoch will change, with proof.
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 {
2020-08-05 06:08:03 +02:00
/// The name of this engine.
fn name ( & self ) -> & str ;
/// Get access to the underlying state machine.
// TODO: decouple.
fn machine ( & self ) -> & M ;
/// The number of additional header fields required for this engine.
fn seal_fields ( & self , _header : & Header ) -> usize {
0
}
/// Additional engine-specific information for the user/developer concerning `header`.
fn extra_info ( & self , _header : & Header ) -> BTreeMap < String , String > {
BTreeMap ::new ( )
}
/// Maximum number of uncles a block is allowed to declare.
fn maximum_uncle_count ( & self , _block : BlockNumber ) -> usize {
0
}
/// Optional maximum gas limit.
fn maximum_gas_limit ( & self ) -> Option < U256 > {
None
}
/// Block transformation functions, before the transactions.
/// `epoch_begin` set to true if this block kicks off an epoch.
fn on_new_block (
& self ,
_block : & mut ExecutedBlock ,
_epoch_begin : bool ,
2020-07-29 10:36:15 +02:00
_ancestry : & mut dyn Iterator < Item = ExtendedHeader > ,
2020-08-05 06:08:03 +02:00
) -> Result < ( ) , M ::Error > {
Ok ( ( ) )
}
/// Block transformation functions, after the transactions.
fn on_close_block ( & self , _block : & mut ExecutedBlock ) -> Result < ( ) , M ::Error > {
Ok ( ( ) )
}
/// Allow mutating the header during seal generation. Currently only used by Clique.
fn on_seal_block ( & self , _block : & mut ExecutedBlock ) -> Result < ( ) , Error > {
Ok ( ( ) )
}
/// 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
}
/// Called in `miner.chain_new_blocks` if the engine wishes to `update_sealing`
/// after a block was recently sealed.
///
/// returns false by default
fn should_reseal_on_update ( & self ) -> bool {
false
}
/// 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.
///
/// It is fine to require access to state or a full client for this function, since
/// light clients do not generate seals.
fn generate_seal ( & self , _block : & ExecutedBlock , _parent : & Header ) -> Seal {
Seal ::None
}
/// 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 : & Header ) -> Result < ( ) , M ::Error > ;
/// 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.
/// The verification module can optionally avoid checking the seal (`check_seal`), if seal verification is disabled this method won't be called.
fn verify_block_basic ( & self , _header : & Header ) -> Result < ( ) , M ::Error > {
Ok ( ( ) )
}
/// Phase 2 verification. Perform costly checks such as transaction signatures. Returns either a null `Ok` or a general error detailing the problem with import.
/// The verification module can optionally avoid checking the seal (`check_seal`), if seal verification is disabled this method won't be called.
fn verify_block_unordered ( & self , _header : & Header ) -> Result < ( ) , M ::Error > {
Ok ( ( ) )
}
/// Phase 3 verification. Check block information against parent. Returns either a null `Ok` or a general error detailing the problem with import.
fn verify_block_family ( & self , _header : & Header , _parent : & Header ) -> Result < ( ) , M ::Error > {
Ok ( ( ) )
}
/// Phase 4 verification. Verify block header against potentially external data.
/// Should only be called when `register_client` has been called previously.
fn verify_block_external ( & self , _header : & Header ) -> Result < ( ) , M ::Error > {
Ok ( ( ) )
}
/// Genesis epoch data.
fn genesis_epoch_data < ' a > (
& self ,
_header : & Header ,
_state : & machine ::Call ,
) -> Result < Vec < u8 > , String > {
Ok ( Vec ::new ( ) )
}
/// 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`.
///
/// If auxiliary data of the block is required, return an auxiliary request and the function will be
/// called again with them.
/// Return `Yes` or `No` when the answer is definitively known.
///
/// Should not interact with state.
fn signals_epoch_end < ' a > ( & self , _header : & Header , _aux : AuxiliaryData < ' a > ) -> EpochChange < M > {
EpochChange ::No
}
/// 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. The client must keep track of finality and provide
/// the latest finalized headers to check against the transition store.
///
/// Return optional transition proof.
fn is_epoch_end (
& self ,
_chain_head : & Header ,
_finalized : & [ H256 ] ,
_chain : & Headers < Header > ,
_transition_store : & PendingTransitionStore ,
) -> Option < Vec < u8 > > {
None
}
/// Create an epoch verifier from validation proof and a flag indicating
/// whether finality is required.
fn epoch_verifier < ' a > ( & self , _header : & Header , _proof : & ' a [ u8 ] ) -> ConstructedVerifier < ' a , M > {
ConstructedVerifier ::Trusted ( Box ::new ( NoOp ) )
}
/// Populate a header's fields based on its parent's header.
/// Usually implements the chain scoring rule based on weight.
fn populate_from_parent ( & self , _header : & mut Header , _parent : & Header ) { }
/// Handle any potential consensus messages;
/// updating consensus state and potentially issuing a new one.
fn handle_message ( & self , _message : & [ u8 ] ) -> Result < ( ) , EngineError > {
Err ( EngineError ::UnexpectedMessage )
}
/// Register a component which signs consensus messages.
2020-07-29 10:36:15 +02:00
fn set_signer ( & self , _signer : Box < dyn EngineSigner > ) { }
2020-08-05 06:08:03 +02:00
/// Sign using the EngineSigner, to be used for consensus tx signing.
fn sign ( & self , _hash : H256 ) -> Result < Signature , M ::Error > {
unimplemented! ( )
}
/// Add Client which can be used for sealing, potentially querying the state and sending messages.
fn register_client ( & self , _client : Weak < M ::EngineClient > ) { }
/// Trigger next step of the consensus engine.
fn step ( & self ) { }
/// Create a factory for building snapshot chunks and restoring from them.
/// Returning `None` indicates that this engine doesn't support snapshot creation.
2020-07-29 10:36:15 +02:00
fn snapshot_components ( & self ) -> Option < Box < dyn SnapshotComponents > > {
2020-08-05 06:08:03 +02:00
None
}
/// Whether this engine supports warp sync.
fn supports_warp ( & self ) -> bool {
self . snapshot_components ( ) . is_some ( )
}
/// Return a new open block header timestamp based on the parent timestamp.
fn open_block_header_timestamp ( & self , parent_timestamp : u64 ) -> u64 {
use std ::{ cmp , time } ;
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
}
2020-12-02 11:31:11 +01:00
// t_nb 9.1 Gather all ancestry actions. Called at the last stage when a block is committed. The Engine must guarantee that
2020-08-05 06:08:03 +02:00
/// the ancestry exists.
fn ancestry_actions (
& self ,
_header : & Header ,
2020-07-29 10:36:15 +02:00
_ancestry : & mut dyn Iterator < Item = ExtendedHeader > ,
2020-08-05 06:08:03 +02:00
) -> Vec < AncestryAction > {
Vec ::new ( )
}
/// Check whether the given new block is the best block, after finalization check.
fn fork_choice ( & self , new : & ExtendedHeader , best : & ExtendedHeader ) -> ForkChoice ;
/// Returns author should used when executing tx's for this block.
fn executive_author ( & self , header : & Header ) -> Result < Address , Error > {
Ok ( * header . author ( ) )
}
2018-05-16 08:58:01 +02:00
}
2020-12-02 11:31:11 +01:00
// t_nb 9.3 Check whether a given block is the best block based on the default total difficulty rule.
2019-03-11 11:37:48 +01:00
pub fn total_difficulty_fork_choice ( new : & ExtendedHeader , best : & ExtendedHeader ) -> ForkChoice {
2020-08-05 06:08:03 +02:00
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 > {
2020-08-05 06:08:03 +02:00
/// 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.
fn account_start_nonce ( & self , block : BlockNumber ) -> U256 {
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 )
}
/// Returns new contract address generation scheme at given block number.
fn create_address_scheme ( & self , number : BlockNumber ) -> CreateContractAddress {
self . machine ( ) . create_address_scheme ( number )
}
2020-12-02 11:31:11 +01:00
// t_nb 5.3.1 Verify a particular transaction is valid.
2020-08-05 06:08:03 +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 > {
self . machine ( ) . verify_transaction_unordered ( t , header )
}
/// 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 > {
self . machine ( ) . verify_transaction_basic ( t , header )
}
/// Additional information.
fn additional_params ( & self ) -> HashMap < String , String > {
self . machine ( ) . additional_params ( )
}
/// 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.
2020-08-05 06:08:03 +02:00
impl < T > EthEngine for T where T : Engine < ::machine ::EthereumMachine > { }
2019-03-13 11:36:13 +01:00
/// Verifier for all blocks within an epoch with self-contained state.
pub trait EpochVerifier < M : machine ::Machine > : Send + Sync {
2020-08-05 06:08:03 +02:00
/// Lightly verify the next block header.
/// This may not be a header belonging to a different epoch.
fn verify_light ( & self , header : & Header ) -> Result < ( ) , M ::Error > ;
/// Perform potentially heavier checks on the next block header.
fn verify_heavy ( & self , header : & Header ) -> Result < ( ) , M ::Error > {
self . verify_light ( header )
}
/// Check a finality proof against this epoch verifier.
/// Returns `Some(hashes)` if the proof proves finality of these hashes.
/// Returns `None` if the proof doesn't prove anything.
fn check_finality_proof ( & self , _proof : & [ u8 ] ) -> Option < Vec < H256 > > {
None
}
2019-03-13 11:36:13 +01:00
}
/// Special "no-op" verifier for stateless, epoch-less engines.
pub struct NoOp ;
impl < M : machine ::Machine > EpochVerifier < M > for NoOp {
2020-08-05 06:08:03 +02:00
fn verify_light ( & self , _header : & Header ) -> Result < ( ) , M ::Error > {
Ok ( ( ) )
}
2019-03-13 11:36:13 +01:00
}