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; bigint gas = 0;
for (AssemblyItem const& item: _items) for (AssemblyItem const& item: _items)
if (item.type() == Push) if (item.type() == Push)
{ gas += GasMeter::pushGas(item.data(), _evmVersion);
auto const instruction = (item.data() == u256(0) && _evmVersion.hasPush0()) ? Instruction::PUSH0 : Instruction::PUSH1;
gas += GasMeter::runGas(instruction, _evmVersion);
}
else if (item.type() == Operation) else if (item.type() == Operation)
{ {
if (item.instruction() == Instruction::EXP) if (item.instruction() == Instruction::EXP)

View File

@ -277,6 +277,14 @@ unsigned GasMeter::runGas(Instruction _instruction, langutil::EVMVersion _evmVer
return 0; 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) u256 GasMeter::dataGas(bytes const& _data, bool _inCreation, langutil::EVMVersion _evmVersion)
{ {
bigint gas = 0; bigint gas = 0;

View File

@ -223,6 +223,9 @@ public:
/// change with EVM versions) /// change with EVM versions)
static unsigned runGas(Instruction _instruction, langutil::EVMVersion _evmVersion); 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. /// @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 /// 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. /// 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) void GasMeterVisitor::operator()(Literal const& _lit)
{ {
m_runGas += evmasm::GasMeter::runGas(evmasm::Instruction::PUSH1, m_dialect.evmVersion()); m_runGas += evmasm::GasMeter::pushGas(valueOfLiteral(_lit), m_dialect.evmVersion());
m_dataGas +=
singleByteDataGas() + if (!m_dialect.evmVersion().hasPush0() || valueOfLiteral(_lit) != u256(0))
evmasm::GasMeter::dataGas( m_dataGas +=
toCompactBigEndian(valueOfLiteral(_lit), 1), singleByteDataGas() +
m_isCreation, evmasm::GasMeter::dataGas(
m_dialect.evmVersion() toCompactBigEndian(valueOfLiteral(_lit), 1),
); m_isCreation,
m_dialect.evmVersion()
);
} }
void GasMeterVisitor::operator()(Identifier const&) void GasMeterVisitor::operator()(Identifier const&)
@ -121,5 +123,7 @@ void GasMeterVisitor::instructionCostsInternal(evmasm::Instruction _instruction)
m_runGas += evmasm::GasCosts::keccak256Gas + evmasm::GasCosts::keccak256WordGas; m_runGas += evmasm::GasCosts::keccak256Gas + evmasm::GasCosts::keccak256WordGas;
else else
m_runGas += evmasm::GasMeter::runGas(_instruction, m_dialect.evmVersion()); 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))); 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 // Strictly speaking the cost of the PUSH0 depends on the targeted EVM version, but the difference
// will not matter here. // will not matter here.
opGas += evmasm::GasMeter::runGas(evmasm::pushInstruction(0), langutil::EVMVersion());; opGas += evmasm::GasMeter::pushGas(u256(0), langutil::EVMVersion());
} }
} }
}; };