Defer code hash calculation.

This commit is contained in:
Tomasz Drwięga 2017-06-30 11:30:32 +02:00
parent a3e693d5c3
commit 5d9f5e3509
No known key found for this signature in database
GPG Key ID: D066F497E62CAF66
12 changed files with 38 additions and 38 deletions

View File

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

View File

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

View File

@ -163,7 +163,8 @@ impl<Cost: CostType> evm::Evm for Interpreter<Cost> {
match result {
InstructionResult::JumpToPosition(position) => {
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 pos = self.verify_jump(position, jump_destinations)?;

View File

@ -462,7 +462,7 @@ fn test_blockhash_eip210(factory: super::Factory) {
gas_price: 0.into(),
value: ActionValue::Transfer(0.into()),
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()),
call_type: CallType::Call,
};
@ -484,7 +484,7 @@ fn test_blockhash_eip210(factory: super::Factory) {
gas_price: 0.into(),
value: ActionValue::Transfer(0.into()),
code: Some(get_prev_hash_code),
code_hash: get_prev_hash_code_hash,
code_hash: Some(get_prev_hash_code_hash),
data: None,
call_type: CallType::Call,
};

View File

@ -35,7 +35,7 @@ pub use types::executed::{Executed, ExecutionResult};
const STACK_SIZE_PER_DEPTH: usize = 24*1024;
/// 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;
match address_scheme {
@ -43,18 +43,20 @@ pub fn contract_address(address_scheme: CreateContractAddress, sender: &Address,
let mut stream = RlpStream::new_list(2);
stream.append(sender);
stream.append(nonce);
From::from(stream.as_raw().sha3())
(From::from(stream.as_raw().sha3()), None)
},
CreateContractAddress::FromCodeHash => {
let code_hash = code.sha3();
let mut buffer = [0xffu8; 20 + 32];
&mut buffer[20..].copy_from_slice(&code_hash[..]);
From::from((&buffer[..]).sha3())
(From::from((&buffer[..]).sha3()), Some(code_hash))
},
CreateContractAddress::FromSenderAndCodeHash => {
let code_hash = code.sha3();
let mut buffer = [0u8; 20 + 32];
&mut buffer[..20].copy_from_slice(&sender[..]);
&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 {
Action::Create => {
let code_hash = t.data.sha3();
let new_address = contract_address(self.engine.create_address_scheme(self.info.number), &sender, &nonce, &code_hash);
let (new_address, code_hash) = contract_address(self.engine.create_address_scheme(self.info.number), &sender, &nonce, &t.data);
let params = ActionParams {
code_address: new_address.clone(),
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,
value: ActionValue::Transfer(t.value),
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()),
call_type: CallType::Call,
};
@ -599,14 +600,14 @@ mod tests {
fn test_contract_address() {
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").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!
evm_test!{test_sender_balance: test_sender_balance_jit, test_sender_balance_int}
fn test_sender_balance(factory: Factory) {
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();
params.address = address.clone();
params.sender = sender.clone();
@ -661,7 +662,7 @@ mod tests {
let code = "7c601080600c6000396000f3006000355415600957005b60203560003555600052601d60036017f0600055".from_hex().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'
//let next_address = contract_address(&address, &U256::zero());
let mut params = ActionParams::default();
@ -715,7 +716,7 @@ mod tests {
let code = "7c601080600c6000396000f3006000355415600957005b60203560003555600052601d60036017f0600055".from_hex().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'
//let next_address = contract_address(&address, &U256::zero());
let mut params = ActionParams::default();
@ -826,7 +827,7 @@ mod tests {
let code = "601080600c6000396000f3006000355415600957005b60203560003555".from_hex().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'
//let next_address = contract_address(&address, &U256::zero());
let mut params = ActionParams::default();
@ -913,7 +914,7 @@ mod tests {
let code = "7c601080600c6000396000f3006000355415600957005b60203560003555600052601d600360e6f0600055".from_hex().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'
//let next_address = contract_address(&address, &U256::zero());
let mut params = ActionParams::default();
@ -965,8 +966,8 @@ mod tests {
let code = "7c601080600c6000396000f3006000355415600957005b60203560003555600052601d60036017f0".from_hex().unwrap();
let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap();
let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &H256::default());
let next_address = contract_address(CreateContractAddress::FromSenderAndNonce, &address, &U256::zero(), &H256::default());
let address = contract_address(CreateContractAddress::FromSenderAndNonce, &sender, &U256::zero(), &[]).0;
let next_address = contract_address(CreateContractAddress::FromSenderAndNonce, &address, &U256::zero(), &[]).0;
let mut params = ActionParams::default();
params.address = address.clone();
params.sender = sender.clone();
@ -1073,7 +1074,7 @@ mod tests {
// 55 - sstore
let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").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();
params.address = address.clone();
params.gas = U256::from(100_000);
@ -1108,7 +1109,7 @@ mod tests {
nonce: U256::zero()
}.sign(keypair.secret(), None);
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);
state.add_balance(&sender, &U256::from(18), CleanupMode::NoEmpty).unwrap();
@ -1237,7 +1238,7 @@ mod tests {
let code = "6064640fffffffff20600055".from_hex().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'
//let next_address = contract_address(&address, &U256::zero());
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_price: 0.into(),
code: code,
code_hash: code_hash,
code_hash: Some(code_hash),
data: Some(H256::from(number).to_vec()),
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 {
// create new contract address
let code_hash = code.sha3();
let address = match self.state.nonce(&self.origin_info.address) {
Ok(nonce) => contract_address(address_scheme, &self.origin_info.address, &nonce, &code_hash),
let (address, code_hash) = match self.state.nonce(&self.origin_info.address) {
Ok(nonce) => contract_address(address_scheme, &self.origin_info.address, &nonce, &code),
Err(e) => {
debug!(target: "ext", "Database corruption encountered: {:?}", e);
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_price: self.origin_info.gas_price,
code: code,
code_hash: code_hash,
code_hash: Some(code_hash),
data: Some(data.to_vec()),
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,
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)
}

View File

@ -1051,7 +1051,7 @@ impl MinerService for Miner {
Action::Call(_) => None,
Action::Create => {
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(),

View File

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

View File

@ -122,7 +122,7 @@ impl trace::VMTracer for Informant {
fn prepare_subtrace(&self, code: &[u8]) -> Self where Self: Sized {
let mut vm = Informant::default();
vm.depth = self.depth + 1;
vm.code = code.into_vec();
vm.code = code.to_vec();
vm.gas_used = self.gas_used;
vm
}

View File

@ -16,7 +16,6 @@
use serde::{Serialize, Serializer};
use serde::ser::SerializeStruct;
use util::Hashable;
use ethcore::miner;
use ethcore::{contract_address, CreateContractAddress};
use ethcore::transaction::{LocalizedTransaction, Action, PendingTransaction, SignedTransaction};
@ -192,7 +191,7 @@ impl Transaction {
gas: t.gas.into(),
input: Bytes::new(t.data.clone()),
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,
},
raw: ::rlp::encode(&t.signed).into_vec().into(),
@ -226,7 +225,7 @@ impl Transaction {
gas: t.gas.into(),
input: Bytes::new(t.data.clone()),
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,
},
raw: ::rlp::encode(&t).into_vec().into(),