diff --git a/libdevcore/Exceptions.h b/libdevcore/Exceptions.h index 48d407564..8398f9c7f 100644 --- a/libdevcore/Exceptions.h +++ b/libdevcore/Exceptions.h @@ -57,5 +57,9 @@ using errinfo_wrongAddress = boost::error_info; using errinfo_comment = boost::error_info; using errinfo_required = boost::error_info; using errinfo_got = boost::error_info; +using errinfo_min = boost::error_info; +using errinfo_max = boost::error_info; using RequirementError = boost::tuple; +using errinfo_hash256 = boost::error_info; +using HashMismatchError = boost::tuple; } diff --git a/libethcore/BlockInfo.cpp b/libethcore/BlockInfo.cpp index 39eadb60e..2546cdcbe 100644 --- a/libethcore/BlockInfo.cpp +++ b/libethcore/BlockInfo.cpp @@ -122,7 +122,7 @@ void BlockInfo::populateFromHeader(RLP const& _header, bool _checkNonce) // check it hashes according to proof of work or that it's the genesis block. if (_checkNonce && parentHash && !ProofOfWork::verify(*this)) - BOOST_THROW_EXCEPTION(InvalidBlockNonce(headerHash(WithoutNonce), nonce, difficulty)); + BOOST_THROW_EXCEPTION(InvalidBlockNonce() << errinfo_hash256(headerHash(WithoutNonce)) << errinfo_nonce(nonce) << errinfo_difficulty(difficulty)); if (gasUsed > gasLimit) BOOST_THROW_EXCEPTION(TooMuchGasUsed() << RequirementError(bigint(gasLimit), bigint(gasUsed)) ); @@ -131,7 +131,7 @@ void BlockInfo::populateFromHeader(RLP const& _header, bool _checkNonce) BOOST_THROW_EXCEPTION(InvalidDifficulty() << RequirementError(bigint(c_minimumDifficulty), bigint(difficulty)) ); if (gasLimit < c_minGasLimit) - BOOST_THROW_EXCEPTION(InvalidGasLimit(gasLimit, c_minGasLimit, c_minGasLimit) << RequirementError(bigint(c_minGasLimit), bigint(gasLimit)) ); + BOOST_THROW_EXCEPTION(InvalidGasLimit() << RequirementError(bigint(c_minGasLimit), bigint(gasLimit)) ); if (number && extraData.size() > c_maximumExtraDataSize) BOOST_THROW_EXCEPTION(ExtraDataTooBig() << RequirementError(bigint(c_maximumExtraDataSize), bigint(extraData.size()))); @@ -143,13 +143,13 @@ void BlockInfo::populate(bytesConstRef _block, bool _checkNonce) RLP header = root[0]; if (!header.isList()) - BOOST_THROW_EXCEPTION(InvalidBlockFormat(0, header.data()) << errinfo_comment("block header needs to be a list")); + BOOST_THROW_EXCEPTION(InvalidBlockFormat() << errinfo_comment("block header needs to be a list") << BadFieldError(0, header.data().toString())); populateFromHeader(header, _checkNonce); if (!root[1].isList()) - BOOST_THROW_EXCEPTION(InvalidBlockFormat(1, root[1].data())); + BOOST_THROW_EXCEPTION(InvalidBlockFormat() << errinfo_comment("block transactions need to be a list") << BadFieldError(1, root[1].data().toString())); if (!root[2].isList()) - BOOST_THROW_EXCEPTION(InvalidBlockFormat(2, root[2].data())); + BOOST_THROW_EXCEPTION(InvalidBlockFormat() << errinfo_comment("block uncles need to be a list") << BadFieldError(2, root[2].data().toString())); } void BlockInfo::verifyInternals(bytesConstRef _block) const @@ -171,7 +171,7 @@ void BlockInfo::verifyInternals(bytesConstRef _block) const ++i; } if (transactionsRoot != t.root()) - BOOST_THROW_EXCEPTION(InvalidTransactionsHash(t.root(), transactionsRoot)); + BOOST_THROW_EXCEPTION(InvalidTransactionsHash() << HashMismatchError(t.root(), transactionsRoot)); if (sha3Uncles != sha3(root[2].data())) BOOST_THROW_EXCEPTION(InvalidUnclesHash()); @@ -217,7 +217,7 @@ void BlockInfo::verifyParent(BlockInfo const& _parent) const if (gasLimit < _parent.gasLimit * (c_gasLimitBoundDivisor - 1) / c_gasLimitBoundDivisor || gasLimit > _parent.gasLimit * (c_gasLimitBoundDivisor + 1) / c_gasLimitBoundDivisor) - BOOST_THROW_EXCEPTION(InvalidGasLimit(gasLimit, _parent.gasLimit * (c_gasLimitBoundDivisor - 1) / c_gasLimitBoundDivisor, _parent.gasLimit * (c_gasLimitBoundDivisor + 1) / c_gasLimitBoundDivisor)); + BOOST_THROW_EXCEPTION(InvalidGasLimit() << errinfo_min((bigint)_parent.gasLimit * (c_gasLimitBoundDivisor - 1) / c_gasLimitBoundDivisor) << errinfo_got((bigint)gasLimit) << errinfo_max((bigint)_parent.gasLimit * (c_gasLimitBoundDivisor + 1) / c_gasLimitBoundDivisor)); if (seedHash != calculateSeedHash(_parent)) BOOST_THROW_EXCEPTION(InvalidSeedHash()); diff --git a/libethcore/Exceptions.cpp b/libethcore/Exceptions.cpp deleted file mode 100644 index 7996a4424..000000000 --- a/libethcore/Exceptions.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - This file is part of cpp-ethereum. - - cpp-ethereum is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - cpp-ethereum is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with cpp-ethereum. If not, see . -*/ -/** @file Exceptions.cpp - * @author Gav Wood - * @date 2014 - */ - -#include "Exceptions.h" -#include -#include - -using namespace std; -using namespace dev; -using namespace dev::eth; - -InvalidBlockFormat::InvalidBlockFormat(int _f, bytesConstRef _d): - Exception("Invalid block format: Bad field " + toString(_f) + " (" + toHex(_d) + ")"), f(_f), d(_d.toBytes()) {} - -UncleInChain::UncleInChain(h256Set _uncles, h256 _block): - Exception("Uncle in block already mentioned: Uncles " + toString(_uncles) + " (" + _block.abridged() + ")"), uncles(_uncles), block(_block) {} - -InvalidTransactionsHash::InvalidTransactionsHash(h256 _head, h256 _real): - Exception("Invalid transactions hash: header says: " + toHex(_head.ref()) + " block is:" + toHex(_real.ref())), head(_head), real(_real) {} - -InvalidGasLimit::InvalidGasLimit(u256 _provided, u256 _n, u256 _x): - Exception("Invalid gas limit (provided: " + toString(provided) + " minimum:" + toString(minimum) + " max:" + toString(maximum) + ")"), provided(_provided), minimum(_n), maximum(_x) {} - -InvalidNonce::InvalidNonce(u256 _required, u256 _candidate): - Exception("Invalid nonce (r: " + toString(_required) + " c:" + toString(_candidate) + ")"), required(_required), candidate(_candidate) {} - -InvalidBlockNonce::InvalidBlockNonce(h256 _h, Nonce _n, u256 _d): - Exception("Invalid nonce (h: " + toString(h) + " n:" + toString(n) + " d:" + toString(d) + ")"), h(_h), n(_n), d(_d) {} diff --git a/libethcore/Exceptions.h b/libethcore/Exceptions.h index cf2b07292..0059854f7 100644 --- a/libethcore/Exceptions.h +++ b/libethcore/Exceptions.h @@ -33,6 +33,8 @@ namespace eth using errinfo_name = boost::error_info; using errinfo_field = boost::error_info; using errinfo_data = boost::error_info; +using errinfo_nonce = boost::error_info; +using errinfo_difficulty = boost::error_info; using BadFieldError = boost::tuple; struct DatabaseAlreadyOpen: virtual dev::Exception {}; @@ -45,27 +47,27 @@ struct FeeTooSmall: virtual dev::Exception {}; struct TooMuchGasUsed: virtual dev::Exception {}; struct ExtraDataTooBig: virtual dev::Exception {}; struct InvalidSignature: virtual dev::Exception {}; -class InvalidBlockFormat: virtual public dev::Exception { public: InvalidBlockFormat(int _f, bytesConstRef _d); int f; bytes d; }; +class InvalidBlockFormat: virtual public dev::Exception {}; struct InvalidUnclesHash: virtual dev::Exception {}; struct InvalidUncle: virtual dev::Exception {}; struct TooManyUncles: virtual dev::Exception {}; struct UncleTooOld: virtual dev::Exception {}; -class UncleInChain: virtual public dev::Exception { public: UncleInChain(h256Set _uncles, h256 _block); h256Set uncles; h256 block; }; +class UncleInChain: virtual public dev::Exception {}; struct DuplicateUncleNonce: virtual dev::Exception {}; struct InvalidStateRoot: virtual dev::Exception {}; struct InvalidGasUsed: virtual dev::Exception {}; -class InvalidTransactionsHash: virtual public dev::Exception { public: InvalidTransactionsHash(h256 _head, h256 _real); h256 head; h256 real; }; +class InvalidTransactionsHash: virtual public dev::Exception {}; struct InvalidTransaction: virtual dev::Exception {}; struct InvalidDifficulty: virtual dev::Exception {}; struct InvalidSeedHash: virtual dev::Exception {}; -class InvalidGasLimit: virtual public dev::Exception { public: InvalidGasLimit(u256 _provided, u256 _n, u256 _x); u256 provided; u256 minimum; u256 maximum; }; +class InvalidGasLimit: virtual public dev::Exception {}; struct InvalidTransactionGasUsed: virtual dev::Exception {}; struct InvalidTransactionsStateRoot: virtual dev::Exception {}; struct InvalidReceiptsStateRoot: virtual dev::Exception {}; struct InvalidTimestamp: virtual dev::Exception {}; struct InvalidLogBloom: virtual dev::Exception {}; -class InvalidNonce: virtual public dev::Exception { public: InvalidNonce(u256 _required, u256 _candidate); u256 required; u256 candidate; }; -class InvalidBlockNonce: virtual public dev::Exception { public: InvalidBlockNonce(h256 _h, Nonce _n, u256 _d); h256 h; Nonce n; u256 d; }; +class InvalidNonce: virtual public dev::Exception {}; +class InvalidBlockNonce: virtual public dev::Exception {}; struct InvalidParentHash: virtual dev::Exception {}; struct InvalidNumber: virtual dev::Exception {}; struct InvalidContractAddress: virtual public dev::Exception {}; diff --git a/libethereum/BlockChain.cpp b/libethereum/BlockChain.cpp index 50630a41c..dd0bfad67 100644 --- a/libethereum/BlockChain.cpp +++ b/libethereum/BlockChain.cpp @@ -243,7 +243,7 @@ h256s BlockChain::import(bytes const& _block, OverlayDB const& _db) RLP blockRLP(_block); if (!blockRLP.isList()) - BOOST_THROW_EXCEPTION(InvalidBlockFormat(0, blockRLP.data()) << errinfo_comment("block header needs to be a list")); + BOOST_THROW_EXCEPTION(InvalidBlockFormat() << errinfo_comment("block header needs to be a list") << BadFieldError(0, blockRLP.data().toString())); bi.populate(&_block); bi.verifyInternals(&_block); diff --git a/libethereum/Executive.cpp b/libethereum/Executive.cpp index 86e2d5568..d8c80a577 100644 --- a/libethereum/Executive.cpp +++ b/libethereum/Executive.cpp @@ -66,7 +66,7 @@ bool Executive::setup() if (m_t.nonce() != nonceReq) { clog(StateDetail) << "Invalid Nonce: Require" << nonceReq << " Got" << m_t.nonce(); - BOOST_THROW_EXCEPTION(InvalidNonce(nonceReq, m_t.nonce())); + BOOST_THROW_EXCEPTION(InvalidNonce() << RequirementError((bigint)nonceReq, (bigint)m_t.nonce())); } // Check gas cost is enough. diff --git a/libethereum/State.cpp b/libethereum/State.cpp index 568629084..c9e65df4b 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -427,7 +427,10 @@ TransactionReceipts State::sync(BlockChain const& _bc, TransactionQueue& _tq, bo } catch (InvalidNonce const& in) { - if (in.required > in.candidate) + bigint const* req = boost::get_error_info(in); + bigint const* got = boost::get_error_info(in); + + if (*req > *got) { // too old _tq.drop(i.first); @@ -554,7 +557,7 @@ u256 State::enact(bytesConstRef _block, BlockChain const& _bc, bool _checkNonce) for (auto const& i: rlp[2]) { if (knownUncles.count(sha3(i.data()))) - BOOST_THROW_EXCEPTION(UncleInChain(knownUncles, sha3(i.data()) )); + BOOST_THROW_EXCEPTION(UncleInChain() << errinfo_comment("Uncle in block already mentioned") << errinfo_data(toString(knownUncles)) << errinfo_hash256(sha3(i.data())) ); BlockInfo uncle = BlockInfo::fromHeader(i.data()); if (nonces.count(uncle.nonce))