From 465490db9796f2b11dbf4917bbe2ca19afb9a6a0 Mon Sep 17 00:00:00 2001 From: Andrei Maiboroda Date: Mon, 16 Dec 2019 19:14:32 +0100 Subject: [PATCH] Add nested detailed error to importRawBlock when full validation fails --- libethereum/ClientTest.cpp | 48 +++++++++++++++++++++++--------------- libethereum/ClientTest.h | 10 ++++---- 2 files changed, 35 insertions(+), 23 deletions(-) diff --git a/libethereum/ClientTest.cpp b/libethereum/ClientTest.cpp index 1725a36276f..959a99cd2ac 100644 --- a/libethereum/ClientTest.cpp +++ b/libethereum/ClientTest.cpp @@ -32,18 +32,8 @@ ClientTest::ClientTest(ChainParams const& _params, int _networkID, p2p::Host& _h : Client( _params, _networkID, _host, _gpForAdoption, _dbPath, std::string(), _forceAction, _limits) { - m_bq.setOnBad([this](Exception& ex) { - { - Guard guard(m_badBlockMutex); - // To preserve original exception type we need to use current_exception(). - // This assumes we're inside catch. - m_lastImportError = boost::current_exception(); - bytes const* block = boost::get_error_info(ex); - m_lastBadBlock = block ? *block : bytes{}; - } - - Client::onBadBlock(ex); - }); + m_bq.setOnBad([this](Exception& _ex) { onBadBlock(_ex); }); + bc().setOnBad([this](Exception& _ex) { onBadBlock(_ex); }); } ClientTest::~ClientTest() @@ -52,6 +42,20 @@ ClientTest::~ClientTest() terminate(); } +void ClientTest::onBadBlock(Exception& _ex) +{ + { + Guard guard(m_badBlockMutex); + // To preserve original exception type we need to use current_exception(). + // This assumes we're inside catch. + m_lastImportError = boost::current_exception(); + bytes const* block = boost::get_error_info(_ex); + m_lastBadBlock = block ? *block : bytes{}; + } + + Client::onBadBlock(_ex); +} + void ClientTest::setChainParams(string const& _genesis) { try @@ -149,12 +153,7 @@ h256 ClientTest::importRawBlock(const string& _blockRLP) if (result != ImportResult::Success) { auto ex = ImportBlockFailed{} << errinfo_importResult(result); - if (result == ImportResult::Malformed) - { - Guard guard(m_badBlockMutex); - if (blockBytes == m_lastBadBlock) - ex << errinfo_nestedException(m_lastImportError); - } + addNestedBadBlockException(blockBytes, ex); BOOST_THROW_EXCEPTION(ex); } @@ -170,7 +169,18 @@ h256 ClientTest::importRawBlock(const string& _blockRLP) // check that it was really imported and not rejected as invalid if (!bc().isKnown(blockHash)) - BOOST_THROW_EXCEPTION(ImportBlockFailed()); + { + auto ex = ImportBlockFailed{}; + addNestedBadBlockException(blockBytes, ex); + BOOST_THROW_EXCEPTION(ex); + } return blockHash; } + +void ClientTest::addNestedBadBlockException(bytes const& _blockBytes, Exception& io_ex) +{ + Guard guard(m_badBlockMutex); + if (_blockBytes == m_lastBadBlock) + io_ex << errinfo_nestedException(m_lastImportError); +} diff --git a/libethereum/ClientTest.h b/libethereum/ClientTest.h index 115d6549157..aabc31728e3 100644 --- a/libethereum/ClientTest.h +++ b/libethereum/ClientTest.h @@ -34,13 +34,15 @@ class ClientTest: public Client void rewindToBlock(unsigned _number); /// Import block data /// @returns hash of the imported block - /// @throws ImportBlockFailed if import failed. If block is rejected by BlockQueue validation, - /// exception contains errinfo_importResult with the reason. If the reason is - /// ImportResult::Malformed, exception contains nested exception with exact validation error. + /// @throws ImportBlockFailed if import failed. If block is rejected as invalid, exception + /// contains nested exception with exact validation error. h256 importRawBlock(std::string const& _blockRLP); bool completeSync(); -protected: +private: + void onBadBlock(Exception& _ex); + void addNestedBadBlockException(bytes const& _blockBytes, Exception& io_ex); + unsigned const m_singleBlockMaxMiningTimeInSeconds = 60; boost::exception_ptr m_lastImportError; bytes m_lastBadBlock;