Skip to content

Commit

Permalink
Use int64 for gas in Transaction::baseGasRequired
Browse files Browse the repository at this point in the history
  • Loading branch information
chfast committed Feb 27, 2017
1 parent b9e31a0 commit 0be997d
Show file tree
Hide file tree
Showing 11 changed files with 23 additions and 44 deletions.
2 changes: 1 addition & 1 deletion ethvm/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ int main(int argc, char** argv)

if (mode == Mode::Statistics)
{
cout << "Gas used: " << res.gasUsed << " (+" << t.gasRequired(se->evmSchedule(envInfo)) << " for transaction, -" << res.gasRefunded << " refunded)" << endl;
cout << "Gas used: " << res.gasUsed << " (+" << t.baseGasRequired(se->evmSchedule(envInfo)) << " for transaction, -" << res.gasRefunded << " refunded)" << endl;
cout << "Output: " << toHex(output) << endl;
LogEntries logs = executive.logs();
cout << logs.size() << " logs" << (logs.empty() ? "." : ":") << endl;
Expand Down
2 changes: 1 addition & 1 deletion libethashseal/Ethash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ void Ethash::verifyTransaction(ImportRequirements::value _ir, TransactionBase co
_t.checkChainId(-4);
}
// Unneeded as it's checked again in Executive. Keep it here since tests assume it's checked.
if (_ir & ImportRequirements::TransactionBasic && _t.gasRequired(evmSchedule(EnvInfo(_bi))) > _t.gas())
if (_ir & ImportRequirements::TransactionBasic && _t.baseGasRequired(evmSchedule(EnvInfo(_bi))) > _t.gas())
BOOST_THROW_EXCEPTION(OutOfGasIntrinsic());
}

Expand Down
8 changes: 4 additions & 4 deletions libethcore/Transaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,12 +163,12 @@ void TransactionBase::checkChainId(int chainId) const
BOOST_THROW_EXCEPTION(InvalidSignature());
}

bigint TransactionBase::gasRequired(bool _contractCreation, bytesConstRef _data, EVMSchedule const& _es, u256 const& _gas)
int64_t TransactionBase::baseGasRequired(bool _contractCreation, bytesConstRef _data, EVMSchedule const& _es)
{
bigint ret = (_contractCreation ? _es.txCreateGas : _es.txGas) + _gas;
int64_t g = _contractCreation ? _es.txCreateGas : _es.txGas;
for (auto i: _data)
ret += i ? _es.txDataNonZeroGas : _es.txDataZeroGas;
return ret;
g += i ? _es.txDataNonZeroGas : _es.txDataZeroGas;
return g;
}

h256 TransactionBase::sha3(IncludeSignature _sig) const
Expand Down
6 changes: 3 additions & 3 deletions libethcore/Transaction.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,11 +144,11 @@ class TransactionBase

void sign(Secret const& _priv); ///< Sign the transaction.

/// @returns true if the transaction contains enough gas for the basic payment.
bigint gasRequired(EVMSchedule const& _es, u256 const& _gas = 0) const { return gasRequired(m_type == TransactionBase::ContractCreation, &m_data, _es, _gas); }
/// @returns amount of gas required for the basic payment.
int64_t baseGasRequired(EVMSchedule const& _es) const { return baseGasRequired(isCreation(), &m_data, _es); }

/// Get the fee associated for a transaction with the given data.
static bigint gasRequired(bool _contractCreation, bytesConstRef _data, EVMSchedule const& _es, u256 const& _gas = 0);
static int64_t baseGasRequired(bool _contractCreation, bytesConstRef _data, EVMSchedule const& _es);

protected:
/// Type of transaction.
Expand Down
12 changes: 6 additions & 6 deletions libethereum/ClientBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const char* WorkInChannel::name() { return EthOrange "⚒" EthGreen "▬▶"; }
const char* WorkOutChannel::name() { return EthOrange "" EthNavy "◀▬"; }
const char* WorkChannel::name() { return EthOrange "" EthWhite " "; }

namespace dev { namespace eth { const u256 c_maxGasEstimate = 50000000; } }
static const int64_t c_maxGasEstimate = 50000000;

pair<h256, Address> ClientBase::submitTransaction(TransactionSkeleton const& _t, Secret const& _secret)
{
Expand Down Expand Up @@ -100,22 +100,22 @@ ExecutionResult ClientBase::create(Address const& _from, u256 _value, bytes cons
return ret;
}

std::pair<u256, ExecutionResult> ClientBase::estimateGas(Address const& _from, u256 _value, Address _dest, bytes const& _data, u256 _maxGas, u256 _gasPrice, BlockNumber _blockNumber, GasEstimationCallback const& _callback)
std::pair<u256, ExecutionResult> ClientBase::estimateGas(Address const& _from, u256 _value, Address _dest, bytes const& _data, int64_t _maxGas, u256 _gasPrice, BlockNumber _blockNumber, GasEstimationCallback const& _callback)
{
try
{
u256 upperBound = _maxGas;
int64_t upperBound = _maxGas;
if (upperBound == Invalid256 || upperBound > c_maxGasEstimate)
upperBound = c_maxGasEstimate;
u256 lowerBound = (u256)Transaction::gasRequired(!_dest, &_data, EVMSchedule(), 0);
int64_t lowerBound = Transaction::baseGasRequired(!_dest, &_data, EVMSchedule());
Block bk = block(_blockNumber);
u256 gasPrice = _gasPrice == Invalid256 ? gasBidPrice() : _gasPrice;
ExecutionResult er;
ExecutionResult lastGood;
bool good = false;
while (upperBound != lowerBound)
{
u256 mid = (lowerBound + upperBound) / 2;
int64_t mid = (lowerBound + upperBound) / 2;
u256 n = bk.transactionsFrom(_from);
Transaction t;
if (_dest)
Expand All @@ -124,7 +124,7 @@ std::pair<u256, ExecutionResult> ClientBase::estimateGas(Address const& _from, u
t = Transaction(_value, gasPrice, mid, _data, n);
t.forceSender(_from);
EnvInfo env(bk.info(), bc().lastHashes(), 0);
env.setGasLimit(mid.convert_to<int64_t>());
env.setGasLimit(mid);
State tempState(bk.state());
tempState.addBalance(_from, (u256)(t.gas() * t.gasPrice() + t.value()));
er = tempState.execute(env, *bc().sealEngine(), t, Permanence::Reverted).first;
Expand Down
2 changes: 1 addition & 1 deletion libethereum/ClientBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ class ClientBase: public Interface
/// Estimate gas usage for call/create.
/// @param _maxGas An upper bound value for estimation, if not provided default value of c_maxGasEstimate will be used.
/// @param _callback Optional callback function for progress reporting
virtual std::pair<u256, ExecutionResult> estimateGas(Address const& _from, u256 _value, Address _dest, bytes const& _data, u256 _maxGas, u256 _gasPrice, BlockNumber _blockNumber, GasEstimationCallback const& _callback) override;
virtual std::pair<u256, ExecutionResult> estimateGas(Address const& _from, u256 _value, Address _dest, bytes const& _data, int64_t _maxGas, u256 _gasPrice, BlockNumber _blockNumber, GasEstimationCallback const& _callback) override;

using Interface::create;

Expand Down
4 changes: 2 additions & 2 deletions libethereum/Executive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,12 +190,12 @@ void Executive::initialize(Transaction const& _transaction)
}

// Check gas cost is enough.
m_baseGasRequired = m_t.gasRequired(m_sealEngine.evmSchedule(m_envInfo));
m_baseGasRequired = m_t.baseGasRequired(m_sealEngine.evmSchedule(m_envInfo));
if (m_baseGasRequired > m_t.gas())
{
clog(ExecutiveWarnChannel) << "Not enough gas to pay for the transaction: Require >" << m_baseGasRequired << " Got" << m_t.gas();
m_excepted = TransactionException::OutOfGasBase;
BOOST_THROW_EXCEPTION(OutOfGasBase() << RequirementError(m_baseGasRequired, (bigint)m_t.gas()));
BOOST_THROW_EXCEPTION(OutOfGasBase() << RequirementError((bigint)m_baseGasRequired, (bigint)m_t.gas()));
}

// Avoid invalid transactions.
Expand Down
2 changes: 1 addition & 1 deletion libethereum/Executive.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ class Executive

unsigned m_depth = 0; ///< The context's call-depth.
TransactionException m_excepted = TransactionException::None; ///< Details if the VM's execution resulted in an exception.
bigint m_baseGasRequired; ///< The base amount of gas requried for executing this transactions.
int64_t m_baseGasRequired; ///< The base amount of gas requried for executing this transaction.
u256 m_gas = 0; ///< The gas for EVM code execution. Initial amount before go() execution, final amount after go() execution.
u256 m_refunded = 0; ///< The amount of gas refunded.

Expand Down
3 changes: 1 addition & 2 deletions libethereum/Interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ struct GasEstimationProgress
};

using GasEstimationCallback = std::function<void(GasEstimationProgress const&)>;
extern const u256 c_maxGasEstimate;

/**
* @brief Main API hub for interfacing with Ethereum.
Expand Down Expand Up @@ -112,7 +111,7 @@ class Interface
/// Estimate gas usage for call/create.
/// @param _maxGas An upper bound value for estimation, if not provided default value of c_maxGasEstimate will be used.
/// @param _callback Optional callback function for progress reporting
virtual std::pair<u256, ExecutionResult> estimateGas(Address const& _from, u256 _value, Address _dest, bytes const& _data, u256 _maxGas, u256 _gasPrice, BlockNumber _blockNumber, GasEstimationCallback const& _callback = GasEstimationCallback()) = 0;
virtual std::pair<u256, ExecutionResult> estimateGas(Address const& _from, u256 _value, Address _dest, bytes const& _data, int64_t _maxGas, u256 _gasPrice, BlockNumber _blockNumber, GasEstimationCallback const& _callback = GasEstimationCallback()) = 0;

// [STATE-QUERY API]

Expand Down
3 changes: 2 additions & 1 deletion libweb3jsonrpc/Eth.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,8 @@ string Eth::eth_estimateGas(Json::Value const& _json)
{
TransactionSkeleton t = toTransactionSkeleton(_json);
setTransactionDefaults(t);
return toJS(client()->estimateGas(t.from, t.value, t.to, t.data, t.gas, t.gasPrice, PendingBlock).first);
int64_t gas = static_cast<int64_t>(t.gas);
return toJS(client()->estimateGas(t.from, t.value, t.to, t.data, gas, t.gasPrice, PendingBlock).first);
}
catch (...)
{
Expand Down
23 changes: 1 addition & 22 deletions test/libethereum/Transaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,30 +33,9 @@ BOOST_FIXTURE_TEST_SUITE(libethereum, TestOutputHelper)
BOOST_AUTO_TEST_CASE(TransactionGasRequired)
{
Transaction tr(fromHex("0xf86d800182521c94095e7baea6a6c7c4c2dfeb977efac326af552d870a8e0358ac39584bc98a7c979f984b031ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804"), CheckTransaction::None);
BOOST_CHECK_MESSAGE(tr.gasRequired(FrontierSchedule) == 21952, "Transaction::GasRequired() has changed!");
BOOST_CHECK_EQUAL(tr.baseGasRequired(FrontierSchedule), 21952);
}

// Out of gas intrinsic no longer checked since it depends on chain params & context.
/*BOOST_AUTO_TEST_CASE(TransactionConstructor)
{
test::TestOutputHelper::initTest();
bool wasException = false;
try
{
Transaction(fromHex("0xf86d800182521c94095e7baea6a6c7c4c2dfeb977efac326af552d870a8e0358ac39584bc98a7c979f984b031ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804"), CheckTransaction::Everything);
}
catch (OutOfGasIntrinsic)
{
wasException = true;
}
catch (Exception)
{
BOOST_ERROR("Exception thrown but expected OutOfGasIntrinsic instead");
}
BOOST_CHECK_MESSAGE(wasException, "Expected OutOfGasIntrinsic exception to be thrown at TransactionConstructor test");
}*/

BOOST_AUTO_TEST_CASE(ExecutionResultOutput)
{
std::stringstream buffer;
Expand Down

0 comments on commit 0be997d

Please sign in to comment.