mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #1369 from ethereum/callcosts
Report infinite gas for calls.
This commit is contained in:
commit
634b0998ba
@ -39,7 +39,7 @@ GasMeter::GasConsumption& GasMeter::GasConsumption::operator+=(GasConsumption co
|
||||
return *this;
|
||||
}
|
||||
|
||||
GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item)
|
||||
GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item, bool _includeExternalCosts)
|
||||
{
|
||||
GasConsumption gas;
|
||||
switch (_item.type())
|
||||
@ -128,23 +128,35 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item)
|
||||
case Instruction::CALLCODE:
|
||||
case Instruction::DELEGATECALL:
|
||||
{
|
||||
gas = GasCosts::callGas;
|
||||
if (u256 const* value = classes.knownConstant(m_state->relativeStackElement(0)))
|
||||
gas += (*value);
|
||||
else
|
||||
if (_includeExternalCosts)
|
||||
// We assume that we do not know the target contract and thus, the consumption is infinite.
|
||||
gas = GasConsumption::infinite();
|
||||
if (_item.instruction() == Instruction::CALL)
|
||||
gas += GasCosts::callNewAccountGas; // We very rarely know whether the address exists.
|
||||
int valueSize = _item.instruction() == Instruction::DELEGATECALL ? 0 : 1;
|
||||
if (!classes.knownZero(m_state->relativeStackElement(-1 - valueSize)))
|
||||
gas += GasCosts::callValueTransferGas;
|
||||
gas += memoryGas(-2 - valueSize, -3 - valueSize);
|
||||
gas += memoryGas(-4 - valueSize, -5 - valueSize);
|
||||
else
|
||||
{
|
||||
gas = GasCosts::callGas;
|
||||
if (u256 const* value = classes.knownConstant(m_state->relativeStackElement(0)))
|
||||
gas += (*value);
|
||||
else
|
||||
gas = GasConsumption::infinite();
|
||||
if (_item.instruction() == Instruction::CALL)
|
||||
gas += GasCosts::callNewAccountGas; // We very rarely know whether the address exists.
|
||||
int valueSize = _item.instruction() == Instruction::DELEGATECALL ? 0 : 1;
|
||||
if (!classes.knownZero(m_state->relativeStackElement(-1 - valueSize)))
|
||||
gas += GasCosts::callValueTransferGas;
|
||||
gas += memoryGas(-2 - valueSize, -3 - valueSize);
|
||||
gas += memoryGas(-4 - valueSize, -5 - valueSize);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Instruction::CREATE:
|
||||
gas = GasCosts::createGas;
|
||||
gas += memoryGas(-1, -2);
|
||||
if (_includeExternalCosts)
|
||||
// We assume that we do not know the target contract and thus, the consumption is infinite.
|
||||
gas = GasConsumption::infinite();
|
||||
else
|
||||
{
|
||||
gas = GasCosts::createGas;
|
||||
gas += memoryGas(-1, -2);
|
||||
}
|
||||
break;
|
||||
case Instruction::EXP:
|
||||
gas = GasCosts::expGas;
|
||||
|
@ -102,7 +102,8 @@ public:
|
||||
|
||||
/// @returns an upper bound on the gas consumed by the given instruction and updates
|
||||
/// the state.
|
||||
GasConsumption estimateMax(AssemblyItem const& _item);
|
||||
/// @param _inculdeExternalCosts if true, include costs caused by other contracts in calls.
|
||||
GasConsumption estimateMax(AssemblyItem const& _item, bool _includeExternalCosts = true);
|
||||
|
||||
u256 const& largestMemoryAccess() const { return m_largestMemoryAccess; }
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user