Line data Source code
1 : /**
2 : * Copyright Soramitsu Co., Ltd. All Rights Reserved.
3 : * SPDX-License-Identifier: Apache-2.0
4 : */
5 :
6 : #include "consensus/yac/storage/yac_vote_storage.hpp"
7 :
8 : #include <algorithm>
9 : #include <utility>
10 :
11 : #include "common/bind.hpp"
12 : #include "consensus/yac/consistency_model.hpp"
13 : #include "consensus/yac/storage/yac_proposal_storage.hpp"
14 : #include "logger/logger_manager.hpp"
15 :
16 : namespace iroha {
17 : namespace consensus {
18 : namespace yac {
19 :
20 : // --------| private api |--------
21 :
22 : auto YacVoteStorage::getProposalStorage(const Round &round) {
23 13206 : return std::find_if(proposal_storages_.begin(),
24 13206 : proposal_storages_.end(),
25 : [&round](const auto &storage) {
26 13100 : return storage.getStorageKey() == round;
27 : });
28 : }
29 :
30 : boost::optional<std::vector<YacProposalStorage>::iterator>
31 : YacVoteStorage::findProposalStorage(const VoteMessage &msg,
32 : PeersNumberType peers_in_round) {
33 6735 : const auto &round = msg.hash.vote_round;
34 6735 : auto val = getProposalStorage(round);
35 6735 : if (val != proposal_storages_.end()) {
36 3590 : return val;
37 : }
38 3145 : if (strategy_->shouldCreateRound(round)) {
39 3145 : return proposal_storages_.emplace(
40 3145 : proposal_storages_.end(),
41 3145 : msg.hash.vote_round,
42 : peers_in_round,
43 3145 : supermajority_checker_,
44 3145 : log_manager_->getChild("ProposalStorage"));
45 : } else {
46 0 : return boost::none;
47 : }
48 6735 : }
49 :
50 : void YacVoteStorage::remove(const iroha::consensus::Round &round) {
51 2883 : auto val = getProposalStorage(round);
52 2883 : if (val != proposal_storages_.end()) {
53 2883 : proposal_storages_.erase(val);
54 2883 : }
55 2883 : auto state = processing_state_.find(round);
56 2883 : if (state != processing_state_.end()) {
57 2883 : processing_state_.erase(state);
58 2883 : }
59 2883 : }
60 :
61 : // --------| public api |--------
62 :
63 : YacVoteStorage::YacVoteStorage(
64 : std::shared_ptr<CleanupStrategy> cleanup_strategy,
65 : std::unique_ptr<SupermajorityChecker> supermajority_checker,
66 : logger::LoggerManagerTreePtr log_manager)
67 273 : : strategy_(std::move(cleanup_strategy)),
68 273 : supermajority_checker_(std::move(supermajority_checker)),
69 273 : log_manager_(std::move(log_manager)) {}
70 :
71 : boost::optional<Answer> YacVoteStorage::store(
72 : std::vector<VoteMessage> state, PeersNumberType peers_in_round) {
73 6735 : return findProposalStorage(state.at(0), peers_in_round) |
74 : [this, &state](auto &&storage) {
75 6735 : const auto &round = storage->getStorageKey();
76 6735 : return storage->insert(state) |
77 : [this, &round](
78 : auto &&insert_outcome) -> boost::optional<Answer> {
79 6281 : this->strategy_->finalize(round, insert_outcome) |
80 : [this](auto &&remove) {
81 2883 : std::for_each(
82 2883 : remove.begin(),
83 2883 : remove.end(),
84 : [this](const auto &round) { this->remove(round); });
85 2883 : };
86 6281 : return insert_outcome;
87 0 : };
88 0 : };
89 0 : }
90 :
91 : bool YacVoteStorage::isCommitted(const Round &round) {
92 3588 : auto iter = getProposalStorage(round);
93 3588 : if (iter == proposal_storages_.end()) {
94 3587 : return false;
95 : }
96 1 : return bool(iter->getState());
97 3588 : }
98 :
99 : ProposalState YacVoteStorage::getProcessingState(const Round &round) {
100 6720 : return processing_state_[round];
101 : }
102 :
103 : void YacVoteStorage::nextProcessingState(const Round &round) {
104 12564 : auto &val = processing_state_[round];
105 12564 : switch (val) {
106 : case ProposalState::kNotSentNotProcessed:
107 3142 : val = ProposalState::kSentNotProcessed;
108 3142 : break;
109 : case ProposalState::kSentNotProcessed:
110 3140 : val = ProposalState::kSentProcessed;
111 3140 : break;
112 : case ProposalState::kSentProcessed:
113 0 : break;
114 : }
115 6282 : }
116 :
117 : } // namespace yac
118 : } // namespace consensus
119 : } // namespace iroha
|