Browse Source

Do not accept contract code with gas greater than 2^63. Keep gas counter in int64 type.

cl-refactor
Paweł Bylica 10 years ago
parent
commit
d1d68505da
  1. 7
      libevmjit-cpp/JitVM.cpp
  2. 1
      libevmjit/Arith256.cpp
  3. 2
      libevmjit/RuntimeData.h
  4. 16
      libevmjit/RuntimeManager.cpp

7
libevmjit-cpp/JitVM.cpp

@ -13,7 +13,9 @@ bytesConstRef JitVM::go(ExtVMFace& _ext, OnOpFunc const&, uint64_t)
{ {
using namespace jit; using namespace jit;
m_data.elems[RuntimeData::Gas] = eth2llvm(m_gas); if (m_gas > std::numeric_limits<decltype(m_data.gas)>::max())
BOOST_THROW_EXCEPTION(OutOfGas()); // Do not accept requests with gas > 2^63 (int64 max)
m_data.elems[RuntimeData::Address] = eth2llvm(fromAddress(_ext.myAddress)); m_data.elems[RuntimeData::Address] = eth2llvm(fromAddress(_ext.myAddress));
m_data.elems[RuntimeData::Caller] = eth2llvm(fromAddress(_ext.caller)); m_data.elems[RuntimeData::Caller] = eth2llvm(fromAddress(_ext.caller));
m_data.elems[RuntimeData::Origin] = eth2llvm(fromAddress(_ext.origin)); m_data.elems[RuntimeData::Origin] = eth2llvm(fromAddress(_ext.origin));
@ -28,6 +30,7 @@ bytesConstRef JitVM::go(ExtVMFace& _ext, OnOpFunc const&, uint64_t)
m_data.code = _ext.code.data(); m_data.code = _ext.code.data();
m_data.codeSize = _ext.code.size(); m_data.codeSize = _ext.code.size();
m_data.callDataSize = _ext.data.size(); m_data.callDataSize = _ext.data.size();
m_data.gas = static_cast<decltype(m_data.gas)>(m_gas);
auto env = reinterpret_cast<Env*>(&_ext); auto env = reinterpret_cast<Env*>(&_ext);
auto exitCode = m_engine.run(_ext.code, &m_data, env); auto exitCode = m_engine.run(_ext.code, &m_data, env);
@ -49,7 +52,7 @@ bytesConstRef JitVM::go(ExtVMFace& _ext, OnOpFunc const&, uint64_t)
break; break;
} }
m_gas = llvm2eth(m_data.elems[RuntimeData::Gas]); m_gas = m_data.gas; // TODO: Remove m_gas field
return {std::get<0>(m_engine.returnData), std::get<1>(m_engine.returnData)}; return {std::get<0>(m_engine.returnData), std::get<1>(m_engine.returnData)};
} }

1
libevmjit/Arith256.cpp

@ -65,7 +65,6 @@ llvm::Value* Arith256::mul(llvm::Value* _arg1, llvm::Value* _arg2)
llvm::Value* Arith256::div(llvm::Value* _arg1, llvm::Value* _arg2) llvm::Value* Arith256::div(llvm::Value* _arg1, llvm::Value* _arg2)
{ {
//return Endianness::toNative(m_builder, binaryOp(m_div, Endianness::toBE(m_builder, _arg1), Endianness::toBE(m_builder, _arg2))); //return Endianness::toNative(m_builder, binaryOp(m_div, Endianness::toBE(m_builder, _arg1), Endianness::toBE(m_builder, _arg2)));
return binaryOp(m_div, _arg1, _arg2); return binaryOp(m_div, _arg1, _arg2);
} }

2
libevmjit/RuntimeData.h

@ -14,7 +14,6 @@ struct RuntimeData
{ {
enum Index enum Index
{ {
Gas,
Address, Address,
Caller, Caller,
Origin, Origin,
@ -37,6 +36,7 @@ struct RuntimeData
byte const* code = nullptr; byte const* code = nullptr;
uint64_t codeSize = 0; uint64_t codeSize = 0;
uint64_t callDataSize = 0; uint64_t callDataSize = 0;
int64_t gas = 0;
}; };
/// VM Environment (ExtVM) opaque type /// VM Environment (ExtVM) opaque type

16
libevmjit/RuntimeManager.cpp

@ -26,7 +26,8 @@ llvm::StructType* RuntimeManager::getRuntimeDataType()
Type::BytePtr, // callData Type::BytePtr, // callData
Type::BytePtr, // code Type::BytePtr, // code
Type::Size, // codeSize Type::Size, // codeSize
Type::Size // callDataSize Type::Size, // callDataSize
Type::Size, // gas
}; };
type = llvm::StructType::create(elems, "RuntimeData"); type = llvm::StructType::create(elems, "RuntimeData");
} }
@ -58,7 +59,6 @@ llvm::Twine getName(RuntimeData::Index _index)
switch (_index) switch (_index)
{ {
default: return "data"; default: return "data";
case RuntimeData::Gas: return "gas";
case RuntimeData::Address: return "address"; case RuntimeData::Address: return "address";
case RuntimeData::Caller: return "caller"; case RuntimeData::Caller: return "caller";
case RuntimeData::Origin: return "origin"; case RuntimeData::Origin: return "origin";
@ -150,7 +150,6 @@ llvm::Value* RuntimeManager::get(Instruction _inst)
switch (_inst) switch (_inst)
{ {
default: assert(false); return nullptr; default: assert(false); return nullptr;
case Instruction::GAS: return get(RuntimeData::Gas);
case Instruction::ADDRESS: return get(RuntimeData::Address); case Instruction::ADDRESS: return get(RuntimeData::Address);
case Instruction::CALLER: return get(RuntimeData::Caller); case Instruction::CALLER: return get(RuntimeData::Caller);
case Instruction::ORIGIN: return get(RuntimeData::Origin); case Instruction::ORIGIN: return get(RuntimeData::Origin);
@ -200,14 +199,17 @@ llvm::Value* RuntimeManager::getJmpBuf()
llvm::Value* RuntimeManager::getGas() llvm::Value* RuntimeManager::getGas()
{ {
return get(RuntimeData::Gas); auto ptr = getBuilder().CreateStructGEP(getDataPtr(), 5);
auto value = getBuilder().CreateLoad(ptr, "gas");
assert(value->getType() == Type::Size);
return getBuilder().CreateZExt(value, Type::Word);
} }
void RuntimeManager::setGas(llvm::Value* _gas) void RuntimeManager::setGas(llvm::Value* _gas)
{ {
llvm::Value* idxList[] = {m_builder.getInt32(0), m_builder.getInt32(0), m_builder.getInt32(RuntimeData::Gas)}; auto ptr = getBuilder().CreateStructGEP(getDataPtr(), 5);
auto ptr = m_builder.CreateInBoundsGEP(getDataPtr(), idxList, "gasPtr"); auto newGas = getBuilder().CreateTrunc(_gas, Type::Size);
m_builder.CreateStore(_gas, ptr); getBuilder().CreateStore(newGas, ptr);
} }
} }

Loading…
Cancel
Save