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

Python3 support progress #238

Open
wants to merge 6 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion fixtures
Submodule fixtures updated 71 files
+73 −87 BlockTests/bcInvalidHeaderTest.json
+181 −148 BlockTests/bcJS_API_Test.json
+571 −907 BlockTests/bcUncleTest.json
+118 −119 BlockTests/bcValidBlockTest.json
+64 −0 StateTests/RandomTests/st201503121046CPPJIT.json
+71 −0 StateTests/RandomTests/st201503121739CPPJIT.json
+71 −0 StateTests/RandomTests/st201503130158PYTHON.json
+71 −0 StateTests/RandomTests/st201503130247PYTHON.json
+71 −0 StateTests/RandomTests/st201503130248PYTHON.json
+71 −0 StateTests/RandomTests/st201503130410PYTHON.json
+71 −0 StateTests/RandomTests/st201503130442PYTHON.json
+71 −0 StateTests/RandomTests/st201503131809PYTHON.json
+71 −0 StateTests/RandomTests/st201503140445PYTHON.json
+71 −0 StateTests/RandomTests/st201503141222CPPJIT.json
+71 −0 StateTests/RandomTests/st201503141321PYTHON.json
+71 −0 StateTests/RandomTests/st201503141331PYTHON.json
+71 −0 StateTests/RandomTests/st201503141735PYTHON.json
+71 −0 StateTests/RandomTests/st201503142152PYTHON.json
+71 −0 StateTests/RandomTests/st201503150107PYTHON.json
+71 −0 StateTests/RandomTests/st201503150239PYTHON.json
+71 −0 StateTests/RandomTests/st201503150559PYTHON.json
+71 −0 StateTests/RandomTests/st201503150708PYTHON.json
+71 −0 StateTests/RandomTests/st201503150941PYTHON.json
+71 −0 StateTests/RandomTests/st201503151133PYTHON.json
+71 −0 StateTests/RandomTests/st201503151223PYTHON.json
+71 −0 StateTests/RandomTests/st201503151248PYTHON.json
+71 −0 StateTests/RandomTests/st201503151255PYTHON.json
+71 −0 StateTests/RandomTests/st201503151745PYTHON.json
+71 −0 StateTests/RandomTests/st201503152246PYTHON.json
+71 −0 StateTests/RandomTests/st201503160053PYTHON.json
+71 −0 StateTests/RandomTests/st201503160310PYTHON.json
+71 −0 StateTests/RandomTests/st201503160443PYTHON.json
+71 −0 StateTests/RandomTests/st201503170617PYTHON.json
+71 −0 StateTests/RandomTests/st201503171111PYTHON.json
+71 −0 StateTests/RandomTests/st201503181220CPPJIT.json
+9 −9 StateTests/RandomTests/st201503181334CPPJIT.json
+71 −0 StateTests/RandomTests/st201503181602CPPJIT.json
+71 −0 StateTests/RandomTests/st201503181659CPPJIT.json
+71 −0 StateTests/RandomTests/st201503181728CPPJIT.json
+71 −0 StateTests/RandomTests/st201503181828CPPJIT.json
+71 −0 StateTests/RandomTests/st201503181847CPPJIT.json
+71 −0 StateTests/RandomTests/st201503181856CPPJIT.json
+71 −0 StateTests/RandomTests/st201503181856PYTHON.json
+71 −0 StateTests/RandomTests/st201503181858PYTHON.json
+71 −0 StateTests/RandomTests/st201503181859PYTHON.json
+71 −0 StateTests/RandomTests/st201503181900PYTHON.json
+71 −0 StateTests/RandomTests/st201503181929PYTHON.json
+71 −0 StateTests/RandomTests/st201503200836JS.json
+71 −0 StateTests/RandomTests/st201503200839JS.json
+71 −0 StateTests/RandomTests/st201503200840JS.json
+71 −0 StateTests/RandomTests/st201503200842JS.json
+71 −0 StateTests/RandomTests/st201503200843JS.json
+71 −0 StateTests/RandomTests/st201503200844JS.json
+71 −0 StateTests/RandomTests/st201503200845JS.json
+71 −0 StateTests/RandomTests/st201503200846JS.json
+71 −0 StateTests/RandomTests/st201503200847JS.json
+71 −0 StateTests/RandomTests/st201503202141CPPJIT.json
+6 −6 StateTests/stCallCreateCallCodeTest.json
+37 −9 StateTests/stInitCodeTest.json
+30 −30 StateTests/stLogTests.json
+42 −42 StateTests/stMemoryTest.json
+73 −10 StateTests/stPreCompiledContracts.json
+8 −1 StateTests/stRecursiveCreate.json
+6 −6 StateTests/stRefundTest.json
+9 −9 StateTests/stSolidityTest.json
+3 −3 StateTests/stSpecialTest.json
+87 −80 StateTests/stSystemOperationsTest.json
+21 −21 StateTests/stTransactionTest.json
+2 −196 TransactionTests/ttWrongRLPTransaction.json
+0 −29 VMTests/vmIOandFlowOperationsTest.json
+9 −9 VMTests/vmSystemOperationsTest.json
27 changes: 14 additions & 13 deletions pyethereum/abi.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import sys, re, json
from pyethereum import utils
from rlp.utils import decode_hex, encode_hex
from rlp.utils import decode_hex, encode_hex, str_to_bytes, bytes_to_str
from pyethereum.utils import encode_int, zpad, big_endian_to_int, is_numeric, is_string

if sys.version_info.major == 2:
Expand All @@ -18,7 +18,7 @@ def json_non_unicode(x):
return x
else:
def json_decode(x):
return json.loads(x)
return json.loads(bytes_to_str(x))


class ContractTranslator():
Expand All @@ -42,7 +42,7 @@ def __init__(self, full_signature):
sys.stderr.write("Warning: multiple methods with the same "
" name. Use %s to call %s with types %r"
% (name, sig_item['name'], encode_types))
sig = name + '(' + ','.join(encode_types) + ')'
sig = str_to_bytes(name + '(' + ','.join(encode_types) + ')')
if sig_item['type'] == 'function':
prefix = big_endian_to_int(utils.sha3(sig)[:4])
decode_types = [f['type'] for f in sig_item['outputs']]
Expand Down Expand Up @@ -127,7 +127,7 @@ def decint(n):

# Encodes a base type
def encode_single(arg, base, sub):
normal_args, len_args, var_args = '', '', ''
normal_args, len_args, var_args = b'', b'', b''
# Unsigned integers: uint<sz>
if base == 'uint':
sub = int(sub)
Expand Down Expand Up @@ -159,7 +159,7 @@ def encode_single(arg, base, sub):
if len(sub):
assert int(sub) <= 32
assert len(arg) <= int(sub)
normal_args = arg + '\x00' * (32 - len(arg))
normal_args = arg + b'\x00' * (32 - len(arg))
# Variable length: string
else:
len_args = zpad(encode_int(len(arg)), 32)
Expand All @@ -186,6 +186,7 @@ def encode_single(arg, base, sub):
normal_args = zpad(decode_hex(arg), 32)
else:
raise Exception("Could not parse address: %r" % arg)

return len_args, normal_args, var_args


Expand Down Expand Up @@ -243,31 +244,31 @@ def encode_any(arg, base, sub, arrlist):
if base == 'string' and sub == '':
raise Exception('Array of dynamic-sized items not allowed: %r'
% arg)
o = ''
o = b''
assert isinstance(arg, list), "Expecting array: %r" % arg
for a in arg:
_, n, _ = encode_any(a, base, sub, arrlist[:-1])
o += n
return zpad(encode_int(len(arg)), 32), '', o
return zpad(encode_int(len(arg)), 32), b'', o
# Fixed-sized arrays
else:
if base == 'string' and sub == '':
if base == 'string' and sub == b'':
raise Exception('Array of dynamic-sized items not allowed')
sz = int(arrlist[-1][1:-1])
assert isinstance(arg, list), "Expecting array: %r" % arg
assert sz == len(arg), "Wrong number of elements in array: %r" % arg
o = ''
o = b''
for a in arg:
_, n, _ = encode_any(a, base, sub, arrlist[:-1])
o += n
return '', o, ''
return b'', o, b''


# Encodes ABI data given a prefix, a list of types, and a list of arguments
def encode_abi(types, args):
len_args = ''
normal_args = ''
var_args = ''
len_args = b''
normal_args = b''
var_args = b''
if len(types) != len(args):
raise Exception("Wrong number of arguments!")
for typ, arg in zip(types, args):
Expand Down
7 changes: 4 additions & 3 deletions pyethereum/blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
ETHASH_LIB = 'pyethash'
else:
from functools import lru_cache
ETHASH_LIB = 'ethash'
ETHASH_LIB = 'pyethash'

from pyethereum.exceptions import *
from pyethereum.slogging import get_logger
Expand Down Expand Up @@ -347,9 +347,10 @@ def check_pow(self, db=None, nonce=None):
mining_output = hashimoto_light(current_full_size, cache,
header_hash, nonce)
diff = self.difficulty
if mining_output['mix digest'] != self.mixhash:
if mining_output[b'mix digest'] != self.mixhash:
return False
return utils.big_endian_to_int(mining_output['result']) <= 2**256 / (diff or 1)

return utils.big_endian_to_int(mining_output[b'result']) <= 2**256 / (diff or 1)

def to_dict(self):
"""Serialize the header to a readable dictionary."""
Expand Down
2 changes: 1 addition & 1 deletion pyethereum/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def default_client_version():
def default_node_id():
x = encode_hex(sha3(to_string(str(uuid.uuid1()))) * 2)
assert len(x) == 128
return x
return x.decode('utf-8')

config_template = \
"""
Expand Down
4 changes: 2 additions & 2 deletions pyethereum/miner.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,8 @@ def mine(self, steps=1000):
for i in range(1, steps + 1):
b.nonce = utils.zpad(utils.int_to_big_endian((nonce + i) & TT64M1), 8)
o = blocks.hashimoto_light(fsz, cache, b.mining_hash, b.nonce)
if o["result"] <= target:
b.mixhash = o["mix digest"]
if o[b"result"] <= target:
b.mixhash = o[b"mix digest"]
break
steps -= 1
if b.header.check_pow():
Expand Down
16 changes: 8 additions & 8 deletions pyethereum/specials.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def proc_ecrecover(ext, msg):
return 0, 0, []
b = [0] * 32
msg.data.extract_copy(b, 0, 0, 32)
h = ''.join([ascii_chr(x) for x in b])
h = b''.join([ascii_chr(x) for x in b])
v = msg.data.extract32(32)
r = msg.data.extract32(64)
s = msg.data.extract32(96)
Expand All @@ -25,7 +25,7 @@ def proc_ecrecover(ext, msg):
def proc_sha256(ext, msg):
print('sha256 proc', msg.gas)
OP_GAS = opcodes.GSHA256BASE + \
(utils.ceil32(msg.data.size) / 32) * opcodes.GSHA256WORD
(utils.ceil32(msg.data.size) // 32) * opcodes.GSHA256WORD
gas_cost = OP_GAS
if msg.gas < gas_cost:
return 0, 0, []
Expand All @@ -37,7 +37,7 @@ def proc_sha256(ext, msg):
def proc_ripemd160(ext, msg):
print('ripemd160 proc', msg.gas)
OP_GAS = opcodes.GRIPEMD160BASE + \
(utils.ceil32(msg.data.size) / 32) * opcodes.GRIPEMD160WORD
(utils.ceil32(msg.data.size) // 32) * opcodes.GRIPEMD160WORD
gas_cost = OP_GAS
if msg.gas < gas_cost:
return 0, 0, []
Expand All @@ -49,7 +49,7 @@ def proc_ripemd160(ext, msg):
def proc_identity(ext, msg):
print('identity proc', msg.gas)
OP_GAS = opcodes.GIDENTITYBASE + \
opcodes.GIDENTITYWORD * (utils.ceil32(msg.data.size) / 32)
opcodes.GIDENTITYWORD * (utils.ceil32(msg.data.size) // 32)
gas_cost = OP_GAS
if msg.gas < gas_cost:
return 0, 0, []
Expand All @@ -58,10 +58,10 @@ def proc_identity(ext, msg):
return 1, msg.gas - gas_cost, o

specials = {
'0000000000000000000000000000000000000001': proc_ecrecover,
'0000000000000000000000000000000000000002': proc_sha256,
'0000000000000000000000000000000000000003': proc_ripemd160,
'0000000000000000000000000000000000000004': proc_identity,
b'0000000000000000000000000000000000000001': proc_ecrecover,
b'0000000000000000000000000000000000000002': proc_sha256,
b'0000000000000000000000000000000000000003': proc_ripemd160,
b'0000000000000000000000000000000000000004': proc_identity,
}

if __name__ == '__main__':
Expand Down
2 changes: 2 additions & 0 deletions pyethereum/tester.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,13 +114,15 @@ def kall_factory(f):
def kall(*args, **kwargs):
_state.block.log_listeners.append(
lambda log: self._translator.listen(log))

o = _state._send(kwargs.get('sender', k0),
self.address,
kwargs.get('value', 0),
self._translator.encode(f, args),
**dict_without(kwargs, 'sender',
'value', 'output'))
_state.block.log_listeners.pop()

# Compute output data
if kwargs.get('output', '') == 'raw':
outdata = o['output']
Expand Down
4 changes: 2 additions & 2 deletions pyethereum/testutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -307,11 +307,11 @@ def blkhash(n):
params1 = copy.deepcopy(params)
if 'post' in params1:
for k, v in list(params1['post'].items()):
if v == {'code': b'0x', 'nonce': '0', 'balance': '0', 'storage': {}}:
if v == {'code': b'0x', 'nonce': b'0', 'balance': b'0', 'storage': {}}:
del params1['post'][k]
if 'post' in params2:
for k, v in list(params2['post'].items()):
if v == {'code': b'0x', 'nonce': '0', 'balance': '0', 'storage': {}}:
if v == {'code': b'0x', 'nonce': b'0', 'balance': b'0', 'storage': {}}:
del params2['post'][k]
for k in ['pre', 'exec', 'env', 'callcreates',
'out', 'gas', 'logs', 'post', 'postStateRoot']:
Expand Down
2 changes: 1 addition & 1 deletion pyethereum/vm.py
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ def vm_execute(ext, msg, code):
elif op == 'MSIZE':
stk.append(len(mem))
elif op == 'GAS':
stk.append(compustate.gas) # AFTER subtracting cost 1
stk.append(int(compustate.gas)) # AFTER subtracting cost 1
elif op[:4] == 'PUSH':
pushnum = int(op[4:])
compustate.pc += pushnum
Expand Down
10 changes: 8 additions & 2 deletions tests/test_blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,13 @@ def do_test_block(filename, testname=None, testdata=None, limit=99999999):
else:
fixtures = testutils.get_tests_from_file_or_dir(
os.path.join('fixtures', 'BlockTests'))
for filename, tests in list(fixtures.items()):
for testname, testdata in list(tests.items())[:500]:
# TODO: tests fail if not in correct order
filenames = sorted(list(fixtures.keys()))
filenames.reverse()
for filename in filenames:
tests = fixtures[filename]
testnames = sorted(list(tests.keys()))
for testname in testnames:
testdata = tests[testname]
func_name = 'test_%s_%s' % (filename, testname)
globals()[func_name] = lambda: do_test_block(filename, testname, testdata)
31 changes: 16 additions & 15 deletions tests/test_contracts.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@


# Test EVM contracts
serpent_code = '''
serpent_code = b'''
def main(a,b):
return(a ^ b)
'''
Expand Down Expand Up @@ -207,11 +207,11 @@ def main(k, v):
def test_namecoin():
s = tester.state()
c = s.abi_contract(namecoin_code)
o1 = c.main("george", 45)
o1 = c.main(b"george", 45)
assert o1 == 1
o2 = c.main("george", 20)
o2 = c.main(b"george", 20)
assert o2 == 0
o3 = c.main("harry", 60)
o3 = c.main(b"harry", 60)
assert o3 == 1

assert s.block.to_dict()
Expand Down Expand Up @@ -958,8 +958,8 @@ def test_saveload2():
s = tester.state()
c = s.contract(saveload_code2)
s.send(tester.k0, c, 0)
assert bitcoin.encode(s.block.get_storage_data(c, 0), 256) == '01ab' + '\x00' * 28
assert bitcoin.encode(s.block.get_storage_data(c, 1), 256) == '01ab' + '\x00' * 28
assert bitcoin.encode(s.block.get_storage_data(c, 0), 256) == b'01ab' + b'\x00' * 28
assert bitcoin.encode(s.block.get_storage_data(c, 1), 256) == b'01ab' + b'\x00' * 28


sdiv_code = """
Expand Down Expand Up @@ -1089,7 +1089,7 @@ def kall(a:arr, b, c:arr, d:str, e):
def test_multiarg_code():
s = tester.state()
c = s.abi_contract(multiarg_code)
o = c.kall([1, 2, 3], 4, [5, 6, 7], "doge", 8)
o = c.kall([1, 2, 3], 4, [5, 6, 7], b"doge", 8)
assert o == [862541, safe_ord('d') + safe_ord('o') + safe_ord('g'), 4]

peano_code = """
Expand Down Expand Up @@ -1198,10 +1198,10 @@ def test_ecrecover():
s = tester.state()
c = s.abi_contract(ecrecover_code)

priv = encode_hex(utils.sha3('some big long brainwallet password'))
priv = encode_hex(utils.sha3(b'some big long brainwallet password'))
pub = bitcoin.privtopub(priv)

msghash = encode_hex(utils.sha3('the quick brown fox jumps over the lazy dog'))
msghash = encode_hex(utils.sha3(b'the quick brown fox jumps over the lazy dog'))
V, R, S = bitcoin.ecdsa_raw_sign(msghash, priv)
assert bitcoin.ecdsa_raw_verify(msghash, (V, R, S), pub)

Expand Down Expand Up @@ -1356,8 +1356,9 @@ def mcopy_test(foo:str, a, b, c):
def test_mcopy():
s = tester.state()
c = s.abi_contract(mcopy_code)
assert c.mcopy_test("123", 5, 6, 259) == \
'\x00'*31+'\x05'+'\x00'*31+'\x06'+'\x00'*30+'\x01\x03'+'123'
a = c.mcopy_test(b"123", 5, 6, 259)
b = b'\x00'*31 + b'\x05' + b'\x00'*31 + b'\x06' + b'\x00'*30 + b'\x01\x03' + b'123'
assert a == b


mcopy_code_2 = """
Expand All @@ -1377,7 +1378,7 @@ def test_mcopy2():
s = tester.state()
c = s.abi_contract(mcopy_code_2)
assert c.mcopy_test() == \
''.join([utils.zpad(utils.int_to_big_endian(x), 32) for x in [99, 111, 119]])
b''.join([utils.zpad(utils.int_to_big_endian(x), 32) for x in [99, 111, 119]])


array_saveload_code = """
Expand Down Expand Up @@ -1470,7 +1471,7 @@ def test_double_array():
s = tester.state()
c = s.abi_contract(double_array_code)
assert c.foo([1, 2, 3], [4, 5, 6, 7]) == [123, 4567]
assert c.bar([1, 2, 3], "moo", [4, 5, 6, 7]) == [123, 4567]
assert c.bar([1, 2, 3], b"moo", [4, 5, 6, 7]) == [123, 4567]


abi_logging_code = """
Expand Down Expand Up @@ -1500,8 +1501,8 @@ def test_abi_logging():
c.test_frog(5)
assert o == [{"_event_type": "frog", "y": 5}]
o.pop()
c.test_moose(7, "nine", 11, [13, 15, 17])
assert o == [{"_event_type": "moose", "a": 7, "b": "nine",
c.test_moose(7, b"nine", 11, [13, 15, 17])
assert o == [{"_event_type": "moose", "a": 7, "b": b"nine",
"c": 11, "d": [13, 15, 17]}]


Expand Down
2 changes: 1 addition & 1 deletion tests/test_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@


def random_string(length):
return ''.join([ascii_chr(random.randint(0, 255)) for _ in range(length)])
return b''.join([ascii_chr(random.randint(0, 255)) for _ in range(length)])


content = {random_string(lk): random_string(lv)
Expand Down
3 changes: 2 additions & 1 deletion tests/test_genesis.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import rlp
from rlp.utils import encode_hex
import pyethereum.utils as utils
from pyethereum.testutils import fixture_to_bytes
from tests.utils import new_db
from pyethereum.slogging import get_logger, configure_logging
logger = get_logger()
Expand All @@ -23,7 +24,7 @@ def genesis_fixture():
# FIXME: assert that link is uptodate
for k in ('genesis_rlp_hex', 'genesis_state_root', 'genesis_hash'):
assert k in genesis_fixture
return genesis_fixture
return fixture_to_bytes(genesis_fixture)


def test_genesis_state_root(genesis_fixture):
Expand Down
4 changes: 2 additions & 2 deletions tests/test_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,8 @@ def get_packeter():
def test_status():
p = get_packeter()
total_difficulty = 1000
head_hash = utils.sha3('head')
genesis_hash = utils.sha3('genesis')
head_hash = utils.sha3(b'head')
genesis_hash = utils.sha3(b'genesis')
msg = p.dump_Status(total_difficulty, head_hash, genesis_hash)
success, res = p.load_packet(msg)
assert success
Expand Down
6 changes: 5 additions & 1 deletion tests/test_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,16 @@ def do_test_state(filename, testname=None, testdata=None, limit=99999999):
fixtures = testutils.get_tests_from_file_or_dir(
os.path.join('fixtures', 'StateTests'))

# TODO: tests fail if not in correct order
filenames = sorted(list(fixtures.keys()))
filenames.reverse()
for filename in filenames:
tests = fixtures[filename]
if 'stQuadraticComplexityTest.json' in filename or \
'stMemoryStressTest.json' in filename:
continue
for testname, testdata in list(tests.items()):
testnames = sorted(list(tests.keys()))
for testname in testnames:
testdata = tests[testname]
func_name = 'test_%s_%s' % (filename, testname)
globals()[func_name] = gen_func(filename, testname, testdata)