Ejemplo n.º 1
0
    def apply_create_message(self):
        snapshot = self.vm_state.snapshot()

        # EIP161 nonce incrementation
        with self.vm_state.state_db() as state_db:
            state_db.increment_nonce(self.msg.storage_address)

        computation = self.apply_message()

        if computation.is_error:
            self.vm_state.revert(snapshot)
            return computation
        else:
            contract_code = computation.output

            if contract_code and len(contract_code) >= EIP170_CODE_SIZE_LIMIT:
                computation._error = OutOfGas(
                    "Contract code size exceeds EIP170 limit of {0}.  Got code of "
                    "size: {1}".format(
                        EIP170_CODE_SIZE_LIMIT,
                        len(contract_code),
                    ))
                self.vm_state.revert(snapshot)
            elif contract_code:
                contract_code_gas_cost = len(
                    contract_code) * constants.GAS_CODEDEPOSIT
                try:
                    computation.gas_meter.consume_gas(
                        contract_code_gas_cost,
                        reason="Write contract code for CREATE",
                    )
                except OutOfGas as err:
                    # Different from Frontier: reverts state on gas failure while
                    # writing contract code.
                    computation._error = err
                    self.vm_state.revert(snapshot)
                else:
                    if self.logger:
                        self.logger.debug(
                            "SETTING CODE: %s -> length: %s | hash: %s",
                            encode_hex(self.msg.storage_address),
                            len(contract_code),
                            encode_hex(keccak(contract_code)))

                    with self.vm_state.state_db() as state_db:
                        state_db.set_code(self.msg.storage_address,
                                          contract_code)
                    self.vm_state.commit(snapshot)
            else:
                self.vm_state.commit(snapshot)
            return computation
Ejemplo n.º 2
0
Archivo: call.py Proyecto: ycdk/py-evm
def compute_eip150_msg_gas(computation, gas, extra_gas, value, mnemonic, callstipend):
    if computation.gas_meter.gas_remaining < extra_gas:
        # It feels wrong to raise an OutOfGas exception outside of GasMeter,
        # but I don't see an easy way around it.
        raise OutOfGas("Out of gas: Needed {0} - Remaining {1} - Reason: {2}".format(
            extra_gas,
            computation.gas_meter.gas_remaining,
            mnemonic,
        ))
    gas = min(
        gas,
        max_child_gas_eip150(computation.gas_meter.gas_remaining - extra_gas))
    total_fee = gas + extra_gas
    child_msg_gas = gas + (callstipend if value else 0)
    return child_msg_gas, total_fee
Ejemplo n.º 3
0
    def consume_gas(self, amount, reason):
        if amount < 0:
            raise ValidationError("Gas consumption amount must be positive")

        if amount > self.gas_remaining:
            raise OutOfGas(
                "Out of gas: Needed {0} - Remaining {1} - Reason: {2}".format(
                    amount,
                    self.gas_remaining,
                    reason,
                ))

        self.gas_remaining -= amount

        self.logger.trace(
            'GAS CONSUMPTION: %s - %s -> %s (%s)',
            self.gas_remaining + amount,
            amount,
            self.gas_remaining,
            reason,
        )