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/buffered_cleanup_strategy.hpp"
7 :
8 : #include "common/visitor.hpp"
9 :
10 : using namespace iroha::consensus::yac;
11 :
12 : boost::optional<CleanupStrategy::RoundsType> BufferedCleanupStrategy::finalize(
13 : RoundType consensus_round, Answer answer) {
14 : using OptRefRoundType = boost::optional<RoundType> &;
15 6287 : auto &target_round = iroha::visit_in_place(
16 : answer,
17 : [this](
18 : const iroha::consensus::yac::CommitMessage &msg) -> OptRefRoundType {
19 : // greater commit removes last reject because previous rejects are not
20 : // required anymore for the consensus
21 6281 : if (last_commit_round_ and last_reject_round_
22 6021 : and *last_commit_round_ < *last_reject_round_) {
23 1 : last_reject_round_ = boost::none;
24 1 : }
25 6281 : return last_commit_round_;
26 : },
27 : [this](const iroha::consensus::yac::RejectMessage &msg)
28 6 : -> OptRefRoundType { return last_reject_round_; });
29 :
30 6287 : if (not target_round or *target_round < consensus_round) {
31 3148 : target_round = consensus_round;
32 3148 : }
33 :
34 6287 : auto removed_rounds = truncateCreatedRounds();
35 6287 : if (removed_rounds.empty()) {
36 3401 : return boost::none;
37 : } else {
38 2886 : return removed_rounds;
39 : }
40 6287 : }
41 :
42 : CleanupStrategy::RoundsType BufferedCleanupStrategy::truncateCreatedRounds() {
43 6287 : CleanupStrategy::RoundsType removed;
44 6287 : if (last_commit_round_) {
45 9174 : while (*last_commit_round_ > created_rounds_.top()) {
46 2892 : removed.push_back(created_rounds_.top());
47 2892 : created_rounds_.pop();
48 : }
49 6282 : }
50 6287 : return removed;
51 6287 : }
52 :
53 : boost::optional<BufferedCleanupStrategy::RoundType>
54 : BufferedCleanupStrategy::minimalRound() const {
55 : // both values unavailable
56 3159 : if (not last_reject_round_ and not last_commit_round_) {
57 273 : return boost::none;
58 : }
59 :
60 : // both values present
61 2886 : if (last_commit_round_ and last_reject_round_) {
62 1 : return std::min(*last_commit_round_, *last_reject_round_);
63 : }
64 :
65 : // one value present
66 2885 : return last_commit_round_ ? last_commit_round_ : last_reject_round_;
67 3159 : }
68 :
69 : bool BufferedCleanupStrategy::shouldCreateRound(const Round &round) {
70 3159 : if (isRequiredCreation(round)) {
71 3159 : createRound(round);
72 3159 : return true;
73 : } else {
74 0 : return false;
75 : }
76 3159 : }
77 :
78 : void BufferedCleanupStrategy::createRound(const Round &round) {
79 3159 : created_rounds_.push(round);
80 3159 : }
81 :
82 : bool BufferedCleanupStrategy::isRequiredCreation(const Round &round) const {
83 : // TODO: 13/12/2018 @muratovv possible DOS-attack on consensus IR-128
84 3159 : auto min_round = minimalRound();
85 3159 : if (min_round) {
86 2886 : return *min_round <= round;
87 : } else {
88 273 : return true;
89 : }
90 3159 : }
|