Browse Source

Added fallback function to gas estimation and fixed mix gas estimation.

Fixes #2156
cl-refactor
chriseth 10 years ago
parent
commit
2b4ddf80ab
  1. 54
      mix/CodeModel.cpp
  2. 5
      solc/CommandLineInterface.cpp
  3. 2
      solc/jsonCompiler.cpp

54
mix/CodeModel.cpp

@ -374,29 +374,55 @@ void CodeModel::gasEstimation(solidity::CompilerStack const& _cs)
dev::solidity::SourceUnit const& sourceUnit = _cs.getAST(*contractDefinition.getLocation().sourceName); dev::solidity::SourceUnit const& sourceUnit = _cs.getAST(*contractDefinition.getLocation().sourceName);
AssemblyItems const* items = _cs.getRuntimeAssemblyItems(n); AssemblyItems const* items = _cs.getRuntimeAssemblyItems(n);
std::map<ASTNode const*, GasMeter::GasConsumption> gasCosts = GasEstimator::breakToStatementLevel(GasEstimator::structuralEstimation(*items, std::vector<ASTNode const*>({&sourceUnit})), {&sourceUnit}); std::map<ASTNode const*, GasMeter::GasConsumption> gasCosts = GasEstimator::breakToStatementLevel(GasEstimator::structuralEstimation(*items, std::vector<ASTNode const*>({&sourceUnit})), {&sourceUnit});
auto gasToString = [](GasMeter::GasConsumption const& _gas)
{
if (_gas.isInfinite)
return QString("0");
else
return QString::fromStdString(toString(_gas.value));
};
// Structural gas costs (per opcode)
for (auto gasItem = gasCosts.begin(); gasItem != gasCosts.end(); ++gasItem) for (auto gasItem = gasCosts.begin(); gasItem != gasCosts.end(); ++gasItem)
{ {
SourceLocation const& location = gasItem->first->getLocation(); SourceLocation const& location = gasItem->first->getLocation();
GasMeter::GasConsumption cost = gasItem->second; GasMeter::GasConsumption cost = gasItem->second;
std::stringstream v; m_gasCostsMaps->push(sourceName, location.start, location.end, gasToString(cost), cost.isInfinite, GasMap::type::Statement);
v << cost.value;
m_gasCostsMaps->push(sourceName, location.start, location.end, QString::fromStdString(v.str()), cost.isInfinite, GasMap::type::Statement);
} }
if (contractDefinition.getConstructor() != nullptr) eth::AssemblyItems const& runtimeAssembly = *_cs.getRuntimeAssemblyItems(n);
// Functional gas costs (per function, but also for accessors)
for (auto it: contractDefinition.getInterfaceFunctions())
{ {
GasMeter::GasConsumption cost = GasEstimator::functionalEstimation(*_cs.getRuntimeAssemblyItems(n), contractDefinition.getConstructor()->externalSignature()); if (!it.second->hasDeclaration())
std::stringstream v; continue;
v << cost.value; SourceLocation loc = it.second->getDeclaration().getLocation();
m_gasCostsMaps->push(sourceName, contractDefinition.getConstructor()->getLocation().start, contractDefinition.getConstructor()->getLocation().end, QString::fromStdString(v.str()), cost.isInfinite, GasMap::type::Constructor); GasMeter::GasConsumption cost = GasEstimator::functionalEstimation(runtimeAssembly, it.second->externalSignature());
m_gasCostsMaps->push(sourceName, loc.start, loc.end, gasToString(cost), cost.isInfinite, GasMap::type::Function);
} }
if (auto const* fallback = contractDefinition.getFallbackFunction())
for (auto func: contractDefinition.getDefinedFunctions()) {
SourceLocation loc = fallback->getLocation();
GasMeter::GasConsumption cost = GasEstimator::functionalEstimation(runtimeAssembly, "INVALID");
m_gasCostsMaps->push(sourceName, loc.start, loc.end, gasToString(cost), cost.isInfinite, GasMap::type::Function);
}
for (auto const& it: contractDefinition.getDefinedFunctions())
{
if (it->isPartOfExternalInterface() || it->isConstructor())
continue;
SourceLocation loc = it->getLocation();
size_t entry = _cs.getFunctionEntryPoint(n, *it);
GasEstimator::GasConsumption cost = GasEstimator::GasConsumption::infinite();
if (entry > 0)
cost = GasEstimator::functionalEstimation(runtimeAssembly, entry, *it);
m_gasCostsMaps->push(sourceName, loc.start, loc.end, gasToString(cost), cost.isInfinite, GasMap::type::Function);
}
if (auto const* constructor = contractDefinition.getConstructor())
{ {
GasMeter::GasConsumption cost = GasEstimator::functionalEstimation(*_cs.getRuntimeAssemblyItems(n), func->externalSignature()); SourceLocation loc = constructor->getLocation();
std::stringstream v; GasMeter::GasConsumption cost = GasEstimator::functionalEstimation(*_cs.getAssemblyItems(n));
v << cost.value; m_gasCostsMaps->push(sourceName, loc.start, loc.end, gasToString(cost), cost.isInfinite, GasMap::type::Constructor);
m_gasCostsMaps->push(sourceName, func->getLocation().start, func->getLocation().end, QString::fromStdString(v.str()), cost.isInfinite, GasMap::type::Function);
} }
} }
} }

5
solc/CommandLineInterface.cpp

@ -273,6 +273,11 @@ void CommandLineInterface::handleGasEstimation(string const& _contract)
GasEstimator::GasConsumption gas = GasEstimator::functionalEstimation(*items, sig); GasEstimator::GasConsumption gas = GasEstimator::functionalEstimation(*items, sig);
cout << " " << sig << ":\t" << gas << endl; cout << " " << sig << ":\t" << gas << endl;
} }
if (contract.getFallbackFunction())
{
GasEstimator::GasConsumption gas = GasEstimator::functionalEstimation(*items, "INVALID");
cout << " fallback:\t" << gas << endl;
}
cout << "internal:" << endl; cout << "internal:" << endl;
for (auto const& it: contract.getDefinedFunctions()) for (auto const& it: contract.getDefinedFunctions())
{ {

2
solc/jsonCompiler.cpp

@ -91,6 +91,8 @@ Json::Value estimateGas(CompilerStack const& _compiler, string const& _contract)
string sig = it.second->externalSignature(); string sig = it.second->externalSignature();
externalFunctions[sig] = gasToJson(GasEstimator::functionalEstimation(*items, sig)); externalFunctions[sig] = gasToJson(GasEstimator::functionalEstimation(*items, sig));
} }
if (contract.getFallbackFunction())
externalFunctions[""] = gasToJson(GasEstimator::functionalEstimation(*items, "INVALID"));
gasEstimates["external"] = externalFunctions; gasEstimates["external"] = externalFunctions;
Json::Value internalFunctions(Json::objectValue); Json::Value internalFunctions(Json::objectValue);
for (auto const& it: contract.getDefinedFunctions()) for (auto const& it: contract.getDefinedFunctions())

Loading…
Cancel
Save