Generalize engine trait (#6591)

* move common forks and parameters to common params

* port specs over to new format

* fix RPC tests

* parity-machine skeleton

* remove block type

* extract out ethereum-specific methods into EthereumMachine

* beginning to integrate Machine into engines. dealing with stale transitions in Ethash

* initial porting to machine

* move block reward back into engine

* abstract block reward logic

* move last hash and DAO HF logic into machine

* begin making engine function parameters generic

* abstract epoch verifier and ethash block reward logic

* instantiate special ethereummachine for ethash in spec

* optional full verification in verify_block_family

* re-instate tx_filter in a way that works for all engines

* fix warnings

* fix most tests, further generalize engine trait

* uncomment nullengine, get ethcore tests compiling

* fix warnings

* update a bunch of specs

* re-enable engine signer, validator set, and transition handler

* migrate basic_authority engine

* move last hashes into executedblock

* port tendermint

* make all ethcore tests pass

* json-tests compilation

* fix RPC tests: change in gas limit for new block changed PoW hash

* fix minor grumbles

* validate chainspecs

* fix broken import

* fix transaction verification for pre-homestead
This commit is contained in:
Robert Habermeier
2017-09-26 14:19:08 +02:00
committed by Gav Wood
parent d8af9f4e7b
commit bc167a211b
85 changed files with 2233 additions and 1923 deletions

View File

@@ -22,7 +22,7 @@ use bigint::hash::H256;
use util::*;
use bytes::{Bytes, BytesRef};
use state::{Backend as StateBackend, State, Substate, CleanupMode};
use engines::Engine;
use machine::EthereumMachine as Machine;
use executive::*;
use vm::{
self, ActionParams, ActionValue, EnvInfo, CallType, Schedule,
@@ -65,12 +65,12 @@ impl OriginInfo {
}
/// Implementation of evm Externalities.
pub struct Externalities<'a, T: 'a, V: 'a, B: 'a, E: 'a + Engine + ?Sized>
pub struct Externalities<'a, T: 'a, V: 'a, B: 'a>
where T: Tracer, V: VMTracer, B: StateBackend
{
state: &'a mut State<B>,
env_info: &'a EnvInfo,
engine: &'a E,
machine: &'a Machine,
depth: usize,
origin_info: OriginInfo,
substate: &'a mut Substate,
@@ -81,14 +81,14 @@ pub struct Externalities<'a, T: 'a, V: 'a, B: 'a, E: 'a + Engine + ?Sized>
static_flag: bool,
}
impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Externalities<'a, T, V, B, E>
where T: Tracer, V: VMTracer, B: StateBackend, E: Engine + ?Sized
impl<'a, T: 'a, V: 'a, B: 'a> Externalities<'a, T, V, B>
where T: Tracer, V: VMTracer, B: StateBackend
{
/// Basic `Externalities` constructor.
#[cfg_attr(feature="dev", allow(too_many_arguments))]
pub fn new(state: &'a mut State<B>,
env_info: &'a EnvInfo,
engine: &'a E,
machine: &'a Machine,
depth: usize,
origin_info: OriginInfo,
substate: &'a mut Substate,
@@ -100,11 +100,11 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Externalities<'a, T, V, B, E>
Externalities {
state: state,
env_info: env_info,
engine: engine,
machine: machine,
depth: depth,
origin_info: origin_info,
substate: substate,
schedule: engine.schedule(env_info.number),
schedule: machine.schedule(env_info.number),
output: output,
tracer: tracer,
vm_tracer: vm_tracer,
@@ -113,8 +113,8 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Externalities<'a, T, V, B, E>
}
}
impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for Externalities<'a, T, V, B, E>
where T: Tracer, V: VMTracer, B: StateBackend, E: Engine + ?Sized
impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B>
where T: Tracer, V: VMTracer, B: StateBackend
{
fn storage_at(&self, key: &H256) -> vm::Result<H256> {
self.state.storage_at(&self.origin_info.address, key).map_err(Into::into)
@@ -149,8 +149,8 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for Externalities<'a, T, V, B, E>
}
fn blockhash(&mut self, number: &U256) -> H256 {
if self.env_info.number + 256 >= self.engine.params().eip210_transition {
let blockhash_contract_address = self.engine.params().eip210_contract_address;
if self.env_info.number + 256 >= self.machine.params().eip210_transition {
let blockhash_contract_address = self.machine.params().eip210_contract_address;
let code_res = self.state.code(&blockhash_contract_address)
.and_then(|code| self.state.code_hash(&blockhash_contract_address).map(|hash| (code, hash)));
@@ -165,7 +165,7 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for Externalities<'a, T, V, B, E>
value: ActionValue::Apparent(self.origin_info.value),
code_address: blockhash_contract_address.clone(),
origin: self.origin_info.origin.clone(),
gas: self.engine.params().eip210_contract_gas,
gas: self.machine.params().eip210_contract_gas,
gas_price: 0.into(),
code: code,
code_hash: Some(code_hash),
@@ -174,7 +174,7 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for Externalities<'a, T, V, B, E>
};
let mut output = H256::new();
let mut ex = Executive::new(self.state, self.env_info, self.engine);
let mut ex = Executive::new(self.state, self.env_info, self.machine);
let r = ex.call(params, self.substate, BytesRef::Fixed(&mut output), self.tracer, self.vm_tracer);
trace!("ext: blockhash contract({}) -> {:?}({}) self.env_info.number={}\n", number, r, output, self.env_info.number);
output
@@ -229,7 +229,7 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for Externalities<'a, T, V, B, E>
}
}
}
let mut ex = Executive::from_parent(self.state, self.env_info, self.engine, self.depth, self.static_flag);
let mut ex = Executive::from_parent(self.state, self.env_info, self.machine, self.depth, self.static_flag);
// TODO: handle internal error separately
match ex.create(params, self.substate, &mut None, self.tracer, self.vm_tracer) {
@@ -283,7 +283,7 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for Externalities<'a, T, V, B, E>
params.value = ActionValue::Transfer(value);
}
let mut ex = Executive::from_parent(self.state, self.env_info, self.engine, self.depth, self.static_flag);
let mut ex = Executive::from_parent(self.state, self.env_info, self.machine, self.depth, self.static_flag);
match ex.call(params, self.substate, BytesRef::Fixed(output), self.tracer, self.vm_tracer) {
Ok(FinalizationResult{ gas_left, return_data, apply_state: true }) => MessageCallResult::Success(gas_left, return_data),
@@ -414,7 +414,6 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for Externalities<'a, T, V, B, E>
#[cfg(test)]
mod tests {
use util::*;
use engines::Engine;
use evm::{EnvInfo, Ext, CallType};
use state::{State, Substate};
use tests::helpers::*;
@@ -444,7 +443,7 @@ mod tests {
struct TestSetup {
state: State<::state_db::StateDB>,
engine: Arc<Engine>,
machine: ::machine::EthereumMachine,
sub_state: Substate,
env_info: EnvInfo
}
@@ -459,7 +458,7 @@ mod tests {
fn new() -> Self {
TestSetup {
state: get_temp_state(),
engine: get_test_spec().engine,
machine: ::spec::Spec::new_test_machine(),
sub_state: Substate::new(),
env_info: get_test_env_info()
}
@@ -473,7 +472,7 @@ mod tests {
let mut tracer = NoopTracer;
let mut vm_tracer = NoopVMTracer;
let ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None), &mut tracer, &mut vm_tracer, false);
let ext = Externalities::new(state, &setup.env_info, &setup.machine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None), &mut tracer, &mut vm_tracer, false);
assert_eq!(ext.env_info().number, 100);
}
@@ -485,7 +484,7 @@ mod tests {
let mut tracer = NoopTracer;
let mut vm_tracer = NoopVMTracer;
let mut ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None), &mut tracer, &mut vm_tracer, false);
let mut ext = Externalities::new(state, &setup.env_info, &setup.machine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None), &mut tracer, &mut vm_tracer, false);
let hash = ext.blockhash(&"0000000000000000000000000000000000000000000000000000000000120000".parse::<U256>().unwrap());
@@ -509,7 +508,7 @@ mod tests {
let mut tracer = NoopTracer;
let mut vm_tracer = NoopVMTracer;
let mut ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None), &mut tracer, &mut vm_tracer, false);
let mut ext = Externalities::new(state, &setup.env_info, &setup.machine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None), &mut tracer, &mut vm_tracer, false);
let hash = ext.blockhash(&"0000000000000000000000000000000000000000000000000000000000120000".parse::<U256>().unwrap());
@@ -524,7 +523,7 @@ mod tests {
let mut tracer = NoopTracer;
let mut vm_tracer = NoopVMTracer;
let mut ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None), &mut tracer, &mut vm_tracer, false);
let mut ext = Externalities::new(state, &setup.env_info, &setup.machine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None), &mut tracer, &mut vm_tracer, false);
let mut output = vec![];
@@ -552,7 +551,7 @@ mod tests {
let mut vm_tracer = NoopVMTracer;
{
let mut ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None), &mut tracer, &mut vm_tracer, false);
let mut ext = Externalities::new(state, &setup.env_info, &setup.machine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None), &mut tracer, &mut vm_tracer, false);
ext.log(log_topics, &log_data).unwrap();
}
@@ -569,7 +568,7 @@ mod tests {
let mut vm_tracer = NoopVMTracer;
{
let mut ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None), &mut tracer, &mut vm_tracer, false);
let mut ext = Externalities::new(state, &setup.env_info, &setup.machine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None), &mut tracer, &mut vm_tracer, false);
ext.suicide(refund_account).unwrap();
}