Skip to content

Commit

Permalink
Change trusted peers type to vector<Peers>. Add merge AddPeer tx into…
Browse files Browse the repository at this point in the history
… block
  • Loading branch information
motxx authored and muratovv committed Jul 30, 2017
1 parent 9802222 commit 3a1293d
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 42 deletions.
104 changes: 77 additions & 27 deletions iroha-cli/bootstrap_network.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@
#include <vector>
#include "ametsuchi/block_serializer.hpp"
#include "common/assert_config.hpp"
#include "common/types.hpp"
#include "ip_tools/ip_tools.hpp"
#include "main/genesis_block_server/genesis_block_server.hpp" // GenesisBlockServicePort
#include "model/block.hpp"
#include "model/model_hash_provider_impl.hpp"
#include "model/peer.hpp"

using namespace assert_config;

Expand Down Expand Up @@ -91,13 +93,12 @@ namespace iroha_cli {
}

/**
* parse trusted peer's ip addresses in `target.conf`
* parse trusted peers in `target.conf`
* @param target_conf_path
* @return trusted peers' ip
* @return std::vector<iroha::model::Peer>
*/
std::vector<std::string> BootstrapNetwork::parse_trusted_peers(
std::vector<iroha::model::Peer> BootstrapNetwork::parse_trusted_peers(
std::string const &target_conf_path) {
std::vector<std::string> ret;
std::ifstream ifs(target_conf_path);
assert_fatal(ifs.is_open(), "Cannot open: '" + target_conf_path + "'");

Expand All @@ -106,18 +107,37 @@ namespace iroha_cli {
doc.ParseStream(isw);
assert_fatal(!doc.HasParseError(), "JSON Parse error: " + target_conf_path);

const char *MemberIp = "ip";
assert_fatal(doc.HasMember(MemberIp),
"In '" + target_conf_path + "', member '" +
std::string(MemberIp) + "' doesn't exist.");
auto json_ips = doc[MemberIp].GetArray();
for (const auto &ip : json_ips) {
assert_fatal(ip.IsString(),
"'" + std::string(MemberIp) + "' has not string value.");
const std::string ip_str = ip.GetString();
assert_fatal(iroha::ip_tools::isIpValid(ip_str),
"Ip '" + ip_str + "' is invalid.");
ret.push_back(ip_str);
const char *MemberPeers = "peers";
assert_fatal(doc.HasMember(MemberPeers), no_member_error(MemberPeers));
auto json_peers = doc[MemberPeers].GetArray();

std::vector<iroha::model::Peer> ret;
for (const auto &json_peer : json_peers) {
iroha::model::Peer peer;

assert_fatal(
json_peer.IsObject(),
type_error("an element in" + std::string(MemberPeers), "object"));
const char *MemberPubkey = "pubkey";
assert_fatal(json_peer.HasMember(MemberPubkey),
no_member_error(MemberPubkey));
assert_fatal(json_peer[MemberPubkey].IsString(),
type_error(MemberPubkey, "string"));
const auto pkbytes =
iroha::hex2bytes(json_peer[MemberPubkey].GetString());

std::copy(pkbytes.begin(), pkbytes.end(), peer.pubkey.begin());

const char *MemberIp = "ip";
assert_fatal(json_peer.HasMember(MemberIp), no_member_error(MemberIp));
assert_fatal(json_peer[MemberIp].IsString(),
type_error(MemberIp, "string"));
const std::string address = json_peer[MemberIp].GetString();
assert_fatal(iroha::ip_tools::isIpValid(address),
std::string(MemberIp) + ": '" + address + "' is invalid.");
peer.address = address;

ret.push_back(peer);
}
return ret;
}
Expand Down Expand Up @@ -167,16 +187,45 @@ namespace iroha_cli {
return block;
}

/**
* merges trusted peers AddPeer tx with given block
* @param block
* @param trusted_peers
* @return iroha::model::Block
*/
iroha::model::Block BootstrapNetwork::merge_tx_add_trusted_peers(
const iroha::model::Block &block,
std::vector<iroha::model::Peer> const &trusted_peers) {
iroha::model::Transaction add_peers_tx;
for (const auto &peer : trusted_peers) {
auto add_peer = std::make_shared<iroha::model::AddPeer>();
add_peer->peer_key = peer.pubkey;
add_peer->address = peer.address;
add_peers_tx.commands.push_back(add_peer);
}
std::vector<iroha::model::Transaction> txs;
txs.push_back(add_peers_tx);
for (const auto &tx : block.transactions) txs.push_back(tx);

auto ret = block;
ret.transactions = txs;
ret.txs_number = ret.transactions.size();

iroha::model::HashProviderImpl hash_provider;
ret.hash = hash_provider.get_hash(ret);
return ret;
}

/**
* aborts bootstrapping network.
* @param trusted_peers
* @param block
*/
void BootstrapNetwork::abort_network(
std::vector<std::string> const &trusted_peers,
std::vector<iroha::model::Peer> const &trusted_peers,
iroha::model::Block const &block) {
for (const auto &ip : trusted_peers) {
client_.set_channel(ip, iroha::GenesisBlockServicePort);
for (const auto &peer : trusted_peers) {
client_.set_channel(peer.address, iroha::GenesisBlockServicePort);
client_.send_abort_genesis_block(block);
}
}
Expand All @@ -185,21 +234,22 @@ namespace iroha_cli {
* bootstraps network of trusted peers.
*/
void BootstrapNetwork::run_network(
std::vector<std::string> const &trusted_peers,
std::vector<iroha::model::Peer> const &trusted_peers,
iroha::model::Block const &genesis_block) {
// send block to trusted peers.
for (const auto &ip : trusted_peers) {
client_.set_channel(ip, iroha::GenesisBlockServicePort);
for (const auto &peer : trusted_peers) {
client_.set_channel(peer.address, iroha::GenesisBlockServicePort);
iroha::protocol::ApplyGenesisBlockResponse response;
auto stat = client_.send_genesis_block(genesis_block, response);
if (!stat.ok() || response.applied() == iroha::protocol::APPLY_FAILURE) {
abort_network(trusted_peers, genesis_block);
assert_fatal(false,
"Failure of creating genesis block. {\"address\":\"" + ip + ":"
+ std::to_string(iroha::GenesisBlockServicePort)
+ "\" \"stat\":\"" + (stat.ok() ? "true" : "false")
+ "\", \"response\":\"" + (response.applied() ? "success" : "failure")
+ "\"}");
"Failure of creating genesis block. {\"address\":\"" +
peer.address + ":" +
std::to_string(iroha::GenesisBlockServicePort) +
"\" \"stat\":\"" + (stat.ok() ? "true" : "false") +
"\", \"response\":\"" +
(response.applied() ? "success" : "failure") + "\"}");
}
}
}
Expand Down
25 changes: 18 additions & 7 deletions iroha-cli/bootstrap_network.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,43 +22,54 @@
#include <vector>
#include "genesis_block_client.hpp"
#include "model/block.hpp"
#include "model/peer.hpp"

namespace iroha_cli {

class BootstrapNetwork {
public:
public:
BootstrapNetwork(GenesisBlockClient& client) : client_(client) {}

/**
* parse trusted peer's ip addresses in `target.conf`
* parses trusted peers in `target.conf`
* @param target_conf_path
* @return trusted peers' ip
* @return std::vector<iroha::model::Peer>
*/
std::vector<std::string> parse_trusted_peers(
std::vector<iroha::model::Peer> parse_trusted_peers(
std::string const& target_conf_path);

/**
* parse transactions in genesis block `genesis.json`
* parses transactions in genesis block `genesis.json`
* @param genesis_json_path
* @return iroha::model::Block
*/
iroha::model::Block parse_genesis_block(
std::string const& genesis_json_path);

/**
* merges trusted peers AddPeer tx with given block
* @param block
* @param trusted_peers
* @return iroha::model::Block
*/
iroha::model::Block merge_tx_add_trusted_peers(
const iroha::model::Block& block,
std::vector<iroha::model::Peer> const& trusted_peers);

/**
* aborts bootstrapping network.
* @param trusted_peers
* @param block
*/
void abort_network(std::vector<std::string> const& trusted_peers,
void abort_network(std::vector<iroha::model::Peer> const& trusted_peers,
iroha::model::Block const& block);

/**
* bootstraps network of trusted peers.
* @param trusted_peers
* @param block
*/
void run_network(std::vector<std::string> const& trusted_peers,
void run_network(std::vector<iroha::model::Peer> const& trusted_peers,
iroha::model::Block const& block);

private:
Expand Down
1 change: 1 addition & 0 deletions iroha-cli/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ int main(int argc, char* argv[]) {
auto bootstrap = iroha_cli::BootstrapNetwork(genesis_block_client);
auto peers = bootstrap.parse_trusted_peers(FLAGS_config);
auto block = bootstrap.parse_genesis_block(FLAGS_genesis_block);
bootstrap.merge_tx_add_trusted_peers(block, peers);
bootstrap.run_network(peers, block);
} else {
assert_config::assert_fatal(false, "Invalid flags");
Expand Down
33 changes: 25 additions & 8 deletions test/module/iroha-cli/bootstrap_network_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ class iroha_cli_test : public ::testing::Test {
block.hash = hash_provider.get_hash(block);
return block;
}

std::string rnd_hex_pk() {
return iroha::create_keypair(iroha::create_seed()).pubkey.to_hexstring();
}
};

class GenesisBlockClientMock : public iroha_cli::GenesisBlockClient {
Expand Down Expand Up @@ -91,24 +95,31 @@ class GenesisBlockClientMock : public iroha_cli::GenesisBlockClient {
TEST_F(iroha_cli_test, NormalWhenParseTrustedPeers) {
auto test_path = "/tmp/_boot_strap_test_target.conf";
std::ofstream ofs(test_path);
ofs << R"({"ip":["192.168.0.3","192.168.0.4","192.168.0.5","192.168.0.6"]})";
ofs << R"({"peers":[
{"pubkey":")" + rnd_hex_pk() + R"(", "ip":"192.168.0.3"},
{"pubkey":")" + rnd_hex_pk() + R"(", "ip":"192.168.0.4"},
{"pubkey":")" + rnd_hex_pk() + R"(", "ip":"192.168.0.5"},
{"pubkey":")" + rnd_hex_pk() + R"(", "ip":"192.168.0.6"}
]
}
)";
ofs.close();

GenesisBlockClientMock client_mock;
iroha_cli::BootstrapNetwork bootstrap(client_mock);
auto peers = bootstrap.parse_trusted_peers(test_path);
ASSERT_EQ(peers.size(), 4);
ASSERT_STREQ(peers[0].c_str(), "192.168.0.3");
ASSERT_STREQ(peers[1].c_str(), "192.168.0.4");
ASSERT_STREQ(peers[2].c_str(), "192.168.0.5");
ASSERT_STREQ(peers[3].c_str(), "192.168.0.6");
ASSERT_STREQ(peers[0].address.c_str(), "192.168.0.3");
ASSERT_STREQ(peers[1].address.c_str(), "192.168.0.4");
ASSERT_STREQ(peers[2].address.c_str(), "192.168.0.5");
ASSERT_STREQ(peers[3].address.c_str(), "192.168.0.6");
ASSERT_TRUE(remove(test_path) == 0);
}

TEST_F(iroha_cli_test, WrongIPNameWhenParseTrustedPeers) {
auto test_path = "/tmp/_bootstrap_test_target.conf";
std::ofstream ofs(test_path);
ofs << R"({"IP":["192.168.0.3","192.168.0.4","192.168.0.5","192.168.0.6"]})";
ofs << R"({"peers":[{"pubkey":")" + rnd_hex_pk() + R"(", "Ip":"192.168.0.5"}]})";
ofs.close();

GenesisBlockClientMock client_mock;
Expand All @@ -120,7 +131,7 @@ TEST_F(iroha_cli_test, WrongIPNameWhenParseTrustedPeers) {
TEST_F(iroha_cli_test, InvalidIPValueWhenParseTrustedPeers) {
auto test_path = "/tmp/_bootstrap_test_target.conf";
std::ofstream ofs(test_path);
ofs << R"({"ip":["192.168.256.3","192.168.0.4","192.168.0.5","192.168.0.6"]})";
ofs << R"({"peers":[{"pubkey":")" + rnd_hex_pk() + R"(", "ip":"192.256.0.5"}]})";
ofs.close();

GenesisBlockClientMock client_mock;
Expand Down Expand Up @@ -187,7 +198,13 @@ TEST_F(iroha_cli_test, NormalWhenRunNetwork) {

auto block = create_genesis_block();

std::vector<iroha::model::Peer> peers(2);
peers[0].address = "192.168.0.3";
peers[0].pubkey = iroha::create_keypair(iroha::create_seed()).pubkey;
peers[1].address = "192.168.0.4";
peers[1].pubkey = iroha::create_keypair(iroha::create_seed()).pubkey;

ASSERT_NO_THROW({
bootstrap.run_network({"192.168.0.3", "192.168.0.4"}, block);
bootstrap.run_network(peers, block);
});
}

0 comments on commit 3a1293d

Please sign in to comment.