Changed the type of gas calculation to bigint instead of size_t

Since the gas calculation can involve multiplication by ``--optimize-runs``, it is possible that
`size_t` is not enough to represent the total gas.
This commit is contained in:
hrkrshnn 2021-04-19 13:08:19 +02:00
parent 94f9410abe
commit 011f8d3ff7
3 changed files with 19 additions and 19 deletions

View File

@ -58,7 +58,7 @@ public:
struct Representation
{
std::unique_ptr<Expression> expression;
size_t cost = size_t(-1);
bigint cost;
};
private:

View File

@ -37,23 +37,23 @@ using namespace solidity;
using namespace solidity::yul;
using namespace solidity::util;
size_t GasMeter::costs(Expression const& _expression) const
bigint GasMeter::costs(Expression const& _expression) const
{
return combineCosts(GasMeterVisitor::costs(_expression, m_dialect, m_isCreation));
}
size_t GasMeter::instructionCosts(evmasm::Instruction _instruction) const
bigint GasMeter::instructionCosts(evmasm::Instruction _instruction) const
{
return combineCosts(GasMeterVisitor::instructionCosts(_instruction, m_dialect, m_isCreation));
}
size_t GasMeter::combineCosts(std::pair<size_t, size_t> _costs) const
bigint GasMeter::combineCosts(std::pair<bigint, bigint> _costs) const
{
return _costs.first * m_runs + _costs.second;
}
pair<size_t, size_t> GasMeterVisitor::costs(
pair<bigint, bigint> GasMeterVisitor::costs(
Expression const& _expression,
EVMDialect const& _dialect,
bool _isCreation
@ -64,7 +64,7 @@ pair<size_t, size_t> GasMeterVisitor::costs(
return {gmv.m_runGas, gmv.m_dataGas};
}
pair<size_t, size_t> GasMeterVisitor::instructionCosts(
pair<bigint, bigint> GasMeterVisitor::instructionCosts(
evmasm::Instruction _instruction,
EVMDialect const& _dialect,
bool _isCreation
@ -92,11 +92,11 @@ void GasMeterVisitor::operator()(Literal const& _lit)
m_runGas += evmasm::GasMeter::runGas(evmasm::Instruction::PUSH1);
m_dataGas +=
singleByteDataGas() +
static_cast<size_t>(evmasm::GasMeter::dataGas(
evmasm::GasMeter::dataGas(
toCompactBigEndian(valueOfLiteral(_lit), 1),
m_isCreation,
m_dialect.evmVersion()
));
);
}
void GasMeterVisitor::operator()(Identifier const&)
@ -105,7 +105,7 @@ void GasMeterVisitor::operator()(Identifier const&)
m_dataGas += singleByteDataGas();
}
size_t GasMeterVisitor::singleByteDataGas() const
bigint GasMeterVisitor::singleByteDataGas() const
{
if (m_isCreation)
return evmasm::GasCosts::txDataNonZeroGas(m_dialect.evmVersion());

View File

@ -42,36 +42,36 @@ struct EVMDialect;
class GasMeter
{
public:
GasMeter(EVMDialect const& _dialect, bool _isCreation, size_t _runs):
GasMeter(EVMDialect const& _dialect, bool _isCreation, bigint _runs):
m_dialect(_dialect),
m_isCreation{_isCreation},
m_runs(_isCreation? 1 : _runs)
{}
/// @returns the full combined costs of deploying and evaluating the expression.
size_t costs(Expression const& _expression) const;
bigint costs(Expression const& _expression) const;
/// @returns the combined costs of deploying and running the instruction, not including
/// the costs for its arguments.
size_t instructionCosts(evmasm::Instruction _instruction) const;
bigint instructionCosts(evmasm::Instruction _instruction) const;
private:
size_t combineCosts(std::pair<size_t, size_t> _costs) const;
bigint combineCosts(std::pair<bigint, bigint> _costs) const;
EVMDialect const& m_dialect;
bool m_isCreation = false;
size_t m_runs;
bigint m_runs;
};
class GasMeterVisitor: public ASTWalker
{
public:
static std::pair<size_t, size_t> costs(
static std::pair<bigint, bigint> costs(
Expression const& _expression,
EVMDialect const& _dialect,
bool _isCreation
);
static std::pair<size_t, size_t> instructionCosts(
static std::pair<bigint, bigint> instructionCosts(
evmasm::Instruction _instruction,
EVMDialect const& _dialect,
bool _isCreation = false
@ -88,7 +88,7 @@ public:
void operator()(Identifier const& _identifier) override;
private:
size_t singleByteDataGas() const;
bigint singleByteDataGas() const;
/// Computes the cost of storing and executing the single instruction (excluding its arguments).
/// For EXP, it assumes that the exponent is at most 255.
/// Does not work particularly exact for anything apart from arithmetic.
@ -96,8 +96,8 @@ private:
EVMDialect const& m_dialect;
bool m_isCreation = false;
size_t m_runGas = 0;
size_t m_dataGas = 0;
bigint m_runGas = 0;
bigint m_dataGas = 0;
};
}