def test_state_fixtures(fixture_name, fixture): header = BlockHeader( coinbase=fixture['env']['currentCoinbase'], difficulty=fixture['env']['currentDifficulty'], block_number=fixture['env']['currentNumber'], gas_limit=fixture['env']['currentGasLimit'], timestamp=fixture['env']['currentTimestamp'], parent_hash=fixture['env']['previousHash'], ) db = MemoryDB() meta_evm = EVMForTesting.configure(db=db)(header=header) evm = meta_evm.get_evm() block = evm.block setup_state_db(fixture['pre'], evm.state_db) Transaction = evm.get_transaction_class() unsigned_transaction = Transaction.create_unsigned_transaction( nonce=fixture['transaction']['nonce'], gas_price=fixture['transaction']['gasPrice'], gas=fixture['transaction']['gasLimit'], to=fixture['transaction']['to'], value=fixture['transaction']['value'], data=fixture['transaction']['data'], ) transaction = unsigned_transaction.as_signed_transaction( private_key=fixture['transaction']['secretKey']) try: computation = evm.apply_transaction(transaction) except InvalidTransaction: transaction_error = True else: transaction_error = False if not transaction_error: expected_logs = [{ 'address': log_entry[0], 'topics': log_entry[1], 'data': log_entry[2], } for log_entry in computation.get_log_entries()] expected_logs == fixture['logs'] expected_output = fixture['out'] if isinstance(expected_output, int): assert len(computation.output) == expected_output else: assert computation.output == expected_output verify_state_db(fixture['post'], evm.state_db)
def test_state_fixtures(fixture_name, fixture): header = BlockHeader( coinbase=fixture['env']['currentCoinbase'], difficulty=fixture['env']['currentDifficulty'], block_number=fixture['env']['currentNumber'], gas_limit=fixture['env']['currentGasLimit'], timestamp=fixture['env']['currentTimestamp'], parent_hash=fixture['env']['previousHash'], ) db = get_db_backend() chain = ChainForTesting(db=db, header=header) state_db = setup_state_db(fixture['pre'], chain.get_state_db()) chain.header.state_root = state_db.root_hash unsigned_transaction = chain.create_unsigned_transaction( nonce=fixture['transaction']['nonce'], gas_price=fixture['transaction']['gasPrice'], gas=fixture['transaction']['gasLimit'], to=fixture['transaction']['to'], value=fixture['transaction']['value'], data=fixture['transaction']['data'], ) transaction = unsigned_transaction.as_signed_transaction( private_key=fixture['transaction']['secretKey']) try: computation = chain.apply_transaction(transaction) except ValidationError: transaction_error = True else: transaction_error = False if not transaction_error: expected_logs = [{ 'address': log_entry[0], 'topics': log_entry[1], 'data': log_entry[2], } for log_entry in computation.get_log_entries()] expected_logs == fixture['logs'] expected_output = fixture['out'] if isinstance(expected_output, int): assert len(computation.output) == expected_output else: assert computation.output == expected_output verify_state_db(fixture['post'], chain.get_state_db())
def test_state_fixtures(fixture, fixture_vm_class): header = BlockHeader( coinbase=fixture['env']['currentCoinbase'], difficulty=fixture['env']['currentDifficulty'], block_number=fixture['env']['currentNumber'], gas_limit=fixture['env']['currentGasLimit'], timestamp=fixture['env']['currentTimestamp'], parent_hash=fixture['env']['previousHash'], ) chaindb = BaseChainDB(get_db_backend()) vm = fixture_vm_class(header=header, chaindb=chaindb) with vm.state.state_db() as state_db: setup_state_db(fixture['pre'], state_db) if 'secretKey' in fixture['transaction']: unsigned_transaction = vm.create_unsigned_transaction( nonce=fixture['transaction']['nonce'], gas_price=fixture['transaction']['gasPrice'], gas=fixture['transaction']['gasLimit'], to=fixture['transaction']['to'], value=fixture['transaction']['value'], data=fixture['transaction']['data'], ) private_key = keys.PrivateKey(fixture['transaction']['secretKey']) transaction = unsigned_transaction.as_signed_transaction( private_key=private_key) elif 'vrs' in fixture['transaction']: v, r, s = ( fixture['transaction']['v'], fixture['transaction']['r'], fixture['transaction']['s'], ) transaction = vm.create_transaction( nonce=fixture['transaction']['nonce'], gas_price=fixture['transaction']['gasPrice'], gas=fixture['transaction']['gasLimit'], to=fixture['transaction']['to'], value=fixture['transaction']['value'], data=fixture['transaction']['data'], v=v, r=r, s=s, ) try: computation = vm.apply_transaction(transaction) except ValidationError as err: transaction_error = err else: transaction_error = False if not transaction_error: log_entries = computation.get_log_entries() actual_logs_hash = hash_log_entries(log_entries) if 'logs' in fixture['post']: expected_logs_hash = fixture['post']['logs'] assert expected_logs_hash == actual_logs_hash elif log_entries: raise AssertionError("Got log {0} entries. hash:{1}".format( len(log_entries), actual_logs_hash, )) if 'out' in fixture: expected_output = fixture['out'] if isinstance(expected_output, int): assert len(computation.output) == expected_output else: assert computation.output == expected_output assert vm.block.header.state_root == fixture['post']['hash']
def test_vm_success_using_fixture(fixture_name, fixture): db = MemoryDB() meta_evm = EVMForTesting(db=db) header = BlockHeader( coinbase=fixture['env']['currentCoinbase'], difficulty=fixture['env']['currentDifficulty'], block_number=fixture['env']['currentNumber'], gas_limit=fixture['env']['currentGasLimit'], timestamp=fixture['env']['currentTimestamp'], parent_hash=fixture['env']['previousHash'], ) evm = meta_evm(header=header) block = evm.block setup_state_db(fixture['pre'], block.state_db) Transaction = evm.get_transaction_class() unsigned_transaction = Transaction.create_unsigned_transaction( nonce=fixture['transaction']['nonce'], gas_price=fixture['transaction']['gasPrice'], gas=fixture['transaction']['gasLimit'], to=fixture['transaction']['to'], value=fixture['transaction']['value'], data=fixture['transaction']['data'], ) transaction = unsigned_transaction.as_signed_transaction( private_key=fixture['transaction']['secretKey']) try: computation = evm.apply_transaction(transaction) except InvalidTransaction: transaction_error = True else: transaction_error = False if not transaction_error: expected_logs = [{ 'address': log_entry[0], 'topics': log_entry[1], 'data': log_entry[2], } for log_entry in computation.get_log_entries()] expected_logs == fixture['logs'] expected_output = fixture['out'] if isinstance(expected_output, int): assert len(computation.output) == expected_output else: assert computation.output == expected_output for account, account_data in sorted(fixture['post'].items()): for slot, expected_storage_value in sorted( account_data['storage'].items()): actual_storage_value = evm.block.state_db.get_storage( account, slot) assert actual_storage_value == expected_storage_value expected_nonce = account_data['nonce'] expected_code = account_data['code'] expected_balance = account_data['balance'] actual_nonce = evm.block.state_db.get_nonce(account) actual_code = evm.block.state_db.get_code(account) actual_balance = evm.block.state_db.get_balance(account) balance_delta = expected_balance - actual_balance assert actual_nonce == expected_nonce assert actual_code == expected_code assert balance_delta == 0, "Expected: {0} - Actual: {1} | Delta: {2}".format( expected_balance, actual_balance, balance_delta) assert evm.block.state_db.state.root_hash == fixture['postStateRoot']
def test_vm_fixtures(fixture, vm_class): chaindb = ChainDB(get_db_backend()) header = BlockHeader( coinbase=fixture['env']['currentCoinbase'], difficulty=fixture['env']['currentDifficulty'], block_number=fixture['env']['currentNumber'], gas_limit=fixture['env']['currentGasLimit'], timestamp=fixture['env']['currentTimestamp'], ) vm = vm_class(header=header, chaindb=chaindb) vm_state = vm.state with vm_state.state_db() as state_db: setup_state_db(fixture['pre'], state_db) code = state_db.get_code(fixture['exec']['address']) # Update state_root manually vm.block.header.state_root = vm_state.state_root message = Message( to=fixture['exec']['address'], sender=fixture['exec']['caller'], value=fixture['exec']['value'], data=fixture['exec']['data'], code=code, gas=fixture['exec']['gas'], ) transaction_context = BaseTransactionContext( origin=fixture['exec']['origin'], gas_price=fixture['exec']['gasPrice'], ) computation = vm.state.get_computation( message, transaction_context).apply_computation( vm.state, message, transaction_context, ) # Update state_root manually vm.block.header.state_root = computation.vm_state.state_root if 'post' in fixture: # # Success checks # assert not computation.is_error log_entries = computation.get_log_entries() if 'logs' in fixture: actual_logs_hash = hash_log_entries(log_entries) expected_logs_hash = fixture['logs'] assert expected_logs_hash == actual_logs_hash elif log_entries: raise AssertionError("Got log entries: {0}".format(log_entries)) expected_output = fixture['out'] assert computation.output == expected_output gas_meter = computation.gas_meter expected_gas_remaining = fixture['gas'] actual_gas_remaining = gas_meter.gas_remaining gas_delta = actual_gas_remaining - expected_gas_remaining assert gas_delta == 0, "Gas difference: {0}".format(gas_delta) call_creates = fixture.get('callcreates', []) assert len(computation.children) == len(call_creates) call_creates = fixture.get('callcreates', []) for child_computation, created_call in zip(computation.children, call_creates): to_address = created_call['destination'] data = created_call['data'] gas_limit = created_call['gasLimit'] value = created_call['value'] assert child_computation.msg.to == to_address assert data == child_computation.msg.data or child_computation.msg.code assert gas_limit == child_computation.msg.gas assert value == child_computation.msg.value post_state = fixture['post'] else: # # Error checks # assert computation.is_error assert isinstance(computation._error, VMError) post_state = fixture['pre'] with vm.state.state_db(read_only=True) as state_db: verify_state_db(post_state, state_db)
def test_vm_fixtures(fixture_name, fixture): db = get_db_backend() header = BlockHeader( coinbase=fixture['env']['currentCoinbase'], difficulty=fixture['env']['currentDifficulty'], block_number=fixture['env']['currentNumber'], gas_limit=fixture['env']['currentGasLimit'], timestamp=fixture['env']['currentTimestamp'], ) chain = ChainForTesting(db=db, header=header) vm = chain.get_vm() with vm.state_db() as state_db: setup_state_db(fixture['pre'], state_db) code = state_db.get_code(fixture['exec']['address']) message = Message( origin=fixture['exec']['origin'], to=fixture['exec']['address'], sender=fixture['exec']['caller'], value=fixture['exec']['value'], data=fixture['exec']['data'], code=code, gas=fixture['exec']['gas'], gas_price=fixture['exec']['gasPrice'], ) computation = vm.apply_computation(message) if 'post' in fixture: # # Success checks # assert computation.error is None expected_logs = [{ 'address': log_entry[0], 'topics': log_entry[1], 'data': log_entry[2], } for log_entry in computation.get_log_entries()] expected_logs == fixture['logs'] expected_output = fixture['out'] assert computation.output == expected_output gas_meter = computation.gas_meter expected_gas_remaining = fixture['gas'] actual_gas_remaining = gas_meter.gas_remaining gas_delta = actual_gas_remaining - expected_gas_remaining assert gas_delta == 0, "Gas difference: {0}".format(gas_delta) call_creates = fixture.get('callcreates', []) assert len(computation.children) == len(call_creates) call_creates = fixture.get('callcreates', []) for child_computation, created_call in zip(computation.children, call_creates): to_address = created_call['destination'] data = created_call['data'] gas_limit = created_call['gasLimit'] value = created_call['value'] assert child_computation.msg.to == to_address assert data == child_computation.msg.data or child_computation.msg.code assert gas_limit == child_computation.msg.gas assert value == child_computation.msg.value post_state = fixture['post'] else: # # Error checks # assert computation.error assert isinstance(computation.error, VMError) post_state = fixture['pre'] with vm.state_db(read_only=True) as state_db: verify_state_db(post_state, state_db)
def test_vm_fixtures(fixture_name, fixture): db = MemoryDB() header = BlockHeader( coinbase=fixture['env']['currentCoinbase'], difficulty=fixture['env']['currentDifficulty'], block_number=fixture['env']['currentNumber'], gas_limit=fixture['env']['currentGasLimit'], timestamp=fixture['env']['currentTimestamp'], ) meta_evm = EVMForTesting.configure(db=db)(header=header) evm = meta_evm.get_evm() setup_state_db(fixture['pre'], evm.state_db) message = Message( origin=fixture['exec']['origin'], to=fixture['exec']['address'], sender=fixture['exec']['caller'], value=fixture['exec']['value'], data=fixture['exec']['data'], code=evm.state_db.get_code(fixture['exec']['address']), gas=fixture['exec']['gas'], gas_price=fixture['exec']['gasPrice'], ) computation = evm.apply_computation(message) if 'post' in fixture: # # Success checks # assert computation.error is None expected_logs = [{ 'address': log_entry[0], 'topics': log_entry[1], 'data': log_entry[2], } for log_entry in computation.get_log_entries()] expected_logs == fixture['logs'] expected_output = fixture['out'] assert computation.output == expected_output gas_meter = computation.gas_meter expected_gas_remaining = fixture['gas'] actual_gas_remaining = gas_meter.gas_remaining gas_delta = actual_gas_remaining - expected_gas_remaining assert gas_delta == 0, "Gas difference: {0}".format(gas_delta) call_creates = fixture.get('callcreates', []) assert len(computation.children) == len(call_creates) for child_computation, created_call in zip( computation.children, fixture.get('callcreates', [])): to_address = created_call['destination'] data = created_call['data'] gas_limit = created_call['gasLimit'] value = created_call['value'] assert child_computation.msg.to == to_address assert data == child_computation.msg.data or child_computation.msg.code assert gas_limit == child_computation.msg.gas assert value == child_computation.msg.value post_state = fixture['post'] else: # # Error checks # assert computation.error assert isinstance(computation.error, VMError) post_state = fixture['pre'] for account, account_data in post_state.items(): for slot, expected_storage_value in account_data['storage'].items(): actual_storage_value = evm.state_db.get_storage(account, slot) assert actual_storage_value == expected_storage_value expected_nonce = account_data['nonce'] expected_code = account_data['code'] expected_balance = account_data['balance'] actual_nonce = evm.state_db.get_nonce(account) actual_code = evm.state_db.get_code(account) actual_balance = evm.state_db.get_balance(account) assert actual_nonce == expected_nonce assert actual_code == expected_code assert actual_balance == expected_balance