Exemple #1
0
def setup_vm(vm_class, chain_id=None):
    db = AtomicDB()
    chain_context = ChainContext(chain_id)
    genesis_header = vm_class.create_genesis_header(
        difficulty=constants.GENESIS_DIFFICULTY,
        timestamp=0,
    )
    return vm_class(genesis_header, ChainDB(db), chain_context,
                    ConsensusContext(db))
Exemple #2
0
def instantiate_vm(vm_class):
  GENESIS_HEADER = BlockHeader(
    difficulty=17179869184,
    block_number=BlockNumber(0),
    gas_limit=5000,
  )
  chain_context = ChainContext(None)
  db = AtomicDB()
  return vm_class(GENESIS_HEADER, ChainDB(db), chain_context, ConsensusContext(db))
Exemple #3
0
def test_mainnet_dao_fork_header_validation(VM, header, previous_header,
                                            valid):
    chain_db = FakeChainDB({})
    consensus_context = ConsensusContext(chain_db.db)
    vm = VM(header=previous_header,
            chaindb=chain_db,
            chain_context=ChainContext(1),
            consensus_context=consensus_context)
    if valid:
        vm.validate_header(header, previous_header, check_seal=True)
    else:
        try:
            vm.validate_header(header, previous_header, check_seal=True)
        except ValidationError:
            pass
        else:
            assert False, "The invalid header %r must fail" % header
Exemple #4
0
def setup_computation(vm_class,
                      create_address,
                      code,
                      chain_id=None,
                      gas=1000000,
                      to=CANONICAL_ADDRESS_A,
                      data=b''):

    message = Message(
        to=to,
        sender=CANONICAL_ADDRESS_B,
        create_address=create_address,
        value=0,
        data=data,
        code=code,
        gas=gas,
    )

    chain_context = ChainContext(chain_id)

    tx_context = vm_class._state_class.transaction_context_class(
        gas_price=1,
        origin=CANONICAL_ADDRESS_B,
    )

    db = AtomicDB()
    vm = vm_class(GENESIS_HEADER, ChainDB(db), chain_context,
                  ConsensusContext(db))

    computation = vm_class._state_class.computation_class(
        state=vm.state,
        message=message,
        transaction_context=tx_context,
    )

    return computation
def test_vm_fixtures(fixture, vm_class, computation_getter):
    db = get_db_backend()
    chaindb = ChainDB(db)
    consensus_context = ConsensusContext(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'],
    )

    # None of the VM tests (currently) test chain ID, so the setting doesn't matter here.
    #   When they *do* start testing ID, they will have to supply it as part of the environment.
    #   For now, just hard-code it to something not used in practice:
    chain_context = ChainContext(chain_id=0)

    vm = vm_class(header=header,
                  chaindb=chaindb,
                  chain_context=chain_context,
                  consensus_context=consensus_context)
    state = vm.state
    setup_state(fixture['pre'], state)
    code = state.get_code(fixture['exec']['address'])
    # Update state_root manually
    vm._block = vm.get_block().copy(header=vm.get_header().copy(
        state_root=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 = vm.get_block().copy(
        header=vm.get_header().copy(state_root=computation.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(f"Got log entries: {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, f"Gas difference: {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
        expected_account_db = fixture['post']
    else:
        #
        # Error checks
        #
        assert computation.is_error
        assert isinstance(computation._error, VMError)
        expected_account_db = fixture['pre']

    verify_state(expected_account_db, vm.state)
Exemple #6
0
def setup_vm(vm_class, chain_id=None):
    db = AtomicDB()
    chain_context = ChainContext(chain_id)
    return vm_class(GENESIS_HEADER, ChainDB(db), chain_context,
                    ConsensusContext(db))