Skip to content

Commit

Permalink
transactions query detects missing txs
Browse files Browse the repository at this point in the history
Signed-off-by: Mikhail Boldyrev <miboldyrev@gmail.com>
  • Loading branch information
MBoldyrev committed Oct 29, 2019
1 parent 850b9a3 commit b6716c6
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 32 deletions.
67 changes: 41 additions & 26 deletions irohad/ametsuchi/impl/postgres_specific_query_executor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,27 +197,36 @@ namespace iroha {
qry.get());
}

template <typename RangeGen, typename Pred>
std::vector<std::unique_ptr<shared_model::interface::Transaction>>
template <typename RangeGen, typename Pred, typename OutputIterator>
iroha::expected::Result<void, std::string>
PostgresSpecificQueryExecutor::getTransactionsFromBlock(
uint64_t block_id, RangeGen &&range_gen, Pred &&pred) {
std::vector<std::unique_ptr<shared_model::interface::Transaction>> result;
auto block = block_store_.fetch(block_id);
if (not block) {
log_->error("Failed to retrieve block with id {}", block_id);
return result;
uint64_t block_id,
RangeGen &&range_gen,
Pred &&pred,
OutputIterator dest_it) {
auto opt_block = block_store_.fetch(block_id);
if (not opt_block) {
return iroha::expected::makeError(
fmt::format("Failed to retrieve block with id {}", block_id));
}
auto &block = opt_block.value();

const auto block_size = block->transactions().size();
for (auto tx_id : range_gen(block_size)) {
if (tx_id >= block_size) {
return iroha::expected::makeError(
fmt::format("Failed to retrieve transaction with id {} "
"from block height {}.",
tx_id,
block_id));
}
auto &tx = block->transactions()[tx_id];
if (pred(tx)) {
*dest_it++ = clone(tx);
}
}

boost::transform(range_gen(boost::size((*block)->transactions()))
| boost::adaptors::transformed(
[&block](auto i) -> decltype(auto) {
return (*block)->transactions()[i];
})
| boost::adaptors::filtered(pred),
std::back_inserter(result),
[&](const auto &tx) { return clone(tx); });

return result;
return {};
}

template <typename QueryTuple,
Expand Down Expand Up @@ -399,12 +408,15 @@ namespace iroha {
response_txs;
// get transactions corresponding to indexes
for (auto &block : index) {
auto txs = this->getTransactionsFromBlock(
auto txs_result = this->getTransactionsFromBlock(
block.first,
[&block](auto) { return block.second; },
[](auto &) { return true; });
std::move(
txs.begin(), txs.end(), std::back_inserter(response_txs));
[](auto &) { return true; },
std::back_inserter(response_txs));
if (auto e = iroha::expected::resultToOptionalError(txs_result)) {
return this->logAndReturnErrorResponse(
QueryErrorType::kStatefulFailed, e.value(), 1, query_hash);
}
}

if (response_txs.empty()) {
Expand Down Expand Up @@ -712,7 +724,7 @@ namespace iroha {
std::vector<std::unique_ptr<shared_model::interface::Transaction>>
response_txs;
for (auto &block : index) {
auto txs = this->getTransactionsFromBlock(
auto txs_result = this->getTransactionsFromBlock(
block.first,
[](auto size) {
return boost::irange(static_cast<decltype(size)>(0), size);
Expand All @@ -722,9 +734,12 @@ namespace iroha {
and (all_perm
or (my_perm
and tx.creatorAccountId() == creator_id));
});
std::move(
txs.begin(), txs.end(), std::back_inserter(response_txs));
},
std::back_inserter(response_txs));
if (auto e = iroha::expected::resultToOptionalError(txs_result)) {
return this->logAndReturnErrorResponse(
QueryErrorType::kStatefulFailed, e.value(), 1, query_hash);
}
}

return query_response_factory_->createTransactionsResponse(
Expand Down
14 changes: 8 additions & 6 deletions irohad/ametsuchi/impl/postgres_specific_query_executor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "ametsuchi/specific_query_executor.hpp"

#include <soci/soci.h>
#include "common/result.hpp"
#include "interfaces/iroha_internal/query_response_factory.hpp"
#include "logger/logger_fwd.hpp"

Expand Down Expand Up @@ -133,13 +134,14 @@ namespace iroha {
private:
/**
* Get transactions from block using range from range_gen and filtered by
* predicate pred
* predicate pred and store them in dest_it
*/
template <typename RangeGen, typename Pred>
std::vector<std::unique_ptr<shared_model::interface::Transaction>>
getTransactionsFromBlock(uint64_t block_id,
RangeGen &&range_gen,
Pred &&pred);
template <typename RangeGen, typename Pred, typename OutputIterator>
iroha::expected::Result<void, std::string> getTransactionsFromBlock(
uint64_t block_id,
RangeGen &&range_gen,
Pred &&pred,
OutputIterator dest_it);

/**
* Execute query and return its response
Expand Down

0 comments on commit b6716c6

Please sign in to comment.