2017-01-25 18:51:41 +01:00
|
|
|
// 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/>.
|
|
|
|
|
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
|
|
|
|
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-01-10 12:23:59 +01:00
|
|
|
use std::sync::Weak;
|
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-01-26 19:18:22 +01:00
|
|
|
use block::ExecutedBlock;
|
2016-10-24 18:35:25 +02:00
|
|
|
use builtin::Builtin;
|
2017-08-22 10:00:44 +02:00
|
|
|
use client::EngineClient;
|
2017-07-12 13:09:17 +02:00
|
|
|
use evm::env_info::{EnvInfo, LastHashes};
|
2017-04-19 14:30:00 +02:00
|
|
|
use error::Error;
|
2016-05-19 00:44:49 +02:00
|
|
|
use evm::Schedule;
|
2017-04-19 14:30:00 +02:00
|
|
|
use header::{Header, BlockNumber};
|
2017-04-19 20:43:24 +02:00
|
|
|
use receipt::Receipt;
|
2017-04-19 20:31:53 +02:00
|
|
|
use snapshot::SnapshotComponents;
|
2017-04-19 20:43:24 +02:00
|
|
|
use spec::CommonParams;
|
2017-01-13 09:51:36 +01:00
|
|
|
use transaction::{UnverifiedTransaction, SignedTransaction};
|
2017-05-05 16:00:40 +02:00
|
|
|
use evm::CreateContractAddress;
|
2017-04-11 17:07:04 +02:00
|
|
|
|
|
|
|
use ethkey::Signature;
|
|
|
|
use util::*;
|
2015-12-20 13:16:12 +01:00
|
|
|
|
2017-05-30 11:52:33 +02:00
|
|
|
/// Default EIP-210 contrat code.
|
|
|
|
/// As defined in https://github.com/ethereum/EIPs/pull/210/commits/9df24a3714af42e3bf350265bdc75b486c909d7f#diff-e02a92c2fb96c1a1bfb05e4c6e2ef5daR49
|
|
|
|
pub const DEFAULT_BLOCKHASH_CONTRACT: &'static str = "73fffffffffffffffffffffffffffffffffffffffe33141561007a57600143036020526000356101006020510755600061010060205107141561005057600035610100610100602051050761010001555b6000620100006020510714156100755760003561010062010000602051050761020001555b610161565b436000351215801561008c5780610095565b623567e0600035125b9050156100a757600060605260206060f35b610100600035430312156100ca57610100600035075460805260206080f3610160565b62010000600035430312156100e857600061010060003507146100eb565b60005b1561010d576101006101006000350507610100015460a052602060a0f361015f565b63010000006000354303121561012d576000620100006000350714610130565b60005b1561015357610100620100006000350507610200015460c052602060c0f361015e565b600060e052602060e0f35b5b5b5b5b";
|
|
|
|
|
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),
|
|
|
|
/// 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),
|
|
|
|
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
|
|
|
}
|
|
|
|
|
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-06-28 13:17:36 +02:00
|
|
|
/// Returns the call result and state proof for each call.
|
|
|
|
pub type Call<'a> = Fn(Address, Bytes) -> Result<(Bytes, Vec<Vec<u8>>), String> + 'a;
|
|
|
|
|
|
|
|
/// Type alias for a function we can get headers by hash through.
|
|
|
|
pub type Headers<'a> = Fn(H256) -> Option<Header> + 'a;
|
|
|
|
|
|
|
|
/// Type alias for a function we can query pending transitions by block hash through.
|
|
|
|
pub type PendingTransitionStore<'a> = Fn(H256) -> Option<PendingTransition> + 'a;
|
|
|
|
|
2017-07-28 19:38:52 +02:00
|
|
|
/// Proof dependent on state.
|
|
|
|
pub trait StateDependentProof {
|
|
|
|
/// Generate a proof, given the state.
|
|
|
|
fn generate_proof(&self, caller: &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, engine: &Engine, proof: &[u8]) -> Result<(), String>;
|
|
|
|
}
|
|
|
|
|
2017-06-28 13:17:36 +02:00
|
|
|
/// Proof generated on epoch change.
|
|
|
|
pub enum Proof {
|
2017-08-03 18:18:19 +02:00
|
|
|
/// Known proof (extracted from signal)
|
2017-06-28 13:17:36 +02:00
|
|
|
Known(Vec<u8>),
|
2017-07-28 19:38:52 +02:00
|
|
|
/// State dependent proof.
|
|
|
|
WithState(Box<StateDependentProof>),
|
2017-06-28 13:17:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Generated epoch verifier.
|
|
|
|
pub enum ConstructedVerifier<'a> {
|
|
|
|
/// Fully trusted verifier.
|
|
|
|
Trusted(Box<EpochVerifier>),
|
|
|
|
/// Verifier unconfirmed. Check whether given finality proof finalizes given hash
|
|
|
|
/// under previous epoch.
|
|
|
|
Unconfirmed(Box<EpochVerifier>, &'a [u8], H256),
|
|
|
|
/// Error constructing verifier.
|
|
|
|
Err(Error),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> ConstructedVerifier<'a> {
|
|
|
|
/// Convert to a result, indicating that any necessary confirmation has been done
|
|
|
|
/// already.
|
|
|
|
pub fn known_confirmed(self) -> Result<Box<EpochVerifier>, Error> {
|
|
|
|
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.
|
|
|
|
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-06-28 13:17:36 +02:00
|
|
|
/// The epoch will change, with proof.
|
|
|
|
Yes(Proof),
|
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,
|
|
|
|
}
|
|
|
|
|
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`.
|
2016-11-04 17:35:02 +01:00
|
|
|
fn extra_info(&self, _header: &Header) -> BTreeMap<String, String> { BTreeMap::new() }
|
2015-12-20 13:16:12 +01:00
|
|
|
|
2016-08-17 19:25:02 +02:00
|
|
|
/// Additional information.
|
2016-09-22 14:50:00 +02:00
|
|
|
fn additional_params(&self) -> HashMap<String, String> { HashMap::new() }
|
2016-08-17 19:25:02 +02:00
|
|
|
|
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
|
|
|
|
2017-04-19 14:30:00 +02:00
|
|
|
/// Get the EVM schedule for the given `block_number`.
|
2017-06-19 11:41:46 +02:00
|
|
|
fn schedule(&self, block_number: BlockNumber) -> Schedule {
|
2017-07-12 13:09:17 +02:00
|
|
|
self.params().schedule(block_number)
|
2017-06-19 11:41:46 +02:00
|
|
|
}
|
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 }
|
2017-06-28 09:10:57 +02:00
|
|
|
/// The nonce with which accounts begin at given block.
|
|
|
|
fn account_start_nonce(&self, block: u64) -> U256 {
|
|
|
|
if block >= self.params().dust_protection_transition {
|
|
|
|
U256::from(self.params().nonce_cap_increment) * U256::from(block)
|
|
|
|
} else {
|
|
|
|
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.
|
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,
|
|
|
|
block: &mut ExecutedBlock,
|
|
|
|
last_hashes: Arc<LastHashes>,
|
|
|
|
_epoch_begin: bool,
|
|
|
|
) -> Result<(), Error> {
|
2017-05-30 11:52:33 +02:00
|
|
|
let parent_hash = block.fields().header.parent_hash().clone();
|
|
|
|
common::push_last_hash(block, last_hashes, self, &parent_hash)
|
|
|
|
}
|
|
|
|
|
2016-02-02 23:43:29 +01:00
|
|
|
/// Block transformation functions, after the transactions.
|
2017-05-30 11:52:33 +02:00
|
|
|
fn on_close_block(&self, _block: &mut ExecutedBlock) -> Result<(), Error> {
|
|
|
|
Ok(())
|
|
|
|
}
|
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 }
|
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.
|
2016-12-08 12:03:34 +01:00
|
|
|
fn generate_seal(&self, _block: &ExecutedBlock) -> Seal { Seal::None }
|
2016-05-03 17:23:53 +02:00
|
|
|
|
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
|
|
|
|
2017-04-13 20:24:21 +02:00
|
|
|
/// Phase 4 verification. Verify block header against potentially external data.
|
|
|
|
fn verify_block_external(&self, _header: &Header, _block: Option<&[u8]>) -> Result<(), Error> { Ok(()) }
|
|
|
|
|
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.
|
2017-01-13 09:51:36 +01:00
|
|
|
fn verify_transaction_basic(&self, t: &UnverifiedTransaction, _header: &Header) -> Result<(), Error> {
|
2017-04-19 14:30:00 +02:00
|
|
|
t.verify_basic(true, Some(self.params().network_id), true)?;
|
2017-01-13 09:51:36 +01:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2016-02-02 23:43:29 +01:00
|
|
|
/// Verify a particular transaction is valid.
|
2017-01-13 09:51:36 +01:00
|
|
|
fn verify_transaction(&self, t: UnverifiedTransaction, _header: &Header) -> Result<SignedTransaction, Error> {
|
|
|
|
SignedTransaction::new(t)
|
|
|
|
}
|
2015-12-20 13:16:12 +01:00
|
|
|
|
2016-11-03 22:22:25 +01:00
|
|
|
/// The network ID that transactions should be signed with.
|
2017-03-08 14:44:07 +01:00
|
|
|
fn signing_network_id(&self, _env_info: &EnvInfo) -> Option<u64> {
|
|
|
|
Some(self.params().chain_id)
|
|
|
|
}
|
2016-11-03 22:22:25 +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.
|
2017-04-12 14:41:19 +02:00
|
|
|
fn verify_block_seal(&self, header: &Header) -> Result<(), Error> {
|
2016-03-01 17:23:44 +01:00
|
|
|
self.verify_block_basic(header, None).and_then(|_| self.verify_block_unordered(header, None))
|
|
|
|
}
|
|
|
|
|
2017-06-28 13:17:36 +02:00
|
|
|
/// Genesis epoch data.
|
|
|
|
fn genesis_epoch_data(&self, _header: &Header, _call: &Call) -> 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
|
|
|
///
|
|
|
|
/// If the block or receipts are required, return `Unsure` and the function will be
|
|
|
|
/// 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-06-28 13:17:36 +02:00
|
|
|
fn signals_epoch_end(&self, _header: &Header, _block: Option<&[u8]>, _receipts: Option<&[Receipt]>)
|
2017-04-18 14:19:10 +02:00
|
|
|
-> 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-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,
|
|
|
|
_chain_head: &Header,
|
|
|
|
_chain: &Headers,
|
|
|
|
_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> {
|
|
|
|
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.
|
2016-12-11 12:50:48 +01:00
|
|
|
/// 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) {
|
2016-08-29 11:35:24 +02:00
|
|
|
header.set_difficulty(parent.difficulty().clone());
|
|
|
|
header.set_gas_limit(parent.gas_limit().clone());
|
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-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
|
|
|
|
2017-03-21 17:36:38 +01: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
|
2015-12-21 18:40:48 +01:00
|
|
|
// from Spec into here and removing the Spec::builtins field.
|
2017-03-21 17:36:38 +01:00
|
|
|
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 })
|
2016-10-20 23:41:15 +02:00
|
|
|
}
|
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.
|
2017-01-18 18:49:50 +01:00
|
|
|
fn set_signer(&self, _account_provider: Arc<AccountProvider>, _address: Address, _password: String) {}
|
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.
|
|
|
|
fn sign(&self, _hash: H256) -> Result<Signature, Error> { unimplemented!() }
|
|
|
|
|
2017-01-10 12:23:59 +01:00
|
|
|
/// Add Client which can be used for sealing, querying the state and sending messages.
|
2017-08-22 10:00:44 +02:00
|
|
|
fn register_client(&self, _client: Weak<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()
|
|
|
|
}
|
|
|
|
|
2017-07-10 17:42:10 +02:00
|
|
|
/// If this engine supports wasm contracts.
|
|
|
|
fn supports_wasm(&self) -> bool {
|
|
|
|
self.params().wasm
|
|
|
|
}
|
|
|
|
|
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-06-28 13:17:36 +02:00
|
|
|
if number >= self.params().eip86_transition {
|
|
|
|
CreateContractAddress::FromCodeHash
|
|
|
|
} else {
|
|
|
|
CreateContractAddress::FromSenderAndNonce
|
|
|
|
}
|
2017-05-05 16:00:40 +02:00
|
|
|
}
|
2015-12-20 13:16:12 +01:00
|
|
|
}
|
2017-05-30 11:52:33 +02:00
|
|
|
|
|
|
|
/// Common engine utilities
|
|
|
|
pub mod common {
|
|
|
|
use block::ExecutedBlock;
|
2017-07-12 13:09:17 +02:00
|
|
|
use evm::env_info::{EnvInfo, LastHashes};
|
2017-05-30 11:52:33 +02:00
|
|
|
use error::Error;
|
|
|
|
use transaction::SYSTEM_ADDRESS;
|
|
|
|
use executive::Executive;
|
2017-07-12 13:09:17 +02:00
|
|
|
use evm::CallType;
|
|
|
|
use evm::action_params::{ActionParams, ActionValue};
|
2017-05-30 11:52:33 +02:00
|
|
|
use trace::{NoopTracer, NoopVMTracer};
|
|
|
|
use state::Substate;
|
|
|
|
|
|
|
|
use util::*;
|
|
|
|
use super::Engine;
|
|
|
|
|
2017-06-28 13:17:36 +02:00
|
|
|
/// Execute a call as the system address.
|
|
|
|
pub fn execute_as_system<E: Engine + ?Sized>(
|
|
|
|
block: &mut ExecutedBlock,
|
|
|
|
last_hashes: Arc<LastHashes>,
|
|
|
|
engine: &E,
|
|
|
|
contract_address: Address,
|
|
|
|
gas: U256,
|
|
|
|
data: Option<Bytes>,
|
|
|
|
) -> Result<Bytes, Error> {
|
|
|
|
let env_info = {
|
|
|
|
let header = block.fields().header;
|
|
|
|
EnvInfo {
|
|
|
|
number: header.number(),
|
|
|
|
author: header.author().clone(),
|
|
|
|
timestamp: header.timestamp(),
|
|
|
|
difficulty: header.difficulty().clone(),
|
|
|
|
last_hashes: last_hashes,
|
|
|
|
gas_used: U256::zero(),
|
|
|
|
gas_limit: gas,
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
let mut state = block.fields_mut().state;
|
|
|
|
let params = ActionParams {
|
|
|
|
code_address: contract_address.clone(),
|
|
|
|
address: contract_address.clone(),
|
|
|
|
sender: SYSTEM_ADDRESS.clone(),
|
|
|
|
origin: SYSTEM_ADDRESS.clone(),
|
|
|
|
gas: gas,
|
|
|
|
gas_price: 0.into(),
|
|
|
|
value: ActionValue::Transfer(0.into()),
|
|
|
|
code: state.code(&contract_address)?,
|
2017-06-30 11:30:32 +02:00
|
|
|
code_hash: Some(state.code_hash(&contract_address)?),
|
2017-06-28 13:17:36 +02:00
|
|
|
data: data,
|
|
|
|
call_type: CallType::Call,
|
|
|
|
};
|
|
|
|
let mut ex = Executive::new(&mut state, &env_info, engine);
|
|
|
|
let mut substate = Substate::new();
|
|
|
|
let mut output = Vec::new();
|
|
|
|
if let Err(e) = ex.call(params, &mut substate, BytesRef::Flexible(&mut output), &mut NoopTracer, &mut NoopVMTracer) {
|
|
|
|
warn!("Encountered error on making system call: {}", e);
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(output)
|
|
|
|
}
|
|
|
|
|
2017-05-30 11:52:33 +02:00
|
|
|
/// Push last known block hash to the state.
|
|
|
|
pub fn push_last_hash<E: Engine + ?Sized>(block: &mut ExecutedBlock, last_hashes: Arc<LastHashes>, engine: &E, hash: &H256) -> Result<(), Error> {
|
|
|
|
if block.fields().header.number() == engine.params().eip210_transition {
|
|
|
|
let state = block.fields_mut().state;
|
|
|
|
state.init_code(&engine.params().eip210_contract_address, engine.params().eip210_contract_code.clone())?;
|
|
|
|
}
|
|
|
|
if block.fields().header.number() >= engine.params().eip210_transition {
|
2017-06-28 13:17:36 +02:00
|
|
|
let _ = execute_as_system(
|
|
|
|
block,
|
|
|
|
last_hashes,
|
|
|
|
engine,
|
|
|
|
engine.params().eip210_contract_address,
|
|
|
|
engine.params().eip210_contract_gas,
|
|
|
|
Some(hash.to_vec()),
|
|
|
|
)?;
|
2017-05-30 11:52:33 +02:00
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|