Merge pull request #8158 from ethereum/fixedhash-ffs

Use multiprecision::msb() in GasMeter and remove FixedHash dependency
This commit is contained in:
Alex Beregszaszi 2020-01-17 14:05:05 +00:00 committed by GitHub
commit 92908f5260
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 12 additions and 19 deletions

View File

@ -19,8 +19,6 @@
#include <libevmasm/KnownState.h>
#include <libsolutil/FixedHash.h>
using namespace std;
using namespace solidity;
using namespace solidity::util;
@ -182,7 +180,14 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item, bool _
case Instruction::EXP:
gas = GasCosts::expGas;
if (u256 const* value = classes.knownConstant(m_state->relativeStackElement(-1)))
gas += GasCosts::expByteGas(m_evmVersion) * (32 - (h256(*value).firstBitSet() / 8));
{
if (*value)
{
// Note: msb() counts from 0 and throws on 0 as input.
unsigned const significantByteCount = (boost::multiprecision::msb(*value) + 1 + 7) / 8;
gas += GasCosts::expByteGas(m_evmVersion) * significantByteCount;
}
}
else
gas += GasCosts::expByteGas(m_evmVersion) * 32;
break;

View File

@ -104,22 +104,6 @@ public:
/// @returns a copy of the object's data as a byte vector.
bytes asBytes() const { return bytes(data(), data() + N); }
/// Returns the index of the first bit set to one, or size() * 8 if no bits are set.
inline unsigned firstBitSet() const
{
unsigned ret = 0;
for (auto d: m_data)
if (d)
{
for (;; ++ret, d <<= 1)
if (d & 0x80)
return ret;
}
else
ret += 8;
return ret;
}
private:
std::array<uint8_t, N> m_data; ///< The binary data.
};

View File

@ -261,6 +261,9 @@ BOOST_AUTO_TEST_CASE(exponent_size)
{
char const* sourceCode = R"(
contract A {
function f(uint x) public returns (uint) {
return x ** 0;
}
function g(uint x) public returns (uint) {
return x ** 0x100;
}
@ -270,6 +273,7 @@ BOOST_AUTO_TEST_CASE(exponent_size)
}
)";
testCreationTimeGas(sourceCode);
testRunTimeGas("f(uint256)", vector<bytes>{encodeArgs(2)});
testRunTimeGas("g(uint256)", vector<bytes>{encodeArgs(2)});
testRunTimeGas("h(uint256)", vector<bytes>{encodeArgs(2)});
}