diff --git a/libethereum/Executive.cpp b/libethereum/Executive.cpp index 93900b51e..a4e844d88 100644 --- a/libethereum/Executive.cpp +++ b/libethereum/Executive.cpp @@ -66,7 +66,7 @@ bool Executive::setup(bytesConstRef _rlp) } // Check gas cost is enough. - u256 gasCost = m_t.data.size() * c_txDataGas + c_txGas; + u256 gasCost = u256(m_t.data.size()) * FeeStructure::c_txDataGas + FeeStructure::c_txGas; if (m_t.gas < gasCost) { diff --git a/libethereum/Interface.h b/libethereum/Interface.h index 7ae650590..6a32e81c4 100644 --- a/libethereum/Interface.h +++ b/libethereum/Interface.h @@ -123,7 +123,7 @@ public: virtual Addresses addresses(int _block) const = 0; /// Get the fee associated for a transaction with the given data. - static u256 txGas(unsigned _dataCount, u256 _gas = 0) { return c_txDataGas * _dataCount + c_txGas + _gas; } + static u256 txGas(unsigned _dataCount, u256 _gas = 0) { return FeeStructure::c_txDataGas * u256(_dataCount) + FeeStructure::c_txGas + _gas; } /// Get the remaining gas limit in this block. virtual u256 gasLimitRemaining() const = 0; diff --git a/libevm/FeeStructure.h b/libevm/FeeStructure.h index 8c1519e86..574021d95 100644 --- a/libevm/FeeStructure.h +++ b/libevm/FeeStructure.h @@ -31,19 +31,19 @@ enum class Instruction: uint8_t; struct FeeStructure { + static uint32_t const c_stepGas = 1; ///< Once per operation, except for SSTORE, SLOAD, BALANCE, SHA3, CREATE, CALL. + static uint32_t const c_balanceGas = 20; ///< Once per BALANCE operation. + static uint32_t const c_sha3Gas = 20; ///< Once per SHA3 operation. + static uint32_t const c_sloadGas = 20; ///< Once per SLOAD operation. + static uint32_t const c_sstoreGas = 100; ///< Once per non-zero storage element in a CREATE call/transaction. Also, once/twice per SSTORE operation depending on whether the zeroness changes (twice iff it changes from zero; nothing at all if to zero) or doesn't (once). + static uint32_t const c_createGas = 100; ///< Once per CREATE operation & contract-creation transaction. + static uint32_t const c_callGas = 20; ///< Once per CALL operation & message call transaction. + static uint32_t const c_memoryGas = 1; ///< Times the address of the (highest referenced byte in memory + 1). NOTE: referencing happens on read, write and in instructions such as RETURN and CALL. + static uint32_t const c_txDataGas = 5; ///< Per byte of data attached to a transaction. NOTE: Not payable on data of calls between transactions. + static uint32_t const c_txGas = 500; ///< Per transaction. NOTE: Not payable on data of calls between transactions. + static uint32_t getInstructionFee(Instruction _inst); }; -static uint32_t const c_stepGas = 1; ///< Once per operation, except for SSTORE, SLOAD, BALANCE, SHA3, CREATE, CALL. -static uint32_t const c_balanceGas = 20; ///< Once per BALANCE operation. -static uint32_t const c_sha3Gas = 20; ///< Once per SHA3 operation. -static uint32_t const c_sloadGas = 20; ///< Once per SLOAD operation. -static uint32_t const c_sstoreGas = 100; ///< Once per non-zero storage element in a CREATE call/transaction. Also, once/twice per SSTORE operation depending on whether the zeroness changes (twice iff it changes from zero; nothing at all if to zero) or doesn't (once). -static uint32_t const c_createGas = 100; ///< Once per CREATE operation & contract-creation transaction. -static uint32_t const c_callGas = 20; ///< Once per CALL operation & message call transaction. -static uint32_t const c_memoryGas = 1; ///< Times the address of the (highest referenced byte in memory + 1). NOTE: referencing happens on read, write and in instructions such as RETURN and CALL. -static uint32_t const c_txDataGas = 5; ///< Per byte of data attached to a transaction. NOTE: Not payable on data of calls between transactions. -static uint32_t const c_txGas = 500; ///< Per transaction. NOTE: Not payable on data of calls between transactions. - } } diff --git a/libevm/VM.h b/libevm/VM.h index 401e30baf..6eb57941d 100644 --- a/libevm/VM.h +++ b/libevm/VM.h @@ -101,7 +101,7 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con Instruction inst = (Instruction)_ext.getCode(m_curPC); // FEES... - bigint runGas = c_stepGas; + bigint runGas = FeeStructure::c_stepGas; bigint newTempSize = m_temp.size(); switch (inst) { @@ -116,15 +116,15 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con case Instruction::SSTORE: require(2); if (!_ext.store(m_stack.back()) && m_stack[m_stack.size() - 2]) - runGas = c_sstoreGas * 2; + runGas = FeeStructure::c_sstoreGas * 2; else if (_ext.store(m_stack.back()) && !m_stack[m_stack.size() - 2]) runGas = 0; else - runGas = c_sstoreGas; + runGas = FeeStructure::c_sstoreGas; break; case Instruction::SLOAD: - runGas = c_sloadGas; + runGas = FeeStructure::c_sloadGas; break; // These all operate on memory and therefore potentially expand it: @@ -146,7 +146,7 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con break; case Instruction::SHA3: require(2); - runGas = c_sha3Gas; + runGas = FeeStructure::c_sha3Gas; newTempSize = memNeed(m_stack.back(), m_stack[m_stack.size() - 2]); break; case Instruction::CALLDATACOPY: @@ -163,18 +163,18 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con break; case Instruction::BALANCE: - runGas = c_balanceGas; + runGas = FeeStructure::c_balanceGas; break; case Instruction::CALL: require(7); - runGas = c_callGas + m_stack[m_stack.size() - 1]; + runGas = FeeStructure::c_callGas + m_stack[m_stack.size() - 1]; newTempSize = std::max(memNeed(m_stack[m_stack.size() - 6], m_stack[m_stack.size() - 7]), memNeed(m_stack[m_stack.size() - 4], m_stack[m_stack.size() - 5])); break; case Instruction::CALLCODE: require(7); - runGas = c_callGas + m_stack[m_stack.size() - 1]; + runGas = FeeStructure::c_callGas + m_stack[m_stack.size() - 1]; newTempSize = std::max(memNeed(m_stack[m_stack.size() - 6], m_stack[m_stack.size() - 7]), memNeed(m_stack[m_stack.size() - 4], m_stack[m_stack.size() - 5])); break; @@ -184,7 +184,7 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con auto inOff = m_stack[m_stack.size() - 2]; auto inSize = m_stack[m_stack.size() - 3]; newTempSize = inOff + inSize; - runGas = c_createGas; + runGas = FeeStructure::c_createGas; break; } @@ -302,7 +302,7 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con newTempSize = (newTempSize + 31) / 32 * 32; if (newTempSize > m_temp.size()) - runGas += c_memoryGas * (newTempSize - m_temp.size()) / 32; + runGas += FeeStructure::c_memoryGas * (newTempSize - m_temp.size()) / 32; if (_onOp) _onOp(osteps - _steps - 1, inst, newTempSize > m_temp.size() ? (newTempSize - m_temp.size()) / 32 : bigint(0), runGas, this, &_ext);