Skip to content

Commit

Permalink
Merge branch 'develop' of https://github.com/hyperledger/iroha into d…
Browse files Browse the repository at this point in the history
…evelop
  • Loading branch information
motxx committed Jul 20, 2017
2 parents e36e8b2 + 28a9704 commit 32925d7
Show file tree
Hide file tree
Showing 27 changed files with 2,615 additions and 63 deletions.
11 changes: 8 additions & 3 deletions irohad/model/impl/command_execution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,13 @@ namespace iroha {
if (!asset)
// No such asset
return false;

if (!queries.getAccount(account_id))
// No such account
return false;
auto account_asset = queries.getAccountAsset(account_id, asset_id);
auto precision = asset.value().precision;

// Amount is wrongly formed
if (amount.get_frac_number() > precision) return false;
AccountAsset accountAsset;
// Such accountAsset not found
if (!account_asset) {
Expand Down Expand Up @@ -169,7 +172,9 @@ namespace iroha {
return false;
// Precision for both wallets
auto precision = asset.value().precision;

if (amount.get_frac_number() > precision)
// Precision is wrong
return false;
// Get src balance
auto src_balance = src_account_assert.value().balance;
// TODO: handle non-trivial arithmetic
Expand Down
12 changes: 5 additions & 7 deletions irohad/model/impl/model_operators.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,13 +194,11 @@ namespace iroha {

/* Transaction */
bool Transaction::operator==(const Transaction &rhs) const {
if (rhs.commands.size() != commands.size()) return false;

// todo change for cycle to comparison with predicate
for (auto i = 0; i < rhs.commands.size(); i++){
if (*rhs.commands.at(i) != *commands.at(i)) return false;
}
return rhs.tx_counter == tx_counter && rhs.signatures == signatures &&
return std::equal(
commands.begin(), commands.end(), rhs.commands.begin(),
rhs.commands.end(),
[](const auto &i, const auto &j) { return *i == *j; }) &&
rhs.tx_counter == tx_counter && rhs.signatures == signatures &&
rhs.created_ts == created_ts;
}

Expand Down
25 changes: 15 additions & 10 deletions irohad/model/impl/stateful_command_validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,15 +82,15 @@ namespace iroha {
bool AssignMasterKey::validate(ametsuchi::WsvQuery &queries,
const Account &creator) {
auto signs = queries.getSignatories(account_id);

auto acc = queries.getAccount(account_id);
return
// Two cases - when creator assigns to itself, or system admin
(creator.account_id == account_id ||
creator.permissions.add_signatory) &&
// Check if account has at lest one signatory
signs &&
// Check if account exist and has at least one signatory
signs && acc.has_value() &&
// Check if new master key is not the same
creator.master_key != pubkey &&
acc.value().master_key != pubkey &&
// Check if new master key is in AccountSignatory relationship
std::find(signs->begin(), signs->end(), pubkey) != signs->end();
}
Expand Down Expand Up @@ -123,7 +123,7 @@ namespace iroha {
// Creator must have permission to create assets
return creator.permissions.create_assets &&
// Name is within some range
asset_name.size() > 0 && asset_name.size() < 8 &&
asset_name.size() > 0 && asset_name.size() < 10 &&
// Account must be well-formed (no system symbols)
std::all_of(std::begin(asset_name), std::end(asset_name),
[](char c) { return std::isalnum(c); });
Expand All @@ -141,7 +141,7 @@ namespace iroha {
// Creator must have permission to create domains
return creator.permissions.create_domains &&
// Name is within some range
domain_name.size() > 0 && domain_name.size() < 8 &&
domain_name.size() > 0 && domain_name.size() < 10 &&
// Account must be well-formed (no system symbols)
std::all_of(std::begin(domain_name), std::end(domain_name),
[](char c) { return std::isalnum(c); });
Expand All @@ -156,14 +156,15 @@ namespace iroha {
*/
bool RemoveSignatory::validate(ametsuchi::WsvQuery &queries,
const Account &creator) {
auto account = queries.getAccount(account_id);
return
// Two cases possible.
// 1. Creator removes signatory from their account
// 2.System admin
(creator.account_id == account_id ||
creator.permissions.remove_signatory) &&
account.has_value() && (creator.account_id == account_id ||
creator.permissions.remove_signatory) &&
// You can't remove master key (first you should reassign it)
pubkey != creator.master_key;
pubkey != account.value().master_key;
}

/**
Expand Down Expand Up @@ -211,13 +212,17 @@ namespace iroha {
return
// Check if src_account exist
queries.getAccount(src_account_id) &&
// Check if dest account exist
queries.getAccount(dest_account_id) &&
// Can account transfer assets
creator.permissions.can_transfer &&
// Creator can transfer only from their account
creator.account_id == src_account_id &&
// Balance in your wallet should be at least amount of transfer
account_asset.value().balance >=
amount.get_joint_amount(asset.value().precision);
amount.get_joint_amount(asset.value().precision) &&
// Amount must be not zero
(amount.frac_part > 0 || amount.int_part > 0);
}

} // namespace model
Expand Down
40 changes: 40 additions & 0 deletions irohad/network/server.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* Copyright Soramitsu Co., Ltd. 2017 All Rights Reserved.
* http://soramitsu.co.jp
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "server.hpp"
#include <grpc++/grpc++.h>

namespace network {
Server::Server(std::shared_ptr<uvw::Loop> loop)
: loop_{loop} {

}

void Server::run_grpc(uvw::Addr addr, bool blocking) {
// bind grpc service
auto listen_on = addr.ip + ":" + std::to_string(addr.port);
builder.AddListeningPort(listen_on,
grpc::InsecureServerCredentials());
builder.RegisterService(&this->consensus_);

auto server = builder.BuildAndStart();

if(blocking) {
server->Wait();
}
}
}
46 changes: 46 additions & 0 deletions irohad/network/server.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/**
* Copyright Soramitsu Co., Ltd. 2017 All Rights Reserved.
* http://soramitsu.co.jp
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifndef IROHA_NETWORK_HPP
#define IROHA_NETWORK_HPP

#include <grpc++/server_builder.h>
#include <consensus/consensus_service.hpp>
#include <consensus/messages.hpp>
#include <uvw.hpp>

namespace network {

/**
* This is an entity, which is listens host:port and emits received messages
* It emits all types of messages defined in consensus/messages.hpp
* GRPC server builder is also here.
*/
class Server : public uvw::Emitter<Server> {
public:
Server(std::shared_ptr<uvw::Loop> loop = uvw::Loop::getDefault());

void run_grpc(uvw::Addr addr, bool blocking = true);

private:
std::shared_ptr<uvw::Loop> loop_;

grpc::ServerBuilder builder;
consensus::ConsensusService consensus_;
};
}
#endif // IROHA_NETWORK_HPP
37 changes: 25 additions & 12 deletions irohad/peer_service/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,30 @@
# transaction_repository
#)

ADD_LIBRARY(peer_service STATIC
monitor.cpp
change_state.cpp
self_state.cpp
synchronizer/synchronizer.cpp
)
#ADD_LIBRARY(peer_service STATIC
# monitor.cpp
# change_state.cpp
# self_state.cpp
# synchronizer/synchronizer.cpp
#)
#
#target_link_libraries(peer_service
# timer
# time64
# logger
# crypto
# schema
#)

add_library(peer_service
node.hpp
service.cpp
service.hpp
connection_to.cpp
connection_to.hpp
)
target_link_libraries(peer_service
timer
time64
logger
crypto
schema
)
uvw
peer_service_grpc
lookup3
)
118 changes: 118 additions & 0 deletions irohad/peer_service/connection_to.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/**
* Copyright Soramitsu Co., Ltd. 2017 All Rights Reserved.
* http://soramitsu.co.jp
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "connection_to.hpp"
#include "service.hpp"

#ifndef SHORT_TIMER_LOW
// milliseconds
#define SHORT_TIMER_LOW 1000
#endif

#ifndef SHORT_TIMER_HIGH
// milliseconds
#define SHORT_TIMER_HIGH 2000
#endif

#ifndef LONG_TIMER_LOW
// milliseconds
#define LONG_TIMER_LOW (1000 * 60 * 1)
#endif

#ifndef LONG_TIMER_HIGH
// milliseconds
#define LONG_TIMER_HIGH (1000 * 60 * 60)
#endif

namespace peerservice {
std::random_device ConnectionTo::random_device;
// generator with random distribution
std::default_random_engine ConnectionTo::generator(
ConnectionTo::random_device());
// uniform distribution for timer : from 1 sec to 2 secs
std::uniform_int_distribution<uint32_t> ConnectionTo::next_short_timer(
SHORT_TIMER_LOW, SHORT_TIMER_HIGH);

// uniform distribution for timer: from 1 min to 1 hour
std::uniform_int_distribution<uint32_t> ConnectionTo::next_long_timer(
LONG_TIMER_LOW, LONG_TIMER_HIGH); // ms

ConnectionTo::ConnectionTo(const Node &n, std::shared_ptr<uvw::Loop> loop)
: node(n) {
if (loop == nullptr) throw std::invalid_argument("loop is null");

this->online = false;
this->timer = loop->resource<uvw::TimerHandle>();

auto to = n.ip + ":" + std::to_string(n.port);
auto channel = grpc::CreateChannel(to, grpc::InsecureChannelCredentials());
stub_ = PeerService::NewStub(channel);
}

ConnectionTo::~ConnectionTo() { this->timer->close(); }

void ConnectionTo::start_timer(
std::uniform_int_distribution<uint32_t> &distr) {
if (timer->active()) timer->stop();

auto timeout_ms = std::chrono::milliseconds(distr(ConnectionTo::generator));
timer->start(timeout_ms, uvw::TimerHandle::Time{0});
}

void ConnectionTo::ping(Heartbeat *request) {
if (request == nullptr) throw std::invalid_argument("request is nullptr");

grpc::ClientContext context;
grpc::Status status;
Heartbeat answer;

status = stub_->RequestHeartbeat(&context, *request, &answer);
printf("[my ledger is %d] ping %s... ", request->height(),
context.peer().c_str());

// TODO: validate heartbeat messages
if (status.ok()) {
// peer is alive
this->make_online();
publish(answer); // publish event to uvw

} else {
if (status.error_code() == grpc::StatusCode::CANCELLED) {
// our heartbeat is invalid (this->myHeartbeat)
// TODO handle this
throw std::invalid_argument("our heartbeat is invalid");
}

// peer is dead
this->make_offline();
}
}

void ConnectionTo::make_online() noexcept {
// TODO: change to logger
printf("alive\n");
this->online = true;
this->start_timer(next_short_timer);
}

void ConnectionTo::make_offline() noexcept {
// TODO: change to logger
printf("dead\n");
this->online = false;
this->start_timer(next_long_timer);
}
}
Loading

0 comments on commit 32925d7

Please sign in to comment.