Skip to content
This repository was archived by the owner on Apr 17, 2019. It is now read-only.

Commit 46c30c6

Browse files
author
Igor Egorov
authored
Merge pull request #2055 from hyperledger/hotfix/rc2
Hotfix for segfault and atomic batches
2 parents 108b2af + 3c41103 commit 46c30c6

27 files changed

+550
-186
lines changed

irohad/main/application.cpp

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "validators/default_validator.hpp"
3333
#include "validators/field_validator.hpp"
3434
#include "validators/protobuf/proto_block_validator.hpp"
35+
#include "validators/protobuf/proto_proposal_validator.hpp"
3536
#include "validators/protobuf/proto_query_validator.hpp"
3637
#include "validators/protobuf/proto_transaction_validator.hpp"
3738

@@ -189,6 +190,26 @@ void Irohad::initNetworkClient() {
189190
}
190191

191192
void Irohad::initFactories() {
193+
// proposal factory
194+
std::shared_ptr<
195+
shared_model::validation::AbstractValidator<iroha::protocol::Transaction>>
196+
proto_transaction_validator = std::make_shared<
197+
shared_model::validation::ProtoTransactionValidator>();
198+
std::unique_ptr<shared_model::validation::AbstractValidator<
199+
shared_model::interface::Proposal>>
200+
proposal_validator = std::make_unique<
201+
shared_model::validation::DefaultProposalValidator>();
202+
std::unique_ptr<
203+
shared_model::validation::AbstractValidator<iroha::protocol::Proposal>>
204+
proto_proposal_validator =
205+
std::make_unique<shared_model::validation::ProtoProposalValidator>(
206+
proto_transaction_validator);
207+
proposal_factory =
208+
std::make_shared<shared_model::proto::ProtoTransportFactory<
209+
shared_model::interface::Proposal,
210+
shared_model::proto::Proposal>>(std::move(proposal_validator),
211+
std::move(proto_proposal_validator));
212+
192213
// transaction factories
193214
transaction_batch_factory_ =
194215
std::make_shared<shared_model::interface::TransactionBatchFactoryImpl>();
@@ -198,10 +219,6 @@ void Irohad::initFactories() {
198219
transaction_validator =
199220
std::make_unique<shared_model::validation::
200221
DefaultOptionalSignedTransactionValidator>();
201-
std::unique_ptr<
202-
shared_model::validation::AbstractValidator<iroha::protocol::Transaction>>
203-
proto_transaction_validator = std::make_unique<
204-
shared_model::validation::ProtoTransactionValidator>();
205222
transaction_factory =
206223
std::make_shared<shared_model::proto::ProtoTransportFactory<
207224
shared_model::interface::Transaction,
@@ -301,6 +318,7 @@ void Irohad::initOrderingGate() {
301318
transaction_batch_factory_,
302319
async_call_,
303320
std::move(factory),
321+
proposal_factory,
304322
persistent_cache,
305323
{blocks.back()->height(), 1},
306324
delay);
@@ -363,7 +381,8 @@ void Irohad::initConsensusGate() {
363381
vote_delay_,
364382
async_call_,
365383
common_objects_factory_);
366-
384+
consensus_gate->onOutcome().subscribe(
385+
consensus_gate_objects.get_subscriber());
367386
log_->info("[Init] => consensus gate");
368387
}
369388

@@ -466,8 +485,10 @@ void Irohad::initTransactionCommandService() {
466485
transaction_factory,
467486
batch_parser,
468487
transaction_batch_factory_,
469-
consensus_gate,
470-
2);
488+
consensus_gate_objects.get_observable().map([](const auto &) {
489+
return ::torii::CommandServiceTransportGrpc::ConsensusGateEvent{};
490+
}),
491+
2); // TODO 18.01.2019 igor-egorov, make it configurable IR-230
471492

472493
log_->info("[Init] => command service");
473494
}

irohad/main/application.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,12 @@ class Irohad {
195195
// persistent cache
196196
std::shared_ptr<iroha::ametsuchi::TxPresenceCache> persistent_cache;
197197

198+
// proposal factory
199+
std::shared_ptr<shared_model::interface::AbstractTransportFactory<
200+
shared_model::interface::Proposal,
201+
iroha::protocol::Proposal>>
202+
proposal_factory;
203+
198204
// ordering gate
199205
std::shared_ptr<iroha::network::OrderingGate> ordering_gate;
200206

@@ -210,6 +216,7 @@ class Irohad {
210216

211217
// consensus gate
212218
std::shared_ptr<iroha::network::ConsensusGate> consensus_gate;
219+
rxcpp::subjects::subject<iroha::consensus::GateObject> consensus_gate_objects;
213220

214221
// synchronizer
215222
std::shared_ptr<iroha::synchronizer::Synchronizer> synchronizer;

irohad/main/impl/on_demand_ordering_init.cpp

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,11 @@ namespace iroha {
4444
auto OnDemandOrderingInit::createNotificationFactory(
4545
std::shared_ptr<network::AsyncGrpcClient<google::protobuf::Empty>>
4646
async_call,
47+
std::shared_ptr<TransportFactoryType> proposal_transport_factory,
4748
std::chrono::milliseconds delay) {
4849
return std::make_shared<ordering::transport::OnDemandOsClientGrpcFactory>(
4950
std::move(async_call),
51+
std::move(proposal_transport_factory),
5052
[] { return std::chrono::system_clock::now(); },
5153
delay);
5254
}
@@ -55,6 +57,7 @@ namespace iroha {
5557
std::shared_ptr<ametsuchi::PeerQueryFactory> peer_query_factory,
5658
std::shared_ptr<network::AsyncGrpcClient<google::protobuf::Empty>>
5759
async_call,
60+
std::shared_ptr<TransportFactoryType> proposal_transport_factory,
5861
std::chrono::milliseconds delay,
5962
std::vector<shared_model::interface::types::HashType> initial_hashes) {
6063
// since top block will be the first in notifier observable, hashes of
@@ -174,7 +177,10 @@ namespace iroha {
174177
.map(map_peers);
175178

176179
return std::make_shared<ordering::OnDemandConnectionManager>(
177-
createNotificationFactory(std::move(async_call), delay), peers);
180+
createNotificationFactory(std::move(async_call),
181+
std::move(proposal_transport_factory),
182+
delay),
183+
peers);
178184
}
179185

180186
auto OnDemandOrderingInit::createGate(
@@ -187,7 +193,6 @@ namespace iroha {
187193
consensus::Round initial_round,
188194
std::function<std::chrono::seconds(
189195
const synchronizer::SynchronizationEvent &)> delay_func) {
190-
191196
auto map = [](auto commit) {
192197
return matchEvent(
193198
commit,
@@ -263,6 +268,7 @@ namespace iroha {
263268
async_call,
264269
std::shared_ptr<shared_model::interface::UnsafeProposalFactory>
265270
proposal_factory,
271+
std::shared_ptr<TransportFactoryType> proposal_transport_factory,
266272
std::shared_ptr<ametsuchi::TxPresenceCache> tx_cache,
267273
consensus::Round initial_round,
268274
std::function<std::chrono::seconds(
@@ -274,16 +280,18 @@ namespace iroha {
274280
std::move(transaction_factory),
275281
std::move(batch_parser),
276282
std::move(transaction_batch_factory));
277-
return createGate(ordering_service,
278-
createConnectionManager(std::move(peer_query_factory),
279-
std::move(async_call),
280-
delay,
281-
std::move(initial_hashes)),
282-
std::make_shared<ordering::cache::OnDemandCache>(),
283-
std::move(proposal_factory),
284-
std::move(tx_cache),
285-
initial_round,
286-
std::move(delay_func));
283+
return createGate(
284+
ordering_service,
285+
createConnectionManager(std::move(peer_query_factory),
286+
std::move(async_call),
287+
std::move(proposal_transport_factory),
288+
delay,
289+
std::move(initial_hashes)),
290+
std::make_shared<ordering::cache::OnDemandCache>(),
291+
std::move(proposal_factory),
292+
std::move(tx_cache),
293+
initial_round,
294+
std::move(delay_func));
287295
}
288296

289297
} // namespace network

irohad/main/impl/on_demand_ordering_init.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ namespace iroha {
2828
* Encapsulates initialization logic for on-demand ordering gate and service
2929
*/
3030
class OnDemandOrderingInit {
31+
public:
32+
using TransportFactoryType =
33+
shared_model::interface::AbstractTransportFactory<
34+
shared_model::interface::Proposal,
35+
iroha::protocol::Proposal>;
36+
3137
private:
3238
/**
3339
* Creates notification factory for individual connections to peers with
@@ -36,6 +42,7 @@ namespace iroha {
3642
auto createNotificationFactory(
3743
std::shared_ptr<network::AsyncGrpcClient<google::protobuf::Empty>>
3844
async_call,
45+
std::shared_ptr<TransportFactoryType> proposal_transport_factory,
3946
std::chrono::milliseconds delay);
4047

4148
/**
@@ -47,6 +54,7 @@ namespace iroha {
4754
std::shared_ptr<ametsuchi::PeerQueryFactory> peer_query_factory,
4855
std::shared_ptr<network::AsyncGrpcClient<google::protobuf::Empty>>
4956
async_call,
57+
std::shared_ptr<TransportFactoryType> proposal_transport_factory,
5058
std::chrono::milliseconds delay,
5159
std::vector<shared_model::interface::types::HashType> initial_hashes);
5260

@@ -117,6 +125,7 @@ namespace iroha {
117125
async_call,
118126
std::shared_ptr<shared_model::interface::UnsafeProposalFactory>
119127
proposal_factory,
128+
std::shared_ptr<TransportFactoryType> proposal_transport_factory,
120129
std::shared_ptr<ametsuchi::TxPresenceCache> tx_cache,
121130
consensus::Round initial_round,
122131
std::function<std::chrono::seconds(

irohad/ordering/impl/on_demand_ordering_gate.cpp

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,12 @@
66
#include "ordering/impl/on_demand_ordering_gate.hpp"
77

88
#include <boost/range/adaptor/filtered.hpp>
9+
#include <boost/range/adaptor/indexed.hpp>
10+
#include <boost/range/adaptor/transformed.hpp>
911
#include <boost/range/empty.hpp>
1012
#include "ametsuchi/tx_presence_cache.hpp"
1113
#include "common/visitor.hpp"
14+
#include "interfaces/iroha_internal/transaction_batch_parser_impl.hpp"
1215
#include "ordering/impl/on_demand_common.hpp"
1316

1417
using namespace iroha;
@@ -108,6 +111,7 @@ OnDemandOrderingGate::processProposalRequest(
108111
boost::optional<std::shared_ptr<shared_model::interface::Proposal>>
109112
OnDemandOrderingGate::removeReplays(
110113
shared_model::interface::Proposal &&proposal) const {
114+
std::vector<bool> proposal_txs_validation_results;
111115
auto tx_is_not_processed = [this](const auto &tx) {
112116
auto tx_result = tx_cache_->check(tx.hash());
113117
if (not tx_result) {
@@ -125,8 +129,28 @@ OnDemandOrderingGate::removeReplays(
125129
return false;
126130
});
127131
};
132+
133+
shared_model::interface::TransactionBatchParserImpl batch_parser;
134+
135+
auto batches = batch_parser.parseBatches(proposal.transactions());
136+
for (auto &batch : batches) {
137+
bool batch_validation_result =
138+
std::all_of(batch.begin(), batch.end(), tx_is_not_processed);
139+
proposal_txs_validation_results.insert(
140+
proposal_txs_validation_results.end(),
141+
batch.size(),
142+
batch_validation_result);
143+
}
144+
128145
auto unprocessed_txs =
129-
boost::adaptors::filter(proposal.transactions(), tx_is_not_processed);
146+
proposal.transactions() | boost::adaptors::indexed()
147+
| boost::adaptors::filtered(
148+
[proposal_txs_validation_results =
149+
std::move(proposal_txs_validation_results)](const auto &el) {
150+
return proposal_txs_validation_results.at(el.index());
151+
})
152+
| boost::adaptors::transformed(
153+
[](const auto &el) -> decltype(auto) { return el.value(); });
130154

131155
auto result = proposal_factory_->unsafeCreateProposal(
132156
proposal.height(), proposal.createdTime(), unprocessed_txs);

irohad/ordering/impl/on_demand_os_client_grpc.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@ OnDemandOsClientGrpc::OnDemandOsClientGrpc(
1919
std::unique_ptr<proto::OnDemandOrdering::StubInterface> stub,
2020
std::shared_ptr<network::AsyncGrpcClient<google::protobuf::Empty>>
2121
async_call,
22+
std::shared_ptr<TransportFactoryType> proposal_factory,
2223
std::function<TimepointType()> time_provider,
2324
std::chrono::milliseconds proposal_request_timeout,
2425
logger::Logger log)
2526
: log_(std::move(log)),
2627
stub_(std::move(stub)),
2728
async_call_(std::move(async_call)),
29+
proposal_factory_(std::move(proposal_factory)),
2830
time_provider_(std::move(time_provider)),
2931
proposal_request_timeout_(proposal_request_timeout) {}
3032

@@ -64,16 +66,28 @@ OnDemandOsClientGrpc::onRequestProposal(consensus::Round round) {
6466
if (not response.has_proposal()) {
6567
return boost::none;
6668
}
67-
return ProposalType{std::make_unique<shared_model::proto::Proposal>(
68-
std::move(response.proposal()))};
69+
return proposal_factory_->build(response.proposal())
70+
.match(
71+
[&](iroha::expected::Value<
72+
std::unique_ptr<shared_model::interface::Proposal>> &v)
73+
-> boost::optional<OdOsNotification::ProposalType> {
74+
return ProposalType{std::move(v).value};
75+
},
76+
[this](iroha::expected::Error<TransportFactoryType::Error> &error)
77+
-> boost::optional<OdOsNotification::ProposalType> {
78+
log_->info(error.error.error); // error
79+
return {};
80+
});
6981
}
7082

7183
OnDemandOsClientGrpcFactory::OnDemandOsClientGrpcFactory(
7284
std::shared_ptr<network::AsyncGrpcClient<google::protobuf::Empty>>
7385
async_call,
86+
std::shared_ptr<TransportFactoryType> proposal_factory,
7487
std::function<OnDemandOsClientGrpc::TimepointType()> time_provider,
7588
OnDemandOsClientGrpc::TimeoutType proposal_request_timeout)
7689
: async_call_(std::move(async_call)),
90+
proposal_factory_(std::move(proposal_factory)),
7791
time_provider_(time_provider),
7892
proposal_request_timeout_(proposal_request_timeout) {}
7993

@@ -82,6 +96,7 @@ std::unique_ptr<OdOsNotification> OnDemandOsClientGrpcFactory::create(
8296
return std::make_unique<OnDemandOsClientGrpc>(
8397
network::createClient<proto::OnDemandOrdering>(to.address()),
8498
async_call_,
99+
proposal_factory_,
85100
time_provider_,
86101
proposal_request_timeout_,
87102
logger::log("OnDemandOsClientGrpc"));

irohad/ordering/impl/on_demand_os_client_grpc.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include "ordering/on_demand_os_transport.hpp"
1010

11+
#include "interfaces/iroha_internal/abstract_transport_factory.hpp"
1112
#include "network/impl/async_grpc_client.hpp"
1213
#include "ordering.grpc.pb.h"
1314

@@ -20,6 +21,10 @@ namespace iroha {
2021
*/
2122
class OnDemandOsClientGrpc : public OdOsNotification {
2223
public:
24+
using TransportFactoryType =
25+
shared_model::interface::AbstractTransportFactory<
26+
shared_model::interface::Proposal,
27+
iroha::protocol::Proposal>;
2328
using TimepointType = std::chrono::system_clock::time_point;
2429
using TimeoutType = std::chrono::milliseconds;
2530

@@ -31,6 +36,7 @@ namespace iroha {
3136
std::unique_ptr<proto::OnDemandOrdering::StubInterface> stub,
3237
std::shared_ptr<network::AsyncGrpcClient<google::protobuf::Empty>>
3338
async_call,
39+
std::shared_ptr<TransportFactoryType> proposal_factory,
3440
std::function<TimepointType()> time_provider,
3541
std::chrono::milliseconds proposal_request_timeout,
3642
logger::Logger log = logger::log("OnDemandOsClientGrpc"));
@@ -45,15 +51,18 @@ namespace iroha {
4551
std::unique_ptr<proto::OnDemandOrdering::StubInterface> stub_;
4652
std::shared_ptr<network::AsyncGrpcClient<google::protobuf::Empty>>
4753
async_call_;
54+
std::shared_ptr<TransportFactoryType> proposal_factory_;
4855
std::function<TimepointType()> time_provider_;
4956
std::chrono::milliseconds proposal_request_timeout_;
5057
};
5158

5259
class OnDemandOsClientGrpcFactory : public OdOsNotificationFactory {
5360
public:
61+
using TransportFactoryType = OnDemandOsClientGrpc::TransportFactoryType;
5462
OnDemandOsClientGrpcFactory(
5563
std::shared_ptr<network::AsyncGrpcClient<google::protobuf::Empty>>
5664
async_call,
65+
std::shared_ptr<TransportFactoryType> proposal_factory,
5766
std::function<OnDemandOsClientGrpc::TimepointType()> time_provider,
5867
OnDemandOsClientGrpc::TimeoutType proposal_request_timeout);
5968

@@ -69,6 +78,7 @@ namespace iroha {
6978
private:
7079
std::shared_ptr<network::AsyncGrpcClient<google::protobuf::Empty>>
7180
async_call_;
81+
std::shared_ptr<TransportFactoryType> proposal_factory_;
7282
std::function<OnDemandOsClientGrpc::TimepointType()> time_provider_;
7383
std::chrono::milliseconds proposal_request_timeout_;
7484
};

irohad/torii/impl/command_service_impl.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,9 @@ namespace torii {
112112
// prepend initial status
113113
.start_with(initial_status)
114114
// select statuses with requested hash
115-
.filter(
116-
[&](auto response) { return response->transactionHash() == hash; })
115+
.filter([hash](auto response) {
116+
return response->transactionHash() == hash;
117+
})
117118
// successfully complete the observable if final status is received.
118119
// final status is included in the observable
119120
.template lift<ResponsePtrType>([](rxcpp::subscriber<ResponsePtrType>

0 commit comments

Comments
 (0)