From daada104cbb3129eb2c630b9092fdeead3c99257 Mon Sep 17 00:00:00 2001 From: JahPowerBit Date: Thu, 26 Mar 2015 14:44:43 +0000 Subject: [PATCH 1/6] [Python3] test_trie_next_prev.py OK --- tests/test_trie_next_prev.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/test_trie_next_prev.py b/tests/test_trie_next_prev.py index cf670336e..b874dc757 100644 --- a/tests/test_trie_next_prev.py +++ b/tests/test_trie_next_prev.py @@ -4,6 +4,7 @@ import pyethereum.trie as trie from tests.utils import new_db from pyethereum.slogging import get_logger, configure_logging +from pyethereum.testutils import fixture_to_bytes logger = get_logger() # customize VM log output to your needs @@ -29,14 +30,14 @@ def run_test(name): logger.debug('testing %s' % name) t = trie.Trie(new_db()) - data = load_tests()[name] + data = fixture_to_bytes(load_tests()[name]) for k in data['in']: logger.debug('updating with (%s, %s)' %(k, k)) t.update(k, k) for point, prev, nxt in data['tests']: - assert nxt == (t.next(point) or '') - assert prev == (t.prev(point) or '') + assert nxt == (t.next(point) or b'') + assert prev == (t.prev(point) or b'') def test_basic(): From a471e01088bb588d1e2c6e45802b24e3c8289b4f Mon Sep 17 00:00:00 2001 From: JahPowerBit Date: Thu, 26 Mar 2015 15:18:12 +0000 Subject: [PATCH 2/6] fix tests/test_db.py for Py3 --- tests/test_db.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_db.py b/tests/test_db.py index bcc9a46a1..15e53295c 100644 --- a/tests/test_db.py +++ b/tests/test_db.py @@ -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) From a3ec95598b8905ab689ac2f946bfa0803be8d222 Mon Sep 17 00:00:00 2001 From: JahPowerBit Date: Thu, 26 Mar 2015 15:30:35 +0000 Subject: [PATCH 3/6] [Python3] test_network.py OK --- pyethereum/config.py | 2 +- tests/test_network.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pyethereum/config.py b/pyethereum/config.py index 6fddbed9d..9ad530c5f 100644 --- a/pyethereum/config.py +++ b/pyethereum/config.py @@ -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 = \ """ diff --git a/tests/test_network.py b/tests/test_network.py index 406f989d2..10bb1d84b 100644 --- a/tests/test_network.py +++ b/tests/test_network.py @@ -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 From 9e0c8e244cb5f34e495858c69e1d200ec27876cd Mon Sep 17 00:00:00 2001 From: JahPowerBit Date: Thu, 26 Mar 2015 15:44:12 +0000 Subject: [PATCH 4/6] fix test_genesis fixtures for Py3 --- tests/test_genesis.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_genesis.py b/tests/test_genesis.py index fbded7c56..a8b3e28cc 100644 --- a/tests/test_genesis.py +++ b/tests/test_genesis.py @@ -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() @@ -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): From e114c163b43ce9405c987ae98a00989e415b083e Mon Sep 17 00:00:00 2001 From: JahPowerBit Date: Thu, 26 Mar 2015 23:13:21 +0000 Subject: [PATCH 5/6] [Python3] fix various tests --- fixtures | 2 +- pyethereum/abi.py | 27 ++++++++++++++------------- pyethereum/blocks.py | 7 ++++--- pyethereum/miner.py | 4 ++-- pyethereum/specials.py | 16 ++++++++-------- pyethereum/tester.py | 2 ++ pyethereum/testutils.py | 4 ++-- pyethereum/vm.py | 2 +- tests/test_contracts.py | 31 ++++++++++++++++--------------- 9 files changed, 50 insertions(+), 45 deletions(-) diff --git a/fixtures b/fixtures index a7081bc54..5af1002b9 160000 --- a/fixtures +++ b/fixtures @@ -1 +1 @@ -Subproject commit a7081bc54e9d72cc480218cb4b218dbb04c7cde7 +Subproject commit 5af1002b96f34cd2c9252c1a6636826d47411ccd diff --git a/pyethereum/abi.py b/pyethereum/abi.py index bb0df8a08..d6e3e906c 100644 --- a/pyethereum/abi.py +++ b/pyethereum/abi.py @@ -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: @@ -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(): @@ -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']] @@ -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 if base == 'uint': sub = int(sub) @@ -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) @@ -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 @@ -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): diff --git a/pyethereum/blocks.py b/pyethereum/blocks.py index 0f3aec411..3cdcfd4e2 100644 --- a/pyethereum/blocks.py +++ b/pyethereum/blocks.py @@ -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 @@ -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.""" diff --git a/pyethereum/miner.py b/pyethereum/miner.py index 6e6a88f11..8288e1335 100644 --- a/pyethereum/miner.py +++ b/pyethereum/miner.py @@ -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(): diff --git a/pyethereum/specials.py b/pyethereum/specials.py index 1b7b27db5..09be3b557 100644 --- a/pyethereum/specials.py +++ b/pyethereum/specials.py @@ -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) @@ -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, [] @@ -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, [] @@ -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, [] @@ -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__': diff --git a/pyethereum/tester.py b/pyethereum/tester.py index 7fa13b1ff..c5af08de8 100644 --- a/pyethereum/tester.py +++ b/pyethereum/tester.py @@ -114,6 +114,7 @@ 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), @@ -121,6 +122,7 @@ def kall(*args, **kwargs): **dict_without(kwargs, 'sender', 'value', 'output')) _state.block.log_listeners.pop() + # Compute output data if kwargs.get('output', '') == 'raw': outdata = o['output'] diff --git a/pyethereum/testutils.py b/pyethereum/testutils.py index df029a657..a697ccab3 100644 --- a/pyethereum/testutils.py +++ b/pyethereum/testutils.py @@ -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']: diff --git a/pyethereum/vm.py b/pyethereum/vm.py index db5199a78..95aaa6dc4 100644 --- a/pyethereum/vm.py +++ b/pyethereum/vm.py @@ -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 diff --git a/tests/test_contracts.py b/tests/test_contracts.py index 0a09b8967..ce9cffe5d 100644 --- a/tests/test_contracts.py +++ b/tests/test_contracts.py @@ -12,7 +12,7 @@ # Test EVM contracts -serpent_code = ''' +serpent_code = b''' def main(a,b): return(a ^ b) ''' @@ -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() @@ -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 = """ @@ -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 = """ @@ -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) @@ -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 = """ @@ -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 = """ @@ -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 = """ @@ -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]}] From 974179afb870c0c9b70db922fe10319d71c788d8 Mon Sep 17 00:00:00 2001 From: JahPowerBit Date: Mon, 30 Mar 2015 10:59:37 +0000 Subject: [PATCH 6/6] Deterministic order for tests loaded from files --- tests/test_blocks.py | 10 ++++++++-- tests/test_state.py | 6 +++++- tests/test_transactions.py | 10 ++++++++-- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/tests/test_blocks.py b/tests/test_blocks.py index a4afd90c8..0171666e1 100644 --- a/tests/test_blocks.py +++ b/tests/test_blocks.py @@ -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) diff --git a/tests/test_state.py b/tests/test_state.py index 3e8e377f1..79efbdb03 100644 --- a/tests/test_state.py +++ b/tests/test_state.py @@ -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) diff --git a/tests/test_transactions.py b/tests/test_transactions.py index c52df5bf2..79a20b4e9 100644 --- a/tests/test_transactions.py +++ b/tests/test_transactions.py @@ -57,11 +57,17 @@ def run_test(filename, testname, testdata): else: fixtures = testutils.get_tests_from_file_or_dir( os.path.join('fixtures', 'TransactionTests')) - for filename, tests in list(fixtures.items()): + # 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] = lambda: run_test(filename, testname, testdata)