Ton

Форк
0
/
manager-hardfork.cpp 
571 строка · 23.6 Кб
1
/*
2
    This file is part of TON Blockchain Library.
3

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.
8

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.
13

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/>.
16

17
    Copyright 2017-2020 Telegram Systems LLP
18
*/
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"
26
#include "fabric.h"
27
#include "manager.h"
28
#include "ton/ton-io.hpp"
29
#include "td/utils/overloaded.h"
30
#include "td/utils/filesystem.h"
31

32
namespace ton {
33

34
namespace validator {
35

36
void ValidatorManagerImpl::sync_complete(td::Promise<td::Unit> promise) {
37
  started_ = true;
38

39
  //ShardIdFull shard_id{masterchainId, shardIdAll};
40
  auto shard_id = shard_to_generate_;
41

42
  auto block_id = block_to_generate_;
43

44
  std::vector<BlockIdExt> prev{block_id};
45

46
  auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<BlockCandidate> R) {
47
    if (R.is_ok()) {
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));
51
    } else {
52
      LOG(ERROR) << "failed to create block: " << R.move_as_error();
53
      std::exit(2);
54
    }
55
  });
56

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));
59
}
60

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;
65
  std::_Exit(0);
66
}
67

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 {
70
    if (R.is_error()) {
71
      promise.set_error(R.move_as_error());
72
    } else {
73
      auto B = R.move_as_ok();
74
      promise.set_value(B->data());
75
    }
76
  });
77

78
  get_block_data_from_db(handle, std::move(P));
79
}
80

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 {
83
    if (R.is_error()) {
84
      promise.set_error(R.move_as_error());
85
    } else {
86
      auto B = R.move_as_ok();
87
      promise.set_value(B->data());
88
    }
89
  });
90

91
  td::actor::send_closure(db_, &Db::get_block_proof, handle, std::move(P));
92
}
93

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 {
97
        if (R.is_error()) {
98
          auto P = td::PromiseCreator::lambda([promise = std::move(promise)](td::Result<td::Ref<Proof>> R) mutable {
99
            if (R.is_error()) {
100
              promise.set_error(R.move_as_error());
101
            } else {
102
              auto B = R.move_as_ok()->export_as_proof_link().move_as_ok();
103
              promise.set_value(B->data());
104
            }
105
          });
106

107
          td::actor::send_closure(db, &Db::get_block_proof, handle, std::move(P));
108
        } else {
109
          auto B = R.move_as_ok();
110
          promise.set_value(B->data());
111
        }
112
      });
113

114
  td::actor::send_closure(db_, &Db::get_block_proof_link, handle, std::move(P));
115
}
116

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 {
119
    if (R.is_error()) {
120
      promise.set_error(R.move_as_error());
121
    } else {
122
      auto B = R.move_as_ok();
123
      promise.set_value(B->data());
124
    }
125
  });
126

127
  td::actor::send_closure(db_, &Db::get_key_block_proof, block_id, std::move(P));
128
}
129

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 {
133
        if (R.is_error()) {
134
          auto P = td::PromiseCreator::lambda([promise = std::move(promise)](td::Result<td::Ref<Proof>> R) mutable {
135
            if (R.is_error()) {
136
              promise.set_error(R.move_as_error());
137
            } else {
138
              auto B = R.move_as_ok()->export_as_proof_link().move_as_ok();
139
              promise.set_value(B->data());
140
            }
141
          });
142

143
          td::actor::send_closure(db, &Db::get_key_block_proof, block_id, std::move(P));
144
        } else {
145
          auto B = R.move_as_ok();
146
          promise.set_value(B->data());
147
        }
148
      });
149

150
  td::actor::send_closure(db_, &Db::get_key_block_proof_link, block_id, std::move(P));
151
}
152

153
void ValidatorManagerImpl::new_external_message(td::BufferSlice data, int priority) {
154
  auto R = create_ext_message(std::move(data), block::SizeLimitsConfig::ExtMsgLimits());
155
  if (R.is_ok()) {
156
    ext_messages_.emplace_back(R.move_as_ok());
157
  }
158
}
159

160
void ValidatorManagerImpl::new_ihr_message(td::BufferSlice data) {
161
  auto R = create_ihr_message(std::move(data));
162
  if (R.is_ok()) {
163
    ihr_messages_.emplace_back(R.move_as_ok());
164
  }
165
}
166

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));
173
    });
174
    auto id = td::actor::create_actor<WaitBlockState>("waitstate", handle, 0, actor_id(this), td::Timestamp::in(10.0),
175
                                                      std::move(P))
176
                  .release();
177
    wait_state_[handle->id()].actor_ = id;
178
    it = wait_state_.find(handle->id());
179
  }
180

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);
184
}
185

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 {
190
        if (R.is_error()) {
191
          promise.set_error(R.move_as_error());
192
          return;
193
        }
194
        td::actor::send_closure(SelfId, &ValidatorManagerImpl::wait_block_state, R.move_as_ok(), 0, timeout,
195
                                std::move(promise));
196
      });
197
  get_block_handle(block_id, true, std::move(P));
198
}
199

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));
206
    });
207
    auto id = td::actor::create_actor<WaitBlockDataDisk>("waitdata", handle, actor_id(this), td::Timestamp::in(10.0),
208
                                                         std::move(P))
209
                  .release();
210
    wait_block_data_[handle->id()].actor_ = id;
211
    it = wait_block_data_.find(handle->id());
212
  }
213

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);
217
}
218

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 {
223
        if (R.is_error()) {
224
          promise.set_error(R.move_as_error());
225
          return;
226
        }
227
        td::actor::send_closure(SelfId, &ValidatorManagerImpl::wait_block_data, R.move_as_ok(), 0, timeout,
228
                                std::move(promise));
229
      });
230
  get_block_handle(block_id, true, std::move(P));
231
}
232

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,
236
                                               std::move(promise))
237
      .release();
238
}
239

240
void ValidatorManagerImpl::wait_prev_block_state(BlockHandle handle, td::uint32 priority, td::Timestamp timeout,
241
                                                 td::Promise<td::Ref<ShardState>> promise) {
242
  CHECK(handle);
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));
249
    } else {
250
      CHECK(shard_parent(shard) == prev_shard);
251
      bool left = shard_child(prev_shard, true) == shard;
252
      auto P =
253
          td::PromiseCreator::lambda([promise = std::move(promise), left](td::Result<td::Ref<ShardState>> R) mutable {
254
            if (R.is_error()) {
255
              promise.set_error(R.move_as_error());
256
            } else {
257
              auto s = R.move_as_ok();
258
              auto r = s->split();
259
              if (r.is_error()) {
260
                promise.set_error(r.move_as_error());
261
              } else {
262
                auto v = r.move_as_ok();
263
                promise.set_value(left ? std::move(v.first) : std::move(v.second));
264
              }
265
            }
266
          });
267
      wait_block_state_short(handle->one_prev(true), 0, timeout, std::move(P));
268
    }
269
  } else {
270
    wait_block_state_merge(handle->one_prev(true), handle->one_prev(false), 0, timeout, std::move(promise));
271
  }
272
}
273

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));
277
}
278

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 {
283
        if (R.is_error()) {
284
          promise.set_error(R.move_as_error());
285
          return;
286
        }
287
        td::actor::send_closure(SelfId, &ValidatorManagerImpl::wait_block_proof, R.move_as_ok(), timeout,
288
                                std::move(promise));
289
      });
290
  get_block_handle(block_id, true, std::move(P));
291
}
292

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));
296
}
297

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 {
302
        if (R.is_error()) {
303
          promise.set_error(R.move_as_error());
304
          return;
305
        }
306
        td::actor::send_closure(SelfId, &ValidatorManagerImpl::wait_block_proof_link, R.move_as_ok(), timeout,
307
                                std::move(promise));
308
      });
309
  get_block_handle(block_id, true, std::move(P));
310
}
311

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));
315
}
316

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 {
321
        if (R.is_error()) {
322
          promise.set_error(R.move_as_error());
323
          return;
324
        }
325
        td::actor::send_closure(SelfId, &ValidatorManagerImpl::wait_block_signatures, R.move_as_ok(), timeout,
326
                                std::move(promise));
327
      });
328
  get_block_handle(block_id, true, std::move(P));
329
}
330

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 {
334
    if (R.is_error()) {
335
      promise.set_error(R.move_as_error());
336
    } else {
337
      auto state = R.move_as_ok();
338
      promise.set_result(state->message_queue());
339
    }
340
  });
341

342
  wait_block_state(handle, 0, timeout, std::move(P));
343
}
344

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 {
350
        if (R.is_error()) {
351
          promise.set_error(R.move_as_error());
352
          return;
353
        }
354
        td::actor::send_closure(SelfId, &ValidatorManagerImpl::wait_block_message_queue, R.move_as_ok(), 0, timeout,
355
                                std::move(promise));
356
      });
357
  get_block_handle(block_id, true, std::move(P));
358
}
359

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);
365
  }
366
  promise.set_result(std::move(res));
367
}
368

369
void ValidatorManagerImpl::get_ihr_messages(ShardIdFull shard, td::Promise<std::vector<td::Ref<IhrMessage>>> promise) {
370
  promise.set_result(ihr_messages_);
371
}
372

373
void ValidatorManagerImpl::get_shard_blocks(BlockIdExt masterchain_block_id,
374
                                            td::Promise<std::vector<td::Ref<ShardTopBlockDescription>>> promise) {
375
}
376

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));
379
}
380

381
void ValidatorManagerImpl::get_block_data_from_db_short(BlockIdExt block_id, td::Promise<td::Ref<BlockData>> promise) {
382
  auto P =
383
      td::PromiseCreator::lambda([db = db_.get(), promise = std::move(promise)](td::Result<BlockHandle> R) mutable {
384
        if (R.is_error()) {
385
          promise.set_error(R.move_as_error());
386
        } else {
387
          auto handle = R.move_as_ok();
388
          td::actor::send_closure(db, &Db::get_block_data, std::move(handle), std::move(promise));
389
        }
390
      });
391
  get_block_handle(block_id, false, std::move(P));
392
}
393

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));
396
}
397

398
void ValidatorManagerImpl::get_shard_state_from_db_short(BlockIdExt block_id,
399
                                                         td::Promise<td::Ref<ShardState>> promise) {
400
  auto P =
401
      td::PromiseCreator::lambda([db = db_.get(), promise = std::move(promise)](td::Result<BlockHandle> R) mutable {
402
        if (R.is_error()) {
403
          promise.set_error(R.move_as_error());
404
        } else {
405
          auto handle = R.move_as_ok();
406
          td::actor::send_closure(db, &Db::get_block_state, std::move(handle), std::move(promise));
407
        }
408
      });
409
  get_block_handle(block_id, false, std::move(P));
410
}
411

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));
416
}
417

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));
420
}
421

422
void ValidatorManagerImpl::get_block_proof_from_db_short(BlockIdExt block_id, td::Promise<td::Ref<Proof>> promise) {
423
  auto P =
424
      td::PromiseCreator::lambda([db = db_.get(), promise = std::move(promise)](td::Result<BlockHandle> R) mutable {
425
        if (R.is_error()) {
426
          promise.set_error(R.move_as_error());
427
        } else {
428
          auto handle = R.move_as_ok();
429
          td::actor::send_closure(db, &Db::get_block_proof, std::move(handle), std::move(promise));
430
        }
431
      });
432
  get_block_handle(block_id, false, std::move(P));
433
}
434

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));
438
}
439

440
void ValidatorManagerImpl::get_block_proof_link_from_db_short(BlockIdExt block_id,
441
                                                              td::Promise<td::Ref<ProofLink>> promise) {
442
  auto P =
443
      td::PromiseCreator::lambda([db = db_.get(), promise = std::move(promise)](td::Result<BlockHandle> R) mutable {
444
        if (R.is_error()) {
445
          promise.set_error(R.move_as_error());
446
        } else {
447
          auto handle = R.move_as_ok();
448
          td::actor::send_closure(db, &Db::get_block_proof_link, std::move(handle), std::move(promise));
449
        }
450
      });
451
  get_block_handle(block_id, false, std::move(P));
452
}
453

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));
457
}
458

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));
462
}
463

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));
467
}
468

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()) {
472
    if (R.is_error()) {
473
      auto S = R.move_as_error();
474
      for (auto &X : it->second.waiting_) {
475
        X.second.set_error(S.clone());
476
      }
477
    } else {
478
      auto r = R.move_as_ok();
479
      for (auto &X : it->second.waiting_) {
480
        X.second.set_result(r);
481
      }
482
    }
483
    wait_state_.erase(it);
484
  }
485
}
486

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()) {
490
    if (R.is_error()) {
491
      auto S = R.move_as_error();
492
      for (auto &X : it->second.waiting_) {
493
        X.second.set_error(S.clone());
494
      }
495
    } else {
496
      auto r = R.move_as_ok();
497
      for (auto &X : it->second.waiting_) {
498
        X.second.set_result(r);
499
      }
500
    }
501
    wait_block_data_.erase(it);
502
  }
503
}
504

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();
509
    if (handle) {
510
      promise.set_value(std::move(handle));
511
      return;
512
    } else {
513
      handles_.erase(it);
514
    }
515
  }
516
  auto P = td::PromiseCreator::lambda(
517
      [id, force, promise = std::move(promise), SelfId = actor_id(this)](td::Result<BlockHandle> R) mutable {
518
        BlockHandle handle;
519
        if (R.is_error()) {
520
          auto S = R.move_as_error();
521
          if (S.code() == ErrorCode::notready && force) {
522
            handle = create_empty_block_handle(id);
523
          } else {
524
            promise.set_error(std::move(S));
525
            return;
526
          }
527
        } else {
528
          handle = R.move_as_ok();
529
        }
530
        td::actor::send_closure(SelfId, &ValidatorManagerImpl::register_block_handle, std::move(handle),
531
                                std::move(promise));
532
      });
533

534
  td::actor::send_closure(db_, &Db::get_block_handle, id, std::move(P));
535
}
536

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));
539
}
540

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();
545
    if (h) {
546
      promise.set_value(std::move(h));
547
      return;
548
    }
549
    handles_.erase(it);
550
  }
551
  handles_.emplace(handle->id(), std::weak_ptr<BlockHandleInterface>(handle));
552
  promise.set_value(std::move(handle));
553
}
554

555
void ValidatorManagerImpl::start_up() {
556
  db_ = create_db_actor(actor_id(this), db_root_, opts_);
557
}
558

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));
561
}
562

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,
566
                                                                  db_root);
567
}
568

569
}  // namespace validator
570

571
}  // namespace ton
572

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.