Browse Source

Restructured exceptions. Boost::exception is now used primarily.

cl-refactor
Christoph Jentzsch 10 years ago
parent
commit
fb876453ca
  1. 22
      alethzero/MainWin.cpp
  2. 2
      libdevcore/Common.h
  3. 7
      libdevcore/CommonData.cpp
  4. 41
      libdevcore/Exceptions.h
  5. 14
      libdevcore/RLP.h
  6. 2
      libdevcrypto/FileSystem.cpp
  7. 12
      libdevcrypto/TrieDB.h
  8. 45
      libethcore/BlockInfo.cpp
  9. 68
      libethcore/Exceptions.h
  10. 21
      libethereum/BlockChain.cpp
  11. 7
      libethereum/BlockChain.h
  12. 2
      libethereum/BlockQueue.cpp
  13. 5
      libethereum/Client.cpp
  14. 14
      libethereum/Executive.cpp
  15. 51
      libethereum/State.cpp
  16. 10
      libethereum/Transaction.cpp
  17. 4
      libethereum/TransactionQueue.cpp
  18. 18
      libevm/VM.h
  19. 2
      libevmface/Instruction.cpp
  20. 2
      liblll/Assembly.cpp
  21. 2
      liblll/Assembly.h
  22. 2
      liblll/CodeFragment.h
  23. 7
      liblll/Compiler.cpp
  24. 2
      liblll/Parser.cpp
  25. 23
      libp2p/Host.cpp
  26. 2
      libp2p/Session.cpp
  27. 2
      libp2p/UPnP.cpp
  28. 5
      libserpent/util.cpp
  29. 14
      libwebthree/WebThree.h
  30. 4
      neth/main.cpp
  31. 3
      sc/cmdline.cpp
  32. 25
      test/vm.cpp

22
alethzero/MainWin.cpp

@ -597,7 +597,7 @@ void Main::on_importKeyFile_triggered()
} }
} }
else else
throw 0; BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("encseed type is not js::str_type") );
if (std::find(m_myKeys.begin(), m_myKeys.end(), k) == m_myKeys.end()) if (std::find(m_myKeys.begin(), m_myKeys.end(), k) == m_myKeys.end())
{ {
m_myKeys.append(k); m_myKeys.append(k);
@ -609,6 +609,9 @@ void Main::on_importKeyFile_triggered()
} }
catch (...) catch (...)
{ {
cerr << "Unhandled exception!" << endl <<
boost::current_exception_diagnostic_information();
QMessageBox::warning(this, "Key File Invalid", "Could not find secret key definition. This is probably not an Ethereum key file."); QMessageBox::warning(this, "Key File Invalid", "Could not find secret key definition. This is probably not an Ethereum key file.");
} }
} }
@ -821,10 +824,8 @@ static bool blockMatch(string const& _f, dev::eth::BlockDetails const& _b, h256
} }
catch (...) catch (...)
{ {
std::cerr << "Unhandled exception!" << std::endl << cerr << "Unhandled exception!" << endl <<
boost::current_exception_diagnostic_information(); boost::current_exception_diagnostic_information();
// possible output would include: function name, __FILE__, __LINE__ (at throw) and all added information,
// such has the block header info added in BlockInfo.cpp line 101-102.
} }
if (toHex(_h.ref()).find(_f) != string::npos) if (toHex(_h.ref()).find(_f) != string::npos)
return true; return true;
@ -1284,6 +1285,14 @@ void Main::on_contracts_currentItemChanged()
{ {
ui->contractInfo->appendHtml("Corrupted trie."); ui->contractInfo->appendHtml("Corrupted trie.");
} }
catch (dev::Exception &_e)
{
_e << dev::errinfo_comment("Could not get contract info.");
cerr << "Unhandled exception!" << endl <<
boost::diagnostic_information(_e);
throw;
}
ui->contractInfo->moveCursor(QTextCursor::Start); ui->contractInfo->moveCursor(QTextCursor::Start);
} }
} }
@ -1623,7 +1632,8 @@ void Main::on_debug_clicked()
} }
catch (dev::Exception const& _e) catch (dev::Exception const& _e)
{ {
statusBar()->showMessage("Error running transaction: " + QString::fromStdString(_e.description())); statusBar()->showMessage("Error running transaction: " + QString::fromStdString(diagnostic_information(_e)));
// this output is aimed at developers, reconsider using _e.what for more user friendly output.
} }
} }
@ -1909,6 +1919,8 @@ void Main::updateDebugger()
} }
catch (...) catch (...)
{ {
cerr << "Unhandled exception!" << endl <<
boost::current_exception_diagnostic_information();
break; // probably hit data segment break; // probably hit data segment
} }
} }

2
libdevcore/Common.h

@ -39,7 +39,7 @@
#include <boost/multiprecision/cpp_int.hpp> #include <boost/multiprecision/cpp_int.hpp>
#include "vector_ref.h" #include "vector_ref.h"
// CryptoPP defines byte in the global namespace, so so must we. // CryptoPP defines byte in the global namespace, so must we.
using byte = uint8_t; using byte = uint8_t;
// Quote a given token stream to turn it into a string. // Quote a given token stream to turn it into a string.

7
libdevcore/CommonData.cpp

@ -23,6 +23,7 @@
#include <random> #include <random>
#include "Exceptions.h" #include "Exceptions.h"
#include <libdevcore/Log.h>
using namespace std; using namespace std;
using namespace dev; using namespace dev;
@ -67,7 +68,7 @@ int dev::fromHex(char _i)
return _i - 'a' + 10; return _i - 'a' + 10;
if (_i >= 'A' && _i <= 'F') if (_i >= 'A' && _i <= 'F')
return _i - 'A' + 10; return _i - 'A' + 10;
throw BadHexCharacter(); BOOST_THROW_EXCEPTION(BadHexCharacter() << errinfo_invalidSymbol(_i));
} }
bytes dev::fromHex(std::string const& _s) bytes dev::fromHex(std::string const& _s)
@ -81,13 +82,13 @@ bytes dev::fromHex(std::string const& _s)
{ {
ret.push_back(fromHex(_s[s++])); ret.push_back(fromHex(_s[s++]));
} }
catch (...){ ret.push_back(0); } catch (...){ ret.push_back(0); cwarn << boost::current_exception_diagnostic_information(); }
for (unsigned i = s; i < _s.size(); i += 2) for (unsigned i = s; i < _s.size(); i += 2)
try try
{ {
ret.push_back((byte)(fromHex(_s[i]) * 16 + fromHex(_s[i + 1]))); ret.push_back((byte)(fromHex(_s[i]) * 16 + fromHex(_s[i + 1])));
} }
catch (...){ ret.push_back(0); } catch (...){ ret.push_back(0); cwarn << boost::current_exception_diagnostic_information(); }
return ret; return ret;
} }

41
libdevcore/Exceptions.h

@ -30,30 +30,19 @@
namespace dev namespace dev
{ {
// base class for all exceptions
class Exception: public std::exception struct Exception: virtual std::exception, virtual boost::exception {};
{
public: struct BadHexCharacter: virtual Exception {};
virtual std::string description() const { return typeid(*this).name(); } struct RLPException: virtual Exception {};
virtual char const* what() const noexcept { return typeid(*this).name(); } struct BadCast: virtual RLPException {};
}; struct BadRLP: virtual RLPException {};
struct NoNetworking: virtual Exception {};
// As an exemplar case I only restructure BadRLP, if I would restrucutre everything the above Exception class struct NoUPnPDevice: virtual Exception {};
// can be replaced completely. struct RootNotFound: virtual Exception {};
struct FileError: virtual Exception {};
struct BException: virtual boost::exception, virtual std::exception {};
// error information to be added to exceptions
// there is no need to derive from any other class then BException just to add more information. typedef boost::error_info<struct tag_invalidSymbol, char> errinfo_invalidSymbol;
// This can be done dynamically during runtime. typedef boost::error_info<struct tag_comment, std::string> errinfo_comment;
struct BadRLP: virtual BException {};
class BadHexCharacter: public Exception {};
class RLPException: public BException {};
class BadCast: public RLPException {};
class NoNetworking: public Exception {};
class NoUPnPDevice: public Exception {};
class RootNotFound: public Exception {};
} }

14
libdevcore/RLP.h

@ -100,11 +100,11 @@ public:
/// @returns the number of items in the list, or zero if it isn't a list. /// @returns the number of items in the list, or zero if it isn't a list.
unsigned itemCount() const { return isList() ? items() : 0; } unsigned itemCount() const { return isList() ? items() : 0; }
unsigned itemCountStrict() const { if (!isList()) throw BadCast(); return items(); } unsigned itemCountStrict() const { if (!isList()) BOOST_THROW_EXCEPTION(BadCast()); return items(); }
/// @returns the number of bytes in the data, or zero if it isn't data. /// @returns the number of bytes in the data, or zero if it isn't data.
unsigned size() const { return isData() ? length() : 0; } unsigned size() const { return isData() ? length() : 0; }
unsigned sizeStrict() const { if (!isData()) throw BadCast(); return length(); } unsigned sizeStrict() const { if (!isData()) BOOST_THROW_EXCEPTION(BadCast()); return length(); }
/// Equality operators; does best-effort conversion and checks for equality. /// Equality operators; does best-effort conversion and checks for equality.
bool operator==(char const* _s) const { return isData() && toString() == _s; } bool operator==(char const* _s) const { return isData() && toString() == _s; }
@ -175,7 +175,7 @@ public:
/// Converts to string. @returns the empty string if not a string. /// Converts to string. @returns the empty string if not a string.
std::string toString() const { if (!isData()) return std::string(); return payload().cropped(0, length()).toString(); } std::string toString() const { if (!isData()) return std::string(); return payload().cropped(0, length()).toString(); }
/// Converts to string. @throws BadCast if not a string. /// Converts to string. @throws BadCast if not a string.
std::string toStringStrict() const { if (!isData()) throw BadCast(); return payload().cropped(0, length()).toString(); } std::string toStringStrict() const { if (!isData()) BOOST_THROW_EXCEPTION(BadCast()); return payload().cropped(0, length()).toString(); }
template <class T> template <class T>
std::vector<T> toVector() const std::vector<T> toVector() const
@ -222,7 +222,7 @@ public:
std::array<T, N> toArray() const std::array<T, N> toArray() const
{ {
if (itemCount() != N || !isList()) if (itemCount() != N || !isList())
throw BadCast(); BOOST_THROW_EXCEPTION(BadCast());
std::array<T, N> ret; std::array<T, N> ret;
for (unsigned i = 0; i < N; ++i) for (unsigned i = 0; i < N; ++i)
{ {
@ -246,7 +246,7 @@ public:
{ {
if ((!isInt() && !(_flags & AllowNonCanon)) || isList() || isNull()) if ((!isInt() && !(_flags & AllowNonCanon)) || isList() || isNull())
if (_flags & ThrowOnFail) if (_flags & ThrowOnFail)
throw BadCast(); BOOST_THROW_EXCEPTION(BadCast());
else else
return 0; return 0;
else {} else {}
@ -254,7 +254,7 @@ public:
auto p = payload(); auto p = payload();
if (p.size() > intTraits<_T>::maxSize && (_flags & FailIfTooBig)) if (p.size() > intTraits<_T>::maxSize && (_flags & FailIfTooBig))
if (_flags & ThrowOnFail) if (_flags & ThrowOnFail)
throw BadCast(); BOOST_THROW_EXCEPTION(BadCast());
else else
return 0; return 0;
else {} else {}
@ -266,7 +266,7 @@ public:
{ {
if (!isData() || (length() > _N::size && (_flags & FailIfTooBig))) if (!isData() || (length() > _N::size && (_flags & FailIfTooBig)))
if (_flags & ThrowOnFail) if (_flags & ThrowOnFail)
throw BadCast(); BOOST_THROW_EXCEPTION(BadCast());
else else
return _N(); return _N();
else{} else{}

2
libdevcrypto/FileSystem.cpp

@ -43,7 +43,7 @@ std::string dev::getDataDir()
#ifndef _MSC_VER // todo? #ifndef _MSC_VER // todo?
cwarn << "getDataDir(): SHGetSpecialFolderPathA() failed."; cwarn << "getDataDir(): SHGetSpecialFolderPathA() failed.";
#endif #endif
throw std::runtime_error("getDataDir() - SHGetSpecialFolderPathA() failed."); BOOST_THROW_EXCEPTION(std::runtime_error("getDataDir() - SHGetSpecialFolderPathA() failed."));
} }
#else #else
boost::filesystem::path dataDirPath; boost::filesystem::path dataDirPath;

12
libdevcrypto/TrieDB.h

@ -30,6 +30,7 @@
#include <memory> #include <memory>
#include <libdevcore/Common.h> #include <libdevcore/Common.h>
#include <libdevcore/Log.h> #include <libdevcore/Log.h>
#include <libdevcore/Exceptions.h>
#include <libdevcrypto/SHA3.h> #include <libdevcrypto/SHA3.h>
#include "MemoryDB.h" #include "MemoryDB.h"
#include "OverlayDB.h" #include "OverlayDB.h"
@ -44,7 +45,7 @@ namespace eth
struct TrieDBChannel: public LogChannel { static const char* name() { return "-T-"; } static const int verbosity = 6; }; struct TrieDBChannel: public LogChannel { static const char* name() { return "-T-"; } static const int verbosity = 6; };
#define tdebug clog(TrieDBChannel) #define tdebug clog(TrieDBChannel)
class InvalidTrie: public std::exception {}; struct InvalidTrie: virtual dev::Exception {};
extern const h256 c_shaNull; extern const h256 c_shaNull;
/** /**
@ -81,7 +82,7 @@ public:
/*std::cout << "Setting root to " << _root << " (patched to " << m_root << ")" << std::endl;*/ /*std::cout << "Setting root to " << _root << " (patched to " << m_root << ")" << std::endl;*/
if (!node(m_root).size()) if (!node(m_root).size())
throw RootNotFound(); BOOST_THROW_EXCEPTION(RootNotFound());
} }
bool haveRoot(h256 _root, bool _enforceRefs = true) { return _root == h256() ? true : m_db->lookup(_root, _enforceRefs).size(); } bool haveRoot(h256 _root, bool _enforceRefs = true) { return _root == h256() ? true : m_db->lookup(_root, _enforceRefs).size(); }
@ -109,7 +110,7 @@ public:
else if (_r.isList()) else if (_r.isList())
descendList(_r, _keyMask, _wasExt, _out, _indent); descendList(_r, _keyMask, _wasExt, _out, _indent);
else else
throw InvalidTrie(); BOOST_THROW_EXCEPTION(InvalidTrie());
} }
void descendList(RLP const& _r, std::set<h256>& _keyMask, bool _wasExt, std::ostream* _out, int _indent) const void descendList(RLP const& _r, std::set<h256>& _keyMask, bool _wasExt, std::ostream* _out, int _indent) const
@ -130,7 +131,7 @@ public:
descendEntry(_r[i], _keyMask, false, _out, _indent + 1); descendEntry(_r[i], _keyMask, false, _out, _indent + 1);
} }
else else
throw InvalidTrie(); BOOST_THROW_EXCEPTION(InvalidTrie());
} }
std::set<h256> leftOvers(std::ostream* _out = nullptr) const std::set<h256> leftOvers(std::ostream* _out = nullptr) const
@ -153,6 +154,7 @@ public:
} }
catch (...) catch (...)
{ {
cwarn << boost::current_exception_diagnostic_information();
return false; return false;
} }
} }
@ -374,7 +376,7 @@ template <class DB> void GenericTrieDB<DB>::iterator::next()
cwarn << rlp; cwarn << rlp;
auto c = rlp.itemCount(); auto c = rlp.itemCount();
cwarn << c; cwarn << c;
throw InvalidTrie(); BOOST_THROW_EXCEPTION(InvalidTrie());
#else #else
m_that = nullptr; m_that = nullptr;
return; return;

45
libethcore/BlockInfo.cpp

@ -91,33 +91,22 @@ void BlockInfo::populateFromHeader(RLP const& _header, bool _checkNonce)
extraData = _header[field = 11].toBytes(); extraData = _header[field = 11].toBytes();
nonce = _header[field = 12].toHash<h256>(); nonce = _header[field = 12].toHash<h256>();
} }
catch (BException const& e)
{
// define error information to be added to the exception
typedef boost::error_info<struct field_info,int> InvalidBlockHeaderFormat_field;
typedef boost::error_info<struct header_field_data,string> InvalidBlockHeaderFormat_header_field_data;
// instead of using a new exception type, we add information to the existing exception
e << InvalidBlockHeaderFormat_field(field);
e << InvalidBlockHeaderFormat_header_field_data(toHex(_header[field].data().toBytes()));
throw; catch (Exception & _e)
}
// this block would be replaced
catch (RLPException const&)
{ {
throw InvalidBlockHeaderFormat(field, _header[field].data()); _e << errinfo_name("invalid block header format") << BadFieldError(field, toHex(_header[field].data().toBytes()));
throw;
} }
// check it hashes according to proof of work or that it's the genesis block. // check it hashes according to proof of work or that it's the genesis block.
if (_checkNonce && parentHash && !Dagger::verify(headerHashWithoutNonce(), nonce, difficulty)) if (_checkNonce && parentHash && !Dagger::verify(headerHashWithoutNonce(), nonce, difficulty))
throw InvalidBlockNonce(headerHashWithoutNonce(), nonce, difficulty); BOOST_THROW_EXCEPTION(InvalidBlockNonce(headerHashWithoutNonce(), nonce, difficulty));
if (gasUsed > gasLimit) if (gasUsed > gasLimit)
throw TooMuchGasUsed(); BOOST_THROW_EXCEPTION(TooMuchGasUsed());
if (number && extraData.size() > 1024) if (number && extraData.size() > 1024)
throw ExtraDataTooBig(); BOOST_THROW_EXCEPTION(ExtraDataTooBig());
} }
void BlockInfo::populate(bytesConstRef _block, bool _checkNonce) void BlockInfo::populate(bytesConstRef _block, bool _checkNonce)
@ -126,13 +115,13 @@ void BlockInfo::populate(bytesConstRef _block, bool _checkNonce)
RLP header = root[0]; RLP header = root[0];
if (!header.isList()) if (!header.isList())
throw InvalidBlockFormat(0, header.data()); BOOST_THROW_EXCEPTION(InvalidBlockFormat(0,header.data()));
populateFromHeader(header, _checkNonce); populateFromHeader(header, _checkNonce);
if (!root[1].isList()) if (!root[1].isList())
throw InvalidBlockFormat(1, root[1].data()); BOOST_THROW_EXCEPTION(InvalidBlockFormat(1, root[1].data()));
if (!root[2].isList()) if (!root[2].isList())
throw InvalidBlockFormat(2, root[2].data()); BOOST_THROW_EXCEPTION(InvalidBlockFormat(2, root[2].data()));
} }
void BlockInfo::verifyInternals(bytesConstRef _block) const void BlockInfo::verifyInternals(bytesConstRef _block) const
@ -154,13 +143,13 @@ void BlockInfo::verifyInternals(bytesConstRef _block) const
++i; ++i;
} }
if (transactionsRoot != t.root()) if (transactionsRoot != t.root())
throw InvalidTransactionsHash(t.root(), transactionsRoot); BOOST_THROW_EXCEPTION(InvalidTransactionsHash(t.root(), transactionsRoot));
if (minGasPrice > mgp) if (minGasPrice > mgp)
throw InvalidMinGasPrice(minGasPrice, mgp); BOOST_THROW_EXCEPTION(InvalidMinGasPrice(minGasPrice, mgp));
if (sha3Uncles != sha3(root[2].data())) if (sha3Uncles != sha3(root[2].data()))
throw InvalidUnclesHash(); BOOST_THROW_EXCEPTION(InvalidUnclesHash());
} }
void BlockInfo::populateFromParent(BlockInfo const& _parent) void BlockInfo::populateFromParent(BlockInfo const& _parent)
@ -193,22 +182,22 @@ void BlockInfo::verifyParent(BlockInfo const& _parent) const
{ {
// Check difficulty is correct given the two timestamps. // Check difficulty is correct given the two timestamps.
if (difficulty != calculateDifficulty(_parent)) if (difficulty != calculateDifficulty(_parent))
throw InvalidDifficulty(); BOOST_THROW_EXCEPTION(InvalidDifficulty());
if (gasLimit != calculateGasLimit(_parent)) if (gasLimit != calculateGasLimit(_parent))
throw InvalidGasLimit(gasLimit, calculateGasLimit(_parent)); BOOST_THROW_EXCEPTION(InvalidGasLimit(gasLimit, calculateGasLimit(_parent)));
// Check timestamp is after previous timestamp. // Check timestamp is after previous timestamp.
if (parentHash) if (parentHash)
{ {
if (parentHash != _parent.hash) if (parentHash != _parent.hash)
throw InvalidParentHash(); BOOST_THROW_EXCEPTION(InvalidParentHash());
if (timestamp < _parent.timestamp) if (timestamp < _parent.timestamp)
throw InvalidTimestamp(); BOOST_THROW_EXCEPTION(InvalidTimestamp());
if (number != _parent.number + 1) if (number != _parent.number + 1)
throw InvalidNumber(); BOOST_THROW_EXCEPTION(InvalidNumber());
} }
} }

68
libethcore/Exceptions.h

@ -7,40 +7,42 @@ namespace dev
namespace eth namespace eth
{ {
class DatabaseAlreadyOpen: public dev::Exception {}; // information to add to exceptions
typedef boost::error_info<struct tag_field, std::string> errinfo_name;
typedef boost::error_info<struct tag_field, int> errinfo_field;
typedef boost::error_info<struct tag_data, std::string> errinfo_data;
typedef boost::tuple<errinfo_field, errinfo_data> BadFieldError;
class NotEnoughCash: public dev::Exception {}; struct DatabaseAlreadyOpen: virtual dev::Exception {};
struct NotEnoughCash: virtual dev::Exception {};
class GasPriceTooLow: public dev::Exception {}; struct GasPriceTooLow: virtual dev::Exception {};
class BlockGasLimitReached: public dev::Exception {}; struct BlockGasLimitReached: virtual dev::Exception {};
class NoSuchContract: public dev::Exception {}; struct NoSuchContract: virtual dev::Exception {};
class ContractAddressCollision: public dev::Exception {}; struct ContractAddressCollision: virtual dev::Exception {};
class FeeTooSmall: public dev::Exception {}; struct FeeTooSmall: virtual dev::Exception {};
class TooMuchGasUsed: public dev::Exception {}; struct TooMuchGasUsed: virtual dev::Exception {};
class ExtraDataTooBig: public dev::Exception {}; struct ExtraDataTooBig: virtual dev::Exception {};
class InvalidSignature: public dev::Exception {}; struct InvalidSignature: virtual dev::Exception {};
class InvalidTransactionFormat: public dev::Exception { public: InvalidTransactionFormat(int _f, bytesConstRef _d): m_f(_f), m_d(_d.toBytes()) {} int m_f; bytes m_d; virtual std::string description() const { return "Invalid transaction format: Bad field " + toString(m_f) + " (" + toHex(m_d) + ")"; } }; class InvalidBlockFormat: public dev::Exception { public: InvalidBlockFormat(int _f, bytesConstRef _d): m_f(_f), m_d(_d.toBytes()) {} int m_f; bytes m_d; virtual const char* what() const noexcept { return ("Invalid block format: Bad field " + toString(m_f) + " (" + toHex(m_d) + ")").c_str(); } };
class InvalidBlockFormat: public dev::Exception { public: InvalidBlockFormat(int _f, bytesConstRef _d): m_f(_f), m_d(_d.toBytes()) {} int m_f; bytes m_d; virtual std::string description() const { return "Invalid block format: Bad field " + toString(m_f) + " (" + toHex(m_d) + ")"; } }; struct InvalidUnclesHash: virtual dev::Exception {};
class InvalidBlockHeaderFormat: public dev::Exception { public: InvalidBlockHeaderFormat(int _f, bytesConstRef _d): m_f(_f), m_d(_d.toBytes()) {} int m_f; bytes m_d; virtual std::string description() const { return "Invalid block header format: Bad field " + toString(m_f) + " (" + toHex(m_d) + ")"; } }; struct InvalidUncle: virtual dev::Exception {};
class InvalidUnclesHash: public dev::Exception {}; struct UncleTooOld: virtual dev::Exception {};
class InvalidUncle: public dev::Exception {}; class UncleInChain: public dev::Exception { public: UncleInChain(h256Set _uncles, h256 _block): m_uncles(_uncles), m_block(_block) {} h256Set m_uncles; h256 m_block;virtual const char* what() const noexcept { return ("Uncle in block already mentioned: Uncles " + toString(m_uncles) + " (" + m_block.abridged() + ")").c_str(); } };
class UncleTooOld: public dev::Exception {}; struct DuplicateUncleNonce: virtual dev::Exception {};
class UncleInChain: public dev::Exception { public: UncleInChain(h256Set _uncles, h256 _block): m_uncles(_uncles), m_block(_block) {} h256Set m_uncles; h256 m_block; virtual std::string description() const { return "Uncle in block already mentioned: Uncles " + toString(m_uncles) + " (" + m_block.abridged() + ")"; } }; struct InvalidStateRoot: virtual dev::Exception {};
class DuplicateUncleNonce: public dev::Exception {}; class InvalidTransactionsHash: public dev::Exception { public: InvalidTransactionsHash(h256 _head, h256 _real): m_head(_head), m_real(_real) {} h256 m_head; h256 m_real; virtual const char* what() const noexcept { return ("Invalid transactions hash: header says: " + toHex(m_head.ref()) + " block is:" + toHex(m_real.ref())).c_str(); } };
class InvalidStateRoot: public dev::Exception {}; struct InvalidTransaction: virtual dev::Exception {};
class InvalidTransactionsHash: public dev::Exception { public: InvalidTransactionsHash(h256 _head, h256 _real): m_head(_head), m_real(_real) {} h256 m_head; h256 m_real; virtual std::string description() const { return "Invalid transactions hash: header says: " + toHex(m_head.ref()) + " block is:" + toHex(m_real.ref()); } }; struct InvalidDifficulty: virtual dev::Exception {};
class InvalidTransaction: public dev::Exception {}; class InvalidGasLimit: public dev::Exception { public: InvalidGasLimit(u256 _provided = 0, u256 _valid = 0): provided(_provided), valid(_valid) {} u256 provided; u256 valid; virtual const char* what() const noexcept { return ("Invalid gas limit (provided: " + toString(provided) + " valid:" + toString(valid) + ")").c_str(); } };
class InvalidDifficulty: public dev::Exception {}; class InvalidMinGasPrice: public dev::Exception { public: InvalidMinGasPrice(u256 _provided = 0, u256 _limit = 0): provided(_provided), limit(_limit) {} u256 provided; u256 limit; virtual const char* what() const noexcept { return ("Invalid minimum gas price (provided: " + toString(provided) + " limit:" + toString(limit) + ")").c_str(); } };
class InvalidGasLimit: public dev::Exception { public: InvalidGasLimit(u256 _provided = 0, u256 _valid = 0): provided(_provided), valid(_valid) {} u256 provided; u256 valid; virtual std::string description() const { return "Invalid gas limit (provided: " + toString(provided) + " valid:" + toString(valid) + ")"; } }; struct InvalidTransactionGasUsed: virtual dev::Exception {};
class InvalidMinGasPrice: public dev::Exception { public: InvalidMinGasPrice(u256 _provided = 0, u256 _limit = 0): provided(_provided), limit(_limit) {} u256 provided; u256 limit; virtual std::string description() const { return "Invalid minimum gas price (provided: " + toString(provided) + " limit:" + toString(limit) + ")"; } }; struct InvalidTransactionStateRoot: virtual dev::Exception {};
class InvalidTransactionGasUsed: public dev::Exception {}; struct InvalidTimestamp: virtual dev::Exception {};
class InvalidTransactionStateRoot: public dev::Exception {}; class InvalidNonce: public dev::Exception { public: InvalidNonce(u256 _required = 0, u256 _candidate = 0): required(_required), candidate(_candidate) {} u256 required; u256 candidate; virtual const char* what() const noexcept { return ("Invalid nonce (r: " + toString(required) + " c:" + toString(candidate) + ")").c_str(); } };
class InvalidTimestamp: public dev::Exception {}; class InvalidBlockNonce: public dev::Exception { public: InvalidBlockNonce(h256 _h = h256(), h256 _n = h256(), u256 _d = 0): h(_h), n(_n), d(_d) {} h256 h; h256 n; u256 d; virtual const char* what() const noexcept { return ("Invalid nonce (h: " + toString(h) + " n:" + toString(n) + " d:" + toString(d) + ")").c_str(); } };
class InvalidNonce: public dev::Exception { public: InvalidNonce(u256 _required = 0, u256 _candidate = 0): required(_required), candidate(_candidate) {} u256 required; u256 candidate; virtual std::string description() const { return "Invalid nonce (r: " + toString(required) + " c:" + toString(candidate) + ")"; } }; struct InvalidParentHash: virtual dev::Exception {};
class InvalidBlockNonce: public dev::Exception { public: InvalidBlockNonce(h256 _h = h256(), h256 _n = h256(), u256 _d = 0): h(_h), n(_n), d(_d) {} h256 h; h256 n; u256 d; virtual std::string description() const { return "Invalid nonce (h: " + toString(h) + " n:" + toString(n) + " d:" + toString(d) + ")"; } }; struct InvalidNumber: virtual dev::Exception {};
class InvalidParentHash: public dev::Exception {}; struct InvalidContractAddress: virtual dev::Exception {};
class InvalidNumber: public dev::Exception {};
class InvalidContractAddress: public dev::Exception {};
} }
} }

21
libethereum/BlockChain.cpp

@ -137,9 +137,9 @@ void BlockChain::open(std::string _path, bool _killExisting)
ldb::DB::Open(o, _path + "/blocks", &m_db); ldb::DB::Open(o, _path + "/blocks", &m_db);
ldb::DB::Open(o, _path + "/details", &m_extrasDB); ldb::DB::Open(o, _path + "/details", &m_extrasDB);
if (!m_db) if (!m_db)
throw DatabaseAlreadyOpen(); BOOST_THROW_EXCEPTION(DatabaseAlreadyOpen());
if (!m_extrasDB) if (!m_extrasDB)
throw DatabaseAlreadyOpen(); BOOST_THROW_EXCEPTION(DatabaseAlreadyOpen());
if (!details(m_genesisHash)) if (!details(m_genesisHash))
{ {
@ -211,12 +211,12 @@ h256s BlockChain::sync(BlockQueue& _bq, OverlayDB const& _stateDB, unsigned _max
} }
catch (UnknownParent) catch (UnknownParent)
{ {
cwarn << "Unknown parent of block!!!" << BlockInfo::headerHash(block).abridged(); cwarn << "Unknown parent of block!!!" << BlockInfo::headerHash(block).abridged() << boost::current_exception_diagnostic_information();
_bq.import(&block, *this); _bq.import(&block, *this);
} }
catch (Exception const& _e) catch (Exception const& _e)
{ {
cwarn << "Unexpected exception!" << _e.description(); cwarn << "Unexpected exception!" << diagnostic_information(_e);
_bq.import(&block, *this); _bq.import(&block, *this);
} }
catch (...) catch (...)
@ -234,6 +234,7 @@ h256s BlockChain::attemptImport(bytes const& _block, OverlayDB const& _stateDB)
} }
catch (...) catch (...)
{ {
cwarn << "Unexpected exception! Could not import block!" << boost::current_exception_diagnostic_information();
return h256s(); return h256s();
} }
} }
@ -253,7 +254,8 @@ h256s BlockChain::import(bytes const& _block, OverlayDB const& _db)
#if ETH_CATCH #if ETH_CATCH
catch (Exception const& _e) catch (Exception const& _e)
{ {
clog(BlockChainNote) << " Malformed block (" << _e.description() << ")."; clog(BlockChainNote) << " Malformed block: " << diagnostic_information(_e);
_e << errinfo_comment("Malformed block ");
throw; throw;
} }
#endif #endif
@ -263,7 +265,7 @@ h256s BlockChain::import(bytes const& _block, OverlayDB const& _db)
if (isKnown(newHash)) if (isKnown(newHash))
{ {
clog(BlockChainNote) << newHash << ": Not new."; clog(BlockChainNote) << newHash << ": Not new.";
throw AlreadyHaveBlock(); BOOST_THROW_EXCEPTION(AlreadyHaveBlock());
} }
// Work out its number as the parent's number + 1 // Work out its number as the parent's number + 1
@ -271,7 +273,7 @@ h256s BlockChain::import(bytes const& _block, OverlayDB const& _db)
{ {
clog(BlockChainNote) << newHash << ": Unknown parent " << bi.parentHash; clog(BlockChainNote) << newHash << ": Unknown parent " << bi.parentHash;
// We don't know the parent (yet) - discard for now. It'll get resent to us if we find out about its ancestry later on. // We don't know the parent (yet) - discard for now. It'll get resent to us if we find out about its ancestry later on.
throw UnknownParent(); BOOST_THROW_EXCEPTION(UnknownParent());
} }
auto pd = details(bi.parentHash); auto pd = details(bi.parentHash);
@ -286,7 +288,7 @@ h256s BlockChain::import(bytes const& _block, OverlayDB const& _db)
{ {
clog(BlockChainNote) << newHash << ": Future time " << bi.timestamp << " (now at " << time(0) << ")"; clog(BlockChainNote) << newHash << ": Future time " << bi.timestamp << " (now at " << time(0) << ")";
// Block has a timestamp in the future. This is no good. // Block has a timestamp in the future. This is no good.
throw FutureTime(); BOOST_THROW_EXCEPTION(FutureTime());
} }
clog(BlockChainNote) << "Attempting import of " << newHash.abridged() << "..."; clog(BlockChainNote) << "Attempting import of " << newHash.abridged() << "...";
@ -342,7 +344,8 @@ h256s BlockChain::import(bytes const& _block, OverlayDB const& _db)
#if ETH_CATCH #if ETH_CATCH
catch (Exception const& _e) catch (Exception const& _e)
{ {
clog(BlockChainNote) << " Malformed block (" << _e.description() << ")."; clog(BlockChainNote) << " Malformed block: " << diagnostic_information(_e);
_e << errinfo_comment("Malformed block ");
throw; throw;
} }
#endif #endif

7
libethereum/BlockChain.h

@ -28,6 +28,7 @@
#include <mutex> #include <mutex>
#include <libdevcore/Log.h> #include <libdevcore/Log.h>
#include <libdevcore/Exceptions.h>
#include <libethcore/CommonEth.h> #include <libethcore/CommonEth.h>
#include <libethcore/BlockInfo.h> #include <libethcore/BlockInfo.h>
#include <libdevcore/Guards.h> #include <libdevcore/Guards.h>
@ -46,9 +47,9 @@ static const h256s NullH256s;
class State; class State;
class OverlayDB; class OverlayDB;
class AlreadyHaveBlock: public std::exception {}; struct AlreadyHaveBlock: virtual Exception {};
class UnknownParent: public std::exception {}; struct UnknownParent: virtual Exception {};
class FutureTime: public std::exception {}; struct FutureTime: virtual Exception {};
struct BlockChainChat: public LogChannel { static const char* name() { return "-B-"; } static const int verbosity = 7; }; struct BlockChainChat: public LogChannel { static const char* name() { return "-B-"; } static const int verbosity = 7; };
struct BlockChainNote: public LogChannel { static const char* name() { return "=B="; } static const int verbosity = 4; }; struct BlockChainNote: public LogChannel { static const char* name() { return "=B="; } static const int verbosity = 4; };

2
libethereum/BlockQueue.cpp

@ -58,7 +58,7 @@ bool BlockQueue::import(bytesConstRef _block, BlockChain const& _bc)
#if ETH_CATCH #if ETH_CATCH
catch (Exception const& _e) catch (Exception const& _e)
{ {
cwarn << "Ignoring malformed block: " << _e.description(); cwarn << "Ignoring malformed block: " << diagnostic_information(_e);
return false; return false;
} }
#endif #endif

5
libethereum/Client.cpp

@ -47,7 +47,10 @@ void VersionChecker::setOk()
{ {
boost::filesystem::create_directory(m_path); boost::filesystem::create_directory(m_path);
} }
catch (...) {} catch (...)
{
cwarn << "Unhandled exception! Failed to create directory: " << m_path << "\n" << boost::current_exception_diagnostic_information();
}
writeFile(m_path + "/protocol", rlp(c_protocolVersion)); writeFile(m_path + "/protocol", rlp(c_protocolVersion));
writeFile(m_path + "/database", rlp(c_databaseVersion)); writeFile(m_path + "/database", rlp(c_databaseVersion));
} }

14
libethereum/Executive.cpp

@ -54,14 +54,14 @@ bool Executive::setup(bytesConstRef _rlp)
if (m_t.nonce != nonceReq) if (m_t.nonce != nonceReq)
{ {
clog(StateChat) << "Invalid Nonce: Require" << nonceReq << " Got" << m_t.nonce; clog(StateChat) << "Invalid Nonce: Require" << nonceReq << " Got" << m_t.nonce;
throw InvalidNonce(nonceReq, m_t.nonce); BOOST_THROW_EXCEPTION(InvalidNonce(nonceReq, m_t.nonce));
} }
// Don't like transactions whose gas price is too low. NOTE: this won't stay here forever - it's just until we get a proper gas price discovery protocol going. // Don't like transactions whose gas price is too low. NOTE: this won't stay here forever - it's just until we get a proper gas price discovery protocol going.
if (m_t.gasPrice < m_s.m_currentBlock.minGasPrice) if (m_t.gasPrice < m_s.m_currentBlock.minGasPrice)
{ {
clog(StateChat) << "Offered gas-price is too low: Require >" << m_s.m_currentBlock.minGasPrice << " Got" << m_t.gasPrice; clog(StateChat) << "Offered gas-price is too low: Require >" << m_s.m_currentBlock.minGasPrice << " Got" << m_t.gasPrice;
throw GasPriceTooLow(); BOOST_THROW_EXCEPTION(GasPriceTooLow());
} }
// Check gas cost is enough. // Check gas cost is enough.
@ -70,7 +70,7 @@ bool Executive::setup(bytesConstRef _rlp)
if (m_t.gas < gasCost) if (m_t.gas < gasCost)
{ {
clog(StateChat) << "Not enough gas to pay for the transaction: Require >" << gasCost << " Got" << m_t.gas; clog(StateChat) << "Not enough gas to pay for the transaction: Require >" << gasCost << " Got" << m_t.gas;
throw OutOfGas(); BOOST_THROW_EXCEPTION(OutOfGas());
} }
u256 cost = m_t.value + m_t.gas * m_t.gasPrice; u256 cost = m_t.value + m_t.gas * m_t.gasPrice;
@ -79,14 +79,14 @@ bool Executive::setup(bytesConstRef _rlp)
if (m_s.balance(m_sender) < cost) if (m_s.balance(m_sender) < cost)
{ {
clog(StateChat) << "Not enough cash: Require >" << cost << " Got" << m_s.balance(m_sender); clog(StateChat) << "Not enough cash: Require >" << cost << " Got" << m_s.balance(m_sender);
throw NotEnoughCash(); BOOST_THROW_EXCEPTION(NotEnoughCash());
} }
u256 startGasUsed = m_s.gasUsed(); u256 startGasUsed = m_s.gasUsed();
if (startGasUsed + m_t.gas > m_s.m_currentBlock.gasLimit) if (startGasUsed + m_t.gas > m_s.m_currentBlock.gasLimit)
{ {
clog(StateChat) << "Too much gas used in this block: Require <" << (m_s.m_currentBlock.gasLimit - startGasUsed) << " Got" << m_t.gas; clog(StateChat) << "Too much gas used in this block: Require <" << (m_s.m_currentBlock.gasLimit - startGasUsed) << " Got" << m_t.gas;
throw BlockGasLimitReached(); BOOST_THROW_EXCEPTION(BlockGasLimitReached());
} }
// Increment associated nonce for sender. // Increment associated nonce for sender.
@ -186,12 +186,12 @@ bool Executive::go(OnOpFunc const& _onOp)
} }
catch (VMException const& _e) catch (VMException const& _e)
{ {
clog(StateChat) << "VM Exception: " << _e.description(); clog(StateChat) << "VM Exception: " << diagnostic_information(_e);
m_endGas = m_vm->gas(); m_endGas = m_vm->gas();
} }
catch (Exception const& _e) catch (Exception const& _e)
{ {
clog(StateChat) << "Exception in VM: " << _e.description(); clog(StateChat) << "Exception in VM: " << diagnostic_information(_e);
} }
catch (std::exception const& _e) catch (std::exception const& _e)
{ {

51
libethereum/State.cpp

@ -54,7 +54,7 @@ OverlayDB State::openDB(std::string _path, bool _killExisting)
ldb::DB* db = nullptr; ldb::DB* db = nullptr;
ldb::DB::Open(o, _path + "/state", &db); ldb::DB::Open(o, _path + "/state", &db);
if (!db) if (!db)
throw DatabaseAlreadyOpen(); BOOST_THROW_EXCEPTION(DatabaseAlreadyOpen());
cnote << "Opened state DB."; cnote << "Opened state DB.";
return OverlayDB(db); return OverlayDB(db);
@ -133,7 +133,7 @@ void State::paranoia(std::string const& _when, bool _enforceRefs) const
if (!isTrieGood(_enforceRefs, false)) if (!isTrieGood(_enforceRefs, false))
{ {
cwarn << "BAD TRIE" << _when; cwarn << "BAD TRIE" << _when;
throw InvalidTrie(); BOOST_THROW_EXCEPTION(InvalidTrie());
} }
#else #else
(void)_when; (void)_when;
@ -334,7 +334,7 @@ bool State::sync(BlockChain const& _bc, h256 _block, BlockInfo const& _bi)
{ {
// TODO: Slightly nicer handling? :-) // TODO: Slightly nicer handling? :-)
cerr << "ERROR: Corrupt block-chain! Delete your block-chain DB and restart." << endl; cerr << "ERROR: Corrupt block-chain! Delete your block-chain DB and restart." << endl;
cerr << _e.description() << endl; cerr << diagnostic_information(_e) << endl;
} }
catch (std::exception const& _e) catch (std::exception const& _e)
{ {
@ -386,6 +386,7 @@ bool State::sync(BlockChain const& _bc, h256 _block, BlockInfo const& _bi)
{ {
// TODO: Slightly nicer handling? :-) // TODO: Slightly nicer handling? :-)
cerr << "ERROR: Corrupt block-chain! Delete your block-chain DB and restart." << endl; cerr << "ERROR: Corrupt block-chain! Delete your block-chain DB and restart." << endl;
cerr << boost::current_exception_diagnostic_information() << endl;
exit(1); exit(1);
} }
@ -503,6 +504,14 @@ h256s State::sync(TransactionQueue& _tq, bool* o_transactionQueueChanged)
else else
_tq.setFuture(i); _tq.setFuture(i);
} }
catch (Exception const& _e)
{
// Something else went wrong - drop it.
_tq.drop(i.first);
if (o_transactionQueueChanged)
*o_transactionQueueChanged = true;
cwarn << "Sync went wrong\n" << diagnostic_information(_e);
}
catch (std::exception const&) catch (std::exception const&)
{ {
// Something else went wrong - drop it. // Something else went wrong - drop it.
@ -527,7 +536,7 @@ u256 State::enact(bytesConstRef _block, BlockChain const* _bc, bool _checkNonce)
#endif #endif
if (m_currentBlock.parentHash != m_previousBlock.hash) if (m_currentBlock.parentHash != m_previousBlock.hash)
throw InvalidParentHash(); BOOST_THROW_EXCEPTION(InvalidParentHash());
// Populate m_currentBlock with the correct values. // Populate m_currentBlock with the correct values.
m_currentBlock.populate(_block, _checkNonce); m_currentBlock.populate(_block, _checkNonce);
@ -553,10 +562,10 @@ u256 State::enact(bytesConstRef _block, BlockChain const* _bc, bool _checkNonce)
cnote << m_state.root() << "\n" << m_state; cnote << m_state.root() << "\n" << m_state;
cnote << *this; cnote << *this;
cnote << "INVALID: " << tr[1].toHash<h256>(); cnote << "INVALID: " << tr[1].toHash<h256>();
throw InvalidTransactionStateRoot(); BOOST_THROW_EXCEPTION(InvalidTransactionStateRoot());
} }
if (tr[2].toInt<u256>() != gasUsed()) if (tr[2].toInt<u256>() != gasUsed())
throw InvalidTransactionGasUsed(); BOOST_THROW_EXCEPTION(InvalidTransactionGasUsed());
bytes k = rlp(i); bytes k = rlp(i);
transactionManifest.insert(&k, tr.data()); transactionManifest.insert(&k, tr.data());
++i; ++i;
@ -565,7 +574,7 @@ u256 State::enact(bytesConstRef _block, BlockChain const* _bc, bool _checkNonce)
if (m_currentBlock.transactionsRoot && transactionManifest.root() != m_currentBlock.transactionsRoot) if (m_currentBlock.transactionsRoot && transactionManifest.root() != m_currentBlock.transactionsRoot)
{ {
cwarn << "Bad transactions state root!"; cwarn << "Bad transactions state root!";
throw InvalidTransactionStateRoot(); BOOST_THROW_EXCEPTION(InvalidTransactionStateRoot());
} }
// Initialise total difficulty calculation. // Initialise total difficulty calculation.
@ -578,16 +587,16 @@ u256 State::enact(bytesConstRef _block, BlockChain const* _bc, bool _checkNonce)
for (auto const& i: RLP(_block)[2]) for (auto const& i: RLP(_block)[2])
{ {
if (knownUncles.count(sha3(i.data()))) if (knownUncles.count(sha3(i.data())))
throw UncleInChain(knownUncles, sha3(i.data())); BOOST_THROW_EXCEPTION(UncleInChain(knownUncles, sha3(i.data()) ));
BlockInfo uncle = BlockInfo::fromHeader(i.data()); BlockInfo uncle = BlockInfo::fromHeader(i.data());
if (nonces.count(uncle.nonce)) if (nonces.count(uncle.nonce))
throw DuplicateUncleNonce(); BOOST_THROW_EXCEPTION(DuplicateUncleNonce());
if (_bc) if (_bc)
{ {
BlockInfo uncleParent(_bc->block(uncle.parentHash)); BlockInfo uncleParent(_bc->block(uncle.parentHash));
if ((bigint)uncleParent.number < (bigint)m_currentBlock.number - 6) if ((bigint)uncleParent.number < (bigint)m_currentBlock.number - 6)
throw UncleTooOld(); BOOST_THROW_EXCEPTION(UncleTooOld());
uncle.verifyParent(uncleParent); uncle.verifyParent(uncleParent);
} }
@ -611,7 +620,7 @@ u256 State::enact(bytesConstRef _block, BlockChain const* _bc, bool _checkNonce)
cnote << *this; cnote << *this;
// Rollback the trie. // Rollback the trie.
m_db.rollback(); m_db.rollback();
throw InvalidStateRoot(); BOOST_THROW_EXCEPTION(InvalidStateRoot());
} }
return tdIncrease; return tdIncrease;
@ -677,13 +686,13 @@ bool State::amIJustParanoid(BlockChain const& _bc)
s.cleanup(false); s.cleanup(false);
return true; return true;
} }
catch (Exception const& e) catch (Exception const& _e)
{ {
cwarn << "Bad block: " << e.description(); cwarn << "Bad block: " << diagnostic_information(_e);
} }
catch (std::exception const& e) catch (std::exception const& _e)
{ {
cwarn << "Bad block: " << e.what(); cwarn << "Bad block: " << _e.what();
} }
return false; return false;
@ -863,7 +872,7 @@ void State::subBalance(Address _id, bigint _amount)
ensureCached(_id, false, false); ensureCached(_id, false, false);
auto it = m_cache.find(_id); auto it = m_cache.find(_id);
if (it == m_cache.end() || (bigint)it->second.balance() < _amount) if (it == m_cache.end() || (bigint)it->second.balance() < _amount)
throw NotEnoughCash(); BOOST_THROW_EXCEPTION(NotEnoughCash());
else else
it->second.addBalance(-_amount); it->second.addBalance(-_amount);
} }
@ -1038,7 +1047,7 @@ u256 State::execute(bytesConstRef _rlp, bytes* o_output, bool _commit)
if (storageRoot(e.t().receiveAddress) && m_db.lookup(storageRoot(e.t().receiveAddress)).empty()) if (storageRoot(e.t().receiveAddress) && m_db.lookup(storageRoot(e.t().receiveAddress)).empty())
{ {
cwarn << "TRIE immediately after execution; no node for receiveAddress"; cwarn << "TRIE immediately after execution; no node for receiveAddress";
throw InvalidTrie(); BOOST_THROW_EXCEPTION(InvalidTrie());
} }
} }
#endif #endif
@ -1093,11 +1102,11 @@ bool State::call(Address _receiveAddress, Address _codeAddress, Address _senderA
} }
catch (VMException const& _e) catch (VMException const& _e)
{ {
clog(StateChat) << "VM Exception: " << _e.description(); clog(StateChat) << "VM Exception: " << diagnostic_information(_e);
} }
catch (Exception const& _e) catch (Exception const& _e)
{ {
clog(StateChat) << "Exception in VM: " << _e.description(); clog(StateChat) << "Exception in VM: " << diagnostic_information(_e);
} }
catch (std::exception const& _e) catch (std::exception const& _e)
{ {
@ -1160,11 +1169,11 @@ h160 State::create(Address _sender, u256 _endowment, u256 _gasPrice, u256* _gas,
} }
catch (VMException const& _e) catch (VMException const& _e)
{ {
clog(StateChat) << "VM Exception: " << _e.description(); clog(StateChat) << "VM Exception: " << diagnostic_information(_e);
} }
catch (Exception const& _e) catch (Exception const& _e)
{ {
clog(StateChat) << "Exception in VM: " << _e.description(); clog(StateChat) << "Exception in VM: " << diagnostic_information(_e);
} }
catch (std::exception const& _e) catch (std::exception const& _e)
{ {

10
libethereum/Transaction.cpp

@ -46,9 +46,10 @@ Transaction::Transaction(bytesConstRef _rlpData, bool _checkSender)
if (_checkSender) if (_checkSender)
m_sender = sender(); m_sender = sender();
} }
catch (RLPException const&) catch (Exception & _e)
{ {
throw InvalidTransactionFormat(field, rlp[field].data()); _e << errinfo_name("invalid transaction format") << BadFieldError(field,toHex(rlp[field].data().toBytes()));
throw;
} }
} }
@ -60,6 +61,7 @@ Address Transaction::safeSender() const noexcept
} }
catch (...) catch (...)
{ {
cwarn << "safeSender() did throw an exception: " << boost::current_exception_diagnostic_information();
return Address(); return Address();
} }
} }
@ -76,7 +78,7 @@ Address Transaction::sender() const
byte pubkey[65]; byte pubkey[65];
int pubkeylen = 65; int pubkeylen = 65;
if (!secp256k1_ecdsa_recover_compact(msg.data(), 32, sig[0].data(), pubkey, &pubkeylen, 0, (int)vrs.v - 27)) if (!secp256k1_ecdsa_recover_compact(msg.data(), 32, sig[0].data(), pubkey, &pubkeylen, 0, (int)vrs.v - 27))
throw InvalidSignature(); BOOST_THROW_EXCEPTION(InvalidSignature());
// TODO: check right160 is correct and shouldn't be left160. // TODO: check right160 is correct and shouldn't be left160.
m_sender = right160(dev::eth::sha3(bytesConstRef(&(pubkey[1]), 64))); m_sender = right160(dev::eth::sha3(bytesConstRef(&(pubkey[1]), 64)));
@ -103,7 +105,7 @@ void Transaction::sign(Secret _priv)
h256 nonce = kFromMessage(msg, _priv); h256 nonce = kFromMessage(msg, _priv);
if (!secp256k1_ecdsa_sign_compact(msg.data(), 32, sig[0].data(), _priv.data(), nonce.data(), &v)) if (!secp256k1_ecdsa_sign_compact(msg.data(), 32, sig[0].data(), _priv.data(), nonce.data(), &v))
throw InvalidSignature(); BOOST_THROW_EXCEPTION(InvalidSignature());
#if ETH_ADDRESS_DEBUG #if ETH_ADDRESS_DEBUG
cout << "---- SIGN -------------------------------" << endl; cout << "---- SIGN -------------------------------" << endl;
cout << "MSG: " << msg << endl; cout << "MSG: " << msg << endl;

4
libethereum/TransactionQueue.cpp

@ -49,9 +49,9 @@ bool TransactionQueue::import(bytesConstRef _transactionRLP)
m_current[h] = _transactionRLP.toBytes(); m_current[h] = _transactionRLP.toBytes();
m_known.insert(h); m_known.insert(h);
} }
catch (InvalidTransactionFormat const& _e) catch (Exception const& _e)
{ {
cwarn << "Ignoring invalid transaction: " << _e.description(); cwarn << "Ignoring invalid transaction: " << diagnostic_information(_e);
return false; return false;
} }
catch (std::exception const& _e) catch (std::exception const& _e)

18
libevm/VM.h

@ -35,11 +35,11 @@ namespace dev
namespace eth namespace eth
{ {
class VMException: public Exception {}; struct VMException: virtual Exception {};
class StepsDone: public VMException {}; struct StepsDone: virtual VMException {};
class BreakPointHit: public VMException {}; struct BreakPointHit: virtual VMException {};
class BadInstruction: public VMException {}; struct BadInstruction: virtual VMException {};
class OutOfGas: public VMException {}; struct OutOfGas: virtual VMException {};
class StackTooSmall: public VMException { public: StackTooSmall(u256 _req, u256 _got): req(_req), got(_got) {} u256 req; u256 got; }; class StackTooSmall: public VMException { public: StackTooSmall(u256 _req, u256 _got): req(_req), got(_got) {} u256 req; u256 got; };
// Convert from a 256-bit integer stack/memory entry into a 160-bit Address hash. // Convert from a 256-bit integer stack/memory entry into a 160-bit Address hash.
@ -70,7 +70,7 @@ public:
template <class Ext> template <class Ext>
bytesConstRef go(Ext& _ext, OnOpFunc const& _onOp = OnOpFunc(), uint64_t _steps = (uint64_t)-1); bytesConstRef go(Ext& _ext, OnOpFunc const& _onOp = OnOpFunc(), uint64_t _steps = (uint64_t)-1);
void require(u256 _n) { if (m_stack.size() < _n) throw StackTooSmall(_n, m_stack.size()); } void require(u256 _n) { if (m_stack.size() < _n) BOOST_THROW_EXCEPTION(StackTooSmall(_n, m_stack.size())); }
void requireMem(unsigned _n) { if (m_temp.size() < _n) { m_temp.resize(_n); } } void requireMem(unsigned _n) { if (m_temp.size() < _n) { m_temp.resize(_n); } }
u256 gas() const { return m_gas; } u256 gas() const { return m_gas; }
u256 curPC() const { return m_curPC; } u256 curPC() const { return m_curPC; }
@ -208,7 +208,7 @@ template <class Ext> dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con
{ {
// Out of gas! // Out of gas!
m_gas = 0; m_gas = 0;
throw OutOfGas(); BOOST_THROW_EXCEPTION(OutOfGas());
} }
m_gas = (u256)((bigint)m_gas - runGas); m_gas = (u256)((bigint)m_gas - runGas);
@ -686,11 +686,11 @@ template <class Ext> dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con
break; break;
} }
default: default:
throw BadInstruction(); BOOST_THROW_EXCEPTION(BadInstruction());
} }
} }
if (_steps == (uint64_t)-1) if (_steps == (uint64_t)-1)
throw StepsDone(); BOOST_THROW_EXCEPTION(StepsDone());
return bytesConstRef(); return bytesConstRef();
} }
} }

2
libevmface/Instruction.cpp

@ -22,6 +22,7 @@
#include "Instruction.h" #include "Instruction.h"
#include <libdevcore/Common.h> #include <libdevcore/Common.h>
#include <libdevcore/Log.h>
using namespace std; using namespace std;
using namespace dev; using namespace dev;
using namespace dev::eth; using namespace dev::eth;
@ -312,6 +313,7 @@ InstructionInfo dev::eth::instructionInfo(Instruction _inst)
} }
catch (...) catch (...)
{ {
cwarn << "<INVALID_INSTRUCTION: " << toString((unsigned)_inst) << ">\n" << boost::current_exception_diagnostic_information();
return InstructionInfo({"<INVALID_INSTRUCTION: " + toString((unsigned)_inst) + ">", 0, 0, 0}); return InstructionInfo({"<INVALID_INSTRUCTION: " + toString((unsigned)_inst) + ">", 0, 0, 0});
} }
} }

2
liblll/Assembly.cpp

@ -102,7 +102,7 @@ void Assembly::append(Assembly const& _a)
void Assembly::append(Assembly const& _a, int _deposit) void Assembly::append(Assembly const& _a, int _deposit)
{ {
if (_deposit > _a.m_deposit) if (_deposit > _a.m_deposit)
throw InvalidDeposit(); BOOST_THROW_EXCEPTION(InvalidDeposit());
else else
{ {
append(_a); append(_a);

2
liblll/Assembly.h

@ -111,7 +111,7 @@ public:
std::ostream& streamOut(std::ostream& _out, std::string const& _prefix = "") const; std::ostream& streamOut(std::ostream& _out, std::string const& _prefix = "") const;
private: private:
void donePath() { if (m_totalDeposit != INT_MAX && m_totalDeposit != m_deposit) throw InvalidDeposit(); } void donePath() { if (m_totalDeposit != INT_MAX && m_totalDeposit != m_deposit) BOOST_THROW_EXCEPTION(InvalidDeposit()); }
unsigned bytesRequired() const; unsigned bytesRequired() const;
unsigned m_usedTags = 0; unsigned m_usedTags = 0;

2
liblll/CodeFragment.h

@ -50,7 +50,7 @@ public:
private: private:
void finalise(CompilerState const& _cs); void finalise(CompilerState const& _cs);
template <class T> void error() const { throw T(); } template <class T> void error() const { BOOST_THROW_EXCEPTION(T() ); }
void constructOperation(sp::utree const& _t, CompilerState& _s); void constructOperation(sp::utree const& _t, CompilerState& _s);
bool m_finalised = false; bool m_finalised = false;

7
liblll/Compiler.cpp

@ -43,7 +43,10 @@ bytes dev::eth::compileLLL(string const& _src, bool _opt, vector<string>* _error
catch (Exception const& _e) catch (Exception const& _e)
{ {
if (_errors) if (_errors)
_errors->push_back(_e.description()); {
_errors->push_back("Parse error.");
_errors->push_back(diagnostic_information(_e));
}
} }
catch (std::exception) catch (std::exception)
{ {
@ -67,7 +70,7 @@ std::string dev::eth::compileLLLToAsm(std::string const& _src, bool _opt, std::v
catch (Exception const& _e) catch (Exception const& _e)
{ {
if (_errors) if (_errors)
_errors->push_back(_e.description()); _errors->push_back(diagnostic_information(_e));
} }
catch (std::exception) catch (std::exception)
{ {

2
liblll/Parser.cpp

@ -140,6 +140,6 @@ void dev::eth::parseTreeLLL(string const& _s, sp::utree& o_out)
qi::phrase_parse(ret, s.cend(), element, space, qi::skip_flag::dont_postskip, o_out); qi::phrase_parse(ret, s.cend(), element, space, qi::skip_flag::dont_postskip, o_out);
for (auto i = ret; i != s.cend(); ++i) for (auto i = ret; i != s.cend(); ++i)
if (!isspace(*i)) if (!isspace(*i))
throw std::exception(); BOOST_THROW_EXCEPTION(std::exception());
} }

23
libp2p/Host.cpp

@ -96,7 +96,7 @@ void Host::start()
{ {
if (i) if (i)
{ {
cwarn << "Couldn't start accepting connections on host. Something very wrong with network?"; cwarn << "Couldn't start accepting connections on host. Something very wrong with network?\n" << boost::current_exception_diagnostic_information();
return; return;
} }
m_acceptor.close(); m_acceptor.close();
@ -238,14 +238,14 @@ void Host::populateAddresses()
#ifdef _WIN32 #ifdef _WIN32
WSAData wsaData; WSAData wsaData;
if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0) if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0)
throw NoNetworking(); BOOST_THROW_EXCEPTION(NoNetworking());
char ac[80]; char ac[80];
if (gethostname(ac, sizeof(ac)) == SOCKET_ERROR) if (gethostname(ac, sizeof(ac)) == SOCKET_ERROR)
{ {
clog(NetWarn) << "Error " << WSAGetLastError() << " when getting local host name."; clog(NetWarn) << "Error " << WSAGetLastError() << " when getting local host name.";
WSACleanup(); WSACleanup();
throw NoNetworking(); BOOST_THROW_EXCEPTION(NoNetworking());
} }
struct hostent* phe = gethostbyname(ac); struct hostent* phe = gethostbyname(ac);
@ -253,7 +253,7 @@ void Host::populateAddresses()
{ {
clog(NetWarn) << "Bad host lookup."; clog(NetWarn) << "Bad host lookup.";
WSACleanup(); WSACleanup();
throw NoNetworking(); BOOST_THROW_EXCEPTION(NoNetworking());
} }
for (int i = 0; phe->h_addr_list[i] != 0; ++i) for (int i = 0; phe->h_addr_list[i] != 0; ++i)
@ -273,7 +273,7 @@ void Host::populateAddresses()
#else #else
ifaddrs* ifaddr; ifaddrs* ifaddr;
if (getifaddrs(&ifaddr) == -1) if (getifaddrs(&ifaddr) == -1)
throw NoNetworking(); BOOST_THROW_EXCEPTION(NoNetworking());
bi::tcp::resolver r(m_ioService); bi::tcp::resolver r(m_ioService);
@ -341,6 +341,7 @@ void Host::ensureAccepting()
m_acceptor.async_accept(m_socket, [=](boost::system::error_code ec) m_acceptor.async_accept(m_socket, [=](boost::system::error_code ec)
{ {
if (!ec) if (!ec)
{
try try
{ {
try { try {
@ -351,10 +352,15 @@ void Host::ensureAccepting()
auto p = std::make_shared<Session>(this, std::move(m_socket), remoteAddress); auto p = std::make_shared<Session>(this, std::move(m_socket), remoteAddress);
p->start(); p->start();
} }
catch (Exception const& _e)
{
clog(NetWarn) << "ERROR: " << diagnostic_information(_e);
}
catch (std::exception const& _e) catch (std::exception const& _e)
{ {
clog(NetWarn) << "ERROR: " << _e.what(); clog(NetWarn) << "ERROR: " << _e.what();
} }
}
m_accepting = false; m_accepting = false;
if (ec.value() < 1) if (ec.value() < 1)
ensureAccepting(); ensureAccepting();
@ -372,6 +378,7 @@ string Host::pocHost()
void Host::connect(std::string const& _addr, unsigned short _port) noexcept void Host::connect(std::string const& _addr, unsigned short _port) noexcept
{ {
for (int i = 0; i < 2; ++i) for (int i = 0; i < 2; ++i)
{
try try
{ {
if (i == 0) if (i == 0)
@ -383,12 +390,18 @@ void Host::connect(std::string const& _addr, unsigned short _port) noexcept
connect(bi::tcp::endpoint(bi::address::from_string(_addr), _port)); connect(bi::tcp::endpoint(bi::address::from_string(_addr), _port));
break; break;
} }
catch (Exception const& _e)
{
// Couldn't connect
clog(NetConnect) << "Bad host " << _addr << "\n" << diagnostic_information(_e);
}
catch (exception const& e) catch (exception const& e)
{ {
// Couldn't connect // Couldn't connect
clog(NetConnect) << "Bad host " << _addr << " (" << e.what() << ")"; clog(NetConnect) << "Bad host " << _addr << " (" << e.what() << ")";
} }
} }
}
void Host::connect(bi::tcp::endpoint const& _ep) void Host::connect(bi::tcp::endpoint const& _ep)
{ {

2
libp2p/Session.cpp

@ -418,7 +418,7 @@ void Session::doRead()
} }
catch (Exception const& _e) catch (Exception const& _e)
{ {
clogS(NetWarn) << "ERROR: " << _e.description(); clogS(NetWarn) << "ERROR: " << diagnostic_information(_e);
dropped(); dropped();
} }
catch (std::exception const& _e) catch (std::exception const& _e)

2
libp2p/UPnP.cpp

@ -87,7 +87,7 @@ UPnP::UPnP()
#endif #endif
{ {
cnote << "UPnP device not found."; cnote << "UPnP device not found.";
throw NoUPnPDevice(); BOOST_THROW_EXCEPTION(NoUPnPDevice());
} }
} }

5
libserpent/util.cpp

@ -6,6 +6,7 @@
#include "bignum.h" #include "bignum.h"
#include <fstream> #include <fstream>
#include <cerrno> #include <cerrno>
#include <libdevcore/Exceptions.h>
//Token or value node constructor //Token or value node constructor
Node token(std::string val, Metadata met) { Node token(std::string val, Metadata met) {
@ -211,7 +212,7 @@ std::string get_file_contents(std::string filename)
in.close(); in.close();
return(contents); return(contents);
} }
throw(errno); BOOST_THROW_EXCEPTION(dev::FileError() << boost::errinfo_file_name(filename) << boost::errinfo_errno(errno));
} }
//Report error //Report error
@ -220,7 +221,7 @@ void err(std::string errtext, Metadata met) {
unsignedToDecimal(met.ln + 1) + ", char " + unsignedToDecimal(met.ch) + unsignedToDecimal(met.ln + 1) + ", char " + unsignedToDecimal(met.ch) +
"): " + errtext; "): " + errtext;
std::cerr << err << "\n"; std::cerr << err << "\n";
throw(err); BOOST_THROW_EXCEPTION(dev::Exception() << dev::errinfo_comment(err));
} }
//Bin to hex //Bin to hex

14
libwebthree/WebThree.h

@ -38,7 +38,7 @@
namespace dev namespace dev
{ {
class InterfaceNotSupported: public Exception { public: InterfaceNotSupported(std::string _f): m_f(_f) {} virtual std::string description() const { return "Interface " + m_f + " not supported."; } private: std::string m_f; }; class InterfaceNotSupported: public Exception { public: InterfaceNotSupported(std::string _f): m_f(_f) {} virtual const char* what() const noexcept { return ("Interface " + m_f + " not supported.").c_str(); } private: std::string m_f; };
enum WorkState enum WorkState
{ {
@ -73,9 +73,9 @@ public:
// The mainline interfaces: // The mainline interfaces:
eth::Client* ethereum() const { if (!m_ethereum) throw InterfaceNotSupported("eth"); return m_ethereum.get(); } eth::Client* ethereum() const { if (!m_ethereum) BOOST_THROW_EXCEPTION(InterfaceNotSupported("eth")); return m_ethereum.get(); }
shh::WhisperHost* whisper() const { if (!m_whisper) throw InterfaceNotSupported("shh"); return m_whisper.get(); } shh::WhisperHost* whisper() const { if (!m_whisper) BOOST_THROW_EXCEPTION(InterfaceNotSupported("shh")); return m_whisper.get(); }
bzz::Interface* swarm() const { throw InterfaceNotSupported("bzz"); } bzz::Interface* swarm() const { BOOST_THROW_EXCEPTION(InterfaceNotSupported("bzz")); }
// Misc stuff: // Misc stuff:
@ -183,9 +183,9 @@ public:
// The mainline interfaces. // The mainline interfaces.
eth::Interface* ethereum() const { if (!m_ethereum) throw InterfaceNotSupported("eth"); return m_ethereum; } eth::Interface* ethereum() const { if (!m_ethereum) BOOST_THROW_EXCEPTION(InterfaceNotSupported("eth")); return m_ethereum; }
shh::Interface* whisper() const { if (!m_whisper) throw InterfaceNotSupported("shh"); return m_whisper; } shh::Interface* whisper() const { if (!m_whisper) BOOST_THROW_EXCEPTION(InterfaceNotSupported("shh")); return m_whisper; }
bzz::Interface* swarm() const { throw InterfaceNotSupported("bzz"); } bzz::Interface* swarm() const { BOOST_THROW_EXCEPTION(InterfaceNotSupported("bzz")); }
// Peer network stuff - forward through RPCSlave, probably with P2PNetworkSlave/Master classes like Whisper & Ethereum. // Peer network stuff - forward through RPCSlave, probably with P2PNetworkSlave/Master classes like Whisper & Ethereum.

4
neth/main.cpp

@ -805,9 +805,9 @@ int main(int argc, char** argv)
cnote << "Saved" << rechex << "to" << outFile; cnote << "Saved" << rechex << "to" << outFile;
} }
catch (dev::eth::InvalidTrie) catch (dev::eth::InvalidTrie const& _e)
{ {
cwarn << "Corrupted trie."; cwarn << "Corrupted trie.\n" << diagnostic_information(_e);
} }
} }
} }

3
sc/cmdline.cpp

@ -5,6 +5,7 @@
#include <map> #include <map>
#include <string> #include <string>
#include <libserpent/funcs.h> #include <libserpent/funcs.h>
#include <libdevcore/Exceptions.h>
int main(int argv, char** argc) { int main(int argv, char** argc) {
if (argv == 1) { if (argv == 1) {
@ -28,7 +29,7 @@ int main(int argv, char** argc) {
else { else {
if (argv == 2) { if (argv == 2) {
std::cerr << "Not enough arguments for serpent cmdline\n"; std::cerr << "Not enough arguments for serpent cmdline\n";
throw(0); BOOST_THROW_EXCEPTION(dev::Exception() << dev::errinfo_comment("Not enough arguments for serpent cmdline"));
} }
input = argc[2]; input = argc[2];
secondInput = argv == 3 ? "" : argc[3]; secondInput = argv == 3 ? "" : argc[3];

25
test/vm.cpp

@ -435,9 +435,14 @@ void doTests(json_spirit::mValue& v, bool _fillin)
{ {
output = vm.go(fev).toBytes(); output = vm.go(fev).toBytes();
} }
catch (std::exception const& e) catch (Exception const& _e)
{ {
cnote << "VM did throw an exception: " << e.what(); cnote << "VM did throw an exception: " << diagnostic_information(_e);
//BOOST_ERROR("Failed VM Test with Exception: " << e.what());
}
catch (std::exception const& _e)
{
cnote << "VM did throw an exception: " << _e.what();
//BOOST_ERROR("Failed VM Test with Exception: " << e.what()); //BOOST_ERROR("Failed VM Test with Exception: " << e.what());
} }
@ -537,9 +542,13 @@ void executeTests(const string& _name)
dev::test::doTests(v, true); dev::test::doTests(v, true);
writeFile("../../../tests/" + _name + ".json", asBytes(json_spirit::write_string(v, true))); writeFile("../../../tests/" + _name + ".json", asBytes(json_spirit::write_string(v, true)));
} }
catch (std::exception const& e) catch (Exception const& _e)
{ {
BOOST_ERROR("Failed VM Test with Exception: " << e.what()); BOOST_ERROR("Failed VM Test with Exception: " << diagnostic_information(_e));
}
catch (std::exception const& _e)
{
BOOST_ERROR("Failed VM Test with Exception: " << _e.what());
} }
#endif #endif
@ -552,9 +561,13 @@ void executeTests(const string& _name)
json_spirit::read_string(s, v); json_spirit::read_string(s, v);
dev::test::doTests(v, false); dev::test::doTests(v, false);
} }
catch (std::exception const& e) catch (Exception const& _e)
{
BOOST_ERROR("Failed VM Test with Exception: " << diagnostic_information(_e));
}
catch (std::exception const& _e)
{ {
BOOST_ERROR("Failed VM Test with Exception: " << e.what()); BOOST_ERROR("Failed VM Test with Exception: " << _e.what());
} }
} }

Loading…
Cancel
Save