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

Commit 6a7074c

Browse files
sorpaasandresilva
authored andcommitted
Comply EIP-86 with the new definition (#9140)
* Comply EIP-86 with the new CREATE2 opcode * Fix rpc compile * Fix interpreter CREATE/CREATE2 stack pop difference * Add unreachable! to fix compile * Fix instruction_info * Fix gas check due to new stack item * Add new tests in executive * Fix have_create2 comment * Remove all unused references of eip86_transition and block_number
1 parent 5126c1a commit 6a7074c

File tree

17 files changed

+96
-73
lines changed

17 files changed

+96
-73
lines changed

ethcore/evm/src/instructions.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,7 @@ lazy_static! {
594594
arr[DELEGATECALL as usize] = Some(InstructionInfo::new("DELEGATECALL", 6, 1, GasPriceTier::Special));
595595
arr[STATICCALL as usize] = Some(InstructionInfo::new("STATICCALL", 6, 1, GasPriceTier::Special));
596596
arr[SUICIDE as usize] = Some(InstructionInfo::new("SUICIDE", 1, 0, GasPriceTier::Special));
597-
arr[CREATE2 as usize] = Some(InstructionInfo::new("CREATE2", 3, 1, GasPriceTier::Special));
597+
arr[CREATE2 as usize] = Some(InstructionInfo::new("CREATE2", 4, 1, GasPriceTier::Special));
598598
arr[REVERT as usize] = Some(InstructionInfo::new("REVERT", 2, 0, GasPriceTier::Zero));
599599
arr
600600
};

ethcore/evm/src/interpreter/gasometer.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,11 @@ impl<Gas: evm::CostType> Gasometer<Gas> {
228228
},
229229
instructions::CREATE | instructions::CREATE2 => {
230230
let gas = Gas::from(schedule.create_gas);
231-
let mem = mem_needed(stack.peek(1), stack.peek(2))?;
231+
let mem = match instruction {
232+
instructions::CREATE => mem_needed(stack.peek(1), stack.peek(2))?,
233+
instructions::CREATE2 => mem_needed(stack.peek(2), stack.peek(3))?,
234+
_ => unreachable!("instruction can only be CREATE/CREATE2 checked above; qed"),
235+
};
232236

233237
Request::GasMemProvide(gas, mem, None)
234238
},

ethcore/evm/src/interpreter/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,11 @@ impl<Cost: CostType> Interpreter<Cost> {
317317
},
318318
instructions::CREATE | instructions::CREATE2 => {
319319
let endowment = stack.pop_back();
320+
let address_scheme = match instruction {
321+
instructions::CREATE => CreateContractAddress::FromSenderAndNonce,
322+
instructions::CREATE2 => CreateContractAddress::FromSenderSaltAndCodeHash(stack.pop_back().into()),
323+
_ => unreachable!("instruction can only be CREATE/CREATE2 checked above; qed"),
324+
};
320325
let init_off = stack.pop_back();
321326
let init_size = stack.pop_back();
322327

@@ -336,7 +341,6 @@ impl<Cost: CostType> Interpreter<Cost> {
336341
}
337342

338343
let contract_code = self.mem.read_slice(init_off, init_size);
339-
let address_scheme = if instruction == instructions::CREATE { CreateContractAddress::FromSenderAndNonce } else { CreateContractAddress::FromSenderAndCodeHash };
340344

341345
let create_result = ext.create(&create_gas.as_u256(), &endowment, contract_code, address_scheme);
342346
return match create_result {

ethcore/src/executive.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,12 @@ pub fn contract_address(address_scheme: CreateContractAddress, sender: &Address,
6161
stream.append(nonce);
6262
(From::from(keccak(stream.as_raw())), None)
6363
},
64-
CreateContractAddress::FromCodeHash => {
64+
CreateContractAddress::FromSenderSaltAndCodeHash(salt) => {
6565
let code_hash = keccak(code);
66-
let mut buffer = [0xffu8; 20 + 32];
67-
&mut buffer[20..].copy_from_slice(&code_hash[..]);
66+
let mut buffer = [0u8; 20 + 32 + 32];
67+
&mut buffer[0..20].copy_from_slice(&sender[..]);
68+
&mut buffer[20..(20+32)].copy_from_slice(&salt[..]);
69+
&mut buffer[(20+32)..].copy_from_slice(&code_hash[..]);
6870
(From::from(keccak(&buffer[..])), Some(code_hash))
6971
},
7072
CreateContractAddress::FromSenderAndCodeHash => {

ethcore/src/externalities.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,4 +574,44 @@ mod tests {
574574

575575
assert_eq!(setup.sub_state.suicides.len(), 1);
576576
}
577+
578+
#[test]
579+
fn can_create() {
580+
use std::str::FromStr;
581+
582+
let mut setup = TestSetup::new();
583+
let state = &mut setup.state;
584+
let mut tracer = NoopTracer;
585+
let mut vm_tracer = NoopVMTracer;
586+
587+
let address = {
588+
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);
589+
match ext.create(&U256::max_value(), &U256::zero(), &[], CreateContractAddress::FromSenderAndNonce) {
590+
ContractCreateResult::Created(address, _) => address,
591+
_ => panic!("Test create failed; expected Created, got Failed/Reverted."),
592+
}
593+
};
594+
595+
assert_eq!(address, Address::from_str("bd770416a3345f91e4b34576cb804a576fa48eb1").unwrap());
596+
}
597+
598+
#[test]
599+
fn can_create2() {
600+
use std::str::FromStr;
601+
602+
let mut setup = TestSetup::new();
603+
let state = &mut setup.state;
604+
let mut tracer = NoopTracer;
605+
let mut vm_tracer = NoopVMTracer;
606+
607+
let address = {
608+
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);
609+
match ext.create(&U256::max_value(), &U256::zero(), &[], CreateContractAddress::FromSenderSaltAndCodeHash(H256::default())) {
610+
ContractCreateResult::Created(address, _) => address,
611+
_ => panic!("Test create failed; expected Created, got Failed/Reverted."),
612+
}
613+
};
614+
615+
assert_eq!(address, Address::from_str("b7c227636666831278bacdb8d7f52933b8698ab9").unwrap());
616+
}
577617
}

ethcore/src/machine.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -309,12 +309,8 @@ impl EthereumMachine {
309309
}
310310

311311
/// Returns new contract address generation scheme at given block number.
312-
pub fn create_address_scheme(&self, number: BlockNumber) -> CreateContractAddress {
313-
if number >= self.params().eip86_transition {
314-
CreateContractAddress::FromCodeHash
315-
} else {
316-
CreateContractAddress::FromSenderAndNonce
317-
}
312+
pub fn create_address_scheme(&self, _number: BlockNumber) -> CreateContractAddress {
313+
CreateContractAddress::FromSenderAndNonce
318314
}
319315

320316
/// Verify a particular transaction is valid, regardless of order.

ethcore/vm/src/ext.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,11 @@ pub enum MessageCallResult {
5353
/// Specifies how an address is calculated for a new contract.
5454
#[derive(Copy, Clone, PartialEq, Eq)]
5555
pub enum CreateContractAddress {
56-
/// Address is calculated from nonce and sender. Pre EIP-86 (Metropolis)
56+
/// Address is calculated from sender and nonce. Pre EIP-86 (Metropolis)
5757
FromSenderAndNonce,
58-
/// Address is calculated from code hash. Default since EIP-86
59-
FromCodeHash,
60-
/// Address is calculated from code hash and sender. Used by CREATE_P2SH instruction.
58+
/// Address is calculated from sender, salt and code hash. EIP-86 CREATE2 scheme.
59+
FromSenderSaltAndCodeHash(H256),
60+
/// Address is calculated from code hash and sender. Used by pwasm create ext.
6161
FromSenderAndCodeHash,
6262
}
6363

ethcore/vm/src/schedule.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ pub struct Schedule {
2222
pub exceptional_failed_code_deposit: bool,
2323
/// Does it have a delegate cal
2424
pub have_delegate_call: bool,
25-
/// Does it have a CREATE_P2SH instruction
25+
/// Does it have a CREATE2 instruction
2626
pub have_create2: bool,
2727
/// Does it have a REVERT instruction
2828
pub have_revert: bool,

rpc/src/v1/helpers/dispatch.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,7 @@ impl<C: miner::BlockChainClient + BlockChainClient, M: MinerService> Dispatcher
178178
}
179179

180180
fn enrich(&self, signed_transaction: SignedTransaction) -> RpcRichRawTransaction {
181-
let block_number = self.client.best_block_header().number();
182-
RpcRichRawTransaction::from_signed(signed_transaction, block_number, self.client.eip86_transition())
181+
RpcRichRawTransaction::from_signed(signed_transaction)
183182
}
184183

185184
fn dispatch_transaction(&self, signed_transaction: PendingTransaction) -> Result<H256> {
@@ -405,8 +404,7 @@ impl Dispatcher for LightDispatcher {
405404
}
406405

407406
fn enrich(&self, signed_transaction: SignedTransaction) -> RpcRichRawTransaction {
408-
let block_number = self.client.best_block_header().number();
409-
RpcRichRawTransaction::from_signed(signed_transaction, block_number, self.client.eip86_transition())
407+
RpcRichRawTransaction::from_signed(signed_transaction)
410408
}
411409

412410
fn dispatch_transaction(&self, signed_transaction: PendingTransaction) -> Result<H256> {

rpc/src/v1/helpers/light_fetch.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ pub struct LightFetch {
6868
}
6969

7070
/// Extract a transaction at given index.
71-
pub fn extract_transaction_at_index(block: encoded::Block, index: usize, eip86_transition: u64) -> Option<Transaction> {
71+
pub fn extract_transaction_at_index(block: encoded::Block, index: usize) -> Option<Transaction> {
7272
block.transactions().into_iter().nth(index)
7373
// Verify if transaction signature is correct.
7474
.and_then(|tx| SignedTransaction::new(tx).ok())
@@ -87,7 +87,7 @@ pub fn extract_transaction_at_index(block: encoded::Block, index: usize, eip86_t
8787
cached_sender,
8888
}
8989
})
90-
.map(|tx| Transaction::from_localized(tx, eip86_transition))
90+
.map(|tx| Transaction::from_localized(tx))
9191
}
9292

9393
// extract the header indicated by the given `HeaderRef` from the given responses.
@@ -366,7 +366,7 @@ impl LightFetch {
366366

367367
// Get a transaction by hash. also returns the index in the block.
368368
// Only returns transactions in the canonical chain.
369-
pub fn transaction_by_hash(&self, tx_hash: H256, eip86_transition: u64)
369+
pub fn transaction_by_hash(&self, tx_hash: H256)
370370
-> impl Future<Item = Option<(Transaction, usize)>, Error = Error> + Send
371371
{
372372
let params = (self.sync.clone(), self.on_demand.clone());
@@ -398,7 +398,7 @@ impl LightFetch {
398398
}
399399

400400
let index = index.index as usize;
401-
let transaction = extract_transaction_at_index(blk, index, eip86_transition);
401+
let transaction = extract_transaction_at_index(blk, index);
402402

403403
if transaction.as_ref().map_or(true, |tx| tx.hash != tx_hash.into()) {
404404
// index is actively wrong: indicated block has

0 commit comments

Comments
 (0)