Merge pull request #5959 from paritytech/dont-compute-hash
Defer code hash calculation.
This commit is contained in:
commit
125aa0aeb4
@ -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(),
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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(¶ms.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)?;
|
||||
|
@ -463,7 +463,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,
|
||||
};
|
||||
@ -485,7 +485,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,
|
||||
};
|
||||
|
@ -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,
|
||||
};
|
||||
@ -600,14 +601,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();
|
||||
@ -662,7 +663,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();
|
||||
@ -716,7 +717,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();
|
||||
@ -827,7 +828,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();
|
||||
@ -914,7 +915,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();
|
||||
@ -966,8 +967,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();
|
||||
@ -1074,7 +1075,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);
|
||||
@ -1109,7 +1110,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();
|
||||
@ -1238,7 +1239,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();
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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(),
|
||||
|
@ -261,7 +261,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(),
|
||||
|
@ -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(),
|
||||
|
Loading…
Reference in New Issue
Block a user