Browse Source

Update gas counting for SSTORE, no refunding yet [#81575908]

cl-refactor
Paweł Bylica 10 years ago
parent
commit
33f1253bbe
  1. 19
      libevmjit/GasMeter.cpp
  2. 2
      libevmjit/Type.h

19
libevmjit/GasMeter.cpp

@ -28,11 +28,9 @@ uint64_t getStepCost(Instruction inst) // TODO: Add this function to FeeSructure
{ {
case Instruction::STOP: case Instruction::STOP:
case Instruction::SUICIDE: case Instruction::SUICIDE:
case Instruction::SSTORE: // Handle cost of SSTORE separately in GasMeter::countSStore()
return 0; return 0;
case Instruction::SSTORE:
return static_cast<uint64_t>(c_sstoreResetGas); // FIXME: Check store gas
case Instruction::SLOAD: case Instruction::SLOAD:
return static_cast<uint64_t>(c_sloadGas); return static_cast<uint64_t>(c_sloadGas);
@ -118,7 +116,6 @@ void GasMeter::count(Instruction _inst)
m_checkCall = m_builder.CreateCall(m_gasCheckFunc, llvm::UndefValue::get(Type::i256)); m_checkCall = m_builder.CreateCall(m_gasCheckFunc, llvm::UndefValue::get(Type::i256));
} }
if (_inst != Instruction::SSTORE) // Handle cost of SSTORE separately in countSStore()
m_blockCost += getStepCost(_inst); m_blockCost += getStepCost(_inst);
if (isCostBlockEnd(_inst)) if (isCostBlockEnd(_inst))
@ -129,20 +126,18 @@ void GasMeter::countSStore(Ext& _ext, llvm::Value* _index, llvm::Value* _newValu
{ {
assert(!m_checkCall); // Everything should've been commited before assert(!m_checkCall); // Everything should've been commited before
static const auto sstoreCost = static_cast<uint64_t>(c_sstoreResetGas); // FIXME: Check store gas static const auto updateCost = static_cast<uint64_t>(c_sstoreResetGas); // TODO: Discuss naming (DB names look better)
static const auto insertCost = static_cast<uint64_t>(c_sstoreSetGas);
// [ADD] if oldValue == 0 and newValue != 0 => 2*cost
// [DEL] if oldValue != 0 and newValue == 0 => 0
auto oldValue = _ext.store(_index); auto oldValue = _ext.store(_index);
auto oldValueIsZero = m_builder.CreateICmpEQ(oldValue, Constant::get(0), "oldValueIsZero"); auto oldValueIsZero = m_builder.CreateICmpEQ(oldValue, Constant::get(0), "oldValueIsZero");
auto newValueIsZero = m_builder.CreateICmpEQ(_newValue, Constant::get(0), "newValueIsZero"); auto newValueIsZero = m_builder.CreateICmpEQ(_newValue, Constant::get(0), "newValueIsZero");
auto oldValueIsntZero = m_builder.CreateICmpNE(oldValue, Constant::get(0), "oldValueIsntZero"); auto oldValueIsntZero = m_builder.CreateICmpNE(oldValue, Constant::get(0), "oldValueIsntZero");
auto newValueIsntZero = m_builder.CreateICmpNE(_newValue, Constant::get(0), "newValueIsntZero"); auto newValueIsntZero = m_builder.CreateICmpNE(_newValue, Constant::get(0), "newValueIsntZero");
auto isAdd = m_builder.CreateAnd(oldValueIsZero, newValueIsntZero, "isAdd"); auto isInsert = m_builder.CreateAnd(oldValueIsZero, newValueIsntZero, "isInsert");
auto isDel = m_builder.CreateAnd(oldValueIsntZero, newValueIsZero, "isDel"); auto isDelete = m_builder.CreateAnd(oldValueIsntZero, newValueIsZero, "isDelete");
auto cost = m_builder.CreateSelect(isAdd, Constant::get(2 * sstoreCost), Constant::get(sstoreCost), "cost"); auto cost = m_builder.CreateSelect(isInsert, Constant::get(insertCost), Constant::get(updateCost), "cost");
cost = m_builder.CreateSelect(isDel, Constant::get(0), cost, "cost"); cost = m_builder.CreateSelect(isDelete, Constant::get(0), cost, "cost");
createCall(m_gasCheckFunc, cost); createCall(m_gasCheckFunc, cost);
} }

2
libevmjit/Type.h

@ -50,7 +50,7 @@ enum class ReturnCode
struct Constant struct Constant
{ {
/// Returns word-size constant /// Returns word-size constant
static llvm::ConstantInt* get(uint64_t _n); static llvm::ConstantInt* get(uint64_t _n); // TODO: add overload with u256
static llvm::ConstantInt* get(ReturnCode _returnCode); static llvm::ConstantInt* get(ReturnCode _returnCode);
}; };

Loading…
Cancel
Save