Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Commit

Permalink
EIP-210
Browse files Browse the repository at this point in the history
  • Loading branch information
arkpar committed May 25, 2017
1 parent bbbdd02 commit d0312ac
Show file tree
Hide file tree
Showing 25 changed files with 381 additions and 191 deletions.
7 changes: 4 additions & 3 deletions ethcore/res/ethereum/metropolis_test.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
"homesteadTransition": "0x0",
"eip150Transition": "0x0",
"eip155Transition": "0x7fffffffffffffff",
"eip155Transition": "0x0",
"eip160Transition": "0x0",
"eip161abcTransition": "0x0",
"eip161dTransition": "0x0",
Expand All @@ -24,9 +24,10 @@
"maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388",
"networkID" : "0x1",
"eip98Transition": "0x7fffffffffffffff",
"eip98Transition": "0x0",
"eip86Transition": "0x0",
"eip140Transition": "0x0"
"eip140Transition": "0x0",
"eip210Transition": "0x0"
},
"genesis": {
"seal": {
Expand Down
12 changes: 8 additions & 4 deletions ethcore/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ impl<'x> OpenBlock<'x> {
let mut r = OpenBlock {
block: ExecutedBlock::new(state, tracing),
engine: engine,
last_hashes: last_hashes,
last_hashes: last_hashes.clone(),
};

r.block.header.set_parent_hash(parent.hash());
Expand All @@ -278,7 +278,7 @@ impl<'x> OpenBlock<'x> {
let gas_floor_target = cmp::max(gas_range_target.0, engine.params().min_gas_limit);
let gas_ceil_target = cmp::max(gas_range_target.1, gas_floor_target);
engine.populate_from_parent(&mut r.block.header, parent, gas_floor_target, gas_ceil_target);
engine.on_new_block(&mut r.block);
engine.on_new_block(&mut r.block, last_hashes)?;
Ok(r)
}

Expand Down Expand Up @@ -373,7 +373,9 @@ impl<'x> OpenBlock<'x> {

let unclosed_state = s.block.state.clone();

s.engine.on_close_block(&mut s.block);
if let Err(e) = s.engine.on_close_block(&mut s.block) {
warn!("Encountered error on closing the block: {}", e);
}
if let Err(e) = s.block.state.commit() {
warn!("Encountered error on state commit: {}", e);
}
Expand All @@ -397,7 +399,9 @@ impl<'x> OpenBlock<'x> {
pub fn close_and_lock(self) -> LockedBlock {
let mut s = self;

s.engine.on_close_block(&mut s.block);
if let Err(e) = s.engine.on_close_block(&mut s.block) {
warn!("Encountered error on closing the block: {}", e);
}

if let Err(e) = s.block.state.commit() {
warn!("Encountered error on state commit: {}", e);
Expand Down
11 changes: 5 additions & 6 deletions ethcore/src/client/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1032,8 +1032,7 @@ impl BlockChainClient for Client {
let original_state = if analytics.state_diffing { Some(state.clone()) } else { None };

let options = TransactOptions { tracing: analytics.transaction_tracing, vm_tracing: analytics.vm_tracing, check_nonce: false };
let mut ret = Executive::new(&mut state, &env_info, &*self.engine, &self.factories.vm)
.transact_virtual(t, options)?;
let mut ret = Executive::new(&mut state, &env_info, &*self.engine).transact_virtual(t, options)?;

// TODO gav move this into Executive.
if let Some(original) = original_state {
Expand Down Expand Up @@ -1063,7 +1062,7 @@ impl BlockChainClient for Client {
let tx = tx.fake_sign(sender);

let mut state = original_state.clone();
Ok(Executive::new(&mut state, &env_info, &*self.engine, &self.factories.vm)
Ok(Executive::new(&mut state, &env_info, &*self.engine)
.transact_virtual(&tx, options.clone())
.map(|r| r.exception.is_none())
.unwrap_or(false))
Expand Down Expand Up @@ -1125,13 +1124,13 @@ impl BlockChainClient for Client {
let rest = txs.split_off(address.index);
for t in txs {
let t = SignedTransaction::new(t).expect(PROOF);
let x = Executive::new(&mut state, &env_info, &*self.engine, &self.factories.vm).transact(&t, Default::default())?;
let x = Executive::new(&mut state, &env_info, &*self.engine).transact(&t, Default::default())?;
env_info.gas_used = env_info.gas_used + x.gas_used;
}
let first = rest.into_iter().next().expect("We split off < `address.index`; Length is checked earlier; qed");
let t = SignedTransaction::new(first).expect(PROOF);
let original_state = if analytics.state_diffing { Some(state.clone()) } else { None };
let mut ret = Executive::new(&mut state, &env_info, &*self.engine, &self.factories.vm).transact(&t, options)?;
let mut ret = Executive::new(&mut state, &env_info, &*self.engine).transact(&t, options)?;
if let Some(original) = original_state {
ret.state_diff = Some(state.diff_from(original).map_err(ExecutionError::from)?)
}
Expand Down Expand Up @@ -1753,7 +1752,7 @@ impl ProvingBlockChainClient for Client {

let mut state = state.replace_backend(backend);
let options = TransactOptions { tracing: false, vm_tracing: false, check_nonce: false };
let res = Executive::new(&mut state, &env_info, &*self.engine, &self.factories.vm).transact(&transaction, options);
let res = Executive::new(&mut state, &env_info, &*self.engine).transact(&transaction, options);

match res {
Err(ExecutionError::Internal(_)) => None,
Expand Down
4 changes: 2 additions & 2 deletions ethcore/src/client/test_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,7 @@ impl BlockChainClient for TestBlockChainClient {

fn nonce(&self, address: &Address, id: BlockId) -> Option<U256> {
match id {
BlockId::Latest => Some(self.nonces.read().get(address).cloned().unwrap_or(self.spec.params.account_start_nonce)),
BlockId::Latest => Some(self.nonces.read().get(address).cloned().unwrap_or(self.spec.params().account_start_nonce)),
_ => None,
}
}
Expand Down Expand Up @@ -747,7 +747,7 @@ impl BlockChainClient for TestBlockChainClient {
value: U256::default(),
data: data,
};
let network_id = Some(self.spec.params.network_id);
let network_id = Some(self.spec.params().network_id);
let sig = self.spec.engine.sign(transaction.hash(network_id)).unwrap();
let signed = SignedTransaction::new(transaction.with_signature(sig, network_id)).unwrap();
self.miner.import_own_transaction(self, signed.into())
Expand Down
5 changes: 3 additions & 2 deletions ethcore/src/engines/authority_round.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,16 +340,17 @@ impl Engine for AuthorityRound {
}

/// Apply the block reward on finalisation of the block.
fn on_close_block(&self, block: &mut ExecutedBlock) {
fn on_close_block(&self, block: &mut ExecutedBlock) -> Result<(), Error> {
let fields = block.fields_mut();
// Bestow block reward
let res = fields.state.add_balance(fields.header.author(), &self.block_reward, CleanupMode::NoEmpty)
.map_err(::error::Error::from)
.and_then(|_| fields.state.commit());
// Commit state so that we can actually figure out the state root.
if let Err(e) = res {
if let Err(ref e) = res {
warn!("Encountered error on closing block: {}", e);
}
res
}

/// Check the number of seal fields.
Expand Down
76 changes: 73 additions & 3 deletions ethcore/src/engines/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ use account_provider::AccountProvider;
use block::ExecutedBlock;
use builtin::Builtin;
use client::Client;
use env_info::EnvInfo;
use env_info::{EnvInfo, LastHashes};
use error::Error;
use evm::Schedule;
use header::{Header, BlockNumber};
Expand All @@ -53,6 +53,9 @@ use evm::CreateContractAddress;
use ethkey::Signature;
use util::*;

/// Default EIP-210 contrat code
pub const DEFAULT_BLOCKHASH_CONTRACT: &'static str = "73fffffffffffffffffffffffffffffffffffffffe33141561007a57600143036020526000356101006020510755600061010060205107141561005057600035610100610100602051050761010001555b6000620100006020510714156100755760003561010062010000602051050761020001555b610161565b436000351215801561008c5780610095565b623567e0600035125b9050156100a757600060605260206060f35b610100600035430312156100ca57610100600035075460805260206080f3610160565b62010000600035430312156100e857600061010060003507146100eb565b60005b1561010d576101006101006000350507610100015460a052602060a0f361015f565b63010000006000354303121561012d576000620100006000350714610130565b60005b1561015357610100620100006000350507610200015460c052602060c0f361015e565b600060e052602060e0f35b5b5b5b5b";

/// Voting errors.
#[derive(Debug)]
pub enum EngineError {
Expand Down Expand Up @@ -159,9 +162,15 @@ pub trait Engine : Sync + Send {
fn account_start_nonce(&self) -> U256 { self.params().account_start_nonce }

/// Block transformation functions, before the transactions.
fn on_new_block(&self, _block: &mut ExecutedBlock) {}
fn on_new_block(&self, block: &mut ExecutedBlock, last_hashes: Arc<LastHashes>) -> Result<(), Error> {
let parent_hash = block.fields().header.parent_hash().clone();
common::push_last_hash(block, last_hashes, self, &parent_hash)
}

/// Block transformation functions, after the transactions.
fn on_close_block(&self, _block: &mut ExecutedBlock) {}
fn on_close_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).
Expand Down Expand Up @@ -314,3 +323,64 @@ pub trait Engine : Sync + Send {
if number >= self.params().eip86_transition { CreateContractAddress::FromCodeHash } else { CreateContractAddress::FromSenderAndNonce }
}
}


/// Common engine utilities
pub mod common {
use block::ExecutedBlock;
use env_info::{EnvInfo, LastHashes};
use error::Error;
use transaction::SYSTEM_ADDRESS;
use executive::Executive;
use types::executed::CallType;
use action_params::{ActionParams, ActionValue};
use trace::{NoopTracer, NoopVMTracer};
use state::Substate;

use util::*;
use super::Engine;

/// 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 {
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: engine.params().eip210_contract_gas,
}
};
let mut state = block.fields_mut().state;
let contract_address = engine.params().eip210_contract_address;
let params = ActionParams {
code_address: contract_address.clone(),
address: contract_address.clone(),
sender: SYSTEM_ADDRESS.clone(),
origin: SYSTEM_ADDRESS.clone(),
gas: engine.params().eip210_contract_gas,
gas_price: 0.into(),
value: ActionValue::Transfer(0.into()),
code: state.code(&contract_address)?,
code_hash: state.code_hash(&contract_address)?,
data: Some(hash.to_vec()),
call_type: CallType::Call,
};
let mut ex = Executive::new(&mut state, &env_info, engine);
let mut substate = Substate::new();
let mut output = [];
if let Err(e) = ex.call(params, &mut substate, BytesRef::Fixed(&mut output), &mut NoopTracer, &mut NoopVMTracer) {
warn!("Encountered error on updating last hashes: {}", e);
}
}
Ok(())
}
}
5 changes: 3 additions & 2 deletions ethcore/src/engines/tendermint/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -482,16 +482,17 @@ impl Engine for Tendermint {
}

/// Apply the block reward on finalisation of the block.
fn on_close_block(&self, block: &mut ExecutedBlock) {
fn on_close_block(&self, block: &mut ExecutedBlock) -> Result<(), Error>{
let fields = block.fields_mut();
// Bestow block reward
let res = fields.state.add_balance(fields.header.author(), &self.block_reward, CleanupMode::NoEmpty)
.map_err(::error::Error::from)
.and_then(|_| fields.state.commit());
// Commit state so that we can actually figure out the state root.
if let Err(e) = res {
if let Err(ref e) = res {
warn!("Encountered error on closing block: {}", e);
}
res
}

fn verify_block_basic(&self, header: &Header, _block: Option<&[u8]>) -> Result<(), Error> {
Expand Down
Loading

0 comments on commit d0312ac

Please sign in to comment.