Browse Source

Gas counting changes: allow memory words counter not greater than gas max (int64 max)

cl-refactor
Paweł Bylica 10 years ago
parent
commit
c633e62102
  1. 1
      libevmjit-cpp/JitVM.cpp
  2. 11
      libevmjit/GasMeter.cpp
  3. 5
      libevmjit/Type.cpp
  4. 3
      libevmjit/Type.h

1
libevmjit-cpp/JitVM.cpp

@ -16,6 +16,7 @@ bytesConstRef JitVM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _step)
using namespace jit;
auto rejected = false;
// TODO: Rejecting transactions with gas limit > 2^63 can be used by attacker to take JIT out of scope
rejected |= m_gas > std::numeric_limits<decltype(m_data.gas)>::max(); // Do not accept requests with gas > 2^63 (int64 max)
rejected |= _ext.gasPrice > std::numeric_limits<decltype(m_data.gasPrice)>::max();
rejected |= _ext.currentBlock.number > std::numeric_limits<decltype(m_data.number)>::max();

11
libevmjit/GasMeter.cpp

@ -94,12 +94,13 @@ GasMeter::GasMeter(llvm::IRBuilder<>& _builder, RuntimeManager& _runtimeManager)
auto outOfGasBB = llvm::BasicBlock::Create(_builder.getContext(), "OutOfGas", m_gasCheckFunc);
auto updateBB = llvm::BasicBlock::Create(_builder.getContext(), "Update", m_gasCheckFunc);
m_builder.SetInsertPoint(checkBB);
auto arg = m_gasCheckFunc->arg_begin();
arg->setName("rt");
++arg;
arg->setName("cost");
auto cost = arg;
m_builder.SetInsertPoint(checkBB);
auto gas = m_runtimeManager.getGas();
auto isOutOfGas = m_builder.CreateICmpUGT(cost, gas, "isOutOfGas");
m_builder.CreateCondBr(isOutOfGas, outOfGasBB, updateBB);
@ -208,8 +209,14 @@ void GasMeter::commitCostBlock()
void GasMeter::countMemory(llvm::Value* _additionalMemoryInWords)
{
assert(_additionalMemoryInWords->getType() == Type::Word);
static_assert(c_memoryGas == 1, "Memory gas cost has changed. Update GasMeter.");
count(_additionalMemoryInWords);
auto gasMax256 = m_builder.CreateZExt(Constant::gasMax, Type::Word);
auto tooHigh = m_builder.CreateICmpUGT(_additionalMemoryInWords, gasMax256, "tooHigh");
auto additionalMemoryInWords64 = m_builder.CreateTrunc(_additionalMemoryInWords, Type::Gas);
additionalMemoryInWords64 = m_builder.CreateSelect(tooHigh, Constant::gasMax, additionalMemoryInWords64, "additionalMemoryInWords");
auto additionalMemoryInWords256 = m_builder.CreateZExt(additionalMemoryInWords64, Type::Word);
count(additionalMemoryInWords256);
}
void GasMeter::countCopy(llvm::Value* _copyWords)

5
libevmjit/Type.cpp

@ -17,6 +17,7 @@ llvm::PointerType* Type::WordPtr;
llvm::IntegerType* Type::lowPrecision;
llvm::IntegerType* Type::Bool;
llvm::IntegerType* Type::Size;
llvm::IntegerType* Type::Gas;
llvm::IntegerType* Type::Byte;
llvm::PointerType* Type::BytePtr;
llvm::Type* Type::Void;
@ -24,6 +25,7 @@ llvm::IntegerType* Type::MainReturn;
llvm::PointerType* Type::EnvPtr;
llvm::PointerType* Type::RuntimeDataPtr;
llvm::PointerType* Type::RuntimePtr;
llvm::ConstantInt* Constant::gasMax;
void Type::init(llvm::LLVMContext& _context)
{
@ -35,6 +37,7 @@ void Type::init(llvm::LLVMContext& _context)
// TODO: Size should be architecture-dependent
Bool = llvm::Type::getInt1Ty(_context);
Size = llvm::Type::getInt64Ty(_context);
Gas = Size;
Byte = llvm::Type::getInt8Ty(_context);
BytePtr = Byte->getPointerTo();
Void = llvm::Type::getVoidTy(_context);
@ -43,6 +46,8 @@ void Type::init(llvm::LLVMContext& _context)
EnvPtr = llvm::StructType::create(_context, "Env")->getPointerTo();
RuntimeDataPtr = RuntimeManager::getRuntimeDataType()->getPointerTo();
RuntimePtr = RuntimeManager::getRuntimeType()->getPointerTo();
Constant::gasMax = llvm::ConstantInt::getSigned(Type::Gas, std::numeric_limits<int64_t>::max());
}
}

3
libevmjit/Type.h

@ -23,6 +23,7 @@ struct Type
static llvm::IntegerType* Bool;
static llvm::IntegerType* Size;
static llvm::IntegerType* Gas;
static llvm::IntegerType* Byte;
static llvm::PointerType* BytePtr;
@ -41,6 +42,8 @@ struct Type
struct Constant
{
static llvm::ConstantInt* gasMax;
/// Returns word-size constant
static llvm::ConstantInt* get(int64_t _n);
static llvm::ConstantInt* get(llvm::APInt const& _n);

Loading…
Cancel
Save