Browse Source

Fix for windows.

Better failure reporting on consensus issues.
cl-refactor
Gav Wood 10 years ago
parent
commit
d1f19fe2d4
  1. 11
      libethereum/Executive.cpp
  2. 1
      libethereum/Executive.h
  3. 33
      libethereum/State.cpp
  4. 21
      libethereum/Transaction.cpp
  5. 3
      libethereum/Transaction.h

11
libethereum/Executive.cpp

@ -32,6 +32,7 @@ using namespace dev;
using namespace dev::eth;
const char* VMTraceChannel::name() { return "EVM"; }
const char* ExecutiveWarnChannel::name() { return WarnChannel::name(); }
Executive::Executive(State& _s, BlockChain const& _bc, unsigned _level):
m_s(_s),
@ -63,7 +64,7 @@ void Executive::initialize(Transaction const& _transaction)
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();
clog(ExecutiveWarnChannel) << "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()));
}
@ -71,7 +72,7 @@ void Executive::initialize(Transaction const& _transaction)
// Check gas cost is enough.
if (!m_t.checkPayment())
{
clog(StateDetail) << "Not enough gas to pay for the transaction: Require >" << m_t.gasRequired() << " Got" << m_t.gas();
clog(ExecutiveWarnChannel) << "Not enough gas to pay for the transaction: Require >" << m_t.gasRequired() << " Got" << m_t.gas();
m_excepted = TransactionException::OutOfGas;
BOOST_THROW_EXCEPTION(OutOfGasBase() << RequirementError(m_t.gasRequired(), (bigint)m_t.gas()));
}
@ -84,13 +85,13 @@ void Executive::initialize(Transaction const& _transaction)
}
catch (...)
{
clog(StateDetail) << "Invalid Signature";
clog(ExecutiveWarnChannel) << "Invalid Signature";
m_excepted = TransactionException::InvalidSignature;
throw;
}
if (m_t.nonce() != nonceReq)
{
clog(StateDetail) << "Invalid Nonce: Require" << nonceReq << " Got" << m_t.nonce();
clog(ExecutiveWarnChannel) << "Invalid Nonce: Require" << nonceReq << " Got" << m_t.nonce();
m_excepted = TransactionException::InvalidNonce;
BOOST_THROW_EXCEPTION(InvalidNonce() << RequirementError((bigint)nonceReq, (bigint)m_t.nonce()));
}
@ -100,7 +101,7 @@ void Executive::initialize(Transaction const& _transaction)
m_totalCost = m_t.value() + m_gasCost;
if (m_s.balance(m_t.sender()) < m_totalCost)
{
clog(StateDetail) << "Not enough cash: Require >" << m_totalCost << " Got" << m_s.balance(m_t.sender());
clog(ExecutiveWarnChannel) << "Not enough cash: Require >" << m_totalCost << " Got" << m_s.balance(m_t.sender());
m_excepted = TransactionException::NotEnoughCash;
BOOST_THROW_EXCEPTION(NotEnoughCash() << RequirementError(m_totalCost, (bigint)m_s.balance(m_t.sender())));
}

1
libethereum/Executive.h

@ -36,6 +36,7 @@ class ExtVM;
struct Manifest;
struct VMTraceChannel: public LogChannel { static const char* name(); static const int verbosity = 11; };
struct ExecutiveWarnChannel: public LogChannel { static const char* name(); static const int verbosity = 6; };
/**
* @brief Message-call/contract-creation executor; useful for executing transactions.

33
libethereum/State.cpp

@ -592,6 +592,24 @@ string State::vmTrace(bytesConstRef _block, BlockChain const& _bc, ImportRequire
return ss.str();
}
template <class Channel>
class LogOverride
{
public:
LogOverride(bool _value): m_old(g_logOverride.count(&typeid(Channel)) ? (int)g_logOverride[&typeid(Channel)] : c_null) { g_logOverride[&typeid(Channel)] = _value; }
~LogOverride()
{
if (m_old == c_null)
g_logOverride.erase(&typeid(Channel));
else
g_logOverride[&typeid(Channel)] = (bool)m_old;
}
private:
static const int c_null = -1;
int m_old;
};
u256 State::enact(bytesConstRef _block, BlockChain const& _bc, ImportRequirements::value _ir)
{
// m_currentBlock is assumed to be prepopulated and reset.
@ -624,7 +642,19 @@ u256 State::enact(bytesConstRef _block, BlockChain const& _bc, ImportRequirement
unsigned i = 0;
for (auto const& tr: rlp[1])
{
execute(lh, Transaction(tr.data(), CheckTransaction::Everything));
try {
LogOverride<ExecutiveWarnChannel> o(false);
execute(lh, Transaction(tr.data(), CheckTransaction::Everything));
}
catch (...)
{
badBlock(_block, "Invalid transaction");
cwarn << " Transaction Index:" << i;
LogOverride<ExecutiveWarnChannel> o(true);
execute(lh, Transaction(tr.data(), CheckTransaction::Everything));
throw;
}
RLPStream receiptRLP;
m_receipts.back().streamRLP(receiptRLP);
receipts.push_back(receiptRLP.out());
@ -1163,6 +1193,7 @@ ExecutionResult State::execute(LastHashes const& _lh, Transaction const& _t, Per
ctrace << "Executing" << e.t() << "on" << h;
ctrace << toHex(e.t().rlp());
#endif
(void)_onOp;
if (!e.execute())
#if ETH_VMTRACE
e.go(e.simpleTrace());

21
libethereum/Transaction.cpp

@ -39,6 +39,27 @@ std::ostream& dev::eth::operator<<(std::ostream& _out, ExecutionResult const& _e
return _out;
}
std::string badTransaction(bytesConstRef _tx, string const& _err)
{
stringstream ret;
ret << "========================================================================" << endl;
ret << "== Software Failure " << (_err + string(max<int>(0, 44 - _err.size()), ' ')) << " ==" << endl;
ret << "== Guru Meditation " << sha3(_tx).abridged() << " ==" << endl;
ret << "========================================================================" << endl;
ret << " Transaction: " << toHex(_tx) << endl;
ret << " Transaction RLP: ";
try {
ret << RLP(_tx);
}
catch (Exception& _e)
{
ret << "Invalid: " << _e.what();
}
ret << endl;
return ret.str();
}
TransactionException dev::eth::toTransactionException(VMException const& _e)
{
if (!!dynamic_cast<BadInstruction const*>(&_e))

3
libethereum/Transaction.h

@ -235,5 +235,8 @@ inline std::ostream& operator<<(std::ostream& _out, Transaction const& _t)
return _out;
}
void badTransaction(bytesConstRef _tx, std::string const& _err);
inline void badTransaction(bytes const& _tx, std::string const& _err) { badTransaction(&_tx, _err); }
}
}

Loading…
Cancel
Save