Skip to content
This repository has been archived by the owner on Oct 28, 2021. It is now read-only.

ClientTest::importRawBlock throws exception with a nested detailed error #5871

Merged
merged 1 commit into from
Dec 16, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions libdevcore/Exceptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "FixedHash.h"
#include <boost/exception/diagnostic_information.hpp>
#include <boost/exception/errinfo_api_function.hpp>
#include <boost/exception/errinfo_nested_exception.hpp>
#include <boost/exception/exception.hpp>
#include <boost/exception/info.hpp>
#include <boost/exception/info_tuple.hpp>
Expand Down Expand Up @@ -78,4 +79,5 @@ using errinfo_externalFunction = boost::errinfo_api_function;
using errinfo_interface = boost::error_info<struct tag_interface, std::string>;
using errinfo_path = boost::error_info<struct tag_path, std::string>;
using errinfo_nodeID = boost::error_info<struct tag_nodeID, h512>;
using errinfo_nestedException = boost::errinfo_nested_exception;
}
27 changes: 25 additions & 2 deletions libethereum/ClientTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,20 @@ ClientTest::ClientTest(ChainParams const& _params, int _networkID, p2p::Host& _h
TransactionQueue::Limits const& _limits)
: 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<errinfo_block>(ex);
m_lastBadBlock = block ? *block : bytes{};
}

Client::onBadBlock(ex);
});
}

ClientTest::~ClientTest()
{
Expand Down Expand Up @@ -131,9 +144,19 @@ h256 ClientTest::importRawBlock(const string& _blockRLP)
{
bytes blockBytes = jsToBytes(_blockRLP, OnFailed::Throw);
h256 blockHash = BlockHeader::headerHashFromBlock(blockBytes);

ImportResult result = queueBlock(blockBytes, true);
if (result != ImportResult::Success)
BOOST_THROW_EXCEPTION(ImportBlockFailed() << errinfo_importResult(result));
{
auto ex = ImportBlockFailed{} << errinfo_importResult(result);
if (result == ImportResult::Malformed)
{
Guard guard(m_badBlockMutex);
if (blockBytes == m_lastBadBlock)
ex << errinfo_nestedException(m_lastImportError);
}
BOOST_THROW_EXCEPTION(ex);
}

if (auto h = m_host.lock())
h->noteNewBlocks();
Expand Down
8 changes: 8 additions & 0 deletions libethereum/ClientTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,19 @@ class ClientTest: public Client
bool mineBlocks(unsigned _count) noexcept;
void modifyTimestamp(int64_t _timestamp);
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.
h256 importRawBlock(std::string const& _blockRLP);
bool completeSync();

protected:
unsigned const m_singleBlockMaxMiningTimeInSeconds = 60;
boost::exception_ptr m_lastImportError;
bytes m_lastBadBlock;
Mutex m_badBlockMutex;
};

ClientTest& asClientTest(Interface& _c);
Expand Down