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
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
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, )