Added GasMeter::gasPush

This commit is contained in:
Matheus Aguiar 2023-07-01 18:23:08 -03:00
parent 60eaa25ec8
commit 43821d7fd1
5 changed files with 26 additions and 14 deletions

View File

@ -83,10 +83,7 @@ bigint ConstantOptimisationMethod::simpleRunGas(AssemblyItems const& _items, lan
bigint gas = 0;
for (AssemblyItem const& item: _items)
if (item.type() == Push)
{
auto const instruction = (item.data() == u256(0) && _evmVersion.hasPush0()) ? Instruction::PUSH0 : Instruction::PUSH1;
gas += GasMeter::runGas(instruction, _evmVersion);
}
gas += GasMeter::pushGas(item.data(), _evmVersion);
else if (item.type() == Operation)
{
if (item.instruction() == Instruction::EXP)

View File

@ -277,6 +277,14 @@ unsigned GasMeter::runGas(Instruction _instruction, langutil::EVMVersion _evmVer
return 0;
}
unsigned GasMeter::pushGas(u256 _value, langutil::EVMVersion _evmVersion)
{
return runGas(
(_evmVersion.hasPush0() && _value == u256(0)) ? Instruction::PUSH0 : Instruction::PUSH1,
_evmVersion
);
}
u256 GasMeter::dataGas(bytes const& _data, bool _inCreation, langutil::EVMVersion _evmVersion)
{
bigint gas = 0;

View File

@ -223,6 +223,9 @@ public:
/// change with EVM versions)
static unsigned runGas(Instruction _instruction, langutil::EVMVersion _evmVersion);
/// @returns gas costs for push instructions (may change depending on EVM version)
static unsigned pushGas(u256 _value, langutil::EVMVersion _evmVersion);
/// @returns the gas cost of the supplied data, depending whether it is in creation code, or not.
/// In case of @a _inCreation, the data is only sent as a transaction and is not stored, whereas
/// otherwise code will be stored and have to pay "createDataGas" cost.

View File

@ -88,14 +88,16 @@ void GasMeterVisitor::operator()(FunctionCall const& _funCall)
void GasMeterVisitor::operator()(Literal const& _lit)
{
m_runGas += evmasm::GasMeter::runGas(evmasm::Instruction::PUSH1, m_dialect.evmVersion());
m_dataGas +=
singleByteDataGas() +
evmasm::GasMeter::dataGas(
toCompactBigEndian(valueOfLiteral(_lit), 1),
m_isCreation,
m_dialect.evmVersion()
);
m_runGas += evmasm::GasMeter::pushGas(valueOfLiteral(_lit), m_dialect.evmVersion());
if (!m_dialect.evmVersion().hasPush0() || valueOfLiteral(_lit) != u256(0))
m_dataGas +=
singleByteDataGas() +
evmasm::GasMeter::dataGas(
toCompactBigEndian(valueOfLiteral(_lit), 1),
m_isCreation,
m_dialect.evmVersion()
);
}
void GasMeterVisitor::operator()(Identifier const&)
@ -121,5 +123,7 @@ void GasMeterVisitor::instructionCostsInternal(evmasm::Instruction _instruction)
m_runGas += evmasm::GasCosts::keccak256Gas + evmasm::GasCosts::keccak256WordGas;
else
m_runGas += evmasm::GasMeter::runGas(_instruction, m_dialect.evmVersion());
m_dataGas += singleByteDataGas();
if (_instruction != evmasm::Instruction::PUSH0)
m_dataGas += singleByteDataGas();
}

View File

@ -772,7 +772,7 @@ void StackLayoutGenerator::fillInJunk(CFG::BasicBlock const& _block, CFG::Functi
yulAssert(util::contains(m_currentFunctionInfo->returnVariables, get<VariableSlot>(_slot)));
// Strictly speaking the cost of the PUSH0 depends on the targeted EVM version, but the difference
// will not matter here.
opGas += evmasm::GasMeter::runGas(evmasm::pushInstruction(0), langutil::EVMVersion());;
opGas += evmasm::GasMeter::pushGas(u256(0), langutil::EVMVersion());
}
}
};