Skip to content
This repository was archived by the owner on May 23, 2023. It is now read-only.

Commit 3907a6e

Browse files
committed
Implement supplemental gas for CALL* EIP150(1b) #413
1 parent a7daa58 commit 3907a6e

File tree

1 file changed

+43
-7
lines changed

1 file changed

+43
-7
lines changed

ethereum/vm.py

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,16 @@ def eat_gas(compustate, amount):
140140
return True
141141

142142

143+
def all_but_1_nth(gas, n):
144+
return gas - (gas // n)
145+
146+
147+
def max_call_gas(gas):
148+
"""Since EIP150 CALLs will send only all but 1/64th of the available gas.
149+
"""
150+
return all_but_1_nth(gas, n=opcodes.CALL_CHILD_LIMIT_DENOM)
151+
152+
143153
def vm_exception(error, **kargs):
144154
log_vm_exit.trace('EXCEPTION', cause=error, **kargs)
145155
return 0, 0, []
@@ -513,14 +523,20 @@ def vm_execute(ext, msg, code):
513523
return vm_exception('OOG EXTENDING MEMORY')
514524
if ext.get_balance(msg.to) >= value and msg.depth < 1024:
515525
cd = CallData(mem, mstart, msz)
516-
create_msg = Message(msg.to, b'', value, compustate.gas, cd, msg.depth + 1)
526+
ingas = compustate.gas
527+
# EIP150(1b) CREATE only provides all but one 64th of the
528+
# parent gas to the child call
529+
if ext.post_anti_dos_hardfork():
530+
ingas = max_call_gas(ingas)
531+
532+
create_msg = Message(msg.to, b'', value, ingas, cd, msg.depth + 1)
517533
o, gas, addr = ext.create(create_msg)
518534
if o:
519535
stk.append(utils.coerce_to_int(addr))
520-
compustate.gas = gas
536+
compustate.gas -= (ingas - gas)
521537
else:
522538
stk.append(0)
523-
compustate.gas = 0
539+
compustate.gas -= ingas
524540
else:
525541
stk.append(0)
526542
elif op == 'CALL':
@@ -535,9 +551,19 @@ def vm_execute(ext, msg, code):
535551
(value > 0) * opcodes.GCALLVALUETRANSFER + \
536552
ext.post_anti_dos_hardfork() * opcodes.CALL_SUPPLEMENTAL_GAS
537553
# ^ EIP150 Increase the gas cost of CALL to 700
554+
555+
if ext.post_anti_dos_hardfork():
556+
# EIP150(1b) if a call asks for more gas than all but one 64th of
557+
# the maximum allowed amount, call with all but one 64th of the
558+
# maximum allowed amount of gas
559+
if compustate.gas < extra_gas:
560+
return vm_exception('OUT OF GAS', needed=extra_gas)
561+
gas = min(gas, max_call_gas(compustate.gas - extra_gas))
562+
else:
563+
if compustate.gas < gas + extra_gas:
564+
return vm_exception('OUT OF GAS', needed=gas + extra_gas)
565+
538566
submsg_gas = gas + opcodes.GSTIPEND * (value > 0)
539-
if compustate.gas < gas + extra_gas:
540-
return vm_exception('OUT OF GAS', needed=gas + extra_gas)
541567
if ext.get_balance(msg.to) >= value and msg.depth < 1024:
542568
compustate.gas -= (gas + extra_gas)
543569
cd = CallData(mem, meminstart, meminsz)
@@ -568,9 +594,19 @@ def vm_execute(ext, msg, code):
568594
extra_gas = (value > 0) * opcodes.GCALLVALUETRANSFER + \
569595
ext.post_anti_dos_hardfork() * opcodes.CALL_SUPPLEMENTAL_GAS
570596
# ^ EIP150 Increase the gas cost of CALLCODE, DELEGATECALL to 700
597+
598+
if ext.post_anti_dos_hardfork():
599+
# EIP150(1b) if a call asks for more gas than all but one 64th of
600+
# the maximum allowed amount, call with all but one 64th of the
601+
# maximum allowed amount of gas
602+
if compustate.gas < extra_gas:
603+
return vm_exception('OUT OF GAS', needed=extra_gas)
604+
gas = min(gas, max_call_gas(compustate.gas - extra_gas))
605+
else:
606+
if compustate.gas < gas + extra_gas:
607+
return vm_exception('OUT OF GAS', needed=gas + extra_gas)
608+
571609
submsg_gas = gas + opcodes.GSTIPEND * (value > 0)
572-
if compustate.gas < gas + extra_gas:
573-
return vm_exception('OUT OF GAS', needed=gas + extra_gas)
574610
if ext.get_balance(msg.to) >= value and msg.depth < 1024:
575611
compustate.gas -= (gas + extra_gas)
576612
to = utils.encode_int(to)

0 commit comments

Comments
 (0)