Skip to content

Commit

Permalink
Shared model/new mutable storage (hyperledger-iroha#1044)
Browse files Browse the repository at this point in the history
Migrate MutableStorage to the new model

Signed-off-by: Dumitru <[email protected]>
  • Loading branch information
x3medima17 committed Mar 30, 2018
1 parent b132c0b commit 57a377b
Show file tree
Hide file tree
Showing 9 changed files with 125 additions and 76 deletions.
22 changes: 13 additions & 9 deletions irohad/ametsuchi/impl/mutable_storage_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,13 @@
#include "ametsuchi/impl/postgres_wsv_command.hpp"
#include "ametsuchi/impl/postgres_wsv_query.hpp"
#include "model/execution/command_executor_factory.hpp"
#include "model/sha3_hash.hpp"

#include "backend/protobuf/from_old_model.hpp"

namespace iroha {
namespace ametsuchi {
MutableStorageImpl::MutableStorageImpl(
hash256_t top_hash,
shared_model::interface::types::HashType top_hash,
std::unique_ptr<pqxx::lazyconnection> connection,
std::unique_ptr<pqxx::nontransaction> transaction,
std::shared_ptr<model::CommandExecutorFactory> command_executors)
Expand All @@ -43,8 +42,10 @@ namespace iroha {
}

bool MutableStorageImpl::apply(
const model::Block &block,
std::function<bool(const model::Block &, WsvQuery &, const hash256_t &)>
const shared_model::interface::Block &block,
std::function<bool(const shared_model::interface::Block &,
WsvQuery &,
const shared_model::interface::types::HashType &)>
function) {
auto execute_transaction = [this](auto &transaction) {
auto execute_command = [this, &transaction](auto command) {
Expand All @@ -64,16 +65,19 @@ namespace iroha {
};

transaction_->exec("SAVEPOINT savepoint_;");
auto old_block = *std::unique_ptr<model::Block>(block.makeOldModel());
auto result = function(block, *wsv_, top_hash_)
and std::all_of(block.transactions.begin(),
block.transactions.end(),
and std::all_of(old_block.transactions.begin(),
old_block.transactions.end(),
execute_transaction);

if (result) {
block_store_.insert(std::make_pair(block.height, block));
block_index_->index(shared_model::proto::from_old(block));
block_store_.insert(std::make_pair(
block.height(),
std::unique_ptr<shared_model::interface::Block>(block.copy())));
block_index_->index(block);

top_hash_ = block.hash;
top_hash_ = block.hash();
transaction_->exec("RELEASE SAVEPOINT savepoint_;");
} else {
transaction_->exec("ROLLBACK TO SAVEPOINT savepoint_;");
Expand Down
17 changes: 10 additions & 7 deletions irohad/ametsuchi/impl/mutable_storage_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,23 +41,26 @@ namespace iroha {

public:
MutableStorageImpl(
hash256_t top_hash,
shared_model::interface::types::HashType top_hash,
std::unique_ptr<pqxx::lazyconnection> connection,
std::unique_ptr<pqxx::nontransaction> transaction,
std::shared_ptr<model::CommandExecutorFactory> command_executors);

bool apply(const model::Block &block,
std::function<bool(const model::Block &,
WsvQuery &,
const hash256_t &)> function) override;
bool apply(
const shared_model::interface::Block &block,
std::function<bool(const shared_model::interface::Block &,
WsvQuery &,
const shared_model::interface::types::HashType &)>
function) override;

~MutableStorageImpl() override;

private:
hash256_t top_hash_;
shared_model::interface::types::HashType top_hash_;
// ordered collection is used to enforce block insertion order in
// StorageImpl::commit
std::map<uint32_t, model::Block> block_store_;
std::map<uint32_t, std::shared_ptr<shared_model::interface::Block>>
block_store_;

std::unique_ptr<pqxx::lazyconnection> connection_;
std::unique_ptr<pqxx::nontransaction> transaction_;
Expand Down
23 changes: 14 additions & 9 deletions irohad/ametsuchi/impl/storage_impl.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright Soramitsu Co., Ltd. 2017 All Rights Reserved.
* Copyright Soramitsu Co., Ltd. 2018 All Rights Reserved.
* http://soramitsu.co.jp
*
* Licensed under the Apache License, Version 2.0 (the "License");
Expand All @@ -22,6 +22,9 @@
#include "ametsuchi/impl/postgres_block_query.hpp"
#include "ametsuchi/impl/postgres_wsv_query.hpp"
#include "ametsuchi/impl/temporary_wsv_impl.hpp"
#include "backend/protobuf/from_old_model.hpp"
#include "converters/protobuf/json_proto_converter.hpp"
#include "interfaces/common_objects/types.hpp"
#include "model/converters/json_common.hpp"
#include "model/execution/command_executor_factory.hpp" // for CommandExecutorFactory
#include "postgres_ordering_service_persistent_state.hpp"
Expand Down Expand Up @@ -111,18 +114,16 @@ namespace iroha {
auto wsv_transaction =
std::make_unique<pqxx::nontransaction>(*postgres_connection, kTmpWsv);

nonstd::optional<hash256_t> top_hash;
nonstd::optional<shared_model::interface::types::HashType> top_hash;

blocks_->getTopBlocks(1)
.subscribe_on(rxcpp::observe_on_new_thread())
.as_blocking()
.subscribe([&top_hash](auto block) {
top_hash = hash256_t::from_string(toBinaryString(block->hash()));
});
.subscribe([&top_hash](auto block) { top_hash = block->hash(); });

return expected::makeValue<std::unique_ptr<MutableStorage>>(
std::make_unique<MutableStorageImpl>(
top_hash.value_or(hash256_t{}),
top_hash.value_or(shared_model::interface::types::HashType("")),
std::move(postgres_connection),
std::move(wsv_transaction),
std::move(command_executors.value())));
Expand All @@ -132,11 +133,12 @@ namespace iroha {
log_->info("create mutable storage");
auto storageResult = createMutableStorage();
bool inserted = false;
auto old_block = shared_model::proto::from_old(block);
storageResult.match(
[&](expected::Value<std::unique_ptr<ametsuchi::MutableStorage>>
&storage) {
inserted =
storage.value->apply(block,
storage.value->apply(old_block,
[](const auto &current_block,
auto &query,
const auto &top_hash) { return true; });
Expand All @@ -158,8 +160,10 @@ namespace iroha {
[&](iroha::expected::Value<std::unique_ptr<MutableStorage>>
&mutableStorage) {
std::for_each(blocks.begin(), blocks.end(), [&](auto block) {
auto old_block = shared_model::proto::from_old(block);
inserted &= mutableStorage.value->apply(
block, [](const auto &block, auto &query, const auto &hash) {
old_block,
[](const auto &block, auto &query, const auto &hash) {
return true;
});
});
Expand Down Expand Up @@ -267,9 +271,10 @@ DROP TABLE IF EXISTS index_by_id_height_asset;
auto storage_ptr = std::move(mutableStorage); // get ownership of storage
auto storage = static_cast<MutableStorageImpl *>(storage_ptr.get());
for (const auto &block : storage->block_store_) {
auto old_block = *std::unique_ptr<model::Block>(block.second->makeOldModel());
block_store_->add(block.first,
stringToBytes(model::converters::jsonToString(
serializer_.serialize(block.second))));
serializer_.serialize(old_block))));
}

storage->transaction_->exec("COMMIT;");
Expand Down
17 changes: 13 additions & 4 deletions irohad/ametsuchi/mutable_storage.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@
#define IROHA_MUTABLE_STORAGE_HPP

#include "common/types.hpp" // for hash256_t
#include "interfaces/common_objects/types.hpp"

namespace shared_model {
namespace interface {
class Block;
}
} // namespace shared_model

namespace iroha {

Expand Down Expand Up @@ -50,10 +57,12 @@ namespace iroha {
* otherwise.
* @return True if block was successfully applied, false otherwise.
*/
virtual bool apply(const model::Block &block,
std::function<bool(const model::Block &,
WsvQuery &,
const hash256_t &)> function) = 0;
virtual bool apply(
const shared_model::interface::Block &block,
std::function<bool(const shared_model::interface::Block &,
WsvQuery &,
const shared_model::interface::types::HashType &)>
function) = 0;

virtual ~MutableStorage() = default;
};
Expand Down
15 changes: 9 additions & 6 deletions irohad/validation/impl/chain_validator_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,16 @@
*/

#include "validation/impl/chain_validator_impl.hpp"
#include "backend/protobuf/from_old_model.hpp"

#include "ametsuchi/impl/postgres_wsv_query.hpp"
#include "consensus/yac/supermajority_checker.hpp"
#include "model/peer.hpp"

namespace iroha {
namespace validation {
ChainValidatorImpl::ChainValidatorImpl(
std::shared_ptr<consensus::yac::SupermajorityChecker> supermajority_checker)
std::shared_ptr<consensus::yac::SupermajorityChecker>
supermajority_checker)
: supermajority_checker_(supermajority_checker) {
log_ = logger::log("ChainValidator");
}
Expand All @@ -40,13 +41,15 @@ namespace iroha {
if (not peers.has_value()) {
return false;
}
return block.prev_hash == top_hash
and supermajority_checker_->hasSupermajority(block.sigs,
peers.value());
auto old_block = *std::unique_ptr<model::Block>(block.makeOldModel());
return block.prevHash() == top_hash
and supermajority_checker_->hasSupermajority(old_block.sigs,
peers.value());
};

// Apply to temporary storage
return storage.apply(block, apply_block);
auto old_block = shared_model::proto::from_old(block);
return storage.apply(old_block, apply_block);
}

bool ChainValidatorImpl::validateChain(OldCommit blocks,
Expand Down
43 changes: 29 additions & 14 deletions test/module/irohad/ametsuchi/ametsuchi_mocks.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,20 +56,29 @@ namespace iroha {
MOCK_METHOD0(getRoles, nonstd::optional<std::vector<std::string>>());
MOCK_METHOD1(
getAccount,
nonstd::optional<std::shared_ptr<shared_model::interface::Account>>(const std::string &account_id));
nonstd::optional<std::shared_ptr<shared_model::interface::Account>>(
const std::string &account_id));
MOCK_METHOD1(getSignatories,
nonstd::optional<std::vector<shared_model::interface::types::PubkeyType>>(
nonstd::optional<
std::vector<shared_model::interface::types::PubkeyType>>(
const std::string &account_id));
MOCK_METHOD1(getAsset,
nonstd::optional<std::shared_ptr<shared_model::interface::Asset>>(const std::string &asset_id));
MOCK_METHOD2(
getAccountAsset,
nonstd::optional<std::shared_ptr<shared_model::interface::AccountAsset>>(const std::string &account_id,
const std::string &asset_id));
MOCK_METHOD0(getPeers, nonstd::optional<std::vector<std::shared_ptr<shared_model::interface::Peer>>>());
MOCK_METHOD1(
getAsset,
nonstd::optional<std::shared_ptr<shared_model::interface::Asset>>(
const std::string &asset_id));
MOCK_METHOD2(getAccountAsset,
nonstd::optional<
std::shared_ptr<shared_model::interface::AccountAsset>>(
const std::string &account_id,
const std::string &asset_id));
MOCK_METHOD0(
getPeers,
nonstd::optional<
std::vector<std::shared_ptr<shared_model::interface::Peer>>>());
MOCK_METHOD1(
getDomain,
nonstd::optional<std::shared_ptr<shared_model::interface::Domain>>(const std::string &domain_id));
nonstd::optional<std::shared_ptr<shared_model::interface::Domain>>(
const std::string &domain_id));
MOCK_METHOD3(hasAccountGrantablePermission,
bool(const std::string &permitee_account_id,
const std::string &account_id,
Expand Down Expand Up @@ -142,8 +151,12 @@ namespace iroha {
getTransactions,
rxcpp::observable<boost::optional<wTransaction>>(
const std::vector<shared_model::crypto::Hash> &tx_hashes));
MOCK_METHOD2(getBlocks, rxcpp::observable<wBlock>(shared_model::interface::types::HeightType, uint32_t));
MOCK_METHOD1(getBlocksFrom, rxcpp::observable<wBlock>(shared_model::interface::types::HeightType));
MOCK_METHOD2(getBlocks,
rxcpp::observable<wBlock>(
shared_model::interface::types::HeightType, uint32_t));
MOCK_METHOD1(getBlocksFrom,
rxcpp::observable<wBlock>(
shared_model::interface::types::HeightType));
MOCK_METHOD1(getTopBlocks, rxcpp::observable<wBlock>(uint32_t));
};

Expand All @@ -158,9 +171,11 @@ namespace iroha {
public:
MOCK_METHOD2(
apply,
bool(const model::Block &,
bool(const shared_model::interface::Block &,
std::function<
bool(const model::Block &, WsvQuery &, const hash256_t &)>));
bool(const shared_model::interface::Block &,
WsvQuery &,
const shared_model::interface::types::HashType &)>));
};

/**
Expand Down
22 changes: 11 additions & 11 deletions test/module/irohad/ametsuchi/ametsuchi_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ using namespace iroha::ametsuchi;
using namespace iroha::model;
using namespace framework::test_subscriber;

auto zero_string = std::string(32, '0'/*, 32*/);
auto zero_string = std::string(32, '0');
auto fake_hash = shared_model::crypto::Hash(zero_string);
auto fake_pubkey = shared_model::crypto::PublicKey(zero_string);

Expand Down Expand Up @@ -119,7 +119,9 @@ void validateAccountAsset(W &&wsv,
ASSERT_TRUE(account_asset);
ASSERT_EQ((*account_asset)->accountId(), account);
ASSERT_EQ((*account_asset)->assetId(), asset);
ASSERT_EQ(*std::unique_ptr<iroha::Amount>((*account_asset)->balance().makeOldModel()), amount);
ASSERT_EQ(*std::unique_ptr<iroha::Amount>(
(*account_asset)->balance().makeOldModel()),
amount);
}

/**
Expand Down Expand Up @@ -156,8 +158,7 @@ void apply(S &&storage, const shared_model::interface::Block &block) {
[](iroha::expected::Error<std::string> &error) {
FAIL() << "MutableStorage: " << error.error;
});
ms->apply(*std::unique_ptr<iroha::model::Block>(block.makeOldModel()),
[](const auto &, auto &, const auto &) { return true; });
ms->apply(block, [](const auto &, auto &, const auto &) { return true; });
storage->commit(std::move(ms));
}

Expand Down Expand Up @@ -273,7 +274,6 @@ TEST_F(AmetsuchiTest, PeerTest) {
ASSERT_EQ(peers->size(), 1);
ASSERT_EQ(peers->at(0)->address(), "192.168.9.1:50051");

// auto pubkey = iroha::blob_t<32>::from_string(zero_string);
ASSERT_EQ(peers->at(0)->pubkey(), fake_pubkey);
}

Expand All @@ -283,10 +283,11 @@ TEST_F(AmetsuchiTest, queryGetAccountAssetTransactionsTest) {
auto blocks = storage->getBlockQuery();

const auto admin = "admin", domain = "domain", user1name = "userone",
user2name = "usertwo", user3name = "userthree", user1id = "userone@domain",
user2id = "usertwo@domain", user3id = "userthree@domain",
asset1name = "assetone", asset2name = "assettwo",
asset1id = "assetone#domain", asset2id = "assettwo#domain";
user2name = "usertwo", user3name = "userthree",
user1id = "userone@domain", user2id = "usertwo@domain",
user3id = "userthree@domain", asset1name = "assetone",
asset2name = "assettwo", asset1id = "assetone#domain",
asset2id = "assettwo#domain";

std::string account, src_account, dest_account, asset;
iroha::Amount amount;
Expand Down Expand Up @@ -470,8 +471,7 @@ TEST_F(AmetsuchiTest, AddSignatoryTest) {
ASSERT_TRUE(signatories);
ASSERT_EQ(signatories->size(), 2);
ASSERT_EQ(signatories->at(0), pubkey1);
ASSERT_EQ(signatories->at(1), pubkey2
);
ASSERT_EQ(signatories->at(1), pubkey2);
}

// 3rd tx (create user2 with pubkey1 that is same as user1's key)
Expand Down
8 changes: 5 additions & 3 deletions test/module/irohad/ametsuchi/kv_storage_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/

#include <gtest/gtest.h>
#include "backend/protobuf/from_old_model.hpp"

#include "ametsuchi/block_query.hpp"
#include "ametsuchi/impl/postgres_wsv_query.hpp"
Expand Down Expand Up @@ -107,7 +108,8 @@ class KVTest : public AmetsuchiTest {
[](iroha::expected::Error<std::string> &error) {
FAIL() << "MutableStorage: " << error.error;
});
ms->apply(block1, [](const auto &blk, auto &query, const auto &top_hash) {
auto old_block = shared_model::proto::from_old(block1);
ms->apply(old_block, [](const auto &blk, auto &query, const auto &top_hash) {
return true;
});
storage->commit(std::move(ms));
Expand All @@ -132,8 +134,8 @@ TEST_F(KVTest, GetNonexistingDetail) {
auto account_id1 = account_name1 + "@" + domain_id;
auto account = wsv_query->getAccount(account_id1);

auto age =
wsv_query->getAccountDetail(account_id1, "userone@ru", "nonexisting-field");
auto age = wsv_query->getAccountDetail(
account_id1, "userone@ru", "nonexisting-field");
ASSERT_FALSE(age);
}

Expand Down
Loading

0 comments on commit 57a377b

Please sign in to comment.