Ton

Форк
0
/
download-next-block.cpp 
170 строк · 6.3 Кб
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 "download-next-block.hpp"
20
#include "ton/ton-tl.hpp"
21
#include "adnl/utils.hpp"
22
#include "download-block.hpp"
23
#include "validator/full-node.h"
24

25
namespace ton {
26

27
namespace validator {
28

29
namespace fullnode {
30

31
DownloadNextBlock::DownloadNextBlock(adnl::AdnlNodeIdShort local_id, overlay::OverlayIdShort overlay_id,
32
                                     BlockHandle prev, adnl::AdnlNodeIdShort download_from, td::uint32 priority,
33
                                     td::Timestamp timeout,
34
                                     td::actor::ActorId<ValidatorManagerInterface> validator_manager,
35
                                     td::actor::ActorId<rldp::Rldp> rldp,
36
                                     td::actor::ActorId<overlay::Overlays> overlays,
37
                                     td::actor::ActorId<adnl::Adnl> adnl,
38
                                     td::actor::ActorId<adnl::AdnlExtClient> client, td::Promise<ReceivedBlock> promise)
39
    : local_id_(local_id)
40
    , overlay_id_(overlay_id)
41
    , prev_(prev)
42
    , download_from_(download_from)
43
    , priority_(priority)
44
    , timeout_(timeout)
45
    , validator_manager_(validator_manager)
46
    , rldp_(rldp)
47
    , overlays_(overlays)
48
    , adnl_(adnl)
49
    , client_(client)
50
    , promise_(std::move(promise)) {
51
}
52

53
void DownloadNextBlock::abort_query(td::Status reason) {
54
  if (promise_) {
55
    if (reason.code() == ErrorCode::notready || reason.code() == ErrorCode::timeout) {
56
      VLOG(FULL_NODE_DEBUG) << "failed to download next block after " << prev_->id() << " from " << download_from_
57
                            << ": " << reason;
58
    } else {
59
      VLOG(FULL_NODE_INFO) << "failed to download next block after " << prev_->id() << " from " << download_from_
60
                           << ": " << reason;
61
    }
62
    promise_.set_error(std::move(reason));
63
  }
64
  stop();
65
}
66

67
void DownloadNextBlock::alarm() {
68
  abort_query(td::Status::Error(ErrorCode::timeout, "timeout"));
69
}
70

71
void DownloadNextBlock::start_up() {
72
  alarm_timestamp() = timeout_;
73

74
  if (prev_->inited_next_left()) {
75
    auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<BlockHandle> R) {
76
      R.ensure();
77
      td::actor::send_closure(SelfId, &DownloadNextBlock::got_next_node_handle, R.move_as_ok());
78
    });
79
    td::actor::send_closure(validator_manager_, &ValidatorManagerInterface::get_block_handle, prev_->one_next(true),
80
                            false, std::move(P));
81
    return;
82
  }
83
  if (!client_.empty()) {
84
    got_node(download_from_);
85
    return;
86
  }
87

88
  if (download_from_.is_zero()) {
89
    auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<std::vector<adnl::AdnlNodeIdShort>> R) {
90
      if (R.is_error()) {
91
        td::actor::send_closure(SelfId, &DownloadNextBlock::abort_query, R.move_as_error());
92
      } else {
93
        auto vec = R.move_as_ok();
94
        if (vec.size() == 0) {
95
          td::actor::send_closure(SelfId, &DownloadNextBlock::abort_query,
96
                                  td::Status::Error(ErrorCode::notready, "no neighbours found"));
97
        } else {
98
          td::actor::send_closure(SelfId, &DownloadNextBlock::got_node, vec[0]);
99
        }
100
      }
101
    });
102

103
    td::actor::send_closure(overlays_, &overlay::Overlays::get_overlay_random_peers, local_id_, overlay_id_, 1,
104
                            std::move(P));
105
  } else {
106
    got_node(download_from_);
107
  }
108
}
109

110
void DownloadNextBlock::got_node(adnl::AdnlNodeIdShort id) {
111
  download_from_ = id;
112

113
  auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::BufferSlice> R) {
114
    if (R.is_error()) {
115
      td::actor::send_closure(SelfId, &DownloadNextBlock::abort_query, R.move_as_error());
116
    } else {
117
      td::actor::send_closure(SelfId, &DownloadNextBlock::got_next_node, R.move_as_ok());
118
    }
119
  });
120

121
  auto query = create_serialize_tl_object<ton_api::tonNode_getNextBlockDescription>(create_tl_block_id(prev_->id()));
122
  if (client_.empty()) {
123
    td::actor::send_closure(overlays_, &overlay::Overlays::send_query, download_from_, local_id_, overlay_id_,
124
                            "get_prepare", std::move(P), td::Timestamp::in(1.0), std::move(query));
125
  } else {
126
    td::actor::send_closure(client_, &adnl::AdnlExtClient::send_query, "get_prepare",
127
                            create_serialize_tl_object_suffix<ton_api::tonNode_query>(std::move(query)),
128
                            td::Timestamp::in(1.0), std::move(P));
129
  }
130
}
131

132
void DownloadNextBlock::got_next_node(td::BufferSlice data) {
133
  auto F = fetch_tl_object<ton_api::tonNode_BlockDescription>(std::move(data), true);
134
  if (F.is_error()) {
135
    abort_query(F.move_as_error());
136
    return;
137
  }
138
  auto f = F.move_as_ok();
139
  if (f->get_id() == ton_api::tonNode_blockDescriptionEmpty::ID) {
140
    abort_query(td::Status::Error(ErrorCode::notready, "not found"));
141
    return;
142
  }
143
  auto g = move_tl_object_as<ton_api::tonNode_blockDescription>(std::move(f));
144

145
  next_block_id_ = create_block_id(g->id_);
146
  finish_query();
147
}
148

149
void DownloadNextBlock::got_next_node_handle(BlockHandle handle) {
150
  //CHECK(handle->inited_proof());
151
  //CHECK(handle->inited_masterchain());
152
  next_block_id_ = handle->id();
153
  finish_query();
154
}
155

156
void DownloadNextBlock::finish_query() {
157
  if (promise_) {
158
    td::actor::create_actor<DownloadBlock>("downloadnext", next_block_id_, local_id_, overlay_id_, prev_,
159
                                           download_from_, priority_, timeout_, validator_manager_, rldp_, overlays_,
160
                                           adnl_, client_, std::move(promise_))
161
        .release();
162
  }
163
  stop();
164
}
165

166
}  // namespace fullnode
167

168
}  // namespace validator
169

170
}  // namespace ton
171

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

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

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

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