Browse Source

Make value transfers symmetric.

cl-refactor
Gav Wood 10 years ago
parent
commit
f3d4351dbf
  1. 33
      libethereum/Executive.cpp
  2. 8
      libethereum/State.h
  3. 6
      libevm/VM.cpp

33
libethereum/Executive.cpp

@ -80,27 +80,31 @@ bool Executive::setup()
}
// Check gas cost is enough.
auto gasCost = Interface::txGas(m_t.data());
auto gasRequired = Interface::txGas(m_t.data());
if (m_t.gas() < gasCost)
if (m_t.gas() < gasRequired)
{
clog(StateDetail) << "Not enough gas to pay for the transaction: Require >" << gasCost << " Got" << m_t.gas();
BOOST_THROW_EXCEPTION(OutOfGas() << RequirementError((bigint)gasCost, (bigint)m_t.gas()));
clog(StateDetail) << "Not enough gas to pay for the transaction: Require >" << gasRequired << " Got" << m_t.gas();
m_excepted = TransactionException::OutOfGas;
BOOST_THROW_EXCEPTION(OutOfGas() << RequirementError((bigint)gasRequired, (bigint)m_t.gas()));
}
bigint cost = m_t.value() + (bigint)m_t.gas() * m_t.gasPrice();
bigint gasCost = (bigint)m_t.gas() * m_t.gasPrice();
bigint totalCost = m_t.value() + gasCost;
// Avoid unaffordable transactions.
if (m_s.balance(m_t.sender()) < cost)
if (m_s.balance(m_t.sender()) < totalCost)
{
clog(StateDetail) << "Not enough cash: Require >" << cost << " Got" << m_s.balance(m_t.sender());
BOOST_THROW_EXCEPTION(NotEnoughCash() << RequirementError(cost, (bigint)m_s.balance(m_t.sender())));
clog(StateDetail) << "Not enough cash: Require >" << totalCost << " Got" << m_s.balance(m_t.sender());
m_excepted = TransactionException::NotEnoughCash;
BOOST_THROW_EXCEPTION(NotEnoughCash() << RequirementError(totalCost, (bigint)m_s.balance(m_t.sender())));
}
u256 startGasUsed = m_s.gasUsed();
if (startGasUsed + (bigint)m_t.gas() > m_s.m_currentBlock.gasLimit)
{
clog(StateDetail) << "Too much gas used in this block: Require <" << (m_s.m_currentBlock.gasLimit - startGasUsed) << " Got" << m_t.gas();
m_excepted = TransactionException::BlockGasLimitReached;
BOOST_THROW_EXCEPTION(BlockGasLimitReached() << RequirementError((bigint)(m_s.m_currentBlock.gasLimit - startGasUsed), (bigint)m_t.gas()));
}
@ -108,8 +112,8 @@ bool Executive::setup()
m_s.noteSending(m_t.sender());
// Pay...
clog(StateDetail) << "Paying" << formatBalance(u256(cost)) << "from sender (includes" << m_t.gas() << "gas at" << formatBalance(m_t.gasPrice()) << ")";
m_s.subBalance(m_t.sender(), cost);
clog(StateDetail) << "Paying" << formatBalance(u256(gasCost)) << "from sender for gas (" << m_t.gas() << "gas at" << formatBalance(m_t.gasPrice()) << ")";
m_s.subBalance(m_t.sender(), gasCost);
if (m_t.isCreation())
return create(m_t.sender(), m_t.value(), m_t.gasPrice(), m_t.gas() - (u256)gasCost, &m_t.data(), m_t.sender());
@ -120,7 +124,6 @@ bool Executive::setup()
bool Executive::call(Address _receiveAddress, Address _codeAddress, Address _senderAddress, u256 _value, u256 _gasPrice, bytesConstRef _data, u256 _gas, Address _originAddress)
{
m_isCreation = false;
m_excepted = TransactionException::None;
// cnote << "Transferring" << formatBalance(_value) << "to receiver.";
auto it = !(_codeAddress & ~h160(0xffffffff)) ? precompiled().find((unsigned)(u160)_codeAddress) : precompiled().end();
if (it != precompiled().end())
@ -130,6 +133,8 @@ bool Executive::call(Address _receiveAddress, Address _codeAddress, Address _sen
{
m_endGas = 0;
m_excepted = TransactionException::OutOfGasBase;
// Bail from exception.
return true; // true actually means "all finished - nothing more to be done regarding go().
}
else
{
@ -147,8 +152,7 @@ bool Executive::call(Address _receiveAddress, Address _codeAddress, Address _sen
else
m_endGas = _gas;
if (m_excepted == TransactionException::None)
m_s.addBalance(_receiveAddress, _value);
m_s.transferBalance(_senderAddress, _receiveAddress, _value);
return !m_ext;
}
@ -168,7 +172,8 @@ bool Executive::create(Address _sender, u256 _endowment, u256 _gasPrice, u256 _g
m_ext = make_shared<ExtVM>(m_s, m_lastHashes, m_newAddress, _sender, _origin, _endowment, _gasPrice, bytesConstRef(), _init, m_depth);
}
m_s.m_cache[m_newAddress] = Account(m_s.balance(m_newAddress) + _endowment, Account::ContractConception);
m_s.m_cache[m_newAddress] = Account(m_s.balance(m_newAddress), Account::ContractConception);
m_s.transferBalance(_sender, m_newAddress, _endowment);
if (_init.empty())
{

8
libethereum/State.h

@ -219,6 +219,14 @@ public:
*/
void subBalance(Address _id, bigint _value);
/**
* @brief Transfers "the balance @a _value between two accounts.
* @param _from Account from which @a _value will be deducted.
* @param _to Account to which @a _value will be added.
* @param _value Amount to be transferred.
*/
void transferBalance(Address _from, Address _to, u256 _value) { subBalance(_from, _value); addBalance(_to, _value); }
/// Get the root of the storage of an account.
h256 storageRoot(Address _contract) const;

6
libevm/VM.cpp

@ -614,10 +614,7 @@ bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _steps)
m_stack.pop_back();
if (_ext.balance(_ext.myAddress) >= endowment && _ext.depth < 1024)
{
_ext.subBalance(endowment);
m_stack.push_back((u160)_ext.create(endowment, m_gas, bytesConstRef(m_temp.data() + initOff, initSize), _onOp));
}
else
m_stack.push_back(0);
break;
@ -644,10 +641,7 @@ bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _steps)
m_stack.pop_back();
if (_ext.balance(_ext.myAddress) >= value && _ext.depth < 1024)
{
_ext.subBalance(value);
m_stack.push_back(_ext.call(inst == Instruction::CALL ? receiveAddress : _ext.myAddress, value, bytesConstRef(m_temp.data() + inOff, inSize), gas, bytesRef(m_temp.data() + outOff, outSize), _onOp, {}, receiveAddress));
}
else
m_stack.push_back(0);

Loading…
Cancel
Save