Skip to content

Commit

Permalink
Make solidity independent from ethcore.
Browse files Browse the repository at this point in the history
  • Loading branch information
chriseth committed Apr 6, 2016
1 parent 193b1c9 commit f227050
Show file tree
Hide file tree
Showing 15 changed files with 98 additions and 144 deletions.
2 changes: 1 addition & 1 deletion libevmasm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ file(GLOB HEADERS "*.h")

include_directories(BEFORE ..)
add_library(${EXECUTABLE} ${SRC_LIST} ${HEADERS})
eth_use(${EXECUTABLE} REQUIRED Dev::devcore Eth::ethcore)
eth_use(${EXECUTABLE} REQUIRED Dev::devcore)

install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib )
install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} )
Expand Down
19 changes: 9 additions & 10 deletions libevmasm/ConstantOptimiser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,12 @@ unsigned ConstantOptimisationMethod::optimiseConstants(

bigint ConstantOptimisationMethod::simpleRunGas(AssemblyItems const& _items)
{
EVMSchedule schedule; // TODO: make relevant to context.
bigint gas = 0;
for (AssemblyItem const& item: _items)
if (item.type() == Push)
gas += GasMeter::runGas(Instruction::PUSH1, schedule);
gas += GasMeter::runGas(Instruction::PUSH1);
else if (item.type() == Operation)
gas += GasMeter::runGas(item.instruction(), schedule);
gas += GasMeter::runGas(item.instruction());
return gas;
}

Expand All @@ -85,11 +84,11 @@ bigint ConstantOptimisationMethod::dataGas(bytes const& _data) const
{
bigint gas;
for (auto b: _data)
gas += b ? m_schedule.txDataNonZeroGas : m_schedule.txDataZeroGas;
gas += b ? GasCosts::txDataNonZeroGas : GasCosts::txDataZeroGas;
return gas;
}
else
return m_schedule.createDataGas * dataSize();
return GasCosts::createDataGas * dataSize();
}

size_t ConstantOptimisationMethod::bytesRequired(AssemblyItems const& _items)
Expand Down Expand Up @@ -121,7 +120,7 @@ bigint LiteralMethod::gasNeeded()
return combineGas(
simpleRunGas({Instruction::PUSH1}),
// PUSHX plus data
(m_params.isCreation ? m_schedule.txDataNonZeroGas : m_schedule.createDataGas) + dataGas(),
(m_params.isCreation ? GasCosts::txDataNonZeroGas : GasCosts::createDataGas) + dataGas(),
0
);
}
Expand All @@ -148,9 +147,9 @@ bigint CodeCopyMethod::gasNeeded()
{
return combineGas(
// Run gas: we ignore memory increase costs
simpleRunGas(m_copyRoutine) + m_schedule.copyGas,
simpleRunGas(m_copyRoutine) + GasCosts::copyGas,
// Data gas for copy routines: Some bytes are zero, but we ignore them.
bytesRequired(m_copyRoutine) * (m_params.isCreation ? m_schedule.txDataNonZeroGas : m_schedule.createDataGas),
bytesRequired(m_copyRoutine) * (m_params.isCreation ? GasCosts::txDataNonZeroGas : GasCosts::createDataGas),
// Data gas for data itself
dataGas(toBigEndian(m_value))
);
Expand Down Expand Up @@ -217,9 +216,9 @@ bigint ComputeMethod::gasNeeded(AssemblyItems const& _routine)
{
size_t numExps = count(_routine.begin(), _routine.end(), Instruction::EXP);
return combineGas(
simpleRunGas(_routine) + numExps * (m_schedule.expGas + m_schedule.expByteGas),
simpleRunGas(_routine) + numExps * (GasCosts::expGas + GasCosts::expByteGas),
// Data gas for routine: Some bytes are zero, but we ignore them.
bytesRequired(_routine) * (m_params.isCreation ? m_schedule.txDataNonZeroGas : m_schedule.createDataGas),
bytesRequired(_routine) * (m_params.isCreation ? GasCosts::txDataNonZeroGas : GasCosts::createDataGas),
0
);
}
8 changes: 0 additions & 8 deletions libevmasm/ConstantOptimiser.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
#include <vector>
#include <libdevcore/CommonData.h>
#include <libdevcore/CommonIO.h>
#include <libethcore/ChainOperationParams.h>

namespace dev
{
Expand All @@ -35,8 +34,6 @@ class AssemblyItem;
using AssemblyItems = std::vector<AssemblyItem>;
class Assembly;

// TODO: FIXME: HOMESTEAD: XXX: @chfast populate m_schedule from an ExtVMFace instance via ExtVMFace::evmSchedule.

/**
* Abstract base class for one way to change how constants are represented in the code.
*/
Expand Down Expand Up @@ -91,7 +88,6 @@ class ConstantOptimisationMethod

Params m_params;
u256 const& m_value;
EVMSchedule m_schedule;
};

/**
Expand All @@ -105,8 +101,6 @@ class LiteralMethod: public ConstantOptimisationMethod
ConstantOptimisationMethod(_params, _value) {}
virtual bigint gasNeeded() override;
virtual void execute(Assembly&, AssemblyItems&) override {}

EVMSchedule m_schedule;
};

/**
Expand All @@ -121,7 +115,6 @@ class CodeCopyMethod: public ConstantOptimisationMethod

protected:
AssemblyItems m_copyRoutine;
EVMSchedule m_schedule;
};

/**
Expand All @@ -148,7 +141,6 @@ class ComputeMethod: public ConstantOptimisationMethod
bigint gasNeeded(AssemblyItems const& _routine);

AssemblyItems m_routine;
EVMSchedule m_schedule;
};

}
Expand Down
53 changes: 32 additions & 21 deletions libevmasm/GasMeter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,13 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item)
m_state->storageContent().count(slot) &&
classes.knownNonZero(m_state->storageContent().at(slot))
))
gas += m_schedule.sstoreResetGas; //@todo take refunds into account
gas += GasCosts::sstoreResetGas; //@todo take refunds into account
else
gas += m_schedule.sstoreSetGas;
gas += GasCosts::sstoreSetGas;
break;
}
case Instruction::SLOAD:
gas += m_schedule.sloadGas;
gas += GasCosts::sloadGas;
break;
case Instruction::RETURN:
gas += memoryGas(0, -1);
Expand All @@ -96,18 +96,18 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item)
}));
break;
case Instruction::SHA3:
gas = m_schedule.sha3Gas;
gas += wordGas(m_schedule.sha3WordGas, m_state->relativeStackElement(-1));
gas = GasCosts::sha3Gas;
gas += wordGas(GasCosts::sha3WordGas, m_state->relativeStackElement(-1));
gas += memoryGas(0, -1);
break;
case Instruction::CALLDATACOPY:
case Instruction::CODECOPY:
gas += memoryGas(0, -2);
gas += wordGas(m_schedule.copyGas, m_state->relativeStackElement(-2));
gas += wordGas(GasCosts::copyGas, m_state->relativeStackElement(-2));
break;
case Instruction::EXTCODECOPY:
gas += memoryGas(-1, -3);
gas += wordGas(m_schedule.copyGas, m_state->relativeStackElement(-3));
gas += wordGas(GasCosts::copyGas, m_state->relativeStackElement(-3));
break;
case Instruction::LOG0:
case Instruction::LOG1:
Expand All @@ -116,10 +116,10 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item)
case Instruction::LOG4:
{
unsigned n = unsigned(_item.instruction()) - unsigned(Instruction::LOG0);
gas = m_schedule.logGas + m_schedule.logTopicGas * n;
gas = GasCosts::logGas + GasCosts::logTopicGas * n;
gas += memoryGas(0, -1);
if (u256 const* value = classes.knownConstant(m_state->relativeStackElement(-1)))
gas += m_schedule.logDataGas * (*value);
gas += GasCosts::logDataGas * (*value);
else
gas = GasConsumption::infinite();
break;
Expand All @@ -128,30 +128,30 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item)
case Instruction::CALLCODE:
case Instruction::DELEGATECALL:
{
gas = m_schedule.callGas;
gas = GasCosts::callGas;
if (u256 const* value = classes.knownConstant(m_state->relativeStackElement(0)))
gas += (*value);
else
gas = GasConsumption::infinite();
if (_item.instruction() == Instruction::CALL)
gas += m_schedule.callNewAccountGas; // We very rarely know whether the address exists.
gas += GasCosts::callNewAccountGas; // We very rarely know whether the address exists.
int valueSize = _item.instruction() == Instruction::DELEGATECALL ? 0 : 1;
if (!classes.knownZero(m_state->relativeStackElement(-1 - valueSize)))
gas += m_schedule.callValueTransferGas;
gas += GasCosts::callValueTransferGas;
gas += memoryGas(-2 - valueSize, -3 - valueSize);
gas += memoryGas(-4 - valueSize, -5 - valueSize);
break;
}
case Instruction::CREATE:
gas = m_schedule.createGas;
gas = GasCosts::createGas;
gas += memoryGas(-1, -2);
break;
case Instruction::EXP:
gas = m_schedule.expGas;
gas = GasCosts::expGas;
if (u256 const* value = classes.knownConstant(m_state->relativeStackElement(-1)))
gas += m_schedule.expByteGas * (32 - (h256(*value).firstBitSet() / 8));
gas += GasCosts::expByteGas * (32 - (h256(*value).firstBitSet() / 8));
else
gas += m_schedule.expByteGas * 32;
gas += GasCosts::expByteGas * 32;
break;
default:
break;
Expand Down Expand Up @@ -187,7 +187,7 @@ GasMeter::GasConsumption GasMeter::memoryGas(ExpressionClasses::Id _position)
auto memGas = [=](u256 const& pos) -> u256
{
u256 size = (pos + 31) / 32;
return m_schedule.memoryGas * size + size * size / m_schedule.quadCoeffDiv;
return GasCosts::memoryGas * size + size * size / GasCosts::quadCoeffDiv;
};
return memGas(*value) - memGas(previous);
}
Expand All @@ -204,14 +204,25 @@ GasMeter::GasConsumption GasMeter::memoryGas(int _stackPosOffset, int _stackPosS
}));
}

u256 GasMeter::runGas(Instruction _instruction, EVMSchedule const& _es)
unsigned GasMeter::runGas(Instruction _instruction)
{
if (_instruction == Instruction::JUMPDEST)
return 1;

int tier = instructionInfo(_instruction).gasPriceTier;
assertThrow(tier != InvalidTier, OptimizerException, "Invalid gas tier.");
return _es.tierStepGas[tier];
switch (instructionInfo(_instruction).gasPriceTier)
{
case 0: return GasCosts::tier0Gas;
case 1: return GasCosts::tier1Gas;
case 2: return GasCosts::tier2Gas;
case 3: return GasCosts::tier3Gas;
case 4: return GasCosts::tier4Gas;
case 5: return GasCosts::tier5Gas;
case 6: return GasCosts::tier6Gas;
case 7: return GasCosts::tier7Gas;
default: break;
}
assertThrow(false, OptimizerException, "Invalid gas tier.");
return 0;
}


48 changes: 41 additions & 7 deletions libevmasm/GasMeter.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
#include <tuple>
#include <libevmasm/ExpressionClasses.h>
#include <libevmasm/AssemblyItem.h>
#include <libethcore/ChainOperationParams.h>

namespace dev
{
Expand All @@ -34,7 +33,44 @@ namespace eth

class KnownState;

// TODO: FIXME: HOMESTEAD: XXX: @chfast populate m_schedule from an ExtVMFace instance via ExtVMFace::evmSchedule.
namespace GasCosts
{
static unsigned const stackLimit = 1024;
static unsigned const tier0Gas = 0;
static unsigned const tier1Gas = 2;
static unsigned const tier2Gas = 3;
static unsigned const tier3Gas = 5;
static unsigned const tier4Gas = 8;
static unsigned const tier5Gas = 10;
static unsigned const tier6Gas = 20;
static unsigned const tier7Gas = 0;
static unsigned const expGas = 10;
static unsigned const expByteGas = 10;
static unsigned const sha3Gas = 30;
static unsigned const sha3WordGas = 6;
static unsigned const sloadGas = 50;
static unsigned const sstoreSetGas = 20000;
static unsigned const sstoreResetGas = 5000;
static unsigned const sstoreRefundGas = 15000;
static unsigned const jumpdestGas = 1;
static unsigned const logGas = 375;
static unsigned const logDataGas = 8;
static unsigned const logTopicGas = 375;
static unsigned const createGas = 32000;
static unsigned const callGas = 40;
static unsigned const callStipend = 2300;
static unsigned const callValueTransferGas = 9000;
static unsigned const callNewAccountGas = 25000;
static unsigned const suicideRefundGas = 24000;
static unsigned const memoryGas = 3;
static unsigned const quadCoeffDiv = 512;
static unsigned const createDataGas = 200;
static unsigned const txGas = 21000;
static unsigned const txCreateGas = 53000;
static unsigned const txDataZeroGas = 4;
static unsigned const txDataNonZeroGas = 68;
static unsigned const copyGas = 3;
}

/**
* Class that helps computing the maximum gas consumption for instructions.
Expand All @@ -47,7 +83,8 @@ class GasMeter
public:
struct GasConsumption
{
GasConsumption(u256 _value = 0, bool _infinite = false): value(_value), isInfinite(_infinite) {}
GasConsumption(unsigned _value = 0, bool _infinite = false): value(_value), isInfinite(_infinite) {}
GasConsumption(u256 _value, bool _infinite = false): value(_value), isInfinite(_infinite) {}
static GasConsumption infinite() { return GasConsumption(0, true); }

GasConsumption& operator+=(GasConsumption const& _other);
Expand All @@ -69,8 +106,7 @@ class GasMeter

u256 const& largestMemoryAccess() const { return m_largestMemoryAccess; }

u256 runGas(Instruction _instruction) const { return runGas(_instruction, m_schedule); }
static u256 runGas(Instruction _instruction, EVMSchedule const& _es);
static unsigned runGas(Instruction _instruction);

private:
/// @returns _multiplier * (_value + 31) / 32, if _value is a known constant and infinite otherwise.
Expand All @@ -85,8 +121,6 @@ class GasMeter
std::shared_ptr<KnownState> m_state;
/// Largest point where memory was accessed since the creation of this object.
u256 m_largestMemoryAccess;

EVMSchedule m_schedule;
};

inline std::ostream& operator<<(std::ostream& _str, GasMeter::GasConsumption const& _consumption)
Expand Down
38 changes: 0 additions & 38 deletions libevmasm/Version.cpp

This file was deleted.

Loading

0 comments on commit f227050

Please sign in to comment.