mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Move gasEstimate into CompilerStack
This commit is contained in:
parent
bd48f181b5
commit
e6221108b6
@ -38,6 +38,7 @@
|
||||
#include <libsolidity/analysis/SyntaxChecker.h>
|
||||
#include <libsolidity/codegen/Compiler.h>
|
||||
#include <libsolidity/interface/InterfaceHandler.h>
|
||||
#include <libsolidity/interface/GasEstimator.h>
|
||||
#include <libsolidity/formal/Why3Translator.h>
|
||||
|
||||
#include <libevmasm/Exceptions.h>
|
||||
@ -841,3 +842,87 @@ string CompilerStack::computeSourceMapping(eth::AssemblyItems const& _items) con
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
Json::Value gasToJson(GasEstimator::GasConsumption const& _gas)
|
||||
{
|
||||
if (_gas.isInfinite || _gas.value > std::numeric_limits<Json::LargestUInt>::max())
|
||||
return Json::Value(Json::nullValue);
|
||||
else
|
||||
return Json::Value(Json::LargestUInt(_gas.value));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Json::Value CompilerStack::gasEstimates(string const& _contractName) const
|
||||
{
|
||||
if (!assemblyItems(_contractName) && !runtimeAssemblyItems(_contractName))
|
||||
return Json::Value();
|
||||
|
||||
using Gas = GasEstimator::GasConsumption;
|
||||
Json::Value output(Json::objectValue);
|
||||
|
||||
if (eth::AssemblyItems const* items = assemblyItems(_contractName))
|
||||
{
|
||||
Gas executionGas = GasEstimator::functionalEstimation(*items);
|
||||
u256 bytecodeSize(runtimeObject(_contractName).bytecode.size());
|
||||
Gas codeDepositGas = bytecodeSize * eth::GasCosts::createDataGas;
|
||||
|
||||
Json::Value creation(Json::objectValue);
|
||||
creation["codeDepositCost"] = gasToJson(codeDepositGas);
|
||||
creation["executionCost"] = gasToJson(executionGas);
|
||||
/// TODO: implement + overload to avoid the need of +=
|
||||
executionGas += codeDepositGas;
|
||||
creation["totalCost"] = gasToJson(executionGas);
|
||||
output["creation"] = creation;
|
||||
}
|
||||
|
||||
if (eth::AssemblyItems const* items = runtimeAssemblyItems(_contractName))
|
||||
{
|
||||
/// External functions
|
||||
ContractDefinition const& contract = contractDefinition(_contractName);
|
||||
Json::Value externalFunctions(Json::objectValue);
|
||||
for (auto it: contract.interfaceFunctions())
|
||||
{
|
||||
string sig = it.second->externalSignature();
|
||||
externalFunctions[sig] = gasToJson(GasEstimator::functionalEstimation(*items, sig));
|
||||
}
|
||||
|
||||
if (contract.fallbackFunction())
|
||||
/// This needs to be set to an invalid signature in order to trigger the fallback,
|
||||
/// without the shortcut (of CALLDATSIZE == 0), and therefore to receive the upper bound.
|
||||
/// An empty string ("") would work to trigger the shortcut only.
|
||||
externalFunctions[""] = gasToJson(GasEstimator::functionalEstimation(*items, "INVALID"));
|
||||
|
||||
if (!externalFunctions.empty())
|
||||
output["external"] = externalFunctions;
|
||||
|
||||
/// Internal functions
|
||||
Json::Value internalFunctions(Json::objectValue);
|
||||
for (auto const& it: contract.definedFunctions())
|
||||
{
|
||||
if (it->isPartOfExternalInterface() || it->isConstructor())
|
||||
continue;
|
||||
|
||||
size_t entry = functionEntryPoint(_contractName, *it);
|
||||
GasEstimator::GasConsumption gas = GasEstimator::GasConsumption::infinite();
|
||||
if (entry > 0)
|
||||
gas = GasEstimator::functionalEstimation(*items, entry, *it);
|
||||
|
||||
FunctionType type(*it);
|
||||
string sig = it->name() + "(";
|
||||
auto paramTypes = type.parameterTypes();
|
||||
for (auto it = paramTypes.begin(); it != paramTypes.end(); ++it)
|
||||
sig += (*it)->toString() + (it + 1 == paramTypes.end() ? "" : ",");
|
||||
sig += ")";
|
||||
internalFunctions[sig] = gasToJson(gas);
|
||||
}
|
||||
|
||||
if (!internalFunctions.empty())
|
||||
output["internal"] = internalFunctions;
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
@ -173,6 +173,9 @@ public:
|
||||
std::string const& onChainMetadata(std::string const& _contractName) const;
|
||||
void useMetadataLiteralSources(bool _metadataLiteralSources) { m_metadataLiteralSources = _metadataLiteralSources; }
|
||||
|
||||
/// @returns a JSON representing the estimated gas usage for contract creation, internal and external functions
|
||||
Json::Value gasEstimates(std::string const& _contractName) const;
|
||||
|
||||
/// @returns the previously used scanner, useful for counting lines during error reporting.
|
||||
Scanner const& scanner(std::string const& _sourceName = "") const;
|
||||
/// @returns the parsed source unit with the supplied name.
|
||||
|
Loading…
Reference in New Issue
Block a user