Browse Source

Move basic instruction fee selection to a function in FeeStructure

cl-refactor
Paweł Bylica 11 years ago
parent
commit
b1ecd3d731
  1. 156
      libevm/FeeStructure.cpp
  2. 28
      libevm/FeeStructure.h
  3. 138
      libevm/VM.h

156
libevm/FeeStructure.cpp

@ -21,3 +21,159 @@
*/
#include "FeeStructure.h"
#include <libevmface/Instruction.h>
namespace dev
{
namespace eth
{
uint32_t FeeStructure::getInstructionFee(Instruction _inst) BOOST_NOEXCEPT_OR_NOTHROW
{
switch (_inst)
{
case Instruction::STOP:
case Instruction::SUICIDE:
default: // In case of bad instruction return 0
return 0;
case Instruction::SSTORE:
return c_sstoreGas;
case Instruction::SLOAD:
return c_sloadGas;
case Instruction::SHA3:
return c_sha3Gas;
case Instruction::BALANCE:
return c_sha3Gas;
case Instruction::CALL:
case Instruction::CALLCODE:
return c_callGas;
case Instruction::CREATE:
return c_createGas;
case Instruction::ADD:
case Instruction::MUL:
case Instruction::SUB:
case Instruction::DIV:
case Instruction::SDIV:
case Instruction::MOD:
case Instruction::SMOD:
case Instruction::EXP:
case Instruction::NEG:
case Instruction::LT:
case Instruction::GT:
case Instruction::SLT:
case Instruction::SGT:
case Instruction::EQ:
case Instruction::NOT:
case Instruction::AND:
case Instruction::OR:
case Instruction::XOR:
case Instruction::BYTE:
case Instruction::ADDMOD:
case Instruction::MULMOD:
case Instruction::ADDRESS:
case Instruction::ORIGIN:
case Instruction::CALLER:
case Instruction::CALLVALUE:
case Instruction::CALLDATALOAD:
case Instruction::CALLDATASIZE:
case Instruction::CODESIZE:
case Instruction::EXTCODESIZE:
case Instruction::GASPRICE:
case Instruction::PREVHASH:
case Instruction::COINBASE:
case Instruction::TIMESTAMP:
case Instruction::NUMBER:
case Instruction::DIFFICULTY:
case Instruction::GASLIMIT:
case Instruction::PUSH1:
case Instruction::PUSH2:
case Instruction::PUSH3:
case Instruction::PUSH4:
case Instruction::PUSH5:
case Instruction::PUSH6:
case Instruction::PUSH7:
case Instruction::PUSH8:
case Instruction::PUSH9:
case Instruction::PUSH10:
case Instruction::PUSH11:
case Instruction::PUSH12:
case Instruction::PUSH13:
case Instruction::PUSH14:
case Instruction::PUSH15:
case Instruction::PUSH16:
case Instruction::PUSH17:
case Instruction::PUSH18:
case Instruction::PUSH19:
case Instruction::PUSH20:
case Instruction::PUSH21:
case Instruction::PUSH22:
case Instruction::PUSH23:
case Instruction::PUSH24:
case Instruction::PUSH25:
case Instruction::PUSH26:
case Instruction::PUSH27:
case Instruction::PUSH28:
case Instruction::PUSH29:
case Instruction::PUSH30:
case Instruction::PUSH31:
case Instruction::PUSH32:
case Instruction::POP:
case Instruction::DUP1:
case Instruction::DUP2:
case Instruction::DUP3:
case Instruction::DUP4:
case Instruction::DUP5:
case Instruction::DUP6:
case Instruction::DUP7:
case Instruction::DUP8:
case Instruction::DUP9:
case Instruction::DUP10:
case Instruction::DUP11:
case Instruction::DUP12:
case Instruction::DUP13:
case Instruction::DUP14:
case Instruction::DUP15:
case Instruction::DUP16:
case Instruction::SWAP1:
case Instruction::SWAP2:
case Instruction::SWAP3:
case Instruction::SWAP4:
case Instruction::SWAP5:
case Instruction::SWAP6:
case Instruction::SWAP7:
case Instruction::SWAP8:
case Instruction::SWAP9:
case Instruction::SWAP10:
case Instruction::SWAP11:
case Instruction::SWAP12:
case Instruction::SWAP13:
case Instruction::SWAP14:
case Instruction::SWAP15:
case Instruction::SWAP16:
case Instruction::JUMP:
case Instruction::JUMPI:
case Instruction::PC:
case Instruction::MSIZE:
case Instruction::GAS:
case Instruction::JUMPDEST:
case Instruction::RETURN:
case Instruction::MSTORE:
case Instruction::MSTORE8:
case Instruction::MLOAD:
case Instruction::CALLDATACOPY:
case Instruction::CODECOPY:
case Instruction::EXTCODECOPY:
return c_stepGas;
}
}
}
}

28
libevm/FeeStructure.h

@ -22,6 +22,8 @@
#pragma once
#include <boost/config.hpp>
namespace dev
{
namespace eth
@ -31,18 +33,20 @@ 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.
/// Returns step fee of the instruction.
/// In case of bad instruction code, returns 0.
static uint32_t getInstructionFee(Instruction _inst) BOOST_NOEXCEPT_OR_NOTHROW;
};
}

138
libevm/VM.h

@ -101,17 +101,10 @@ template <class Ext> dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con
Instruction inst = (Instruction)_ext.getCode(m_curPC);
// FEES...
bigint runGas = FeeStructure::c_stepGas;
bigint runGas = FeeStructure::getInstructionFee(inst);
bigint newTempSize = m_temp.size();
switch (inst)
{
case Instruction::STOP:
runGas = 0;
break;
case Instruction::SUICIDE:
runGas = 0;
break;
case Instruction::SSTORE:
require(2);
@ -119,12 +112,6 @@ template <class Ext> dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con
runGas = FeeStructure::c_sstoreGas * 2;
else if (_ext.store(m_stack.back()) && !m_stack[m_stack.size() - 2])
runGas = 0;
else
runGas = FeeStructure::c_sstoreGas;
break;
case Instruction::SLOAD:
runGas = FeeStructure::c_sloadGas;
break;
// These all operate on memory and therefore potentially expand it:
@ -146,7 +133,6 @@ template <class Ext> dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con
break;
case Instruction::SHA3:
require(2);
runGas = FeeStructure::c_sha3Gas;
newTempSize = memNeed(m_stack.back(), m_stack[m_stack.size() - 2]);
break;
case Instruction::CALLDATACOPY:
@ -161,20 +147,11 @@ template <class Ext> dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con
require(4);
newTempSize = memNeed(m_stack[m_stack.size() - 2], m_stack[m_stack.size() - 4]);
break;
case Instruction::BALANCE:
runGas = FeeStructure::c_balanceGas;
break;
case Instruction::CALL:
require(7);
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 = FeeStructure::c_callGas + m_stack[m_stack.size() - 1];
runGas += 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,120 +161,9 @@ template <class Ext> 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 = FeeStructure::c_createGas;
break;
}
case Instruction::ADD:
case Instruction::MUL:
case Instruction::SUB:
case Instruction::DIV:
case Instruction::SDIV:
case Instruction::MOD:
case Instruction::SMOD:
case Instruction::EXP:
case Instruction::NEG:
case Instruction::LT:
case Instruction::GT:
case Instruction::SLT:
case Instruction::SGT:
case Instruction::EQ:
case Instruction::NOT:
case Instruction::AND:
case Instruction::OR:
case Instruction::XOR:
case Instruction::BYTE:
case Instruction::ADDMOD:
case Instruction::MULMOD:
case Instruction::ADDRESS:
case Instruction::ORIGIN:
case Instruction::CALLER:
case Instruction::CALLVALUE:
case Instruction::CALLDATALOAD:
case Instruction::CALLDATASIZE:
case Instruction::CODESIZE:
case Instruction::EXTCODESIZE:
case Instruction::GASPRICE:
case Instruction::PREVHASH:
case Instruction::COINBASE:
case Instruction::TIMESTAMP:
case Instruction::NUMBER:
case Instruction::DIFFICULTY:
case Instruction::GASLIMIT:
case Instruction::PUSH1:
case Instruction::PUSH2:
case Instruction::PUSH3:
case Instruction::PUSH4:
case Instruction::PUSH5:
case Instruction::PUSH6:
case Instruction::PUSH7:
case Instruction::PUSH8:
case Instruction::PUSH9:
case Instruction::PUSH10:
case Instruction::PUSH11:
case Instruction::PUSH12:
case Instruction::PUSH13:
case Instruction::PUSH14:
case Instruction::PUSH15:
case Instruction::PUSH16:
case Instruction::PUSH17:
case Instruction::PUSH18:
case Instruction::PUSH19:
case Instruction::PUSH20:
case Instruction::PUSH21:
case Instruction::PUSH22:
case Instruction::PUSH23:
case Instruction::PUSH24:
case Instruction::PUSH25:
case Instruction::PUSH26:
case Instruction::PUSH27:
case Instruction::PUSH28:
case Instruction::PUSH29:
case Instruction::PUSH30:
case Instruction::PUSH31:
case Instruction::PUSH32:
case Instruction::POP:
case Instruction::DUP1:
case Instruction::DUP2:
case Instruction::DUP3:
case Instruction::DUP4:
case Instruction::DUP5:
case Instruction::DUP6:
case Instruction::DUP7:
case Instruction::DUP8:
case Instruction::DUP9:
case Instruction::DUP10:
case Instruction::DUP11:
case Instruction::DUP12:
case Instruction::DUP13:
case Instruction::DUP14:
case Instruction::DUP15:
case Instruction::DUP16:
case Instruction::SWAP1:
case Instruction::SWAP2:
case Instruction::SWAP3:
case Instruction::SWAP4:
case Instruction::SWAP5:
case Instruction::SWAP6:
case Instruction::SWAP7:
case Instruction::SWAP8:
case Instruction::SWAP9:
case Instruction::SWAP10:
case Instruction::SWAP11:
case Instruction::SWAP12:
case Instruction::SWAP13:
case Instruction::SWAP14:
case Instruction::SWAP15:
case Instruction::SWAP16:
case Instruction::JUMP:
case Instruction::JUMPI:
case Instruction::PC:
case Instruction::MSIZE:
case Instruction::GAS:
case Instruction::JUMPDEST:
break;
default:
BOOST_THROW_EXCEPTION(BadInstruction());
}
newTempSize = (newTempSize + 31) / 32 * 32;

Loading…
Cancel
Save