forked from ton-blockchain/ton
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvalidator-session.hpp
210 lines (167 loc) · 7.62 KB
/
validator-session.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
/*
This file is part of TON Blockchain Library.
TON Blockchain Library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
TON Blockchain Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
*/
#pragma once
#include <set>
#include <map>
#include <list>
#include <atomic>
#include "validator-session.h"
#include "validator-session-state.h"
#include "keys/encryptor.h"
#include "catchain/catchain.h"
namespace ton {
namespace validatorsession {
class ValidatorSessionImpl : public ValidatorSession {
private:
class BlockExtra : public catchain::CatChainBlock::Extra {
public:
const ValidatorSessionState *get_ref() const {
return state_;
}
BlockExtra(const ValidatorSessionState *state) : state_(std::move(state)) {
}
private:
const ValidatorSessionState *state_;
};
bool requested_new_block_ = false;
bool requested_new_block_now_ = false;
const ValidatorSessionState *real_state_ = nullptr;
const ValidatorSessionState *virtual_state_ = nullptr;
td::uint32 cur_round_ = 0;
td::Timestamp round_started_at_ = td::Timestamp::never();
td::Timestamp round_debug_at_ = td::Timestamp::never();
std::set<ValidatorSessionCandidateId> pending_approve_;
std::map<ValidatorSessionCandidateId, td::BufferSlice> pending_reject_;
std::set<ValidatorSessionCandidateId> rejected_;
std::map<ValidatorSessionCandidateId, std::pair<UnixTime, td::BufferSlice>> approved_;
std::set<ValidatorSessionCandidateId> active_requests_;
bool pending_generate_ = false;
bool generated_ = false;
bool sent_generated_ = false;
ValidatorSessionCandidateId generated_block_;
bool pending_sign_ = false;
bool signed_ = false;
ValidatorSessionCandidateId signed_block_;
td::BufferSlice signature_;
std::array<std::map<ValidatorSessionCandidateId, tl_object_ptr<ton_api::validatorSession_candidate>>, 100> blocks_;
catchain::CatChainSessionId unique_hash_;
std::unique_ptr<Callback> callback_;
std::string db_root_;
td::actor::ActorId<keyring::Keyring> keyring_;
td::actor::ActorId<adnl::Adnl> adnl_;
td::actor::ActorId<rldp::Rldp> rldp_;
td::actor::ActorId<overlay::Overlays> overlay_manager_;
td::actor::ActorOwn<catchain::CatChain> catchain_;
std::unique_ptr<ValidatorSessionDescription> description_;
void on_new_round(td::uint32 round);
void on_catchain_started();
void check_vote_for_slot(td::uint32 att);
void check_generate_slot();
void check_sign_slot();
void check_approve();
void check_action(td::uint32 att);
void check_all();
std::unique_ptr<catchain::CatChain::Callback> make_catchain_callback() {
class cb : public catchain::CatChain::Callback {
public:
void process_blocks(std::vector<catchain::CatChainBlock *> blocks) override {
td::actor::send_closure(id_, &ValidatorSessionImpl::process_blocks, std::move(blocks));
}
void finished_processing() override {
td::actor::send_closure(id_, &ValidatorSessionImpl::finished_processing);
}
void preprocess_block(catchain::CatChainBlock *block) override {
td::actor::send_closure(id_, &ValidatorSessionImpl::preprocess_block, block);
}
void process_broadcast(PublicKeyHash src, td::BufferSlice data) override {
td::actor::send_closure(id_, &ValidatorSessionImpl::process_broadcast, src, std::move(data));
}
void process_message(PublicKeyHash src, td::BufferSlice data) override {
td::actor::send_closure(id_, &ValidatorSessionImpl::process_message, src, std::move(data));
}
void process_query(PublicKeyHash src, td::BufferSlice data, td::Promise<td::BufferSlice> promise) override {
td::actor::send_closure(id_, &ValidatorSessionImpl::process_query, src, std::move(data), std::move(promise));
}
void started() override {
td::actor::send_closure(id_, &ValidatorSessionImpl::on_catchain_started);
}
cb(td::actor::ActorId<ValidatorSessionImpl> id) : id_(id) {
}
private:
td::actor::ActorId<ValidatorSessionImpl> id_;
};
return std::make_unique<cb>(actor_id(this));
}
auto &description() {
return *description_.get();
}
td::uint32 local_idx() {
return description_->get_self_idx();
}
ton::PublicKeyHash local_id() {
return description_->get_source_id(description_->get_self_idx());
}
void request_new_block(bool now);
void get_broadcast_p2p(PublicKeyHash node, ValidatorSessionFileHash file_hash,
ValidatorSessionCollatedDataFileHash collated_data_file_hash, PublicKeyHash src,
td::uint32 round, ValidatorSessionRootHash root_hash, td::Promise<td::BufferSlice> promise,
td::Timestamp timeout);
bool started_ = false;
bool catchain_started_ = false;
public:
ValidatorSessionImpl(catchain::CatChainSessionId session_id, ValidatorSessionOptions opts, PublicKeyHash local_id,
std::vector<ValidatorSessionNode> nodes, std::unique_ptr<Callback> callback,
td::actor::ActorId<keyring::Keyring> keyring, td::actor::ActorId<adnl::Adnl> adnl,
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<overlay::Overlays> overlays,
std::string db_root);
void start_up() override;
void alarm() override;
void start() override;
void destroy() override;
void process_blocks(std::vector<catchain::CatChainBlock *> blocks);
void finished_processing();
void preprocess_block(catchain::CatChainBlock *block);
void process_broadcast(PublicKeyHash src, td::BufferSlice data);
void process_message(PublicKeyHash src, td::BufferSlice data);
void process_query(PublicKeyHash src, td::BufferSlice data, td::Promise<td::BufferSlice> promise);
void try_approve_block(const SentBlock *block);
void try_sign();
void candidate_decision_fail(td::uint32 round, ValidatorSessionCandidateId hash, std::string result,
td::BufferSlice proof);
void candidate_decision_ok(td::uint32 round, ValidatorSessionCandidateId hash, RootHash root_hash, FileHash file_hash,
td::uint32 ok_from);
void candidate_approved_signed(td::uint32 round, ValidatorSessionCandidateId hash, td::uint32 ok_from,
td::BufferSlice signature);
void generated_block(td::uint32 round, ValidatorSessionRootHash root_hash, td::BufferSlice data,
td::BufferSlice collated);
void signed_block(td::uint32 round, ValidatorSessionCandidateId hash, td::BufferSlice signature);
void end_request(td::uint32 round, ValidatorSessionCandidateId block_id) {
if (cur_round_ == round) {
active_requests_.erase(block_id);
}
}
PrintId print_id() const override {
return PrintId{unique_hash_, description_->get_source_id(description_->get_self_idx())};
}
};
} // namespace validatorsession
} // namespace ton
namespace td {
inline td::StringBuilder &operator<<(td::StringBuilder &sb,
const ton::validatorsession::ValidatorSessionImpl *session) {
sb << session->print_id();
return sb;
}
} // namespace td