2
This file is part of TON Blockchain Library.
4
TON Blockchain Library is free software: you can redistribute it and/or modify
5
it under the terms of the GNU Lesser General Public License as published by
6
the Free Software Foundation, either version 2 of the License, or
7
(at your option) any later version.
9
TON Blockchain Library is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
GNU Lesser General Public License for more details.
14
You should have received a copy of the GNU Lesser General Public License
15
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
17
Copyright 2017-2020 Telegram Systems LLP
19
#include "manager-hardfork.hpp"
20
#include "validator-group.hpp"
21
#include "adnl/utils.hpp"
22
#include "downloaders/wait-block-state.hpp"
23
#include "downloaders/wait-block-state-merge.hpp"
24
#include "downloaders/wait-block-data-disk.hpp"
25
#include "validator-group.hpp"
28
#include "ton/ton-io.hpp"
29
#include "td/utils/overloaded.h"
30
#include "td/utils/filesystem.h"
36
void ValidatorManagerImpl::sync_complete(td::Promise<td::Unit> promise) {
39
//ShardIdFull shard_id{masterchainId, shardIdAll};
40
auto shard_id = shard_to_generate_;
42
auto block_id = block_to_generate_;
44
std::vector<BlockIdExt> prev{block_id};
46
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<BlockCandidate> R) {
48
auto v = R.move_as_ok();
49
LOG(ERROR) << "created block " << v.id;
50
td::actor::send_closure(SelfId, &ValidatorManagerImpl::created_candidate, std::move(v));
52
LOG(ERROR) << "failed to create block: " << R.move_as_error();
57
LOG(ERROR) << "running collate query";
58
run_collate_hardfork(shard_id, block_id, prev, actor_id(this), td::Timestamp::in(10.0), std::move(P));
61
void ValidatorManagerImpl::created_candidate(BlockCandidate candidate) {
62
td::write_file(db_root_ + "/static/" + candidate.id.file_hash.to_hex(), candidate.data.as_slice()).ensure();
63
LOG(ERROR) << "success, block " << candidate.id << " = " << candidate.id.to_str() << " saved to disk";
64
std::cout << candidate.id.to_str() << std::endl << std::flush;
68
void ValidatorManagerImpl::get_block_data(BlockHandle handle, td::Promise<td::BufferSlice> promise) {
69
auto P = td::PromiseCreator::lambda([promise = std::move(promise)](td::Result<td::Ref<BlockData>> R) mutable {
71
promise.set_error(R.move_as_error());
73
auto B = R.move_as_ok();
74
promise.set_value(B->data());
78
get_block_data_from_db(handle, std::move(P));
81
void ValidatorManagerImpl::get_block_proof(BlockHandle handle, td::Promise<td::BufferSlice> promise) {
82
auto P = td::PromiseCreator::lambda([promise = std::move(promise)](td::Result<td::Ref<Proof>> R) mutable {
84
promise.set_error(R.move_as_error());
86
auto B = R.move_as_ok();
87
promise.set_value(B->data());
91
td::actor::send_closure(db_, &Db::get_block_proof, handle, std::move(P));
94
void ValidatorManagerImpl::get_block_proof_link(BlockHandle handle, td::Promise<td::BufferSlice> promise) {
95
auto P = td::PromiseCreator::lambda(
96
[promise = std::move(promise), handle, db = db_.get()](td::Result<td::Ref<ProofLink>> R) mutable {
98
auto P = td::PromiseCreator::lambda([promise = std::move(promise)](td::Result<td::Ref<Proof>> R) mutable {
100
promise.set_error(R.move_as_error());
102
auto B = R.move_as_ok()->export_as_proof_link().move_as_ok();
103
promise.set_value(B->data());
107
td::actor::send_closure(db, &Db::get_block_proof, handle, std::move(P));
109
auto B = R.move_as_ok();
110
promise.set_value(B->data());
114
td::actor::send_closure(db_, &Db::get_block_proof_link, handle, std::move(P));
117
void ValidatorManagerImpl::get_key_block_proof(BlockIdExt block_id, td::Promise<td::BufferSlice> promise) {
118
auto P = td::PromiseCreator::lambda([promise = std::move(promise)](td::Result<td::Ref<Proof>> R) mutable {
120
promise.set_error(R.move_as_error());
122
auto B = R.move_as_ok();
123
promise.set_value(B->data());
127
td::actor::send_closure(db_, &Db::get_key_block_proof, block_id, std::move(P));
130
void ValidatorManagerImpl::get_key_block_proof_link(BlockIdExt block_id, td::Promise<td::BufferSlice> promise) {
131
auto P = td::PromiseCreator::lambda(
132
[promise = std::move(promise), block_id, db = db_.get()](td::Result<td::Ref<ProofLink>> R) mutable {
134
auto P = td::PromiseCreator::lambda([promise = std::move(promise)](td::Result<td::Ref<Proof>> R) mutable {
136
promise.set_error(R.move_as_error());
138
auto B = R.move_as_ok()->export_as_proof_link().move_as_ok();
139
promise.set_value(B->data());
143
td::actor::send_closure(db, &Db::get_key_block_proof, block_id, std::move(P));
145
auto B = R.move_as_ok();
146
promise.set_value(B->data());
150
td::actor::send_closure(db_, &Db::get_key_block_proof_link, block_id, std::move(P));
153
void ValidatorManagerImpl::new_external_message(td::BufferSlice data, int priority) {
154
auto R = create_ext_message(std::move(data), block::SizeLimitsConfig::ExtMsgLimits());
156
ext_messages_.emplace_back(R.move_as_ok());
160
void ValidatorManagerImpl::new_ihr_message(td::BufferSlice data) {
161
auto R = create_ihr_message(std::move(data));
163
ihr_messages_.emplace_back(R.move_as_ok());
167
void ValidatorManagerImpl::wait_block_state(BlockHandle handle, td::uint32 priority, td::Timestamp timeout,
168
td::Promise<td::Ref<ShardState>> promise) {
169
auto it = wait_state_.find(handle->id());
170
if (it == wait_state_.end()) {
171
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this), handle](td::Result<td::Ref<ShardState>> R) {
172
td::actor::send_closure(SelfId, &ValidatorManagerImpl::finished_wait_state, handle->id(), std::move(R));
174
auto id = td::actor::create_actor<WaitBlockState>("waitstate", handle, 0, actor_id(this), td::Timestamp::in(10.0),
177
wait_state_[handle->id()].actor_ = id;
178
it = wait_state_.find(handle->id());
181
it->second.waiting_.emplace_back(
182
std::pair<td::Timestamp, td::Promise<td::Ref<ShardState>>>(timeout, std::move(promise)));
183
td::actor::send_closure(it->second.actor_, &WaitBlockState::update_timeout, timeout, 0);
186
void ValidatorManagerImpl::wait_block_state_short(BlockIdExt block_id, td::uint32 priority, td::Timestamp timeout,
187
td::Promise<td::Ref<ShardState>> promise) {
188
auto P = td::PromiseCreator::lambda(
189
[SelfId = actor_id(this), timeout, promise = std::move(promise)](td::Result<BlockHandle> R) mutable {
191
promise.set_error(R.move_as_error());
194
td::actor::send_closure(SelfId, &ValidatorManagerImpl::wait_block_state, R.move_as_ok(), 0, timeout,
197
get_block_handle(block_id, true, std::move(P));
200
void ValidatorManagerImpl::wait_block_data(BlockHandle handle, td::uint32 priority, td::Timestamp timeout,
201
td::Promise<td::Ref<BlockData>> promise) {
202
auto it = wait_block_data_.find(handle->id());
203
if (it == wait_block_data_.end()) {
204
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this), handle](td::Result<td::Ref<BlockData>> R) {
205
td::actor::send_closure(SelfId, &ValidatorManagerImpl::finished_wait_data, handle->id(), std::move(R));
207
auto id = td::actor::create_actor<WaitBlockDataDisk>("waitdata", handle, actor_id(this), td::Timestamp::in(10.0),
210
wait_block_data_[handle->id()].actor_ = id;
211
it = wait_block_data_.find(handle->id());
214
it->second.waiting_.emplace_back(
215
std::pair<td::Timestamp, td::Promise<td::Ref<BlockData>>>(timeout, std::move(promise)));
216
td::actor::send_closure(it->second.actor_, &WaitBlockDataDisk::update_timeout, timeout);
219
void ValidatorManagerImpl::wait_block_data_short(BlockIdExt block_id, td::uint32 priority, td::Timestamp timeout,
220
td::Promise<td::Ref<BlockData>> promise) {
221
auto P = td::PromiseCreator::lambda(
222
[SelfId = actor_id(this), timeout, promise = std::move(promise)](td::Result<BlockHandle> R) mutable {
224
promise.set_error(R.move_as_error());
227
td::actor::send_closure(SelfId, &ValidatorManagerImpl::wait_block_data, R.move_as_ok(), 0, timeout,
230
get_block_handle(block_id, true, std::move(P));
233
void ValidatorManagerImpl::wait_block_state_merge(BlockIdExt left_id, BlockIdExt right_id, td::uint32 priority,
234
td::Timestamp timeout, td::Promise<td::Ref<ShardState>> promise) {
235
td::actor::create_actor<WaitBlockStateMerge>("merge", left_id, right_id, 0, actor_id(this), timeout,
240
void ValidatorManagerImpl::wait_prev_block_state(BlockHandle handle, td::uint32 priority, td::Timestamp timeout,
241
td::Promise<td::Ref<ShardState>> promise) {
243
CHECK(!handle->is_zero());
244
if (!handle->merge_before()) {
245
auto shard = handle->id().shard_full();
246
auto prev_shard = handle->one_prev(true).shard_full();
247
if (shard == prev_shard) {
248
wait_block_state_short(handle->one_prev(true), 0, timeout, std::move(promise));
250
CHECK(shard_parent(shard) == prev_shard);
251
bool left = shard_child(prev_shard, true) == shard;
253
td::PromiseCreator::lambda([promise = std::move(promise), left](td::Result<td::Ref<ShardState>> R) mutable {
255
promise.set_error(R.move_as_error());
257
auto s = R.move_as_ok();
260
promise.set_error(r.move_as_error());
262
auto v = r.move_as_ok();
263
promise.set_value(left ? std::move(v.first) : std::move(v.second));
267
wait_block_state_short(handle->one_prev(true), 0, timeout, std::move(P));
270
wait_block_state_merge(handle->one_prev(true), handle->one_prev(false), 0, timeout, std::move(promise));
274
void ValidatorManagerImpl::wait_block_proof(BlockHandle handle, td::Timestamp timeout,
275
td::Promise<td::Ref<Proof>> promise) {
276
td::actor::send_closure(db_, &Db::get_block_proof, handle, std::move(promise));
279
void ValidatorManagerImpl::wait_block_proof_short(BlockIdExt block_id, td::Timestamp timeout,
280
td::Promise<td::Ref<Proof>> promise) {
281
auto P = td::PromiseCreator::lambda(
282
[SelfId = actor_id(this), timeout, promise = std::move(promise)](td::Result<BlockHandle> R) mutable {
284
promise.set_error(R.move_as_error());
287
td::actor::send_closure(SelfId, &ValidatorManagerImpl::wait_block_proof, R.move_as_ok(), timeout,
290
get_block_handle(block_id, true, std::move(P));
293
void ValidatorManagerImpl::wait_block_proof_link(BlockHandle handle, td::Timestamp timeout,
294
td::Promise<td::Ref<ProofLink>> promise) {
295
td::actor::send_closure(db_, &Db::get_block_proof_link, std::move(handle), std::move(promise));
298
void ValidatorManagerImpl::wait_block_proof_link_short(BlockIdExt block_id, td::Timestamp timeout,
299
td::Promise<td::Ref<ProofLink>> promise) {
300
auto P = td::PromiseCreator::lambda(
301
[SelfId = actor_id(this), timeout, promise = std::move(promise)](td::Result<BlockHandle> R) mutable {
303
promise.set_error(R.move_as_error());
306
td::actor::send_closure(SelfId, &ValidatorManagerImpl::wait_block_proof_link, R.move_as_ok(), timeout,
309
get_block_handle(block_id, true, std::move(P));
312
void ValidatorManagerImpl::wait_block_signatures(BlockHandle handle, td::Timestamp timeout,
313
td::Promise<td::Ref<BlockSignatureSet>> promise) {
314
td::actor::send_closure(db_, &Db::get_block_signatures, handle, std::move(promise));
317
void ValidatorManagerImpl::wait_block_signatures_short(BlockIdExt block_id, td::Timestamp timeout,
318
td::Promise<td::Ref<BlockSignatureSet>> promise) {
319
auto P = td::PromiseCreator::lambda(
320
[SelfId = actor_id(this), timeout, promise = std::move(promise)](td::Result<BlockHandle> R) mutable {
322
promise.set_error(R.move_as_error());
325
td::actor::send_closure(SelfId, &ValidatorManagerImpl::wait_block_signatures, R.move_as_ok(), timeout,
328
get_block_handle(block_id, true, std::move(P));
331
void ValidatorManagerImpl::wait_block_message_queue(BlockHandle handle, td::uint32 priority, td::Timestamp timeout,
332
td::Promise<td::Ref<MessageQueue>> promise) {
333
auto P = td::PromiseCreator::lambda([promise = std::move(promise)](td::Result<td::Ref<ShardState>> R) mutable {
335
promise.set_error(R.move_as_error());
337
auto state = R.move_as_ok();
338
promise.set_result(state->message_queue());
342
wait_block_state(handle, 0, timeout, std::move(P));
345
void ValidatorManagerImpl::wait_block_message_queue_short(BlockIdExt block_id, td::uint32 priority,
346
td::Timestamp timeout,
347
td::Promise<td::Ref<MessageQueue>> promise) {
348
auto P = td::PromiseCreator::lambda(
349
[SelfId = actor_id(this), timeout, promise = std::move(promise)](td::Result<BlockHandle> R) mutable {
351
promise.set_error(R.move_as_error());
354
td::actor::send_closure(SelfId, &ValidatorManagerImpl::wait_block_message_queue, R.move_as_ok(), 0, timeout,
357
get_block_handle(block_id, true, std::move(P));
360
void ValidatorManagerImpl::get_external_messages(
361
ShardIdFull shard, td::Promise<std::vector<std::pair<td::Ref<ExtMessage>, int>>> promise) {
362
std::vector<std::pair<td::Ref<ExtMessage>, int>> res;
363
for (const auto &x : ext_messages_) {
364
res.emplace_back(x, 0);
366
promise.set_result(std::move(res));
369
void ValidatorManagerImpl::get_ihr_messages(ShardIdFull shard, td::Promise<std::vector<td::Ref<IhrMessage>>> promise) {
370
promise.set_result(ihr_messages_);
373
void ValidatorManagerImpl::get_shard_blocks(BlockIdExt masterchain_block_id,
374
td::Promise<std::vector<td::Ref<ShardTopBlockDescription>>> promise) {
377
void ValidatorManagerImpl::get_block_data_from_db(ConstBlockHandle handle, td::Promise<td::Ref<BlockData>> promise) {
378
td::actor::send_closure(db_, &Db::get_block_data, handle, std::move(promise));
381
void ValidatorManagerImpl::get_block_data_from_db_short(BlockIdExt block_id, td::Promise<td::Ref<BlockData>> promise) {
383
td::PromiseCreator::lambda([db = db_.get(), promise = std::move(promise)](td::Result<BlockHandle> R) mutable {
385
promise.set_error(R.move_as_error());
387
auto handle = R.move_as_ok();
388
td::actor::send_closure(db, &Db::get_block_data, std::move(handle), std::move(promise));
391
get_block_handle(block_id, false, std::move(P));
394
void ValidatorManagerImpl::get_shard_state_from_db(ConstBlockHandle handle, td::Promise<td::Ref<ShardState>> promise) {
395
td::actor::send_closure(db_, &Db::get_block_state, handle, std::move(promise));
398
void ValidatorManagerImpl::get_shard_state_from_db_short(BlockIdExt block_id,
399
td::Promise<td::Ref<ShardState>> promise) {
401
td::PromiseCreator::lambda([db = db_.get(), promise = std::move(promise)](td::Result<BlockHandle> R) mutable {
403
promise.set_error(R.move_as_error());
405
auto handle = R.move_as_ok();
406
td::actor::send_closure(db, &Db::get_block_state, std::move(handle), std::move(promise));
409
get_block_handle(block_id, false, std::move(P));
412
void ValidatorManagerImpl::get_block_candidate_from_db(PublicKey source, BlockIdExt id,
413
FileHash collated_data_file_hash,
414
td::Promise<BlockCandidate> promise) {
415
td::actor::send_closure(db_, &Db::get_block_candidate, source, id, collated_data_file_hash, std::move(promise));
418
void ValidatorManagerImpl::get_block_proof_from_db(ConstBlockHandle handle, td::Promise<td::Ref<Proof>> promise) {
419
td::actor::send_closure(db_, &Db::get_block_proof, std::move(handle), std::move(promise));
422
void ValidatorManagerImpl::get_block_proof_from_db_short(BlockIdExt block_id, td::Promise<td::Ref<Proof>> promise) {
424
td::PromiseCreator::lambda([db = db_.get(), promise = std::move(promise)](td::Result<BlockHandle> R) mutable {
426
promise.set_error(R.move_as_error());
428
auto handle = R.move_as_ok();
429
td::actor::send_closure(db, &Db::get_block_proof, std::move(handle), std::move(promise));
432
get_block_handle(block_id, false, std::move(P));
435
void ValidatorManagerImpl::get_block_proof_link_from_db(ConstBlockHandle handle,
436
td::Promise<td::Ref<ProofLink>> promise) {
437
td::actor::send_closure(db_, &Db::get_block_proof_link, std::move(handle), std::move(promise));
440
void ValidatorManagerImpl::get_block_proof_link_from_db_short(BlockIdExt block_id,
441
td::Promise<td::Ref<ProofLink>> promise) {
443
td::PromiseCreator::lambda([db = db_.get(), promise = std::move(promise)](td::Result<BlockHandle> R) mutable {
445
promise.set_error(R.move_as_error());
447
auto handle = R.move_as_ok();
448
td::actor::send_closure(db, &Db::get_block_proof_link, std::move(handle), std::move(promise));
451
get_block_handle(block_id, false, std::move(P));
454
void ValidatorManagerImpl::get_block_by_lt_from_db(AccountIdPrefixFull account, LogicalTime lt,
455
td::Promise<ConstBlockHandle> promise) {
456
td::actor::send_closure(db_, &Db::get_block_by_lt, account, lt, std::move(promise));
459
void ValidatorManagerImpl::get_block_by_unix_time_from_db(AccountIdPrefixFull account, UnixTime ts,
460
td::Promise<ConstBlockHandle> promise) {
461
td::actor::send_closure(db_, &Db::get_block_by_unix_time, account, ts, std::move(promise));
464
void ValidatorManagerImpl::get_block_by_seqno_from_db(AccountIdPrefixFull account, BlockSeqno seqno,
465
td::Promise<ConstBlockHandle> promise) {
466
td::actor::send_closure(db_, &Db::get_block_by_seqno, account, seqno, std::move(promise));
469
void ValidatorManagerImpl::finished_wait_state(BlockIdExt block_id, td::Result<td::Ref<ShardState>> R) {
470
auto it = wait_state_.find(block_id);
471
if (it != wait_state_.end()) {
473
auto S = R.move_as_error();
474
for (auto &X : it->second.waiting_) {
475
X.second.set_error(S.clone());
478
auto r = R.move_as_ok();
479
for (auto &X : it->second.waiting_) {
480
X.second.set_result(r);
483
wait_state_.erase(it);
487
void ValidatorManagerImpl::finished_wait_data(BlockIdExt block_id, td::Result<td::Ref<BlockData>> R) {
488
auto it = wait_block_data_.find(block_id);
489
if (it != wait_block_data_.end()) {
491
auto S = R.move_as_error();
492
for (auto &X : it->second.waiting_) {
493
X.second.set_error(S.clone());
496
auto r = R.move_as_ok();
497
for (auto &X : it->second.waiting_) {
498
X.second.set_result(r);
501
wait_block_data_.erase(it);
505
void ValidatorManagerImpl::get_block_handle(BlockIdExt id, bool force, td::Promise<BlockHandle> promise) {
506
auto it = handles_.find(id);
507
if (it != handles_.end()) {
508
auto handle = it->second.lock();
510
promise.set_value(std::move(handle));
516
auto P = td::PromiseCreator::lambda(
517
[id, force, promise = std::move(promise), SelfId = actor_id(this)](td::Result<BlockHandle> R) mutable {
520
auto S = R.move_as_error();
521
if (S.code() == ErrorCode::notready && force) {
522
handle = create_empty_block_handle(id);
524
promise.set_error(std::move(S));
528
handle = R.move_as_ok();
530
td::actor::send_closure(SelfId, &ValidatorManagerImpl::register_block_handle, std::move(handle),
534
td::actor::send_closure(db_, &Db::get_block_handle, id, std::move(P));
537
void ValidatorManagerImpl::get_cell_db_reader(td::Promise<std::shared_ptr<vm::CellDbReader>> promise) {
538
td::actor::send_closure(db_, &Db::get_cell_db_reader, std::move(promise));
541
void ValidatorManagerImpl::register_block_handle(BlockHandle handle, td::Promise<BlockHandle> promise) {
542
auto it = handles_.find(handle->id());
543
if (it != handles_.end()) {
544
auto h = it->second.lock();
546
promise.set_value(std::move(h));
551
handles_.emplace(handle->id(), std::weak_ptr<BlockHandleInterface>(handle));
552
promise.set_value(std::move(handle));
555
void ValidatorManagerImpl::start_up() {
556
db_ = create_db_actor(actor_id(this), db_root_, opts_);
559
void ValidatorManagerImpl::try_get_static_file(FileHash file_hash, td::Promise<td::BufferSlice> promise) {
560
td::actor::send_closure(db_, &Db::try_get_static_file, file_hash, std::move(promise));
563
td::actor::ActorOwn<ValidatorManagerInterface> ValidatorManagerHardforkFactory::create(
564
td::Ref<ValidatorManagerOptions> opts, ShardIdFull shard, BlockIdExt shard_top_block_id, std::string db_root) {
565
return td::actor::create_actor<validator::ValidatorManagerImpl>("manager", std::move(opts), shard_top_block_id,
569
} // namespace validator