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 <libevmasm/KnownState.h>
#include <libsolutil/FixedHash.h>
using namespace std; using namespace std;
using namespace solidity; using namespace solidity;
using namespace solidity::util; using namespace solidity::util;
@ -182,7 +180,14 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item, bool _
case Instruction::EXP: case Instruction::EXP:
gas = GasCosts::expGas; gas = GasCosts::expGas;
if (u256 const* value = classes.knownConstant(m_state->relativeStackElement(-1))) 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 else
gas += GasCosts::expByteGas(m_evmVersion) * 32; gas += GasCosts::expByteGas(m_evmVersion) * 32;
break; break;

View File

@ -104,22 +104,6 @@ public:
/// @returns a copy of the object's data as a byte vector. /// @returns a copy of the object's data as a byte vector.
bytes asBytes() const { return bytes(data(), data() + N); } 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: private:
std::array<uint8_t, N> m_data; ///< The binary data. 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"( char const* sourceCode = R"(
contract A { contract A {
function f(uint x) public returns (uint) {
return x ** 0;
}
function g(uint x) public returns (uint) { function g(uint x) public returns (uint) {
return x ** 0x100; return x ** 0x100;
} }
@ -270,6 +273,7 @@ BOOST_AUTO_TEST_CASE(exponent_size)
} }
)"; )";
testCreationTimeGas(sourceCode); testCreationTimeGas(sourceCode);
testRunTimeGas("f(uint256)", vector<bytes>{encodeArgs(2)});
testRunTimeGas("g(uint256)", vector<bytes>{encodeArgs(2)}); testRunTimeGas("g(uint256)", vector<bytes>{encodeArgs(2)});
testRunTimeGas("h(uint256)", vector<bytes>{encodeArgs(2)}); testRunTimeGas("h(uint256)", vector<bytes>{encodeArgs(2)});
} }