diff --git a/mix/ClientModel.cpp b/mix/ClientModel.cpp index aaf330185..f3455b4ce 100644 --- a/mix/ClientModel.cpp +++ b/mix/ClientModel.cpp @@ -27,6 +27,7 @@ #include #include "AppContext.h" #include "DebuggingStateWrapper.h" +#include "Exceptions.h" #include "QContractDefinition.h" #include "QVariableDeclaration.h" #include "ContractCallDataEncoder.h" @@ -155,8 +156,8 @@ void ClientModel::setupState(QVariantMap _state) void ClientModel::executeSequence(std::vector const& _sequence, u256 _balance) { if (m_running) - throw (std::logic_error("debugging already running")); - auto compilerRes = m_context->codeModel()->code(); + BOOST_THROW_EXCEPTION(ExecutionStateException()); + CompilationResult* compilerRes = m_context->codeModel()->code(); std::shared_ptr contractDef = compilerRes->sharedContract(); m_running = true; @@ -171,52 +172,48 @@ void ClientModel::executeSequence(std::vector const& _seque bytes contractCode = compilerRes->bytes(); m_client->resetState(_balance); onStateReset(); - for (auto const& t: _sequence) + for (TransactionSettings const& transaction: _sequence) { ContractCallDataEncoder encoder; - QFunctionDefinition* f = nullptr; - if (!t.stdContractUrl.isEmpty()) + QFunctionDefinition const* f = nullptr; + if (!transaction.stdContractUrl.isEmpty()) { //std contract - dev::bytes const& stdContractCode = m_context->codeModel()->getStdContractCode(t.stdContractUrl); - Address address = deployContract(stdContractCode, t); - m_stdContractAddresses[t.functionId] = address; - m_stdContractNames[address] = t.functionId; + dev::bytes const& stdContractCode = m_context->codeModel()->getStdContractCode(transaction.stdContractUrl); + Address address = deployContract(stdContractCode, transaction); + m_stdContractAddresses[transaction.functionId] = address; + m_stdContractNames[address] = transaction.functionId; } else { //encode data f = nullptr; - if (t.functionId.isEmpty()) + if (transaction.functionId.isEmpty()) f = contractDef->constructor(); else - { - for (int tf = 0; tf < contractDef->functionsList().size(); tf++) - { - if (contractDef->functionsList().at(tf)->name() == t.functionId) + for (QFunctionDefinition const* tf: contractDef->functionsList()) + if (tf->name() == transaction.functionId) { - f = contractDef->functionsList().at(tf); + f = tf; break; } - } - } if (!f) - throw std::runtime_error("function " + t.functionId.toStdString() + " not found"); + BOOST_THROW_EXCEPTION(FunctionNotFoundException() << FunctionName(transaction.functionId.toStdString())); encoder.encode(f); for (int p = 0; p < f->parametersList().size(); p++) { QVariableDeclaration* var = f->parametersList().at(p); u256 value = 0; - auto v = t.parameterValues.find(var->name()); - if (v != t.parameterValues.cend()) + auto v = transaction.parameterValues.find(var->name()); + if (v != transaction.parameterValues.cend()) value = v->second; encoder.encode(var, value); } - if (t.functionId.isEmpty()) + if (transaction.functionId.isEmpty()) { - Address newAddress = deployContract(contractCode, t); + Address newAddress = deployContract(contractCode, transaction); if (newAddress != m_contractAddress) { m_contractAddress = newAddress; @@ -224,7 +221,7 @@ void ClientModel::executeSequence(std::vector const& _seque } } else - callContract(m_contractAddress, encoder.encodedData(), t); + callContract(m_contractAddress, encoder.encodedData(), transaction); } onNewTransaction(); } @@ -247,7 +244,7 @@ void ClientModel::executeSequence(std::vector const& _seque void ClientModel::showDebugger() { - auto const& last = m_client->record().back().transactions.back(); + ExecutionResult const& last = m_client->record().back().transactions.back(); showDebuggerForTransaction(last); } @@ -336,17 +333,13 @@ void ClientModel::onNewTransaction() contract = function; } else - { function = QObject::tr("Constructor"); - } } else { //call if (tr.transactionData.size() >= 4) - { functionHash = FixedHash<4>(tr.transactionData.data(), FixedHash<4>::ConstructFromPointer); - } function = QString::fromStdString(toJS(functionHash)); } diff --git a/mix/Exceptions.h b/mix/Exceptions.h index cd679a878..ea4cb87b3 100644 --- a/mix/Exceptions.h +++ b/mix/Exceptions.h @@ -36,10 +36,13 @@ namespace mix struct QmlLoadException: virtual Exception {}; struct FileIoException: virtual Exception {}; struct InvalidBlockException: virtual Exception {}; +struct FunctionNotFoundException: virtual Exception {}; +struct ExecutionStateException: virtual Exception {}; typedef boost::error_info QmlErrorInfo; typedef boost::error_info FileError; typedef boost::error_info BlockIndex; +typedef boost::error_info FunctionName; } } diff --git a/mix/MixClient.cpp b/mix/MixClient.cpp index e582564c0..ba25dfbbc 100644 --- a/mix/MixClient.cpp +++ b/mix/MixClient.cpp @@ -126,11 +126,7 @@ void MixClient::executeTransaction(Transaction const& _t, State& _state) void MixClient::validateBlock(int _block) const { if (_block != -1 && _block != 0 && (unsigned)_block >= m_blocks.size() - 1) - { - InvalidBlockException exception; - exception << BlockIndex(_block); - BOOST_THROW_EXCEPTION(exception); - } + BOOST_THROW_EXCEPTION(InvalidBlockException() << BlockIndex(_block)); } void MixClient::mine() @@ -244,31 +240,23 @@ eth::LocalisedLogEntries MixClient::logs(unsigned _watchId) const eth::LocalisedLogEntries MixClient::logs(eth::LogFilter const& _f) const { LocalisedLogEntries ret; - unsigned blockNumber = m_blocks.size() - 1; - unsigned begin = std::min(blockNumber, (unsigned)_f.latest()); - unsigned end = std::min(blockNumber, std::min(begin, (unsigned)_f.earliest())); - unsigned m = _f.max(); - unsigned s = _f.skip(); - unsigned n = begin; - for (; ret.size() != m && n != end; n--) + unsigned blockCount = m_blocks.size(); //last block contains pending transactions + unsigned block = std::min(blockCount, (unsigned)_f.latest()); + unsigned end = std::min(blockCount, std::min(block, (unsigned)_f.earliest())); + for (; ret.size() != _f.max() && block != end; block--) { - bool pendingBlock = n == blockNumber; - if (pendingBlock || _f.matches(m_blocks[n].info.logBloom)) + bool pendingBlock = (block == blockCount); + if (pendingBlock || _f.matches(m_blocks[block].info.logBloom)) { - for (ExecutionResult const& t: m_blocks[n].transactions) + for (ExecutionResult const& t: m_blocks[block].transactions) { if (pendingBlock || _f.matches(t.receipt.bloom())) { - LogEntries le = _f.matches(t.receipt); - if (le.size()) + LogEntries logEntries = _f.matches(t.receipt); + if (logEntries.size()) { - for (unsigned j = 0; j < le.size() && ret.size() != m; ++j) - { - if (s) - s--; - else - ret.insert(ret.begin(), LocalisedLogEntry(le[j], n)); - } + for (unsigned entry = _f.skip(); entry < logEntries.size() && ret.size() != _f.max(); ++entry) + ret.insert(ret.begin(), LocalisedLogEntry(logEntries[entry], block)); } } }