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

Commit 4547a90

Browse files
sorpaasandresilva
authored andcommitted
Implement CREATE2 gas changes and fix some potential overflowing (#9694)
* Implement CREATE2 gas changes and fix some potential overflowing * Ignore create2 state tests * Split CREATE and CREATE2 in gasometer * Generalize rounding (x + 31) / 32 to to_word_size
1 parent fb08edd commit 4547a90

File tree

3 files changed

+131
-9
lines changed

3 files changed

+131
-9
lines changed

ethcore/evm/src/evm.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ impl Finalize for Result<GasLeft> {
5757

5858
/// Cost calculation type. For low-gas usage we calculate costs using usize instead of U256
5959
pub trait CostType: Sized + From<usize> + Copy
60-
+ ops::Mul<Output=Self> + ops::Div<Output=Self> + ops::Add<Output=Self> +ops::Sub<Output=Self>
60+
+ ops::Mul<Output=Self> + ops::Div<Output=Self> + ops::Add<Output=Self> + ops::Sub<Output=Self>
6161
+ ops::Shr<usize, Output=Self> + ops::Shl<usize, Output=Self>
6262
+ cmp::Ord + fmt::Debug {
6363
/// Converts this cost into `U256`

ethcore/evm/src/interpreter/gasometer.rs

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -176,9 +176,8 @@ impl<Gas: evm::CostType> Gasometer<Gas> {
176176
Request::GasMem(default_gas, mem_needed(stack.peek(0), stack.peek(1))?)
177177
},
178178
instructions::SHA3 => {
179-
let w = overflowing!(add_gas_usize(Gas::from_u256(*stack.peek(1))?, 31));
180-
let words = w >> 5;
181-
let gas = Gas::from(schedule.sha3_gas) + (Gas::from(schedule.sha3_word_gas) * words);
179+
let words = overflowing!(to_word_size(Gas::from_u256(*stack.peek(1))?));
180+
let gas = overflowing!(Gas::from(schedule.sha3_gas).overflow_add(overflowing!(Gas::from(schedule.sha3_word_gas).overflow_mul(words))));
182181
Request::GasMem(gas, mem_needed(stack.peek(0), stack.peek(1))?)
183182
},
184183
instructions::CALLDATACOPY | instructions::CODECOPY | instructions::RETURNDATACOPY => {
@@ -231,9 +230,24 @@ impl<Gas: evm::CostType> Gasometer<Gas> {
231230

232231
Request::GasMemProvide(gas, mem, Some(requested))
233232
},
234-
instructions::CREATE | instructions::CREATE2 => {
233+
instructions::CREATE => {
234+
let start = stack.peek(1);
235+
let len = stack.peek(2);
236+
235237
let gas = Gas::from(schedule.create_gas);
236-
let mem = mem_needed(stack.peek(1), stack.peek(2))?;
238+
let mem = mem_needed(start, len)?;
239+
240+
Request::GasMemProvide(gas, mem, None)
241+
},
242+
instructions::CREATE2 => {
243+
let start = stack.peek(1);
244+
let len = stack.peek(2);
245+
246+
let base = Gas::from(schedule.create_gas);
247+
let word = overflowing!(to_word_size(Gas::from_u256(*len)?));
248+
let word_gas = overflowing!(Gas::from(schedule.sha3_word_gas).overflow_mul(word));
249+
let gas = overflowing!(base.overflow_add(word_gas));
250+
let mem = mem_needed(start, len)?;
237251

238252
Request::GasMemProvide(gas, mem, None)
239253
},
@@ -283,8 +297,8 @@ impl<Gas: evm::CostType> Gasometer<Gas> {
283297
},
284298
Request::GasMemCopy(gas, mem_size, copy) => {
285299
let (mem_gas_cost, new_mem_gas, new_mem_size) = self.mem_gas_cost(schedule, current_mem_size, &mem_size)?;
286-
let copy = overflowing!(add_gas_usize(copy, 31)) >> 5;
287-
let copy_gas = Gas::from(schedule.copy_gas) * copy;
300+
let copy = overflowing!(to_word_size(copy));
301+
let copy_gas = overflowing!(Gas::from(schedule.copy_gas).overflow_mul(copy));
288302
let gas = overflowing!(gas.overflow_add(copy_gas));
289303
let gas = overflowing!(gas.overflow_add(mem_gas_cost));
290304

@@ -311,7 +325,7 @@ impl<Gas: evm::CostType> Gasometer<Gas> {
311325
};
312326

313327
let current_mem_size = Gas::from(current_mem_size);
314-
let req_mem_size_rounded = (overflowing!(mem_size.overflow_add(Gas::from(31 as usize))) >> 5) << 5;
328+
let req_mem_size_rounded = overflowing!(to_word_size(*mem_size)) << 5;
315329

316330
let (mem_gas_cost, new_mem_gas) = if req_mem_size_rounded > current_mem_size {
317331
let new_mem_gas = gas_for_mem(req_mem_size_rounded)?;
@@ -343,6 +357,16 @@ fn add_gas_usize<Gas: evm::CostType>(value: Gas, num: usize) -> (Gas, bool) {
343357
value.overflow_add(Gas::from(num))
344358
}
345359

360+
#[inline]
361+
fn to_word_size<Gas: evm::CostType>(value: Gas) -> (Gas, bool) {
362+
let (gas, overflow) = add_gas_usize(value, 31);
363+
if overflow {
364+
return (gas, overflow);
365+
}
366+
367+
(gas >> 5, false)
368+
}
369+
346370
#[inline]
347371
fn calculate_eip1283_sstore_gas<Gas: evm::CostType>(schedule: &Schedule, original: &U256, current: &U256, new: &U256) -> Gas {
348372
Gas::from(

ethcore/res/ethereum/tests-issues/currents.json

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,104 @@
365365
"chain": "Constantinople (test)"
366366
}
367367
}
368+
},
369+
{
370+
"reference": "9590",
371+
"failing": "stCreate2Test",
372+
"subtests": {
373+
"call_then_create2_successful_then_returndatasize": {
374+
"subnumbers": ["1"],
375+
"chain": "Constantinople (test)"
376+
},
377+
"returndatacopy_afterFailing_create": {
378+
"subnumbers": ["1"],
379+
"chain": "Constantinople (test)"
380+
},
381+
"create2checkFieldsInInitcode": {
382+
"subnumbers": ["1","2","3","5","6","7"],
383+
"chain": "Constantinople (test)"
384+
},
385+
"Create2Recursive": {
386+
"subnumbers": ["*"],
387+
"chain": "Constantinople (test)"
388+
},
389+
"create2collisionBalance": {
390+
"subnumbers": ["2","3"],
391+
"chain": "Constantinople (test)"
392+
},
393+
"create2InitCodes": {
394+
"subnumbers": ["1","5","6","7","8","9"],
395+
"chain": "Constantinople (test)"
396+
},
397+
"Create2OOGafterInitCode": {
398+
"subnumbers": ["2"],
399+
"chain": "Constantinople (test)"
400+
},
401+
"CreateMessageRevertedOOGInInit": {
402+
"subnumbers": ["2"],
403+
"chain": "Constantinople (test)"
404+
},
405+
"returndatacopy_following_revert_in_create": {
406+
"subnumbers": ["*"],
407+
"chain": "Constantinople (test)"
408+
},
409+
"create2collisionSelfdestructed": {
410+
"subnumbers": ["2"],
411+
"chain": "Constantinople (test)"
412+
},
413+
"returndatacopy_0_0_following_successful_create": {
414+
"subnumbers": ["*"],
415+
"chain": "Constantinople (test)"
416+
},
417+
"Create2OnDepth1023": {
418+
"subnumbers": ["*"],
419+
"chain": "Constantinople (test)"
420+
},
421+
"Create2OOGafterInitCodeReturndata2": {
422+
"subnumbers": ["2"],
423+
"chain": "Constantinople (test)"
424+
},
425+
"RevertOpcodeInCreateReturns": {
426+
"subnumbers": ["*"],
427+
"chain": "Constantinople (test)"
428+
},
429+
"CREATE2_ContractSuicideDuringInit_ThenStoreThenReturn": {
430+
"subnumbers": ["*"],
431+
"chain": "Constantinople (test)"
432+
},
433+
"returndatasize_following_successful_create": {
434+
"subnumbers": ["*"],
435+
"chain": "Constantinople (test)"
436+
},
437+
"call_outsize_then_create2_successful_then_returndatasize": {
438+
"subnumbers": ["*"],
439+
"chain": "Constantinople (test)"
440+
},
441+
"CreateMessageReverted": {
442+
"subnumbers": ["2"],
443+
"chain": "Constantinople (test)"
444+
},
445+
"CREATE2_Suicide": {
446+
"subnumbers": ["*"],
447+
"chain": "Constantinople (test)"
448+
},
449+
"Create2OOGafterInitCodeRevert": {
450+
"subnumbers": ["*"],
451+
"chain": "Constantinople (test)"
452+
},
453+
"Create2OnDepth1024": {
454+
"subnumbers": ["*"],
455+
"chain": "Constantinople (test)"
456+
},
457+
"create2collisionStorage": {
458+
"subnumbers": ["2","3"],
459+
"chain": "Constantinople (test)"
460+
},
461+
"create2callPrecompiles": {
462+
"subnumbers": ["*"],
463+
"chain": "Constantinople (test)"
464+
}
465+
}
368466
}
369467
]
370468
}

0 commit comments

Comments
 (0)