Add recomputation check for number representation.

This commit is contained in:
chriseth 2017-04-03 14:40:39 +02:00 committed by Alex Beregszaszi
parent 2c1fb46bc3
commit 54210ea89f
2 changed files with 56 additions and 1 deletions

View File

@ -232,6 +232,54 @@ AssemblyItems ComputeMethod::findRepresentation(u256 const& _value)
}
}
bool ComputeMethod::checkRepresentation(u256 const& _value)
{
// This is a tiny EVM that can only evaluate some instructions.
vector<u256> stack;
for (AssemblyItem const& item: m_routine)
{
switch (item.type())
{
case Operation:
{
if (stack.size() < size_t(item.arguments()))
return false;
u256* sp = &stack.back();
switch (item.instruction())
{
case Instruction::MUL:
sp[-1] = sp[0] * sp[-1];
break;
case Instruction::EXP:
if (sp[-1] > 0xff)
return false;
sp[-1] = boost::multiprecision::pow(sp[0], unsigned(sp[-1]));
break;
case Instruction::ADD:
sp[-1] = sp[0] + sp[-1];
break;
case Instruction::SUB:
sp[-1] = sp[0] - sp[-1];
break;
case Instruction::NOT:
sp[0] = ~sp[0];
break;
default:
return false;
}
stack.resize(stack.size() + item.deposit());
break;
}
case Push:
stack.push_back(item.data());
break;
default:
return false;
}
}
return stack.size() == 1 && stack.front() == _value;
}
bigint ComputeMethod::gasNeeded(AssemblyItems const& _routine)
{
size_t numExps = count(_routine.begin(), _routine.end(), Instruction::EXP);

View File

@ -21,10 +21,13 @@
#pragma once
#include <vector>
#include <libevmasm/Exceptions.h>
#include <libdevcore/CommonData.h>
#include <libdevcore/CommonIO.h>
#include <vector>
namespace dev
{
namespace eth
@ -130,6 +133,8 @@ public:
ConstantOptimisationMethod(_params, _value)
{
m_routine = findRepresentation(m_value);
if (!checkRepresentation(m_value))
BOOST_THROW_EXCEPTION(AssemblyException());
}
virtual bigint gasNeeded() override { return gasNeeded(m_routine); }
@ -141,6 +146,8 @@ public:
protected:
/// Tries to recursively find a way to compute @a _value.
AssemblyItems findRepresentation(u256 const& _value);
/// Recomputes the value from the calculated representation and checks for correctness.
bool checkRepresentation(u256 const& _value);
bigint gasNeeded(AssemblyItems const& _routine);
/// Counter for the complexity of optimization, will stop when it reaches zero.