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 struct Representation
{ {
std::unique_ptr<Expression> expression; std::unique_ptr<Expression> expression;
size_t cost = size_t(-1); bigint cost;
}; };
private: private:

View File

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

View File

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