Merge pull request #5959 from paritytech/dont-compute-hash

Defer code hash calculation.
This commit is contained in:
Robert Habermeier 2017-07-06 19:00:19 +02:00 committed by GitHub
commit 125aa0aeb4
11 changed files with 37 additions and 37 deletions

View File

@ -48,7 +48,7 @@ pub struct ActionParams {
/// Address of currently executed code. /// Address of currently executed code.
pub code_address: Address, pub code_address: Address,
/// Hash of currently executed code. /// Hash of currently executed code.
pub code_hash: H256, pub code_hash: Option<H256>,
/// Receive address. Usually equal to code_address, /// Receive address. Usually equal to code_address,
/// except when called using CALLCODE. /// except when called using CALLCODE.
pub address: Address, pub address: Address,
@ -76,7 +76,7 @@ impl Default for ActionParams {
fn default() -> ActionParams { fn default() -> ActionParams {
ActionParams { ActionParams {
code_address: Address::new(), code_address: Address::new(),
code_hash: SHA3_EMPTY, code_hash: Some(SHA3_EMPTY),
address: Address::new(), address: Address::new(),
sender: Address::new(), sender: Address::new(),
origin: Address::new(), origin: Address::new(),
@ -95,7 +95,7 @@ impl From<ethjson::vm::Transaction> for ActionParams {
let address: Address = t.address.into(); let address: Address = t.address.into();
ActionParams { ActionParams {
code_address: Address::new(), code_address: Address::new(),
code_hash: (&*t.code).sha3(), code_hash: Some((&*t.code).sha3()),
address: address, address: address,
sender: t.sender.into(), sender: t.sender.into(),
origin: t.origin.into(), origin: t.origin.into(),

View File

@ -1841,7 +1841,7 @@ fn transaction_receipt(engine: &Engine, mut tx: LocalizedTransaction, mut receip
gas_used: receipt.gas_used - prior_gas_used, gas_used: receipt.gas_used - prior_gas_used,
contract_address: match tx.action { contract_address: match tx.action {
Action::Call(_) => None, Action::Call(_) => None,
Action::Create => Some(contract_address(engine.create_address_scheme(block_number), &sender, &tx.nonce, &tx.data.sha3())) Action::Create => Some(contract_address(engine.create_address_scheme(block_number), &sender, &tx.nonce, &tx.data).0)
}, },
logs: receipt.logs.into_iter().enumerate().map(|(i, log)| LocalizedLogEntry { logs: receipt.logs.into_iter().enumerate().map(|(i, log)| LocalizedLogEntry {
entry: log, entry: log,

View File

@ -434,7 +434,7 @@ pub mod common {
gas_price: 0.into(), gas_price: 0.into(),
value: ActionValue::Transfer(0.into()), value: ActionValue::Transfer(0.into()),
code: state.code(&contract_address)?, code: state.code(&contract_address)?,
code_hash: state.code_hash(&contract_address)?, code_hash: Some(state.code_hash(&contract_address)?),
data: data, data: data,
call_type: CallType::Call, call_type: CallType::Call,
}; };

View File

@ -163,7 +163,8 @@ impl<Cost: CostType> evm::Evm for Interpreter<Cost> {
match result { match result {
InstructionResult::JumpToPosition(position) => { InstructionResult::JumpToPosition(position) => {
if valid_jump_destinations.is_none() { if valid_jump_destinations.is_none() {
valid_jump_destinations = Some(self.cache.jump_destinations(&params.code_hash, code)); let code_hash = params.code_hash.clone().unwrap_or_else(|| code.sha3());
valid_jump_destinations = Some(self.cache.jump_destinations(&code_hash, code));
} }
let jump_destinations = valid_jump_destinations.as_ref().expect("jump_destinations are initialized on first jump; qed"); let jump_destinations = valid_jump_destinations.as_ref().expect("jump_destinations are initialized on first jump; qed");
let pos = self.verify_jump(position, jump_destinations)?; let pos = self.verify_jump(position, jump_destinations)?;

View File

@ -463,7 +463,7 @@ fn test_blockhash_eip210(factory: super::Factory) {
gas_price: 0.into(), gas_price: 0.into(),
value: ActionValue::Transfer(0.into()), value: ActionValue::Transfer(0.into()),
code: Some(blockhash_contract_code.clone()), code: Some(blockhash_contract_code.clone()),
code_hash: blockhash_contract_code_hash, code_hash: Some(blockhash_contract_code_hash),
data: Some(H256::from(i - 1).to_vec()), data: Some(H256::from(i - 1).to_vec()),
call_type: CallType::Call, call_type: CallType::Call,
}; };
@ -485,7 +485,7 @@ fn test_blockhash_eip210(factory: super::Factory) {
gas_price: 0.into(), gas_price: 0.into(),
value: ActionValue::Transfer(0.into()), value: ActionValue::Transfer(0.into()),
code: Some(get_prev_hash_code), code: Some(get_prev_hash_code),
code_hash: get_prev_hash_code_hash, code_hash: Some(get_prev_hash_code_hash),
data: None, data: None,
call_type: CallType::Call, call_type: CallType::Call,
}; };

View File

@ -35,7 +35,7 @@ pub use types::executed::{Executed, ExecutionResult};
const STACK_SIZE_PER_DEPTH: usize = 24*1024; const STACK_SIZE_PER_DEPTH: usize = 24*1024;
/// Returns new address created from address, nonce, and code hash /// Returns new address created from address, nonce, and code hash
pub fn contract_address(address_scheme: CreateContractAddress, sender: &Address, nonce: &U256, code_hash: &H256) -> Address { pub fn contract_address(address_scheme: CreateContractAddress, sender: &Address, nonce: &U256, code: &[u8]) -> (Address, Option<H256>) {
use rlp::RlpStream; use rlp::RlpStream;
match address_scheme { match address_scheme {
@ -43,18 +43,20 @@ pub fn contract_address(address_scheme: CreateContractAddress, sender: &Address,
let mut stream = RlpStream::new_list(2); let mut stream = RlpStream::new_list(2);
stream.append(sender); stream.append(sender);
stream.append(nonce); stream.append(nonce);
From::from(stream.as_raw().sha3()) (From::from(stream.as_raw().sha3()), None)
}, },
CreateContractAddress::FromCodeHash => { CreateContractAddress::FromCodeHash => {
let code_hash = code.sha3();
let mut buffer = [0xffu8; 20 + 32]; let mut buffer = [0xffu8; 20 + 32];
&mut buffer[20..].copy_from_slice(&code_hash[..]); &mut buffer[20..].copy_from_slice(&code_hash[..]);
From::from((&buffer[..]).sha3()) (From::from((&buffer[..]).sha3()), Some(code_hash))
}, },
CreateContractAddress::FromSenderAndCodeHash => { CreateContractAddress::FromSenderAndCodeHash => {
let code_hash = code.sha3();
let mut buffer = [0u8; 20 + 32]; let mut buffer = [0u8; 20 + 32];
&mut buffer[..20].copy_from_slice(&sender[..]); &mut buffer[..20].copy_from_slice(&sender[..]);
&mut buffer[20..].copy_from_slice(&code_hash[..]); &mut buffer[20..].copy_from_slice(&code_hash[..]);
From::from((&buffer[..]).sha3()) (From::from((&buffer[..]).sha3()), Some(code_hash))
}, },
} }
} }
@ -205,8 +207,7 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> {
let (result, output) = match t.action { let (result, output) = match t.action {
Action::Create => { Action::Create => {
let code_hash = t.data.sha3(); let (new_address, code_hash) = contract_address(self.engine.create_address_scheme(self.info.number), &sender, &nonce, &t.data);
let new_address = contract_address(self.engine.create_address_scheme(self.info.number), &sender, &nonce, &code_hash);
let params = ActionParams { let params = ActionParams {
code_address: new_address.clone(), code_address: new_address.clone(),
code_hash: code_hash, code_hash: code_hash,
@ -232,7 +233,7 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> {
gas_price: t.gas_price, gas_price: t.gas_price,
value: ActionValue::Transfer(t.value), value: ActionValue::Transfer(t.value),
code: self.state.code(address)?, code: self.state.code(address)?,
code_hash: self.state.code_hash(address)?, code_hash: Some(self.state.code_hash(address)?),
data: Some(t.data.clone()), data: Some(t.data.clone()),
call_type: CallType::Call, call_type: CallType::Call,
}; };
@ -600,14 +601,14 @@ mod tests {
fn test_contract_address() { fn test_contract_address() {
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
let expected_address = Address::from_str("3f09c73a5ed19289fb9bdc72f1742566df146f56").unwrap(); let expected_address = Address::from_str("3f09c73a5ed19289fb9bdc72f1742566df146f56").unwrap();
assert_eq!(expected_address, contract_address(CreateContractAddress::FromSenderAndNonce, &address, &U256::from(88), &H256::default())); assert_eq!(expected_address, contract_address(CreateContractAddress::FromSenderAndNonce, &address, &U256::from(88), &[]).0);
} }
// TODO: replace params with transactions! // TODO: replace params with transactions!
evm_test!{test_sender_balance: test_sender_balance_jit, test_sender_balance_int} evm_test!{test_sender_balance: test_sender_balance_jit, test_sender_balance_int}
fn test_sender_balance(factory: Factory) { fn test_sender_balance(factory: Factory) {
let sender = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); let sender = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &H256::default()); let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &[]).0;
let mut params = ActionParams::default(); let mut params = ActionParams::default();
params.address = address.clone(); params.address = address.clone();
params.sender = sender.clone(); params.sender = sender.clone();
@ -662,7 +663,7 @@ mod tests {
let code = "7c601080600c6000396000f3006000355415600957005b60203560003555600052601d60036017f0600055".from_hex().unwrap(); let code = "7c601080600c6000396000f3006000355415600957005b60203560003555600052601d60036017f0600055".from_hex().unwrap();
let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(); let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap();
let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &H256::default()); let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &[]).0;
// TODO: add tests for 'callcreate' // TODO: add tests for 'callcreate'
//let next_address = contract_address(&address, &U256::zero()); //let next_address = contract_address(&address, &U256::zero());
let mut params = ActionParams::default(); let mut params = ActionParams::default();
@ -716,7 +717,7 @@ mod tests {
let code = "7c601080600c6000396000f3006000355415600957005b60203560003555600052601d60036017f0600055".from_hex().unwrap(); let code = "7c601080600c6000396000f3006000355415600957005b60203560003555600052601d60036017f0600055".from_hex().unwrap();
let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(); let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap();
let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &H256::default()); let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &[]).0;
// TODO: add tests for 'callcreate' // TODO: add tests for 'callcreate'
//let next_address = contract_address(&address, &U256::zero()); //let next_address = contract_address(&address, &U256::zero());
let mut params = ActionParams::default(); let mut params = ActionParams::default();
@ -827,7 +828,7 @@ mod tests {
let code = "601080600c6000396000f3006000355415600957005b60203560003555".from_hex().unwrap(); let code = "601080600c6000396000f3006000355415600957005b60203560003555".from_hex().unwrap();
let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(); let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap();
let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &H256::default()); let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &[]).0;
// TODO: add tests for 'callcreate' // TODO: add tests for 'callcreate'
//let next_address = contract_address(&address, &U256::zero()); //let next_address = contract_address(&address, &U256::zero());
let mut params = ActionParams::default(); let mut params = ActionParams::default();
@ -914,7 +915,7 @@ mod tests {
let code = "7c601080600c6000396000f3006000355415600957005b60203560003555600052601d600360e6f0600055".from_hex().unwrap(); let code = "7c601080600c6000396000f3006000355415600957005b60203560003555600052601d600360e6f0600055".from_hex().unwrap();
let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(); let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap();
let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &H256::default()); let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &[]).0;
// TODO: add tests for 'callcreate' // TODO: add tests for 'callcreate'
//let next_address = contract_address(&address, &U256::zero()); //let next_address = contract_address(&address, &U256::zero());
let mut params = ActionParams::default(); let mut params = ActionParams::default();
@ -966,8 +967,8 @@ mod tests {
let code = "7c601080600c6000396000f3006000355415600957005b60203560003555600052601d60036017f0".from_hex().unwrap(); let code = "7c601080600c6000396000f3006000355415600957005b60203560003555600052601d60036017f0".from_hex().unwrap();
let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(); let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap();
let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &H256::default()); let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &[]).0;
let next_address = contract_address(CreateContractAddress::FromSenderAndNonce, &address, &U256::zero(), &H256::default()); let next_address = contract_address(CreateContractAddress::FromSenderAndNonce, &address, &U256::zero(), &[]).0;
let mut params = ActionParams::default(); let mut params = ActionParams::default();
params.address = address.clone(); params.address = address.clone();
params.sender = sender.clone(); params.sender = sender.clone();
@ -1074,7 +1075,7 @@ mod tests {
// 55 - sstore // 55 - sstore
let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(); let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap();
let code = "600160005401600055600060006000600060003060e05a03f1600155".from_hex().unwrap(); let code = "600160005401600055600060006000600060003060e05a03f1600155".from_hex().unwrap();
let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &H256::default()); let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &[]).0;
let mut params = ActionParams::default(); let mut params = ActionParams::default();
params.address = address.clone(); params.address = address.clone();
params.gas = U256::from(100_000); params.gas = U256::from(100_000);
@ -1109,7 +1110,7 @@ mod tests {
nonce: U256::zero() nonce: U256::zero()
}.sign(keypair.secret(), None); }.sign(keypair.secret(), None);
let sender = t.sender(); let sender = t.sender();
let contract = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &H256::default()); let contract = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &[]).0;
let mut state = get_temp_state_with_factory(factory); let mut state = get_temp_state_with_factory(factory);
state.add_balance(&sender, &U256::from(18), CleanupMode::NoEmpty).unwrap(); state.add_balance(&sender, &U256::from(18), CleanupMode::NoEmpty).unwrap();
@ -1238,7 +1239,7 @@ mod tests {
let code = "6064640fffffffff20600055".from_hex().unwrap(); let code = "6064640fffffffff20600055".from_hex().unwrap();
let sender = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); let sender = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &H256::default()); let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &[]).0;
// TODO: add tests for 'callcreate' // TODO: add tests for 'callcreate'
//let next_address = contract_address(&address, &U256::zero()); //let next_address = contract_address(&address, &U256::zero());
let mut params = ActionParams::default(); let mut params = ActionParams::default();

View File

@ -157,7 +157,7 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for Externalities<'a, T, V, B, E>
gas: self.engine.params().eip210_contract_gas, gas: self.engine.params().eip210_contract_gas,
gas_price: 0.into(), gas_price: 0.into(),
code: code, code: code,
code_hash: code_hash, code_hash: Some(code_hash),
data: Some(H256::from(number).to_vec()), data: Some(H256::from(number).to_vec()),
call_type: CallType::Call, call_type: CallType::Call,
}; };
@ -187,9 +187,8 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for Externalities<'a, T, V, B, E>
fn create(&mut self, gas: &U256, value: &U256, code: &[u8], address_scheme: CreateContractAddress) -> ContractCreateResult { fn create(&mut self, gas: &U256, value: &U256, code: &[u8], address_scheme: CreateContractAddress) -> ContractCreateResult {
// create new contract address // create new contract address
let code_hash = code.sha3(); let (address, code_hash) = match self.state.nonce(&self.origin_info.address) {
let address = match self.state.nonce(&self.origin_info.address) { Ok(nonce) => contract_address(address_scheme, &self.origin_info.address, &nonce, &code),
Ok(nonce) => contract_address(address_scheme, &self.origin_info.address, &nonce, &code_hash),
Err(e) => { Err(e) => {
debug!(target: "ext", "Database corruption encountered: {:?}", e); debug!(target: "ext", "Database corruption encountered: {:?}", e);
return ContractCreateResult::Failed return ContractCreateResult::Failed
@ -258,7 +257,7 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for Externalities<'a, T, V, B, E>
gas: *gas, gas: *gas,
gas_price: self.origin_info.gas_price, gas_price: self.origin_info.gas_price,
code: code, code: code,
code_hash: code_hash, code_hash: Some(code_hash),
data: Some(data.to_vec()), data: Some(data.to_vec()),
call_type: call_type, call_type: call_type,
}; };

View File

@ -123,7 +123,7 @@ impl<'a, T: 'a, V: 'a, B: 'a, E: 'a> Ext for TestExt<'a, T, V, B, E>
gas_limit: *gas, gas_limit: *gas,
value: *value value: *value
}); });
let contract_address = contract_address(address, &self.sender, &self.nonce, &code.sha3()); let contract_address = contract_address(address, &self.sender, &self.nonce, &code).0;
ContractCreateResult::Created(contract_address, *gas) ContractCreateResult::Created(contract_address, *gas)
} }

View File

@ -1051,7 +1051,7 @@ impl MinerService for Miner {
Action::Call(_) => None, Action::Call(_) => None,
Action::Create => { Action::Create => {
let sender = tx.sender(); let sender = tx.sender();
Some(contract_address(self.engine.create_address_scheme(pending.header().number()), &sender, &tx.nonce, &tx.data.sha3())) Some(contract_address(self.engine.create_address_scheme(pending.header().number()), &sender, &tx.nonce, &tx.data).0)
} }
}, },
logs: receipt.logs.clone(), logs: receipt.logs.clone(),

View File

@ -261,7 +261,7 @@ impl Spec {
trace!(target: "spec", " .. root before = {}", state.root()); trace!(target: "spec", " .. root before = {}", state.root());
let params = ActionParams { let params = ActionParams {
code_address: address.clone(), code_address: address.clone(),
code_hash: constructor.sha3(), code_hash: Some(constructor.sha3()),
address: address.clone(), address: address.clone(),
sender: from.clone(), sender: from.clone(),
origin: from.clone(), origin: from.clone(),

View File

@ -16,7 +16,6 @@
use serde::{Serialize, Serializer}; use serde::{Serialize, Serializer};
use serde::ser::SerializeStruct; use serde::ser::SerializeStruct;
use util::Hashable;
use ethcore::miner; use ethcore::miner;
use ethcore::{contract_address, CreateContractAddress}; use ethcore::{contract_address, CreateContractAddress};
use ethcore::transaction::{LocalizedTransaction, Action, PendingTransaction, SignedTransaction}; use ethcore::transaction::{LocalizedTransaction, Action, PendingTransaction, SignedTransaction};
@ -192,7 +191,7 @@ impl Transaction {
gas: t.gas.into(), gas: t.gas.into(),
input: Bytes::new(t.data.clone()), input: Bytes::new(t.data.clone()),
creates: match t.action { creates: match t.action {
Action::Create => Some(contract_address(scheme, &t.sender(), &t.nonce, &t.data.sha3()).into()), Action::Create => Some(contract_address(scheme, &t.sender(), &t.nonce, &t.data).0.into()),
Action::Call(_) => None, Action::Call(_) => None,
}, },
raw: ::rlp::encode(&t.signed).into_vec().into(), raw: ::rlp::encode(&t.signed).into_vec().into(),
@ -226,7 +225,7 @@ impl Transaction {
gas: t.gas.into(), gas: t.gas.into(),
input: Bytes::new(t.data.clone()), input: Bytes::new(t.data.clone()),
creates: match t.action { creates: match t.action {
Action::Create => Some(contract_address(scheme, &t.sender(), &t.nonce, &t.data.sha3()).into()), Action::Create => Some(contract_address(scheme, &t.sender(), &t.nonce, &t.data).0.into()),
Action::Call(_) => None, Action::Call(_) => None,
}, },
raw: ::rlp::encode(&t).into_vec().into(), raw: ::rlp::encode(&t).into_vec().into(),