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

Commit 6d7e28a

Browse files
vubvub
authored andcommitted
EIP 150
1 parent 5cf85aa commit 6d7e28a

File tree

8 files changed

+92
-17
lines changed

8 files changed

+92
-17
lines changed

ethereum/config.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@
6161
DAO_FORK_BLKNUM = 1920000,
6262
CHILD_DAO_LIST = map(utils.normalize_address, child_dao_list),
6363
DAO_WITHDRAWER = utils.normalize_address('0xbf4ed7b27f1d666546e30d74d50d173d20bca754'),
64+
# Anti-DoS fork
65+
ANTI_DOS_FORK_BLKNUM = 2**99,
6466
# Default consensus strategy: ethash, poa, casper, pbft
6567
CONSENSUS_STRATEGY = 'ethash',
6668
# Serenity fork

ethereum/opcodes.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@
6868
0xf1: ['CALL', 7, 1, 40],
6969
0xf2: ['CALLCODE', 7, 1, 40],
7070
0xf3: ['RETURN', 2, 0, 0],
71-
0xf4: ['DELEGATECALL', 6, 0, 40],
71+
0xf4: ['DELEGATECALL', 6, 1, 40],
7272
0xf5: ['CALLBLACKBOX', 7, 1, 40],
7373
0xff: ['SUICIDE', 1, 0, 0],
7474
}
@@ -124,3 +124,11 @@
124124
GSTORAGEKILL = 5000
125125
GSTORAGEMOD = 5000
126126
GSTORAGEADD = 20000
127+
128+
SLOAD_SUPPLEMENTAL_GAS = 150
129+
CALL_SUPPLEMENTAL_GAS = 660
130+
EXTCODELOAD_SUPPLEMENTAL_GAS = 680
131+
BALANCE_SUPPLEMENTAL_GAS = 380
132+
CALL_CHILD_LIMIT_NUM = 63
133+
CALL_CHILD_LIMIT_DENOM = 64
134+
SUICIDE_SUPPLEMENTAL_GAS = 5000

ethereum/state.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,9 @@ def is_HOMESTEAD(self, at_fork_height=False):
442442
def is_SERENITY(self, at_fork_height=False):
443443
return self._is_X_fork('SERENITY', at_fork_height)
444444

445+
def is_ANTI_DOS(self, at_fork_height=False):
446+
return self._is_X_fork('ANTI_DOS', at_fork_height)
447+
445448
def is_DAO(self, at_fork_height=False):
446449
return self._is_X_fork('DAO', at_fork_height)
447450

ethereum/state_transition.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,7 @@ def __init__(self, state, tx):
428428
self.post_homestead_hardfork = lambda: state.is_HOMESTEAD()
429429
self.post_metropolis_hardfork = lambda: state.is_METROPOLIS()
430430
self.post_serenity_hardfork = lambda: state.is_SERENITY()
431+
self.post_anti_dos_hardfork = lambda: state.is_ANTI_DOS()
431432
self.blockhash_store = state.config['METROPOLIS_BLOCKHASH_STORE']
432433
self.snapshot = state.snapshot
433434
self.revert = state.revert
@@ -473,6 +474,7 @@ def __init__(self, state):
473474
self.post_homestead_hardfork = lambda: state.is_HOMESTEAD()
474475
self.post_metropolis_hardfork = lambda: state.is_METROPOLIS()
475476
self.post_serenity_hardfork = lambda: state.is_SERENITY()
477+
self.post_anti_dos_hardfork = lambda: state.is_ANTI_DOS()
476478
self.blockhash_store = state.config['METROPOLIS_BLOCKHASH_STORE']
477479
self.snapshot = state.snapshot
478480
self.revert = state.revert

ethereum/tests/test_blocks.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ def valueconv(k, v):
4545
return v
4646

4747

48+
def safe_decode(x):
49+
if x[:2] == '0x':
50+
x = x[2:]
51+
return decode_hex(x)
52+
53+
4854
def run_block_test(params, config_overrides = {}):
4955
env = Env(db.EphemDB())
5056
genesis_decl = {}
@@ -54,9 +60,9 @@ def run_block_test(params, config_overrides = {}):
5460
genesis_decl[param] = params["genesisBlockHeader"][param]
5561
genesis_decl["alloc"] = params["pre"]
5662
c = chain.Chain(genesis=genesis_decl, env=env)
57-
assert c.state.prev_headers[0].state_root == decode_hex(params["genesisBlockHeader"]["stateRoot"])
58-
assert c.state.trie.root_hash == decode_hex(params["genesisBlockHeader"]["stateRoot"])
59-
assert c.state.prev_headers[0].hash == decode_hex(params["genesisBlockHeader"]["hash"])
63+
assert c.state.prev_headers[0].state_root == safe_decode(params["genesisBlockHeader"]["stateRoot"])
64+
assert c.state.trie.root_hash == safe_decode(params["genesisBlockHeader"]["stateRoot"])
65+
assert c.state.prev_headers[0].hash == safe_decode(params["genesisBlockHeader"]["hash"])
6066

6167

6268
old_config = copy.deepcopy(env.config)
@@ -68,15 +74,15 @@ def run_block_test(params, config_overrides = {}):
6874
if 'blockHeader' not in blk:
6975
success = True
7076
try:
71-
rlpdata = decode_hex(blk["rlp"][2:])
77+
rlpdata = safe_decode(blk["rlp"][2:])
7278
success = c.add_block(rlp.decode(rlpdata, Block))
7379
except (ValueError, TypeError, AttributeError, VerificationFailed,
7480
DecodingError, DeserializationError, InvalidTransaction,
7581
InvalidNonce, KeyError), e:
7682
success = False
7783
assert not success
7884
else:
79-
rlpdata = decode_hex(blk["rlp"][2:])
85+
rlpdata = safe_decode(blk["rlp"][2:])
8086
assert c.add_block(rlp.decode(rlpdata, Block))
8187
env.config = old_config
8288

ethereum/testutils.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,13 @@ def run_state_test(params, mode):
394394
'out', 'gas', 'logs', 'postStateRoot']:
395395
_shouldbe = params1.get(k, None)
396396
_reallyis = params2.get(k, None)
397-
if _shouldbe != _reallyis:
397+
passed = False
398+
if isinstance(_shouldbe, (str, bytes, unicode)) and _shouldbe[0] == '#':
399+
if int(_shouldbe[1:]) == len(decode_hex(remove_0x_head(_reallyis))):
400+
passed = True
401+
if _shouldbe == _reallyis:
402+
passed = True
403+
if not passed:
398404
print 's', shouldbe
399405
print 'r', reallyis
400406
print state.trie.to_dict()

ethereum/vm.py

Lines changed: 57 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,13 @@ def data_copy(compustate, size):
135135
return True
136136

137137

138+
def eat_gas(compustate, amount):
139+
if compustate.gas < amount:
140+
return vm_exception("OUT OF GAS")
141+
else:
142+
compustate.gas -= amount
143+
144+
138145
def vm_exception(error, **kargs):
139146
log_vm_exit.trace('EXCEPTION', cause=error, **kargs)
140147
return 0, 0, []
@@ -331,6 +338,9 @@ def vm_execute(ext, msg, code):
331338
elif op == 'ADDRESS':
332339
stk.append(utils.coerce_to_int(msg.to))
333340
elif op == 'BALANCE':
341+
if ext.post_anti_dos_hardfork():
342+
if not eat_gas(compustate, opcodes.BALANCE_SUPPLEMENTAL_GAS):
343+
return vm_exception("OUT OF GAS")
334344
addr = utils.coerce_addr_to_hex(stk.pop() % 2**160)
335345
stk.append(ext.get_balance(addr))
336346
elif op == 'ORIGIN':
@@ -366,9 +376,15 @@ def vm_execute(ext, msg, code):
366376
elif op == 'GASPRICE':
367377
stk.append(ext.tx_gasprice)
368378
elif op == 'EXTCODESIZE':
379+
if ext.post_anti_dos_hardfork():
380+
if not eat_gas(compustate, opcodes.EXTCODELOAD_SUPPLEMENTAL_GAS):
381+
return vm_exception("OUT OF GAS")
369382
addr = utils.coerce_addr_to_hex(stk.pop() % 2**160)
370383
stk.append(len(ext.get_code(addr) or b''))
371384
elif op == 'EXTCODECOPY':
385+
if ext.post_anti_dos_hardfork():
386+
if not eat_gas(compustate, opcodes.EXTCODELOAD_SUPPLEMENTAL_GAS):
387+
return vm_exception("OUT OF GAS")
372388
addr = utils.coerce_addr_to_hex(stk.pop() % 2**160)
373389
start, s2, size = stk.pop(), stk.pop(), stk.pop()
374390
extcode = ext.get_code(addr) or b''
@@ -422,6 +438,9 @@ def vm_execute(ext, msg, code):
422438
return vm_exception('OOG EXTENDING MEMORY')
423439
mem[s0] = s1 % 256
424440
elif op == 'SLOAD':
441+
if ext.post_anti_dos_hardfork():
442+
if not eat_gas(compustate, opcodes.SLOAD_SUPPLEMENTAL_GAS):
443+
return vm_exception("OUT OF GAS")
425444
stk.append(ext.get_storage_data(msg.to, stk.pop()))
426445
elif op == 'SSTORE':
427446
s0, s1 = stk.pop(), stk.pop()
@@ -529,7 +548,10 @@ def vm_execute(ext, msg, code):
529548
return vm_exception('OOG EXTENDING MEMORY')
530549
if ext.get_balance(msg.to) >= value and msg.depth < 1024:
531550
cd = CallData(mem, mstart, msz)
532-
create_msg = Message(msg.to, b'', value, compustate.gas, cd, msg.depth + 1)
551+
ingas = compustate.gas
552+
if ext.post_anti_dos_hardfork():
553+
ingas = ingas * opcodes.CALL_CHILD_LIMIT_NUM / CALL_CHILD_LIMIT_DENOM
554+
create_msg = Message(msg.to, b'', value, ingas, cd, msg.depth + 1)
533555
o, gas, addr = ext.create(create_msg)
534556
if o:
535557
stk.append(utils.coerce_to_int(addr))
@@ -548,12 +570,21 @@ def vm_execute(ext, msg, code):
548570
to = utils.encode_int(to)
549571
to = ((b'\x00' * (32 - len(to))) + to)[12:]
550572
extra_gas = (not ext.account_exists(to)) * opcodes.GCALLNEWACCOUNT + \
551-
(value > 0) * opcodes.GCALLVALUETRANSFER
573+
(value > 0) * opcodes.GCALLVALUETRANSFER + \
574+
ext.post_anti_dos_hardfork() * opcodes.CALL_SUPPLEMENTAL_GAS
575+
submsg_gas = gas + opcodes.GSTIPEND * (value > 0)
576+
if ext.post_anti_dos_hardfork():
577+
if compustate.gas < extra_gas:
578+
return vm_exception('OUT OF GAS', needed=extra_gas)
579+
elif gas > (compustate.gas - extra_gas) * opcodes.CALL_CHILD_LIMIT_NUM / opcodes.CALL_CHILD_LIMIT_DENOM:
580+
gas = (compustate.gas - extra_gas) * opcodes.CALL_CHILD_LIMIT_NUM / opcodes.CALL_CHILD_LIMIT_DENOM
581+
else:
582+
if compustate.gas < gas + extra_gas:
583+
return vm_exception('OUT OF GAS', needed=gas+extra_gas)
552584
submsg_gas = gas + opcodes.GSTIPEND * (value > 0)
553-
if compustate.gas < gas + extra_gas:
554-
return vm_exception('OUT OF GAS', needed=gas+extra_gas)
555585
if ext.get_balance(msg.to) >= value and msg.depth < 1024:
556586
compustate.gas -= (gas + extra_gas)
587+
assert compustate.gas >= 0
557588
cd = CallData(mem, meminstart, meminsz)
558589
call_msg = Message(msg.to, to, value, submsg_gas, cd,
559590
msg.depth + 1, code_address=to)
@@ -579,12 +610,20 @@ def vm_execute(ext, msg, code):
579610
if not mem_extend(mem, compustate, op, meminstart, meminsz) or \
580611
not mem_extend(mem, compustate, op, memoutstart, memoutsz):
581612
return vm_exception('OOG EXTENDING MEMORY')
582-
extra_gas = (value > 0) * opcodes.GCALLVALUETRANSFER
613+
extra_gas = (value > 0) * opcodes.GCALLVALUETRANSFER + \
614+
ext.post_anti_dos_hardfork() * opcodes.CALL_SUPPLEMENTAL_GAS
583615
submsg_gas = gas + opcodes.GSTIPEND * (value > 0)
584-
if compustate.gas < gas + extra_gas:
585-
return vm_exception('OUT OF GAS', needed=gas+extra_gas)
616+
if ext.post_anti_dos_hardfork():
617+
if compustate.gas < extra_gas:
618+
return vm_exception('OUT OF GAS', needed=extra_gas)
619+
elif gas > (compustate.gas - extra_gas) * opcodes.CALL_CHILD_LIMIT_NUM / opcodes.CALL_CHILD_LIMIT_DENOM:
620+
gas = (compustate.gas - extra_gas) * opcodes.CALL_CHILD_LIMIT_NUM / opcodes.CALL_CHILD_LIMIT_DENOM
621+
else:
622+
if compustate.gas < gas + extra_gas:
623+
return vm_exception('OUT OF GAS', needed=gas+extra_gas)
586624
if ext.get_balance(msg.to) >= value and msg.depth < 1024:
587625
compustate.gas -= (gas + extra_gas)
626+
assert compustate.gas >= 0
588627
to = utils.encode_int(to)
589628
to = ((b'\x00' * (32 - len(to))) + to)[12:]
590629
cd = CallData(mem, meminstart, meminsz)
@@ -615,8 +654,12 @@ def vm_execute(ext, msg, code):
615654
if not mem_extend(mem, compustate, op, datastart, datasz) or \
616655
not mem_extend(mem, compustate, op, codestart, codesz):
617656
return vm_exception('OOG EXTENDING MEMORY')
618-
if compustate.gas < gas:
619-
return vm_exception('OUT OF GAS', needed=gas)
657+
if ext.post_anti_dos_hardfork():
658+
if gas > compustate.gas * opcodes.CALL_CHILD_LIMIT_NUM / opcodes.CALL_CHILD_LIMIT_DENOM:
659+
gas = compustate.gas * opcodes.CALL_CHILD_LIMIT_NUM / opcodes.CALL_CHILD_LIMIT_DENOM
660+
else:
661+
if gas > compustate.gas:
662+
return vm_exception("OUT OF GAS", needed=gas)
620663
compustate.gas -= gas
621664
code = ''.join([chr(x) for x in mem[codestart: codestart + codesz]])
622665
call_msg = Message('\x00'*20, '\x00'*20, 0, gas, CallData(mem, datastart, datasz),
@@ -637,6 +680,11 @@ def vm_execute(ext, msg, code):
637680
return vm_exception('OOG EXTENDING MEMORY')
638681
return peaceful_exit('RETURN', compustate.gas, mem[s0: s0 + s1])
639682
elif op == 'SUICIDE':
683+
if ext.post_anti_dos_hardfork():
684+
if gas < opcodes.SUICIDE_SUPPLEMENTAL_GAS:
685+
return vm_exception("OUT OF GAS")
686+
else:
687+
gas -= opcodes.SUICIDE_SUPPLEMENTAL_GAS
640688
to = utils.encode_int(stk.pop())
641689
to = ((b'\x00' * (32 - len(to))) + to)[12:]
642690
xfer = ext.get_balance(msg.to)

fixtures

Submodule fixtures updated 659 files

0 commit comments

Comments
 (0)