|
|
@ -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()) |
|
|
|
{ |
|
|
|