def test_db(): db = new_db() a, b = db, db assert a == b assert a.uncommitted == b.uncommitted a.put('a', 'b') b.get('a') == 'b' assert a.uncommitted == b.uncommitted a.commit() assert a.uncommitted == b.uncommitted assert 'test' not in db db = new_db() assert a != db
def test_genesis_db(): k, v, k2, v2 = accounts() db = new_db() blk = blocks.genesis(db, {v: utils.denoms.ether * 1}) store_block(blk) blk2 = blocks.genesis(db, {v: utils.denoms.ether * 1}) blk3 = blocks.genesis(db) assert blk == blk2 assert blk != blk3 db = new_db() blk2 = blocks.genesis(db, {v: utils.denoms.ether * 1}) blk3 = blocks.genesis(db) assert blk == blk2 assert blk != blk3
def test_deserialize_commit(): k, v, k2, v2 = accounts() db = new_db() blk = blocks.genesis(db) db.put(blk.hash, blk.serialize()) db.commit() assert blk == blocks.get_block(db, blk.hash)
def test_block_serialization_with_transaction_empty_genesis(): k, v, k2, v2 = accounts() db = new_db() a_blk = mkquickgenesis({}) store_block(a_blk) tx = get_transaction(gasprice=10) # must fail, as there is no balance a_blk2 = mine_next_block(a_blk, transactions=[tx]) assert tx not in a_blk2.get_transactions()
def test_mine_block_with_transaction(): k, v, k2, v2 = accounts() # mine two blocks db = new_db() a_blk = mkquickgenesis({v: utils.denoms.ether * 1}) store_block(a_blk) tx = get_transaction() a_blk2 = mine_next_block(a_blk, transactions=[tx]) assert tx in a_blk2.get_transactions()
def test_genesis_hash(genesis_fixture): """ py current: 7e2c3861f556686d7bc3ce4e93fa0011020868dc769838aca66bcc82010a2c60 fixtures 15.10.:f68067286ddb7245c2203b18135456de1fc4ed6a24a2d9014195faa7900025bf py poc6: 08436a4d33c77e6acf013e586a3333ad152f25d31df8b68749d85046810e1f4b fixtures 19.9,: 08436a4d33c77e6acf013e586a3333ad152f25d31df8b68749d85046810e1f4b """ genesis = blocks.genesis(new_db()) assert genesis.hex_hash() == genesis_fixture['genesis_hash']
def test_mine_block_with_transaction(): k, v, k2, v2 = accounts() db = new_db() blk = mkquickgenesis({v: utils.denoms.ether * 1}) store_block(blk) tx = get_transaction() blk = mine_next_block(blk, transactions=[tx]) assert tx in blk.get_transactions() assert blk.get_balance(v) == utils.denoms.finney * 990 assert blk.get_balance(v2) == utils.denoms.finney * 10
def test_mine_block(): k, v, k2, v2 = accounts() db = new_db() blk = mkquickgenesis({v: utils.denoms.ether * 1}) store_block(blk) blk2 = mine_next_block(blk, coinbase=v) store_block(blk2) assert blk2.get_balance(v) == blocks.BLOCK_REWARD + blk.get_balance(v) assert blk.state.db.db == blk2.state.db.db assert blk2.get_parent() == blk
def test_invalid_transaction(): k, v, k2, v2 = accounts() db = new_db() blk = mkquickgenesis({v2: utils.denoms.ether * 1}) store_block(blk) tx = get_transaction() blk = mine_next_block(blk, transactions=[tx]) assert blk.get_balance(v) == 0 assert blk.get_balance(v2) == utils.denoms.ether * 1 assert tx not in blk.get_transactions()
def test_genesis(): k, v, k2, v2 = accounts() db = new_db() blk = blocks.genesis(db, {v: utils.denoms.ether * 1}) sr = blk.state_root assert blk.state.db.db == db.db db.put(blk.hash, blk.serialize()) blk.state.db.commit() assert sr in db db.commit() assert sr in db blk2 = blocks.genesis(db, {v: utils.denoms.ether * 1}) blk3 = blocks.genesis(db) assert blk == blk2 assert blk != blk3 db = new_db() blk2 = blocks.genesis(db, {v: utils.denoms.ether * 1}) blk3 = blocks.genesis(db) assert blk == blk2 assert blk != blk3
def test_transfer(): db = new_db() k, v, k2, v2 = accounts() blk = blocks.genesis(db, {v: utils.denoms.ether * 1}) b_v = blk.get_balance(v) b_v2 = blk.get_balance(v2) value = 42 success = blk.transfer_value(v, v2, value) assert success assert blk.get_balance(v) == b_v - value assert blk.get_balance(v2) == b_v2 + value
def test_failing_transfer(): db = new_db() k, v, k2, v2 = accounts() blk = blocks.genesis(db, {v: utils.denoms.ether * 1}) b_v = blk.get_balance(v) b_v2 = blk.get_balance(v2) value = utils.denoms.ether * 2 # should fail success = blk.transfer_value(v, v2, value) assert not success assert blk.get_balance(v) == b_v assert blk.get_balance(v2) == b_v2
def run_test(name): logger.debug('testing %s' % name) t = trie.Trie(new_db()) data = 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 '')
def test_transaction(): k, v, k2, v2 = accounts() db = new_db() blk = mkquickgenesis({v: utils.denoms.ether * 1}) store_block(blk) blk = mine_next_block(blk) tx = get_transaction() assert tx not in blk.get_transactions() success, res = processblock.apply_transaction(blk, tx) assert tx in blk.get_transactions() assert blk.get_balance(v) == utils.denoms.finney * 990 assert blk.get_balance(v2) == utils.denoms.finney * 10
def run_test(name): logger.debug('testing %s' % name) t = trie.Trie(new_db()) data = 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 '')
def test_mine_block_with_transaction(): k, v, k2, v2 = accounts() db = new_db() blk = mkquickgenesis({v: utils.denoms.ether * 1}) store_block(blk) tx = get_transaction() blk2 = mine_next_block(blk, coinbase=v, transactions=[tx]) assert tx in blk2.get_transactions() store_block(blk2) assert tx in blk2.get_transactions() assert blocks.get_block(blk2.hash) == blk2 assert tx.gasprice == 0 assert blk2.get_balance( v) == blocks.BLOCK_REWARD + blk.get_balance(v) - tx.value assert blk.state.db.db == blk2.state.db.db assert blk2.get_parent() == blk assert tx in blk2.get_transactions() assert tx not in blk.get_transactions()
def test_gas_deduction(): k, v, k2, v2 = accounts() blk = blocks.genesis(new_db(), {v: utils.denoms.ether * 1}) v_old_balance = blk.get_balance(v) assert blk.get_balance(blk.coinbase) == 0 gasprice = 1 startgas = 10000 code1 = serpent.compile(namecoin_code) tx1 = transactions.contract(0, gasprice, startgas, 0, code1).sign(k) success, addr = processblock.apply_transaction(blk, tx1) assert success assert blk.coinbase != v assert v_old_balance > blk.get_balance(v) assert v_old_balance == blk.get_balance(v) + blk.get_balance(blk.coinbase) intrinsic_gas_used = opcodes.GTXCOST intrinsic_gas_used += opcodes.GTXDATAZERO * tx1.data.count(chr(0)) intrinsic_gas_used += opcodes.GTXDATANONZERO * (len(tx1.data) - tx1.data.count(chr(0))) assert v_old_balance - blk.get_balance(v) >= intrinsic_gas_used * gasprice
def do_test_vm(filename, testname=None, limit=99999999): if testname is None: for testname in vm_tests_fixtures()[filename].keys()[:limit]: do_test_vm(filename, testname) return if testname in faulty: logger.debug('skipping test:%r in %r' % (testname, filename)) return logger.debug('running test:%r in %r' % (testname, filename)) params = vm_tests_fixtures()[filename][testname] pre = params['pre'] exek = params['transaction'] env = params['env'] post = params['post'] check_testdata(env.keys(), [ 'currentGasLimit', 'currentTimestamp', 'previousHash', 'currentCoinbase', 'currentDifficulty', 'currentNumber' ]) # setup env blk = blocks.Block(new_db(), prevhash=env['previousHash'].decode('hex'), number=int(env['currentNumber']), coinbase=env['currentCoinbase'], difficulty=int(env['currentDifficulty']), gas_limit=int(env['currentGasLimit']), timestamp=int(env['currentTimestamp'])) # code FIXME WHAT TO DO WITH THIS CODE??? # if isinstance(env['code'], str): # continue # else: # addr = 0 # FIXME # blk.set_code(addr, ''.join(map(chr, env['code']))) # setup state for address, h in pre.items(): check_testdata(h.keys(), ['code', 'nonce', 'balance', 'storage']) blk.set_nonce(address, int(h['nonce'])) blk.set_balance(address, int(h['balance'])) blk.set_code(address, h['code'][2:].decode('hex')) for k, v in h['storage'].iteritems(): blk.set_storage_data(address, u.big_endian_to_int(k[2:].decode('hex')), u.big_endian_to_int(v[2:].decode('hex'))) # execute transactions tx = transactions.Transaction(nonce=int(exek['nonce'] or "0"), gasprice=int(exek['gasPrice'] or "0"), startgas=int(exek['gasLimit'] or "0"), to=exek['to'], value=int(exek['value'] or "0"), data=exek['data'][2:].decode('hex')).sign( exek['secretKey']) orig_apply_msg = pb.apply_msg def apply_msg_wrapper(ext, msg, code): def blkhash(n): if n >= blk.number or n < blk.number - 256: return '' else: return u.sha3(str(n)) ext.block_hash = blkhash return orig_apply_msg(ext, msg, code) pb.apply_msg = apply_msg_wrapper try: success, output = pb.apply_transaction(blk, tx) blk.commit_state() except pb.InvalidTransaction: output = '' logger.debug('Transaction not valid') pass if tx.to == '': output = blk.get_code(output) pb.apply_msg = orig_apply_msg assert '0x' + output.encode('hex') == params['out'] # check state for address, data in post.items(): state = blk.account_to_dict(address, for_vmtest=True) state.pop('storage_root', None) assert state == data
] def do_test_vm(filename, testname=None, limit=99999999): if testname is None: for testname in vm_tests_fixtures()[filename].keys()[:limit]: do_test_vm(filename, testname) return if testname in faulty: logger.debug('skipping test:%r in %r' % (testname, filename)) return logger.debug('running test:%r in %r' % (testname, filename)) params = vm_tests_fixtures()[filename][testname] run_test_vm(params) db = new_db() def run_test_vm(params): print params pre = params['pre'] exek = params['exec'] callcreates = params.get('callcreates', []) env = params['env'] post = params.get('post', {}) check_testdata(env.keys(), ['currentGasLimit', 'currentTimestamp', 'previousHash', 'currentCoinbase', 'currentDifficulty', 'currentNumber']) # setup env blk = blocks.Block(db,
Read genesis block from fixtures. """ genesis_fixture = None with open('fixtures/BasicTests/genesishashestest.json', 'r') as f: genesis_fixture = json.load(f) assert genesis_fixture is not None, "Could not read genesishashtest.json from fixtures. Make sure you did 'git submodule init'!" # FIXME: assert that link is uptodate for k in ('genesis_rlp_hex', 'genesis_state_root', 'genesis_hash', 'initial_alloc'): assert k in genesis_fixture return genesis_fixture def test_genesis_state_root(genesis_fixture): genesis = blocks.genesis(new_db()) assert genesis.state_root.encode('hex') == genesis_fixture['genesis_state_root'] def test_genesis_initial_alloc(genesis_fixture): genesis = blocks.genesis(new_db()) for k, v in blocks.GENESIS_INITIAL_ALLOC.items(): assert genesis.get_balance(k) == v def test_genesis_hash(genesis_fixture): genesis = blocks.genesis(new_db()) assert genesis.hex_hash() == genesis_fixture['genesis_hash'] if __name__ == '__main__': print 'current genesis:', blocks.genesis(new_db()).hex_hash()
def run_test_vm(params): pre = params['pre'] exek = params['exec'] callcreates = params.get('callcreates', []) env = params['env'] post = params.get('post', {}) check_testdata(env.keys(), [ 'currentGasLimit', 'currentTimestamp', 'previousHash', 'currentCoinbase', 'currentDifficulty', 'currentNumber' ]) # setup env db = new_db() blk = blocks.Block(db, prevhash=env['previousHash'].decode('hex'), number=int(env['currentNumber']), coinbase=env['currentCoinbase'], difficulty=int(env['currentDifficulty']), gas_limit=int(env['currentGasLimit']), timestamp=int(env['currentTimestamp'])) # code FIXME WHAT TO DO WITH THIS CODE??? # if isinstance(env['code'], str): # continue # else: # addr = 0 # FIXME # blk.set_code(addr, ''.join(map(chr, env['code']))) # setup state for address, h in pre.items(): check_testdata(h.keys(), ['code', 'nonce', 'balance', 'storage']) blk.set_nonce(address, int(h['nonce'])) blk.set_balance(address, int(h['balance'])) blk.set_code(address, h['code'][2:].decode('hex')) for k, v in h['storage']: blk.set_storage_data(address, u.big_endian_to_int(k.decode('hex')), u.big_endian_to_int(v.decode('hex'))) # execute transactions sender = exek['caller'] # a party that originates a call recvaddr = exek['address'] tx = transactions.Transaction(nonce=blk._get_acct_item( exek['caller'], 'nonce'), gasprice=int(exek['gasPrice']), startgas=int(exek['gas']), to=recvaddr, value=int(exek['value']), data=exek['data'][2:].decode('hex')) tx.sender = sender # capture apply_message calls apply_message_calls = [] orig_apply_msg = pb.apply_msg def apply_msg_wrapper(_ext, msg, code, toplevel=False): hexdata = msg.data.extract_all().encode('hex') apply_message_calls.append( dict(gasLimit=msg.gas, value=msg.value, destination=msg.to, data=hexdata)) if not toplevel: pb.apply_msg = orig_apply_msg result, gas_rem, data = orig_apply_msg(_ext, msg, code) if not toplevel: pb.apply_msg = apply_msg_wrapper return result, gas_rem, data pb.apply_msg = apply_msg_wrapper ext = pb.VMExt(blk, tx) msg = vm.Message(tx.sender, tx.to, tx.value, tx.startgas, vm.CallData([ord(x) for x in tx.data])) success, gas_remained, output = \ vm.vm_execute(ext, msg, exek['code'][2:].decode('hex')) pb.apply_msg = orig_apply_msg blk.commit_state() """ generally expected that the test implementer will read env, exec and pre then check their results against gas, logs, out, post and callcreates. If an exception is expected, then latter sections are absent in the test. Since the reverting of the state is not part of the VM tests. """ if not success: return for k in ['gas', 'logs', 'out', 'post', 'callcreates']: assert k in params assert len(callcreates) == len(apply_message_calls) # check against callcreates for i, callcreate in enumerate(callcreates): amc = apply_message_calls[i] assert callcreate['data'] == '0x' + amc['data'] assert callcreate['gasLimit'] == str(amc['gasLimit']) assert callcreate['value'] == str(amc['value']) assert callcreate['destination'] == amc['destination'] if 'out' in params: assert '0x' + ''.join(map(chr, output)).encode('hex') == params['out'] if 'gas' in params: assert str(gas_remained) == params['gas'] if 'logs' in params: """ The logs sections is a mapping between the blooms and their corresponding logentries. Each logentry has the format: address: The address of the logentry. data: The data of the logentry. topics: The topics of the logentry, given as an array of values. """ test_logs = params['logs'] vm_logs = [] for log in tx.logs: vm_logs.append({ "bloom": bloom.b64(bloom.bloom_from_list( log.bloomables())).encode('hex'), "address": log.address, "data": '0x' + log.data.encode('hex'), "topics": [ u.zpad(u.int_to_big_endian(t), 32).encode('hex') for t in log.topics ] }) assert len(vm_logs) == len(test_logs) assert vm_logs == test_logs # check state for address, data in post.items(): state = blk.account_to_dict(address, for_vmtest=True) state.pop('storage_root', None) # attribute not present in vmtest fixtures assert data == state db.delete_db()
def mkgenesis(initial_alloc={}): return blocks.genesis(new_db(), initial_alloc)
def test_genesis_hash(genesis_fixture): genesis = blocks.genesis(new_db()) assert genesis.hex_hash() == genesis_fixture['genesis_hash']
def do_test_vm(filename, testname=None, limit=99999999): if testname is None: for testname in vm_tests_fixtures()[filename].keys()[:limit]: do_test_vm(filename, testname) return if testname in faulty: logger.debug('skipping test:%r in %r' % (testname, filename)) return logger.debug('running test:%r in %r' % (testname, filename)) params = vm_tests_fixtures()[filename][testname] run_test_vm(params) db = new_db() def run_test_vm(params): print params pre = params['pre'] exek = params['exec'] callcreates = params.get('callcreates', []) env = params['env'] post = params.get('post', {}) check_testdata(env.keys(), [ 'currentGasLimit', 'currentTimestamp', 'previousHash', 'currentCoinbase', 'currentDifficulty', 'currentNumber' ]) # setup env
def test_genesis_state_root(genesis_fixture): genesis = blocks.genesis(new_db()) assert genesis.state_root.encode( 'hex') == genesis_fixture['genesis_state_root']
def test_genesis_initial_alloc(genesis_fixture): genesis = blocks.genesis(new_db()) for k, v in blocks.GENESIS_INITIAL_ALLOC.items(): assert genesis.get_balance(k) == v
def test_transient_block(): db = new_db() blk = blocks.genesis(db) tb_blk = blocks.TransientBlock(blk.serialize()) assert blk.hash == tb_blk.hash assert blk.number == tb_blk.number
def mkquickgenesis(initial_alloc={}): "set INITIAL_DIFFICULTY to a value that is quickly minable" return blocks.genesis(new_db(), initial_alloc, difficulty=2**16)
def do_test_vm(filename, testname=None, limit=99999999): if testname is None: for testname in vm_tests_fixtures()[filename].keys()[:limit]: do_test_vm(filename, testname) return if testname in faulty: logger.debug('skipping test:%r in %r' % (testname, filename)) return logger.debug('running test:%r in %r' % (testname, filename)) params = vm_tests_fixtures()[filename][testname] pre = params['pre'] exek = params['transaction'] env = params['env'] post = params['post'] check_testdata(env.keys(), ['currentGasLimit', 'currentTimestamp', 'previousHash', 'currentCoinbase', 'currentDifficulty', 'currentNumber']) # setup env blk = blocks.Block(new_db(), prevhash=env['previousHash'].decode('hex'), number=int(env['currentNumber']), coinbase=env['currentCoinbase'], difficulty=int(env['currentDifficulty']), gas_limit=int(env['currentGasLimit']), timestamp=int(env['currentTimestamp'])) # code FIXME WHAT TO DO WITH THIS CODE??? # if isinstance(env['code'], str): # continue # else: # addr = 0 # FIXME # blk.set_code(addr, ''.join(map(chr, env['code']))) # setup state for address, h in pre.items(): check_testdata(h.keys(), ['code', 'nonce', 'balance', 'storage']) blk.set_nonce(address, int(h['nonce'])) blk.set_balance(address, int(h['balance'])) blk.set_code(address, h['code'][2:].decode('hex')) for k, v in h['storage'].iteritems(): blk.set_storage_data(address, u.big_endian_to_int(k[2:].decode('hex')), u.big_endian_to_int(v[2:].decode('hex'))) # execute transactions tx = transactions.Transaction( nonce=int(exek['nonce'] or "0"), gasprice=int(exek['gasPrice'] or "0"), startgas=int(exek['gasLimit'] or "0"), to=exek['to'], value=int(exek['value'] or "0"), data=exek['data'][2:].decode('hex')).sign(exek['secretKey']) orig_apply_msg = pb.apply_msg def apply_msg_wrapper(ext, msg, code): def blkhash(n): if n >= blk.number or n < blk.number - 256: return '' else: return u.sha3(str(n)) ext.block_hash = blkhash return orig_apply_msg(ext, msg, code) pb.apply_msg = apply_msg_wrapper try: success, output = pb.apply_transaction(blk, tx) blk.commit_state() except pb.InvalidTransaction: output = '' logger.debug('Transaction not valid') pass if tx.to == '': output = blk.get_code(output) pb.apply_msg = orig_apply_msg assert '0x' + output.encode('hex') == params['out'] # check state for address, data in post.items(): state = blk.account_to_dict(address, for_vmtest=True) state.pop('storage_root', None) assert state == data