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

Commit d5c822c

Browse files
vubvub
authored andcommitted
Further VMExt abstraction
1 parent 27d2ece commit d5c822c

File tree

4 files changed

+121
-15
lines changed

4 files changed

+121
-15
lines changed

ethereum/blocks.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ def calc_difficulty(parent, timestamp):
7777
period_count = (parent.number + 1) // config['EXPDIFF_PERIOD']
7878
if period_count >= config['EXPDIFF_FREE_PERIODS']:
7979
o = max(o + 2**(period_count - config['EXPDIFF_FREE_PERIODS']), config['MIN_DIFF'])
80-
# print('Calculating difficulty of block %d, timestamp difference %d, parent diff %d, child diff %d' % (parent.number + 1, timestamp - parent.timestamp, parent.difficulty, o))
8180
return o
8281

8382

ethereum/processblock.py

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -227,10 +227,13 @@ class VMExt():
227227
def __init__(self, block, tx):
228228
self._block = block
229229
self.get_code = block.get_code
230+
self.set_code = block.set_code
230231
self.get_balance = block.get_balance
231232
self.set_balance = block.set_balance
233+
self.delta_balance = block.delta_balance
232234
self.get_nonce = block.get_nonce
233235
self.set_nonce = block.set_nonce
236+
self.increment_nonce = block.increment_nonce
234237
self.set_storage_data = block.set_storage_data
235238
self.get_storage_data = block.get_storage_data
236239
self.get_storage_bytes = block.get_storage_bytes
@@ -254,6 +257,10 @@ def __init__(self, block, tx):
254257
self.account_exists = block.account_exists
255258
self.post_homestead_hardfork = lambda: block.number >= block.config['HOMESTEAD_FORK_BLKNUM']
256259
self.post_metropolis_hardfork = lambda: block.number >= block.config['METROPOLIS_FORK_BLKNUM']
260+
self.snapshot = block.snapshot
261+
self.revert = block.revert
262+
self.transfer_value = block.transfer_value
263+
self.reset_storage = block.reset_storage
257264

258265

259266
def apply_msg(ext, msg):
@@ -275,9 +282,9 @@ def _apply_msg(ext, msg, code):
275282
state=ext.log_storage(msg.to))
276283
# log_state.trace('CODE', code=code)
277284
# Transfer value, instaquit if not enough
278-
snapshot = ext._block.snapshot()
285+
snapshot = ext.snapshot()
279286
if msg.transfers_value:
280-
if not ext._block.transfer_value(msg.sender, msg.to, msg.value):
287+
if not ext.transfer_value(msg.sender, msg.to, msg.value):
281288
log_msg.debug('MSG TRANSFER FAILED', have=ext.get_balance(msg.to),
282289
want=msg.value)
283290
return 1, msg.gas, []
@@ -301,7 +308,7 @@ def _apply_msg(ext, msg, code):
301308

302309
if res == 0:
303310
log_msg.debug('REVERTING')
304-
ext._block.revert(snapshot)
311+
ext.revert(snapshot)
305312

306313
return res, gas, dat
307314

@@ -311,7 +318,7 @@ def create_contract(ext, msg):
311318
#print('CREATING WITH GAS', msg.gas)
312319
sender = decode_hex(msg.sender) if len(msg.sender) == 40 else msg.sender
313320
code = msg.data.extract_all()
314-
if ext._block.number >= ext._block.config["METROPOLIS_FORK_BLKNUM"]:
321+
if ext.post_metropolis_hardfork():
315322
msg.to = mk_metropolis_contract_address(msg.sender, code)
316323
if ext.get_code(msg.to):
317324
if ext.get_nonce(msg.to) >= 2**40:
@@ -322,19 +329,19 @@ def create_contract(ext, msg):
322329
msg.to = normalize_address((ext.get_nonce(msg.to) - 1) % 2**160)
323330
else:
324331
if ext.tx_origin != msg.sender:
325-
ext._block.increment_nonce(msg.sender)
326-
nonce = utils.encode_int(ext._block.get_nonce(msg.sender) - 1)
332+
ext.increment_nonce(msg.sender)
333+
nonce = utils.encode_int(ext.get_nonce(msg.sender) - 1)
327334
msg.to = mk_contract_address(sender, nonce)
328335
b = ext.get_balance(msg.to)
329336
if b > 0:
330337
ext.set_balance(msg.to, b)
331-
ext._block.set_nonce(msg.to, 0)
332-
ext._block.set_code(msg.to, b'')
333-
ext._block.reset_storage(msg.to)
338+
ext.set_nonce(msg.to, 0)
339+
ext.set_code(msg.to, b'')
340+
ext.reset_storage(msg.to)
334341
msg.is_create = True
335342
# assert not ext.get_code(msg.to)
336343
msg.data = vm.CallData([], 0, 0)
337-
snapshot = ext._block.snapshot()
344+
snapshot = ext.snapshot()
338345
res, gas, dat = _apply_msg(ext, msg, code)
339346
assert utils.is_numeric(gas)
340347

@@ -346,11 +353,11 @@ def create_contract(ext, msg):
346353
gas -= gcost
347354
else:
348355
dat = []
349-
log_msg.debug('CONTRACT CREATION OOG', have=gas, want=gcost, block_number=ext._block.number)
350-
if ext._block.number >= ext._block.config['HOMESTEAD_FORK_BLKNUM']:
351-
ext._block.revert(snapshot)
356+
log_msg.debug('CONTRACT CREATION OOG', have=gas, want=gcost, block_number=ext.block_number)
357+
if ext.post_homestead_hardfork():
358+
ext.revert(snapshot)
352359
return 0, 0, b''
353-
ext._block.set_code(msg.to, b''.join(map(ascii_chr, dat)))
360+
ext.set_code(msg.to, b''.join(map(ascii_chr, dat)))
354361
return 1, gas, msg.to
355362
else:
356363
return 0, gas, b''

ethereum/testutils.py

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
from ethereum.utils import to_string, safe_ord, parse_int_or_hex, zpad
1212
from ethereum.utils import remove_0x_head, int_to_hex, normalize_address
1313
from ethereum.config import Env
14+
from ethereum import state_transition
15+
from state import State
1416
import json
1517
import os
1618
import time
@@ -277,6 +279,103 @@ def normalize_value(k, p):
277279
return time_post - time_pre
278280

279281

282+
class FakeHeader():
283+
def __init__(self, h):
284+
self.hash = h
285+
self.uncles = []
286+
287+
fake_headers = {}
288+
289+
def mk_fake_header(blknum):
290+
if blknum not in fake_headers:
291+
fake_headers[blknum] = FakeHeader(utils.sha3(to_string(blknum)))
292+
return fake_headers[blknum]
293+
294+
def run_state_test1(params, mode):
295+
pre = params['pre']
296+
exek = params['transaction']
297+
env = params['env']
298+
299+
assert set(env.keys()) == set(['currentGasLimit', 'currentTimestamp',
300+
'previousHash', 'currentCoinbase',
301+
'currentDifficulty', 'currentNumber'])
302+
assert len(env['currentCoinbase']) == 40
303+
304+
state = State(db=db,
305+
prev_headers=[mk_fake_header(i) for i in range(parse_int_or_hex(env['currentNumber']) -1, max(-1, parse_int_or_hex(env['currentNumber']) -257), -1)],
306+
block_number=parse_int_or_hex(env['currentNumber']),
307+
block_coinbase=utils.normalize_address(env['currentCoinbase']),
308+
timestamp=parse_int_or_hex(env['currentTimestamp']),
309+
gas_limit=parse_int_or_hex(env['currentGasLimit']))
310+
# setup state
311+
for address, h in list(pre.items()):
312+
assert len(address) == 40
313+
address = decode_hex(address)
314+
assert set(h.keys()) == set(['code', 'nonce', 'balance', 'storage'])
315+
state.set_nonce(address, parse_int_or_hex(h['nonce']))
316+
state.set_balance(address, parse_int_or_hex(h['balance']))
317+
state.set_code(address, decode_hex(h['code'][2:]))
318+
for k, v in h['storage'].items():
319+
state.set_storage_data(address,
320+
utils.big_endian_to_int(decode_hex(k[2:])),
321+
decode_hex(v[2:]))
322+
323+
for address, h in list(pre.items()):
324+
address = decode_hex(address)
325+
assert state.get_nonce(address) == parse_int_or_hex(h['nonce'])
326+
assert state.get_balance(address) == parse_int_or_hex(h['balance'])
327+
assert state.get_code(address) == decode_hex(h['code'][2:])
328+
for k, v in h['storage'].items():
329+
assert state.get_storage_data(address, utils.big_endian_to_int(
330+
decode_hex(k[2:]))) == utils.big_endian_to_int(decode_hex(v[2:]))
331+
332+
try:
333+
tx = transactions.Transaction(
334+
nonce=parse_int_or_hex(exek['nonce'] or b"0"),
335+
gasprice=parse_int_or_hex(exek['gasPrice'] or b"0"),
336+
startgas=parse_int_or_hex(exek['gasLimit'] or b"0"),
337+
to=normalize_address(exek['to'], allow_blank=True),
338+
value=parse_int_or_hex(exek['value'] or b"0"),
339+
data=decode_hex(remove_0x_head(exek['data'])))
340+
except InvalidTransaction:
341+
tx = None
342+
success, output = False, b''
343+
time_pre = time.time()
344+
time_post = time_pre
345+
else:
346+
if 'secretKey' in exek:
347+
tx.sign(exek['secretKey'])
348+
elif all(key in exek for key in ['v', 'r', 's']):
349+
tx.v = decode_hex(remove_0x_head(exek['v']))
350+
tx.r = decode_hex(remove_0x_head(exek['r']))
351+
tx.s = decode_hex(remove_0x_head(exek['s']))
352+
else:
353+
assert False
354+
355+
time_pre = time.time()
356+
state.commit()
357+
print state.to_dict()
358+
snapshot = state.snapshot()
359+
try:
360+
print('trying')
361+
success, output, logs = state_transition.apply_transaction(state, tx)
362+
assert success
363+
state.commit()
364+
print('success')
365+
except InvalidTransaction:
366+
success, output = False, b''
367+
state.commit()
368+
pass
369+
except AssertionError:
370+
success, output = False, b''
371+
state.commit()
372+
pass
373+
time_post = time.time()
374+
375+
if tx.to == b'':
376+
output = state.get_code(output) if output else b''
377+
378+
280379
# Fills up a vm test without post data, or runs the test
281380
def run_state_test(params, mode):
282381
pre = params['pre']

ethereum/utils.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ def int_to_32bytearray(i):
117117

118118
def sha3(seed):
119119
sha3_count[0] += 1
120+
# print seed
120121
return sha3_256(to_string(seed))
121122

122123
assert encode_hex(sha3('')) == b'c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470'

0 commit comments

Comments
 (0)